aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2014-07-30 06:33:25 -0400
committerWill Deacon <will.deacon@arm.com>2014-09-16 14:14:57 -0400
commitc757e8528a304214d0a9be2e99011b94bf374d37 (patch)
tree616522ae592a60aa42bc24fef57e445e3835fca6 /drivers/iommu
parent844e35bdfe834fccb5def1bc4cd614ca22409d0c (diff)
iommu/arm-smmu: use page shift instead of page size to avoid division
Arbitrary integer division is not available in all ARM CPUs, so the GCC may spit out calls to helper functions which are not implemented in the kernel. This patch avoids these problems in the SMMU driver by using page shift instead of page size, so that divisions by the page size (as required by the vSMMU code) can be expressed as a simple right shift. Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'drivers/iommu')
-rw-r--r--drivers/iommu/arm-smmu.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index e8d311152203..482cc9e3138a 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -59,7 +59,7 @@
59 59
60/* SMMU global address space */ 60/* SMMU global address space */
61#define ARM_SMMU_GR0(smmu) ((smmu)->base) 61#define ARM_SMMU_GR0(smmu) ((smmu)->base)
62#define ARM_SMMU_GR1(smmu) ((smmu)->base + (smmu)->pagesize) 62#define ARM_SMMU_GR1(smmu) ((smmu)->base + (1 << (smmu)->pgshift))
63 63
64/* 64/*
65 * SMMU global address space with conditional offset to access secure 65 * SMMU global address space with conditional offset to access secure
@@ -224,7 +224,7 @@
224 224
225/* Translation context bank */ 225/* Translation context bank */
226#define ARM_SMMU_CB_BASE(smmu) ((smmu)->base + ((smmu)->size >> 1)) 226#define ARM_SMMU_CB_BASE(smmu) ((smmu)->base + ((smmu)->size >> 1))
227#define ARM_SMMU_CB(smmu, n) ((n) * (smmu)->pagesize) 227#define ARM_SMMU_CB(smmu, n) ((n) * (1 << (smmu)->pgshift))
228 228
229#define ARM_SMMU_CB_SCTLR 0x0 229#define ARM_SMMU_CB_SCTLR 0x0
230#define ARM_SMMU_CB_RESUME 0x8 230#define ARM_SMMU_CB_RESUME 0x8
@@ -354,7 +354,7 @@ struct arm_smmu_device {
354 354
355 void __iomem *base; 355 void __iomem *base;
356 unsigned long size; 356 unsigned long size;
357 unsigned long pagesize; 357 unsigned long pgshift;
358 358
359#define ARM_SMMU_FEAT_COHERENT_WALK (1 << 0) 359#define ARM_SMMU_FEAT_COHERENT_WALK (1 << 0)
360#define ARM_SMMU_FEAT_STREAM_MATCH (1 << 1) 360#define ARM_SMMU_FEAT_STREAM_MATCH (1 << 1)
@@ -1814,12 +1814,12 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
1814 1814
1815 /* ID1 */ 1815 /* ID1 */
1816 id = readl_relaxed(gr0_base + ARM_SMMU_GR0_ID1); 1816 id = readl_relaxed(gr0_base + ARM_SMMU_GR0_ID1);
1817 smmu->pagesize = (id & ID1_PAGESIZE) ? SZ_64K : SZ_4K; 1817 smmu->pgshift = (id & ID1_PAGESIZE) ? 16 : 12;
1818 1818
1819 /* Check for size mismatch of SMMU address space from mapped region */ 1819 /* Check for size mismatch of SMMU address space from mapped region */
1820 size = 1 << 1820 size = 1 <<
1821 (((id >> ID1_NUMPAGENDXB_SHIFT) & ID1_NUMPAGENDXB_MASK) + 1); 1821 (((id >> ID1_NUMPAGENDXB_SHIFT) & ID1_NUMPAGENDXB_MASK) + 1);
1822 size *= (smmu->pagesize << 1); 1822 size *= 2 << smmu->pgshift;
1823 if (smmu->size != size) 1823 if (smmu->size != size)
1824 dev_warn(smmu->dev, 1824 dev_warn(smmu->dev,
1825 "SMMU address space size (0x%lx) differs from mapped region size (0x%lx)!\n", 1825 "SMMU address space size (0x%lx) differs from mapped region size (0x%lx)!\n",