aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjorn Andersson <bjorn.andersson@linaro.org>2019-05-10 20:11:50 -0700
committerBjorn Andersson <bjorn.andersson@linaro.org>2019-05-30 09:40:33 -0700
commitf29fc8e41ca60ec7006f91ad597dd479eb5c6468 (patch)
tree07294253056b39e9a38b7f96e7e7a4813bf9b747
parent8e0efaf57b2537251d05110f38b3a07d0dba1eb5 (diff)
iommu: arm-smmu: Don't blindly use first SMR to calculate mask
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
-rw-r--r--drivers/iommu/arm-smmu.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 88d757c8cf4e..3f3a2b47670a 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1211,23 +1211,35 @@ static void arm_smmu_test_smr_masks(struct arm_smmu_device *smmu)
{
void __iomem *gr0_base = ARM_SMMU_GR0(smmu);
u32 smr;
+ int idx;
if (!smmu->smrs)
return;
+ for (idx = 0; idx < smmu->num_mapping_groups; idx++) {
+ smr = readl_relaxed(gr0_base + ARM_SMMU_GR0_SMR(idx));
+ if (!(smr & SMR_VALID))
+ break;
+ }
+
+ if (idx == smmu->num_mapping_groups) {
+ dev_err(smmu->dev, "Unable to compute streamid_mask\n");
+ return;
+ }
+
/*
* SMR.ID bits may not be preserved if the corresponding MASK
* bits are set, so check each one separately. We can reject
* masters later if they try to claim IDs outside these masks.
*/
smr = smmu->streamid_mask << SMR_ID_SHIFT;
- writel_relaxed(smr, gr0_base + ARM_SMMU_GR0_SMR(0));
- smr = readl_relaxed(gr0_base + ARM_SMMU_GR0_SMR(0));
+ writel_relaxed(smr, gr0_base + ARM_SMMU_GR0_SMR(idx));
+ smr = readl_relaxed(gr0_base + ARM_SMMU_GR0_SMR(idx));
smmu->streamid_mask = smr >> SMR_ID_SHIFT;
smr = smmu->streamid_mask << SMR_MASK_SHIFT;
- writel_relaxed(smr, gr0_base + ARM_SMMU_GR0_SMR(0));
- smr = readl_relaxed(gr0_base + ARM_SMMU_GR0_SMR(0));
+ writel_relaxed(smr, gr0_base + ARM_SMMU_GR0_SMR(idx));
+ smr = readl_relaxed(gr0_base + ARM_SMMU_GR0_SMR(idx));
smmu->smr_mask_mask = smr >> SMR_MASK_SHIFT;
}