summaryrefslogtreecommitdiff
path: root/kernel/irq
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2021-12-10 23:18:55 +0100
committerThomas Gleixner <tglx@linutronix.de>2021-12-16 22:16:38 +0100
commit013bd8e543c2c777b586cf033c588ea82bd502db (patch)
treef6177388fe82c29084b7319f24818bc704f86d5d /kernel/irq
parent34fff62827b254f8a43633cc878deb04bf11297c (diff)
device: Add device:: Msi_data pointer and struct msi_device_data
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. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Tested-by: Michael Kelley <mikelley@microsoft.com> Tested-by: Nishanth Menon <nm@ti.com> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Link: https://lore.kernel.org/r/20211210221813.676660809@linutronix.de
Diffstat (limited to 'kernel/irq')
-rw-r--r--kernel/irq/msi.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c
index b3f73ef0376c..6bca6ad9bf69 100644
--- a/kernel/irq/msi.c
+++ b/kernel/irq/msi.c
@@ -73,6 +73,38 @@ void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg)
}
EXPORT_SYMBOL_GPL(get_cached_msi_msg);
+static void msi_device_data_release(struct device *dev, void *res)
+{
+ WARN_ON_ONCE(!list_empty(&dev->msi_list));
+ dev->msi.data = NULL;
+}
+
+/**
+ * msi_setup_device_data - Setup MSI device data
+ * @dev: Device for which MSI device data should be set up
+ *
+ * Return: 0 on success, appropriate error code otherwise
+ *
+ * This can be called more than once for @dev. If the MSI device data is
+ * already allocated the call succeeds. The allocated memory is
+ * automatically released when the device is destroyed.
+ */
+int msi_setup_device_data(struct device *dev)
+{
+ struct msi_device_data *md;
+
+ if (dev->msi.data)
+ return 0;
+
+ md = devres_alloc(msi_device_data_release, sizeof(*md), GFP_KERNEL);
+ if (!md)
+ return -ENOMEM;
+
+ dev->msi.data = md;
+ devres_add(dev, md);
+ return 0;
+}
+
#ifdef CONFIG_SYSFS
static ssize_t msi_mode_show(struct device *dev, struct device_attribute *attr,
char *buf)