Create struct msi_device_data and add a pointer of that type to struct dev_msi_info, which is part of struct device. Provide an allocator function which can be invoked from the MSI interrupt allocation code pathes. Add a properties field to the data structure as a first member so the allocation size is not zero bytes. The field will be uses later on.
Showing the changes to kernel (1 of 3 files). Show all
Unified · Split
| @@ -73,6 +73,38 @@ void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg) · 72 unmodified lines | ||
| 73 | 73 | } |
| 74 | 74 | EXPORT_SYMBOL_GPL(get_cached_msi_msg); |
| 75 | 75 | |
| 76 | +static void msi_device_data_release(struct device *dev, void *res) | |
| 77 | +{ | |
| 78 | + WARN_ON_ONCE(!list_empty(&dev->msi_list)); | |
| 79 | + dev->msi.data = NULL; | |
| 80 | +} | |
| 81 | + | |
| 82 | +/** | |
| 83 | + * msi_setup_device_data - Setup MSI device data | |
| 84 | + * @dev: Device for which MSI device data should be set up | |
| 85 | + * | |
| 86 | + * Return: 0 on success, appropriate error code otherwise | |
| 87 | + * | |
| 88 | + * This can be called more than once for @dev. If the MSI device data is | |
| 89 | + * already allocated the call succeeds. The allocated memory is | |
| 90 | + * automatically released when the device is destroyed. | |
| 91 | + */ | |
| 92 | +int msi_setup_device_data(struct device *dev) | |
| 93 | +{ | |
| 94 | + struct msi_device_data *md; | |
| 95 | + | |
| 96 | + if (dev->msi.data) | |
| 97 | + return 0; | |
| 98 | + | |
| 99 | + md = devres_alloc(msi_device_data_release, sizeof(*md), GFP_KERNEL); | |
| 100 | + if (!md) | |
| 101 | + return -ENOMEM; | |
| 102 | + | |
| 103 | + dev->msi.data = md; | |
| 104 | + devres_add(dev, md); | |
| 105 | + return 0; | |
| 106 | +} | |
| 107 | + | |
| 76 | 108 | #ifdef CONFIG_SYSFS |
| 77 | 109 | static ssize_t msi_mode_show(struct device *dev, struct device_attribute *attr, |
| 78 | 110 | char *buf) |