[PATCH v6 04/16] drivers: iommu: make of_iommu_set/get_ops() DT agnostic

Robin Murphy robin.murphy at arm.com
Tue Nov 1 09:36:10 PDT 2016


Bikeshed alert...

On 18/10/16 17:04, Lorenzo Pieralisi wrote:
> The of_iommu_{set/get}_ops() API is used to associate a device
> tree node with a specific set of IOMMU operations. The same
> kernel interface is required on systems booting with ACPI, where
> devices are not associated with a device tree node, therefore
> the interface requires generalization.
> 
> The struct device fwnode member represents the fwnode token
> associated with the device and the struct it points at is firmware
> specific; regardless, it is initialized on both ACPI and DT systems
> and makes an ideal candidate to use it to associate a set of IOMMU
> operations to a given device, through its struct device.fwnode member
> pointer.
> 
> Convert the DT specific of_iommu_{set/get}_ops() interface to
> use struct device.fwnode as a look-up token, making the interface
> usable on ACPI systems.
> 
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> Cc: Will Deacon <will.deacon at arm.com>
> Cc: Hanjun Guo <hanjun.guo at linaro.org>
> Cc: Robin Murphy <robin.murphy at arm.com>
> Cc: Joerg Roedel <joro at 8bytes.org>
> ---
>  drivers/iommu/iommu.c    | 43 +++++++++++++++++++++++++++++++++++++++++++
>  drivers/iommu/of_iommu.c | 39 ---------------------------------------
>  include/linux/iommu.h    | 14 ++++++++++++++
>  include/linux/of_iommu.h | 12 ++++++++++--
>  4 files changed, 67 insertions(+), 41 deletions(-)
> 
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 9a2f196..320eb8c 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -1615,6 +1615,49 @@ int iommu_request_dm_for_dev(struct device *dev)
>  	return ret;
>  }
>  
> +struct fwnode_iommu_node {

Having just pulled in this patch in isolation for some hacking, I
realise that by about the fifth time one reads "fwnode_iommu_node" it
just looks like meaningless gibberish. Can we just call it
"iommu_instance" instead, as that's what it's representing here?

> +	struct list_head list;
> +	struct fwnode_handle *fwnode;
> +	const struct iommu_ops *ops;
> +};
> +static LIST_HEAD(fwnode_iommu_list);
> +static DEFINE_SPINLOCK(fwnode_iommu_lock);
> +
> +void fwnode_iommu_set_ops(struct fwnode_handle *fwnode,
> +			  const struct iommu_ops *ops)
> +{
> +	struct fwnode_iommu_node *iommu =
> +				kzalloc(sizeof(*iommu), GFP_KERNEL);

(plus it shortens this line so it really doesn't the awkward break)

Apologies, (the original rubbish name was my fault anyway)
Robin.

> +
> +	if (WARN_ON(!iommu))
> +		return;
> +
> +	if (is_of_node(fwnode))
> +		of_node_get(to_of_node(fwnode));
> +
> +	INIT_LIST_HEAD(&iommu->list);
> +	iommu->fwnode = fwnode;
> +	iommu->ops = ops;
> +	spin_lock(&fwnode_iommu_lock);
> +	list_add_tail(&iommu->list, &fwnode_iommu_list);
> +	spin_unlock(&fwnode_iommu_lock);
> +}
> +
> +const struct iommu_ops *fwnode_iommu_get_ops(struct fwnode_handle *fwnode)
> +{
> +	struct fwnode_iommu_node *node;
> +	const struct iommu_ops *ops = NULL;
> +
> +	spin_lock(&fwnode_iommu_lock);
> +	list_for_each_entry(node, &fwnode_iommu_list, list)
> +		if (node->fwnode == fwnode) {
> +			ops = node->ops;
> +			break;
> +		}
> +	spin_unlock(&fwnode_iommu_lock);
> +	return ops;
> +}
> +
>  int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
>  		      const struct iommu_ops *ops)
>  {
> diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> index 5b82862..0f57ddc 100644
> --- a/drivers/iommu/of_iommu.c
> +++ b/drivers/iommu/of_iommu.c
> @@ -96,45 +96,6 @@ int of_get_dma_window(struct device_node *dn, const char *prefix, int index,
>  }
>  EXPORT_SYMBOL_GPL(of_get_dma_window);
>  
> -struct of_iommu_node {
> -	struct list_head list;
> -	struct device_node *np;
> -	const struct iommu_ops *ops;
> -};
> -static LIST_HEAD(of_iommu_list);
> -static DEFINE_SPINLOCK(of_iommu_lock);
> -
> -void of_iommu_set_ops(struct device_node *np, const struct iommu_ops *ops)
> -{
> -	struct of_iommu_node *iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
> -
> -	if (WARN_ON(!iommu))
> -		return;
> -
> -	of_node_get(np);
> -	INIT_LIST_HEAD(&iommu->list);
> -	iommu->np = np;
> -	iommu->ops = ops;
> -	spin_lock(&of_iommu_lock);
> -	list_add_tail(&iommu->list, &of_iommu_list);
> -	spin_unlock(&of_iommu_lock);
> -}
> -
> -const struct iommu_ops *of_iommu_get_ops(struct device_node *np)
> -{
> -	struct of_iommu_node *node;
> -	const struct iommu_ops *ops = NULL;
> -
> -	spin_lock(&of_iommu_lock);
> -	list_for_each_entry(node, &of_iommu_list, list)
> -		if (node->np == np) {
> -			ops = node->ops;
> -			break;
> -		}
> -	spin_unlock(&of_iommu_lock);
> -	return ops;
> -}
> -
>  static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
>  {
>  	struct of_phandle_args *iommu_spec = data;
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index 436dc21..15d5478 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -351,6 +351,9 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
>  		      const struct iommu_ops *ops);
>  void iommu_fwspec_free(struct device *dev);
>  int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
> +void fwnode_iommu_set_ops(struct fwnode_handle *fwnode,
> +			  const struct iommu_ops *ops);
> +const struct iommu_ops *fwnode_iommu_get_ops(struct fwnode_handle *fwnode);
>  
>  #else /* CONFIG_IOMMU_API */
>  
> @@ -580,6 +583,17 @@ static inline int iommu_fwspec_add_ids(struct device *dev, u32 *ids,
>  	return -ENODEV;
>  }
>  
> +static inline void fwnode_iommu_set_ops(struct fwnode_handle *fwnode,
> +					const struct iommu_ops *ops)
> +{
> +}
> +
> +static inline
> +const struct iommu_ops *fwnode_iommu_get_ops(struct fwnode_handle *fwnode)
> +{
> +	return NULL;
> +}
> +
>  #endif /* CONFIG_IOMMU_API */
>  
>  #endif /* __LINUX_IOMMU_H */
> diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
> index e80b9c7..7681007 100644
> --- a/include/linux/of_iommu.h
> +++ b/include/linux/of_iommu.h
> @@ -31,8 +31,16 @@ static inline const struct iommu_ops *of_iommu_configure(struct device *dev,
>  
>  #endif	/* CONFIG_OF_IOMMU */
>  
> -void of_iommu_set_ops(struct device_node *np, const struct iommu_ops *ops);
> -const struct iommu_ops *of_iommu_get_ops(struct device_node *np);
> +static inline void of_iommu_set_ops(struct device_node *np,
> +				    const struct iommu_ops *ops)
> +{
> +	fwnode_iommu_set_ops(&np->fwnode, ops);
> +}
> +
> +static inline const struct iommu_ops *of_iommu_get_ops(struct device_node *np)
> +{
> +	return fwnode_iommu_get_ops(&np->fwnode);
> +}
>  
>  extern struct of_device_id __iommu_of_table;
>  
> 




More information about the linux-arm-kernel mailing list