summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/iommu/tegra-smmu.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 4ec354968df4..c44ad13be4f3 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -1125,7 +1125,6 @@ static int smmu_iommu_map_pages(struct iommu_domain *domain, unsigned long iova,
{
struct smmu_as *as = domain->priv;
struct smmu_device *smmu = as->smmu;
- unsigned long flags;
u32 *pdir = page_address(as->pdir_page);
int err = 0;
unsigned long iova_base = iova;
@@ -1137,8 +1136,6 @@ static int smmu_iommu_map_pages(struct iommu_domain *domain, unsigned long iova,
else if (dma_get_attr(DMA_ATTR_WRITE_ONLY, (struct dma_attrs *)prot))
attrs &= ~_READABLE;
- spin_lock_irqsave(&as->lock, flags);
-
while (total > 0) {
int pdn = SMMU_ADDR_TO_PDN(iova);
int ptn = SMMU_ADDR_TO_PTN(iova);
@@ -1148,11 +1145,15 @@ static int smmu_iommu_map_pages(struct iommu_domain *domain, unsigned long iova,
u32 *ptbl;
u32 *pte;
int i;
+ unsigned long flags;
+
+ spin_lock_irqsave(&as->lock, flags);
if (pdir[pdn] == _PDE_VACANT(pdn)) {
tbl_page = alloc_ptbl(as, iova, !flush_all);
if (!tbl_page) {
err = -ENOMEM;
+ spin_unlock_irqrestore(&as->lock, flags);
goto out;
}
@@ -1182,14 +1183,14 @@ skip:
iova += PAGE_SIZE * count;
total -= count;
pages += count;
+
+ spin_unlock_irqrestore(&as->lock, flags);
}
out:
if (flush_all)
flush_ptc_and_tlb_as(as, iova_base,
iova_base + total * PAGE_SIZE);
-
- spin_unlock_irqrestore(&as->lock, flags);
return err;
}