Message ID | 20211126230524.416227100@linutronix.de (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | genirq/msi, PCI/MSI: Spring cleaning - Part 2 | expand |
On Sat, 27 Nov 2021 02:20:19 +0100 (CET) Thomas Gleixner <tglx@linutronix.de> wrote: > Add new allocation functions which can be activated by domain info > flags. They store the groups pointer in struct msi_device_data. > > Signed-off-by: Thomas Gleixner <tglx@linutronix.de> A few trivial comments... > --- > include/linux/msi.h | 12 +++++++++++- > kernel/irq/msi.c | 42 ++++++++++++++++++++++++++++++++++++++++-- > 2 files changed, 51 insertions(+), 3 deletions(-) > > --- a/include/linux/msi.h > +++ b/include/linux/msi.h > @@ -174,9 +174,11 @@ struct msi_desc { > /** > * msi_device_data - MSI per device data > * @lock: Spinlock to protect register access > + * @attrs: Pointer to the sysfs attribute group > */ > struct msi_device_data { > - raw_spinlock_t lock; > + raw_spinlock_t lock; Trivial: Move the alignment change back to patch 2. > + const struct attribute_group **attrs; > }; > > int msi_setup_device_data(struct device *dev); > @@ -242,10 +244,16 @@ void pci_msi_mask_irq(struct irq_data *d > void pci_msi_unmask_irq(struct irq_data *data); > > #ifdef CONFIG_SYSFS > +int msi_device_populate_sysfs(struct device *dev); > +void msi_device_destroy_sysfs(struct device *dev); > + > const struct attribute_group **msi_populate_sysfs(struct device *dev); > void msi_destroy_sysfs(struct device *dev, > const struct attribute_group **msi_irq_groups); > #else > +static inline int msi_device_populate_sysfs(struct device *dev) { return 0; } > +static inline void msi_device_destroy_sysfs(struct device *dev) { } > + > static inline const struct attribute_group **msi_populate_sysfs(struct device *dev) > { > return NULL; > @@ -393,6 +401,8 @@ enum { > MSI_FLAG_MUST_REACTIVATE = (1 << 5), > /* Is level-triggered capable, using two messages */ > MSI_FLAG_LEVEL_CAPABLE = (1 << 6), > + /* Populate sysfs on alloc() and destroy it on free() */ > + MSI_FLAG_DEV_SYSFS = (1 << 7), > }; > > int msi_domain_set_affinity(struct irq_data *data, const struct cpumask *mask, > --- a/kernel/irq/msi.c > +++ b/kernel/irq/msi.c > @@ -214,6 +214,20 @@ const struct attribute_group **msi_popul > } > > /** > + * msi_device_populate_sysfs - Populate msi_irqs sysfs entries for a device > + * @dev: The device(PCI, platform etc) which will get sysfs entries Space after device > + */ > +int msi_device_populate_sysfs(struct device *dev) > +{ > + const struct attribute_group **group = msi_populate_sysfs(dev); > + > + if (IS_ERR(group)) > + return PTR_ERR(group); > + dev->msi.data->attrs = group; > + return 0; > +} > + > +/** > * msi_destroy_sysfs - Destroy msi_irqs sysfs entries for devices > * @dev: The device(PCI, platform etc) who will remove sysfs entries > * @msi_irq_groups: attribute_group for device msi_irqs entries > @@ -239,6 +253,17 @@ void msi_destroy_sysfs(struct device *de > kfree(msi_irq_groups); > } > } > + > +/** > + * msi_device_destroy_sysfs - Destroy msi_irqs sysfs entries for a device > + * @dev: The device(PCI, platform etc) for which to remove > + * sysfs entries > + */ > +void msi_device_destroy_sysfs(struct device *dev) > +{ > + msi_destroy_sysfs(dev, dev->msi.data->attrs); > + dev->msi.data->attrs = NULL; > +} > #endif > > #ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN > @@ -686,8 +711,19 @@ int msi_domain_alloc_irqs(struct irq_dom > { > struct msi_domain_info *info = domain->host_data; > struct msi_domain_ops *ops = info->ops; > + int ret; > > - return ops->domain_alloc_irqs(domain, dev, nvec); > + ret = ops->domain_alloc_irqs(domain, dev, nvec); > + if (ret) > + return ret; > + > + if (!(info->flags & MSI_FLAG_DEV_SYSFS)) > + return 0; > + > + ret = msi_device_populate_sysfs(dev); > + if (ret) > + msi_domain_free_irqs(domain, dev); > + return ret; > } > > void __msi_domain_free_irqs(struct irq_domain *domain, struct device *dev) > @@ -726,7 +762,9 @@ void msi_domain_free_irqs(struct irq_dom > struct msi_domain_info *info = domain->host_data; > struct msi_domain_ops *ops = info->ops; > > - return ops->domain_free_irqs(domain, dev); > + if (info->flags & MSI_FLAG_DEV_SYSFS) > + msi_device_destroy_sysfs(dev); > + ops->domain_free_irqs(domain, dev); > } > > /** > > _______________________________________________ > iommu mailing list > iommu@lists.linux-foundation.org > https://lists.linuxfoundation.org/mailman/listinfo/iommu
--- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -174,9 +174,11 @@ struct msi_desc { /** * msi_device_data - MSI per device data * @lock: Spinlock to protect register access + * @attrs: Pointer to the sysfs attribute group */ struct msi_device_data { - raw_spinlock_t lock; + raw_spinlock_t lock; + const struct attribute_group **attrs; }; int msi_setup_device_data(struct device *dev); @@ -242,10 +244,16 @@ void pci_msi_mask_irq(struct irq_data *d void pci_msi_unmask_irq(struct irq_data *data); #ifdef CONFIG_SYSFS +int msi_device_populate_sysfs(struct device *dev); +void msi_device_destroy_sysfs(struct device *dev); + const struct attribute_group **msi_populate_sysfs(struct device *dev); void msi_destroy_sysfs(struct device *dev, const struct attribute_group **msi_irq_groups); #else +static inline int msi_device_populate_sysfs(struct device *dev) { return 0; } +static inline void msi_device_destroy_sysfs(struct device *dev) { } + static inline const struct attribute_group **msi_populate_sysfs(struct device *dev) { return NULL; @@ -393,6 +401,8 @@ enum { MSI_FLAG_MUST_REACTIVATE = (1 << 5), /* Is level-triggered capable, using two messages */ MSI_FLAG_LEVEL_CAPABLE = (1 << 6), + /* Populate sysfs on alloc() and destroy it on free() */ + MSI_FLAG_DEV_SYSFS = (1 << 7), }; int msi_domain_set_affinity(struct irq_data *data, const struct cpumask *mask, --- a/kernel/irq/msi.c +++ b/kernel/irq/msi.c @@ -214,6 +214,20 @@ const struct attribute_group **msi_popul } /** + * msi_device_populate_sysfs - Populate msi_irqs sysfs entries for a device + * @dev: The device(PCI, platform etc) which will get sysfs entries + */ +int msi_device_populate_sysfs(struct device *dev) +{ + const struct attribute_group **group = msi_populate_sysfs(dev); + + if (IS_ERR(group)) + return PTR_ERR(group); + dev->msi.data->attrs = group; + return 0; +} + +/** * msi_destroy_sysfs - Destroy msi_irqs sysfs entries for devices * @dev: The device(PCI, platform etc) who will remove sysfs entries * @msi_irq_groups: attribute_group for device msi_irqs entries @@ -239,6 +253,17 @@ void msi_destroy_sysfs(struct device *de kfree(msi_irq_groups); } } + +/** + * msi_device_destroy_sysfs - Destroy msi_irqs sysfs entries for a device + * @dev: The device(PCI, platform etc) for which to remove + * sysfs entries + */ +void msi_device_destroy_sysfs(struct device *dev) +{ + msi_destroy_sysfs(dev, dev->msi.data->attrs); + dev->msi.data->attrs = NULL; +} #endif #ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN @@ -686,8 +711,19 @@ int msi_domain_alloc_irqs(struct irq_dom { struct msi_domain_info *info = domain->host_data; struct msi_domain_ops *ops = info->ops; + int ret; - return ops->domain_alloc_irqs(domain, dev, nvec); + ret = ops->domain_alloc_irqs(domain, dev, nvec); + if (ret) + return ret; + + if (!(info->flags & MSI_FLAG_DEV_SYSFS)) + return 0; + + ret = msi_device_populate_sysfs(dev); + if (ret) + msi_domain_free_irqs(domain, dev); + return ret; } void __msi_domain_free_irqs(struct irq_domain *domain, struct device *dev) @@ -726,7 +762,9 @@ void msi_domain_free_irqs(struct irq_dom struct msi_domain_info *info = domain->host_data; struct msi_domain_ops *ops = info->ops; - return ops->domain_free_irqs(domain, dev); + if (info->flags & MSI_FLAG_DEV_SYSFS) + msi_device_destroy_sysfs(dev); + ops->domain_free_irqs(domain, dev); } /**
Add new allocation functions which can be activated by domain info flags. They store the groups pointer in struct msi_device_data. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- include/linux/msi.h | 12 +++++++++++- kernel/irq/msi.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 51 insertions(+), 3 deletions(-)