aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/iommu/arm-smmu.c27
1 files changed, 12 insertions, 15 deletions
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 398802ad9d2d..b7cd5d07d6fb 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1116,6 +1116,9 @@ static void arm_smmu_master_free_smrs(struct arm_smmu_device *smmu,
1116 void __iomem *gr0_base = ARM_SMMU_GR0(smmu); 1116 void __iomem *gr0_base = ARM_SMMU_GR0(smmu);
1117 struct arm_smmu_smr *smrs = cfg->smrs; 1117 struct arm_smmu_smr *smrs = cfg->smrs;
1118 1118
1119 if (!smrs)
1120 return;
1121
1119 /* Invalidate the SMRs before freeing back to the allocator */ 1122 /* Invalidate the SMRs before freeing back to the allocator */
1120 for (i = 0; i < cfg->num_streamids; ++i) { 1123 for (i = 0; i < cfg->num_streamids; ++i) {
1121 u8 idx = smrs[i].idx; 1124 u8 idx = smrs[i].idx;
@@ -1128,20 +1131,6 @@ static void arm_smmu_master_free_smrs(struct arm_smmu_device *smmu,
1128 kfree(smrs); 1131 kfree(smrs);
1129} 1132}
1130 1133
1131static void arm_smmu_bypass_stream_mapping(struct arm_smmu_device *smmu,
1132 struct arm_smmu_master_cfg *cfg)
1133{
1134 int i;
1135 void __iomem *gr0_base = ARM_SMMU_GR0(smmu);
1136
1137 for (i = 0; i < cfg->num_streamids; ++i) {
1138 u16 sid = cfg->streamids[i];
1139
1140 writel_relaxed(S2CR_TYPE_BYPASS,
1141 gr0_base + ARM_SMMU_GR0_S2CR(sid));
1142 }
1143}
1144
1145static int arm_smmu_domain_add_master(struct arm_smmu_domain *smmu_domain, 1134static int arm_smmu_domain_add_master(struct arm_smmu_domain *smmu_domain,
1146 struct arm_smmu_master_cfg *cfg) 1135 struct arm_smmu_master_cfg *cfg)
1147{ 1136{
@@ -1168,13 +1157,21 @@ static int arm_smmu_domain_add_master(struct arm_smmu_domain *smmu_domain,
1168static void arm_smmu_domain_remove_master(struct arm_smmu_domain *smmu_domain, 1157static void arm_smmu_domain_remove_master(struct arm_smmu_domain *smmu_domain,
1169 struct arm_smmu_master_cfg *cfg) 1158 struct arm_smmu_master_cfg *cfg)
1170{ 1159{
1160 int i;
1171 struct arm_smmu_device *smmu = smmu_domain->smmu; 1161 struct arm_smmu_device *smmu = smmu_domain->smmu;
1162 void __iomem *gr0_base = ARM_SMMU_GR0(smmu);
1172 1163
1173 /* 1164 /*
1174 * We *must* clear the S2CR first, because freeing the SMR means 1165 * We *must* clear the S2CR first, because freeing the SMR means
1175 * that it can be re-allocated immediately. 1166 * that it can be re-allocated immediately.
1176 */ 1167 */
1177 arm_smmu_bypass_stream_mapping(smmu, cfg); 1168 for (i = 0; i < cfg->num_streamids; ++i) {
1169 u32 idx = cfg->smrs ? cfg->smrs[i].idx : cfg->streamids[i];
1170
1171 writel_relaxed(S2CR_TYPE_BYPASS,
1172 gr0_base + ARM_SMMU_GR0_S2CR(idx));
1173 }
1174
1178 arm_smmu_master_free_smrs(smmu, cfg); 1175 arm_smmu_master_free_smrs(smmu, cfg);
1179} 1176}
1180 1177