iommu/arm-smmu: Check the return type of map_sg and take appropriate action

We cannot call unmap directly if the map_sg fails partially as the tlb
invalidate functions need to enable/prepare clocks, which require
non-atomic context. Let map_sg return the failure and handle this when
we are out of the atomic context.

Change-Id: I6401c1e281850aeda27e32524cae34324045f762
Signed-off-by: Rohit Vaswani <rvaswani@codeaurora.org>
Signed-off-by: Patrick Daly <pdaly@codeaurora.org>
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 2d412c4..597923b 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1606,6 +1606,7 @@
 			   struct scatterlist *sg, unsigned int nents, int prot)
 {
 	int ret;
+	size_t size;
 	unsigned long flags;
 	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
 	struct io_pgtable_ops *ops = smmu_domain->pgtbl_ops;
@@ -1614,8 +1615,12 @@
 		return -ENODEV;
 
 	spin_lock_irqsave(&smmu_domain->pgtbl_lock, flags);
-	ret = ops->map_sg(ops, iova, sg, nents, prot);
+	ret = ops->map_sg(ops, iova, sg, nents, prot, &size);
 	spin_unlock_irqrestore(&smmu_domain->pgtbl_lock, flags);
+
+	if (!ret)
+		arm_smmu_unmap(domain, iova, size);
+
 	return ret;
 }