diff options
-rw-r--r-- | drivers/iommu/arm-smmu.c | 27 |
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 | ||
1131 | static 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 | |||
1145 | static int arm_smmu_domain_add_master(struct arm_smmu_domain *smmu_domain, | 1134 | static 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, | |||
1168 | static void arm_smmu_domain_remove_master(struct arm_smmu_domain *smmu_domain, | 1157 | static 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 | ||