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

2016-11-07 Thread Lorenzo Pieralisi
On Tue, Nov 01, 2016 at 04:36:10PM +, Robin Murphy wrote:
> 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 
> > Cc: Will Deacon 
> > Cc: Hanjun Guo 
> > Cc: Robin Murphy 
> > Cc: Joerg Roedel 
> > ---
> >  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?

Agreed, how about iommu_(fw)entry ? Anyway, I will do, point taken.

> > +   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)

No worries, you have a point, will update for next (hopefully last)
posting.

Thanks !
Lorenzo

> Robin.
> 
> > +
> > +   if (WARN_ON(!iommu))
> > +   return;
> > +
> > +   if (is_of_node(fwnode))
> > +   of_node_get(to_of_node(fwnode));
> > +
> > +   INIT_LIST_HEAD(>list);
> > +   iommu->fwnode = fwnode;
> > +   iommu->ops = ops;
> > +   spin_lock(_iommu_lock);
> > +   list_add_tail(>list, _iommu_list);
> > +   spin_unlock(_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(_iommu_lock);
> > +   list_for_each_entry(node, _iommu_list, list)
> > +   if (node->fwnode == fwnode) {
> > +   ops = node->ops;
> > +   break;
> > +   }
> > +   spin_unlock(_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(>list);
> > -   iommu->np = np;
> > -   iommu->ops = ops;
> > -   spin_lock(_iommu_lock);
> > -   list_add_tail(>list, _iommu_list);
> > -   spin_unlock(_iommu_lock);
> > -}
> > -
> > -const struct iommu_ops *of_iommu_get_ops(struct device_node *np)
> > -{
> > -   struct of_iommu_node *node;
> > -   const struct 

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

2016-11-07 Thread Lorenzo Pieralisi
On Tue, Nov 01, 2016 at 04:36:10PM +, Robin Murphy wrote:
> 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 
> > Cc: Will Deacon 
> > Cc: Hanjun Guo 
> > Cc: Robin Murphy 
> > Cc: Joerg Roedel 
> > ---
> >  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?

Agreed, how about iommu_(fw)entry ? Anyway, I will do, point taken.

> > +   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)

No worries, you have a point, will update for next (hopefully last)
posting.

Thanks !
Lorenzo

> Robin.
> 
> > +
> > +   if (WARN_ON(!iommu))
> > +   return;
> > +
> > +   if (is_of_node(fwnode))
> > +   of_node_get(to_of_node(fwnode));
> > +
> > +   INIT_LIST_HEAD(>list);
> > +   iommu->fwnode = fwnode;
> > +   iommu->ops = ops;
> > +   spin_lock(_iommu_lock);
> > +   list_add_tail(>list, _iommu_list);
> > +   spin_unlock(_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(_iommu_lock);
> > +   list_for_each_entry(node, _iommu_list, list)
> > +   if (node->fwnode == fwnode) {
> > +   ops = node->ops;
> > +   break;
> > +   }
> > +   spin_unlock(_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(>list);
> > -   iommu->np = np;
> > -   iommu->ops = ops;
> > -   spin_lock(_iommu_lock);
> > -   list_add_tail(>list, _iommu_list);
> > -   spin_unlock(_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(_iommu_lock);
> > -   list_for_each_entry(node, _iommu_list, list)
> 

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

2016-11-01 Thread Robin Murphy
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 
> Cc: Will Deacon 
> Cc: Hanjun Guo 
> Cc: Robin Murphy 
> Cc: Joerg Roedel 
> ---
>  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(>list);
> + iommu->fwnode = fwnode;
> + iommu->ops = ops;
> + spin_lock(_iommu_lock);
> + list_add_tail(>list, _iommu_list);
> + spin_unlock(_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(_iommu_lock);
> + list_for_each_entry(node, _iommu_list, list)
> + if (node->fwnode == fwnode) {
> + ops = node->ops;
> + break;
> + }
> + spin_unlock(_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(>list);
> - iommu->np = np;
> - iommu->ops = ops;
> - spin_lock(_iommu_lock);
> - list_add_tail(>list, _iommu_list);
> - spin_unlock(_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(_iommu_lock);
> - list_for_each_entry(node, _iommu_list, list)
> - if (node->np == np) {
> - ops = node->ops;
> - break;
> - }
> - spin_unlock(_iommu_lock);
> - return ops;
> -}
> -
>  static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
>  {
>   struct of_phandle_args 

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

2016-11-01 Thread Robin Murphy
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 
> Cc: Will Deacon 
> Cc: Hanjun Guo 
> Cc: Robin Murphy 
> Cc: Joerg Roedel 
> ---
>  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(>list);
> + iommu->fwnode = fwnode;
> + iommu->ops = ops;
> + spin_lock(_iommu_lock);
> + list_add_tail(>list, _iommu_list);
> + spin_unlock(_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(_iommu_lock);
> + list_for_each_entry(node, _iommu_list, list)
> + if (node->fwnode == fwnode) {
> + ops = node->ops;
> + break;
> + }
> + spin_unlock(_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(>list);
> - iommu->np = np;
> - iommu->ops = ops;
> - spin_lock(_iommu_lock);
> - list_add_tail(>list, _iommu_list);
> - spin_unlock(_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(_iommu_lock);
> - list_for_each_entry(node, _iommu_list, list)
> - if (node->np == np) {
> - ops = node->ops;
> - break;
> - }
> - spin_unlock(_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
> --- 

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

2016-10-18 Thread Lorenzo Pieralisi
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 
Cc: Will Deacon 
Cc: Hanjun Guo 
Cc: Robin Murphy 
Cc: Joerg Roedel 
---
 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 {
+   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);
+
+   if (WARN_ON(!iommu))
+   return;
+
+   if (is_of_node(fwnode))
+   of_node_get(to_of_node(fwnode));
+
+   INIT_LIST_HEAD(>list);
+   iommu->fwnode = fwnode;
+   iommu->ops = ops;
+   spin_lock(_iommu_lock);
+   list_add_tail(>list, _iommu_list);
+   spin_unlock(_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(_iommu_lock);
+   list_for_each_entry(node, _iommu_list, list)
+   if (node->fwnode == fwnode) {
+   ops = node->ops;
+   break;
+   }
+   spin_unlock(_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(>list);
-   iommu->np = np;
-   iommu->ops = ops;
-   spin_lock(_iommu_lock);
-   list_add_tail(>list, _iommu_list);
-   spin_unlock(_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(_iommu_lock);
-   list_for_each_entry(node, _iommu_list, list)
-   if (node->np == np) {
-   ops = node->ops;
-   break;
-   }
-   spin_unlock(_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 /* 

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

2016-10-18 Thread Lorenzo Pieralisi
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 
Cc: Will Deacon 
Cc: Hanjun Guo 
Cc: Robin Murphy 
Cc: Joerg Roedel 
---
 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 {
+   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);
+
+   if (WARN_ON(!iommu))
+   return;
+
+   if (is_of_node(fwnode))
+   of_node_get(to_of_node(fwnode));
+
+   INIT_LIST_HEAD(>list);
+   iommu->fwnode = fwnode;
+   iommu->ops = ops;
+   spin_lock(_iommu_lock);
+   list_add_tail(>list, _iommu_list);
+   spin_unlock(_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(_iommu_lock);
+   list_for_each_entry(node, _iommu_list, list)
+   if (node->fwnode == fwnode) {
+   ops = node->ops;
+   break;
+   }
+   spin_unlock(_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(>list);
-   iommu->np = np;
-   iommu->ops = ops;
-   spin_lock(_iommu_lock);
-   list_add_tail(>list, _iommu_list);
-   spin_unlock(_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(_iommu_lock);
-   list_for_each_entry(node, _iommu_list, list)
-   if (node->np == np) {
-   ops = node->ops;
-   break;
-   }
-   spin_unlock(_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,