[RFC v1 2/7] iommu/arm-smmu-v3: Add erratum framework functions
shameer
shameerali.kolothum.thodi at huawei.com
Sat May 13 02:47:26 PDT 2017
This will provide a way to replace the existing skip_prefetch_cmd
erratum using the new framework.
Signed-off-by: shameer <shameerali.kolothum.thodi at huawei.com>
---
drivers/iommu/arm-smmu-v3.c | 58 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index a166590..f20d5d5 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -664,16 +664,72 @@ enum smmu_erratum_match_type {
se_match_dt,
};
+void erratum_skip_prefetch_cmd(struct arm_smmu_device *smmu, void *arg)
+{
+ smmu->options |= ARM_SMMU_OPT_SKIP_PREFETCH;
+}
+
struct smmu_erratum_workaround {
enum smmu_erratum_match_type match_type;
const void *id; /* Indicate the Erratum ID */
const char *desc_str;
+ void (*enable)(struct arm_smmu_device *, void *);
};
static const struct smmu_erratum_workaround smmu_workarounds[] = {
};
+typedef bool (*se_match_fn_t)(const struct smmu_erratum_workaround *,
+ const void *);
+static
+bool smmu_check_dt_erratum(const struct smmu_erratum_workaround *wa,
+ const void *arg)
+{
+ const struct device_node *np = arg;
+
+ return of_property_read_bool(np, wa->id);
+}
+
+static void smmu_enable_errata(struct arm_smmu_device *smmu,
+ enum smmu_erratum_match_type type,
+ se_match_fn_t match_fn,
+ void *arg)
+{
+ const struct smmu_erratum_workaround *wa = smmu_workarounds;
+
+ for (; wa->desc_str; wa++) {
+ if (wa->match_type != type)
+ continue;
+
+ if (match_fn(wa, arg)) {
+ if (wa->enable) {
+ wa->enable(smmu, arg);
+ dev_info(smmu->dev,
+ "Enabling workaround for %s\n",
+ wa->desc_str);
+ }
+ }
+ }
+}
+
+
+static void smmu_check_workarounds(struct arm_smmu_device *smmu,
+ enum smmu_erratum_match_type type,
+ void *arg)
+{
+ se_match_fn_t match_fn = NULL;
+
+ switch (type) {
+ case se_match_dt:
+ match_fn = smmu_check_dt_erratum;
+ break;
+ }
+
+ smmu_enable_errata(smmu, type, match_fn, arg);
+
+}
+
static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom)
{
return container_of(dom, struct arm_smmu_domain, domain);
@@ -2641,6 +2697,8 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev,
parse_driver_options(smmu);
+ smmu_check_workarounds(smmu, se_match_dt, dev->of_node);
+
if (of_dma_is_coherent(dev->of_node))
smmu->features |= ARM_SMMU_FEAT_COHERENCY;
--
2.5.0
More information about the linux-arm-kernel
mailing list