iommu/tegra-smmu: Move flush_dcache to tegra-smmu.c

Drivers should not be using __cpuc_* functions nor outer_cache_flush()
directly.  This change partly cleans up tegra-smmu.c.

The only difference between cache handling of the tegra variants is
Denver, which omits the call to outer_cache_flush().  This is due to
Denver being an ARM64 CPU, and the ARM64 architecture does not provide
this function.  (This, in itself, is a good reason why these should not
be used.)

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
[treding@nvidia.com: fix build failure on 64-bit ARM]
Signed-off-by: Thierry Reding <treding@nvidia.com>
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index d649b06..42b13c0 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -16,6 +16,8 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 
+#include <asm/cacheflush.h>
+
 #include <soc/tegra/ahb.h>
 #include <soc/tegra/mc.h>
 
@@ -145,6 +147,24 @@
 	return (iova >> SMMU_PTE_SHIFT) & (SMMU_NUM_PTE - 1);
 }
 
+static void smmu_flush_dcache(struct page *page, unsigned long offset,
+			      size_t size)
+{
+#ifdef CONFIG_ARM
+	phys_addr_t phys = page_to_phys(page) + offset;
+#endif
+	void *virt = page_address(page) + offset;
+
+#ifdef CONFIG_ARM
+	__cpuc_flush_dcache_area(virt, size);
+	outer_flush_range(phys, phys + size);
+#endif
+
+#ifdef CONFIG_ARM64
+	__flush_dcache_area(virt, size);
+#endif
+}
+
 static inline void smmu_flush_ptc(struct tegra_smmu *smmu, struct page *page,
 				  unsigned long offset)
 {
@@ -392,7 +412,7 @@
 	if (err < 0)
 		return err;
 
-	smmu->soc->ops->flush_dcache(as->pd, 0, SMMU_SIZE_PD);
+	smmu_flush_dcache(as->pd, 0, SMMU_SIZE_PD);
 	smmu_flush_ptc(smmu, as->pd, 0);
 	smmu_flush_tlb_asid(smmu, as->id);
 
@@ -521,11 +541,11 @@
 
 		as->pts[pde] = page;
 
-		smmu->soc->ops->flush_dcache(page, 0, SMMU_SIZE_PT);
+		smmu_flush_dcache(page, 0, SMMU_SIZE_PT);
 
 		pd[pde] = SMMU_MK_PDE(page, SMMU_PDE_ATTR | SMMU_PDE_NEXT);
 
-		smmu->soc->ops->flush_dcache(as->pd, pde << 2, 4);
+		smmu_flush_dcache(as->pd, pde << 2, 4);
 		smmu_flush_ptc(smmu, as->pd, pde << 2);
 		smmu_flush_tlb_section(smmu, as->id, iova);
 		smmu_flush(smmu);
@@ -562,7 +582,7 @@
 		pd[pde] = 0;
 
 		/* Flush the page directory entry */
-		smmu->soc->ops->flush_dcache(as->pd, offset, sizeof(*pd));
+		smmu_flush_dcache(as->pd, offset, sizeof(*pd));
 		smmu_flush_ptc(smmu, as->pd, offset);
 		smmu_flush_tlb_section(smmu, as->id, iova);
 		smmu_flush(smmu);
@@ -582,7 +602,7 @@
 
 	*pte = val;
 
-	smmu->soc->ops->flush_dcache(pte_page, offset, 4);
+	smmu_flush_dcache(pte_page, offset, 4);
 	smmu_flush_ptc(smmu, pte_page, offset);
 	smmu_flush_tlb_group(smmu, as->id, iova);
 	smmu_flush(smmu);