[RFC v1 2/7] iommu/arm-smmu-v3: Add erratum framework functions

Robin Murphy robin.murphy at arm.com
Tue May 16 06:08:00 PDT 2017


On 13/05/17 10:47, shameer wrote:
> This will provide a way to replace the existing skip_prefetch_cmd
> erratum using the new framework.

Yikes, between this and patch 1 we're already pushing 70 lines of new
code, and it still doesn't actually do anything yet. Implementing the
SMMUv3 equivalent of SMMUv2's acpi_smmu_get_data() would probably be
about 10 lines; all you need to do is set some quirk flags based on a
compatible value. These quirks aren't really any different in principle
to the firmware COHACC overrides that we already process.

Sorry, I'm saying no to a massively overengineered "framework" for
something so relatively simple.

Robin.

> 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;
>  
> 




More information about the linux-arm-kernel mailing list