Add new allocation functions which can be activated by domain info flags. They store the groups pointer in struct msi_device_data.
Unified · Split
| @@ -56,6 +56,8 @@ struct irq_data; · 55 unmodified lines | ||
| 56 | 56 | struct msi_desc; |
| 57 | 57 | struct pci_dev; |
| 58 | 58 | struct platform_msi_priv_data; |
| 59 | +struct attribute_group; | |
| 60 | + | |
| 59 | 61 | void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg); |
| 60 | 62 | #ifdef CONFIG_GENERIC_MSI_IRQ |
| 61 | 63 | void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg); |
| @@ -174,9 +176,11 @@ struct msi_desc { · 112 unmodified lines | ||
| 174 | 176 | /** |
| 175 | 177 | * msi_device_data - MSI per device data |
| 176 | 178 | * @properties: MSI properties which are interesting to drivers |
| 179 | + * @attrs: Pointer to the sysfs attribute group | |
| 177 | 180 | */ |
| 178 | 181 | struct msi_device_data { |
| 179 | 182 | unsigned long properties; |
| 183 | + const struct attribute_group **attrs; | |
| 180 | 184 | }; |
| 181 | 185 | |
| 182 | 186 | int msi_setup_device_data(struct device *dev); |
| @@ -199,6 +199,20 @@ error_attrs: · 198 unmodified lines | ||
| 199 | 199 | return ERR_PTR(ret); |
| 200 | 200 | } |
| 201 | 201 | |
| 202 | +/** | |
| 203 | + * msi_device_populate_sysfs - Populate msi_irqs sysfs entries for a device | |
| 204 | + * @dev: The device (PCI, platform etc) which will get sysfs entries | |
| 205 | + */ | |
| 206 | +int msi_device_populate_sysfs(struct device *dev) | |
| 207 | +{ | |
| 208 | + const struct attribute_group **group = msi_populate_sysfs(dev); | |
| 209 | + | |
| 210 | + if (IS_ERR(group)) | |
| 211 | + return PTR_ERR(group); | |
| 212 | + dev->msi.data->attrs = group; | |
| 213 | + return 0; | |
| 214 | +} | |
| 215 | + | |
| 202 | 216 | /** |
| 203 | 217 | * msi_destroy_sysfs - Destroy msi_irqs sysfs entries for devices |
| 204 | 218 | * @dev: The device(PCI, platform etc) who will remove sysfs entries |
| @@ -225,6 +239,17 @@ void msi_destroy_sysfs(struct device *dev, const struct attribute_group **msi_ir · 20 unmodified lines | ||
| 225 | 239 | kfree(msi_irq_groups); |
| 226 | 240 | } |
| 227 | 241 | } |
| 242 | + | |
| 243 | +/** | |
| 244 | + * msi_device_destroy_sysfs - Destroy msi_irqs sysfs entries for a device | |
| 245 | + * @dev: The device (PCI, platform etc) for which to remove | |
| 246 | + * sysfs entries | |
| 247 | + */ | |
| 248 | +void msi_device_destroy_sysfs(struct device *dev) | |
| 249 | +{ | |
| 250 | + msi_destroy_sysfs(dev, dev->msi.data->attrs); | |
| 251 | + dev->msi.data->attrs = NULL; | |
| 252 | +} | |
| 228 | 253 | #endif |
| 229 | 254 | |
| 230 | 255 | #ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN |
| @@ -672,8 +697,19 @@ int msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev, · 441 unmodified lines | ||
| 672 | 697 | { |
| 673 | 698 | struct msi_domain_info *info = domain->host_data; |
| 674 | 699 | struct msi_domain_ops *ops = info->ops; |
| 700 | + int ret; | |
| 701 | + | |
| 702 | + ret = ops->domain_alloc_irqs(domain, dev, nvec); | |
| 703 | + if (ret) | |
| 704 | + return ret; | |
| 705 | + | |
| 706 | + if (!(info->flags & MSI_FLAG_DEV_SYSFS)) | |
| 707 | + return 0; | |
| 675 | 708 | |
| 676 | − return ops->domain_alloc_irqs(domain, dev, nvec); | |
| 709 | + ret = msi_device_populate_sysfs(dev); | |
| 710 | + if (ret) | |
| 711 | + msi_domain_free_irqs(domain, dev); | |
| 712 | + return ret; | |
| 677 | 713 | } |
| 678 | 714 | |
| 679 | 715 | void __msi_domain_free_irqs(struct irq_domain *domain, struct device *dev) |
| @@ -712,7 +748,9 @@ void msi_domain_free_irqs(struct irq_domain *domain, struct device *dev) · 32 unmodified lines | ||
| 712 | 748 | struct msi_domain_info *info = domain->host_data; |
| 713 | 749 | struct msi_domain_ops *ops = info->ops; |
| 714 | 750 | |
| 715 | − return ops->domain_free_irqs(domain, dev); | |
| 751 | + if (info->flags & MSI_FLAG_DEV_SYSFS) | |
| 752 | + msi_device_destroy_sysfs(dev); | |
| 753 | + ops->domain_free_irqs(domain, dev); | |
| 716 | 754 | } |
| 717 | 755 | |
| 718 | 756 | /** |