On Thu, Nov 30, 2023 at 2:11 AM Jason Gunthorpe <jgg@xxxxxxxxxx> wrote: > > Similar to of_iommu_for_each_id() this parses the VIOT ACPI description > and invokes a function over each entry in the table. > > Have viot_iommu_configure() use the new function to call > viot_dev_iommu_init(). > > Signed-off-by: Jason Gunthorpe <jgg@xxxxxxxxxx> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx> > --- > drivers/acpi/viot.c | 54 +++++++++++++++++++++++---------------- > include/linux/acpi_viot.h | 11 ++++++++ > 2 files changed, 43 insertions(+), 22 deletions(-) > > diff --git a/drivers/acpi/viot.c b/drivers/acpi/viot.c > index c8025921c129b2..7ab35ef05c84e0 100644 > --- a/drivers/acpi/viot.c > +++ b/drivers/acpi/viot.c > @@ -25,13 +25,6 @@ > #include <linux/pci.h> > #include <linux/platform_device.h> > > -struct viot_iommu { > - /* Node offset within the table */ > - unsigned int offset; > - struct fwnode_handle *fwnode; > - struct list_head list; > -}; > - > struct viot_endpoint { > union { > /* PCI range */ > @@ -304,10 +297,10 @@ void __init acpi_viot_init(void) > acpi_put_table(hdr); > } > > -static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu, > - u32 epid) > +static int viot_dev_iommu_init(struct viot_iommu *viommu, u32 epid, void *info) > { > const struct iommu_ops *ops; > + struct device *dev = info; > > if (!viommu) > return -ENODEV; > @@ -324,11 +317,17 @@ static int viot_dev_iommu_init(struct device *dev, struct viot_iommu *viommu, > return acpi_iommu_fwspec_init(dev, epid, viommu->fwnode, ops); > } > > -static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data) > +struct viot_pci_iommu_alias_info { > + struct device *dev; > + viot_for_each_fn fn; > + void *info; > +}; > + > +static int __for_each_pci_alias(struct pci_dev *pdev, u16 dev_id, void *data) > { > u32 epid; > struct viot_endpoint *ep; > - struct device *aliased_dev = data; > + struct viot_pci_iommu_alias_info *info = data; > u32 domain_nr = pci_domain_nr(pdev->bus); > > list_for_each_entry(ep, &viot_pci_ranges, list) { > @@ -339,14 +338,14 @@ static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data) > epid = ((domain_nr - ep->segment_start) << 16) + > dev_id - ep->bdf_start + ep->endpoint_id; > > - return viot_dev_iommu_init(aliased_dev, ep->viommu, > - epid); > + return info->fn(ep->viommu, epid, info->info); > } > } > return -ENODEV; > } > > -static int viot_mmio_dev_iommu_init(struct platform_device *pdev) > +static int __for_each_platform(struct platform_device *pdev, > + viot_for_each_fn fn, void *info) > { > struct resource *mem; > struct viot_endpoint *ep; > @@ -357,12 +356,28 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev) > > list_for_each_entry(ep, &viot_mmio_endpoints, list) { > if (ep->address == mem->start) > - return viot_dev_iommu_init(&pdev->dev, ep->viommu, > - ep->endpoint_id); > + return fn(ep->viommu, ep->endpoint_id, info); > } > return -ENODEV; > } > > +int viot_iommu_for_each_id(struct device *dev, viot_for_each_fn fn, void *info) > +{ > + if (dev_is_pci(dev)) { > + struct viot_pci_iommu_alias_info pci_info = { > + .dev = dev, > + .fn = fn, > + .info = info, > + }; > + return pci_for_each_dma_alias(to_pci_dev(dev), > + __for_each_pci_alias, &pci_info); > + } > + > + if (dev_is_platform(dev)) > + return __for_each_platform(to_platform_device(dev), fn, info); > + return -ENODEV; > +} > + > /** > * viot_iommu_configure - Setup IOMMU ops for an endpoint described by VIOT > * @dev: the endpoint > @@ -371,10 +386,5 @@ static int viot_mmio_dev_iommu_init(struct platform_device *pdev) > */ > int viot_iommu_configure(struct device *dev) > { > - if (dev_is_pci(dev)) > - return pci_for_each_dma_alias(to_pci_dev(dev), > - viot_pci_dev_iommu_init, dev); > - else if (dev_is_platform(dev)) > - return viot_mmio_dev_iommu_init(to_platform_device(dev)); > - return -ENODEV; > + return viot_iommu_for_each_id(dev, viot_dev_iommu_init, dev); > } > diff --git a/include/linux/acpi_viot.h b/include/linux/acpi_viot.h > index a5a12243156377..fce4eefcae4aad 100644 > --- a/include/linux/acpi_viot.h > +++ b/include/linux/acpi_viot.h > @@ -5,6 +5,17 @@ > > #include <linux/acpi.h> > > +struct viot_iommu { > + /* Node offset within the table */ > + unsigned int offset; > + struct fwnode_handle *fwnode; > + struct list_head list; > +}; > + > +typedef int (*viot_for_each_fn)(struct viot_iommu *viommu, u32 epid, > + void *info); > +int viot_iommu_for_each_id(struct device *dev, viot_for_each_fn fn, void *info); > + > #ifdef CONFIG_ACPI_VIOT > void __init acpi_viot_early_init(void); > void __init acpi_viot_init(void); > -- > 2.42.0 >