summaryrefslogtreecommitdiffstats
path: root/kernel/irq
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2022-11-25 00:24:22 +0100
committerThomas Gleixner <tglx@linutronix.de>2022-12-05 19:20:59 +0100
commit64258eaa442b0b7d7eac8942cf27863ad9e6028e (patch)
treed815f55ff54b1c60c34c7cfe4e7ce818895b50af /kernel/irq
parentf1139f905bd2d8bec59be0c1404b592279ae0ac9 (diff)
downloadlinux-64258eaa442b0b7d7eac8942cf27863ad9e6028e.tar.bz2
genirq/msi: Add pointers for per device irq domains
With the upcoming per device MSI interrupt domain support it is necessary to store the domain pointers per device. Instead of delegating that storage to device drivers or subsystems add a domain pointer to the msi_dev_domain array in struct msi_device_data. This pointer is also used to take care of tearing down the irq domains when msi_device_data is cleaned up via devres. The interfaces into the MSI core will be changed from irqdomain pointer based interfaces to domain id based interfaces to support multiple MSI domains on a single device (e.g. PCI/MSI[-X] and PCI/IMS. Once the per device domain support is complete the irq domain pointer in struct device::msi.domain will not longer contain a pointer to the "global" MSI domain. It will contain a pointer to the MSI parent domain instead. It would be a horrible maze of conditionals to evaluate all over the place which domain pointer should be used, i.e. the "global" one in device::msi::domain or one from the internal pointer array. To avoid this evaluate in msi_setup_device_data() whether the irq domain which is associated to a device is a "global" or a parent MSI domain. If it is global then copy the pointer into the first entry of the msi_dev_domain array. This allows to convert interfaces and implementation to domain ids while keeping everything existing working. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Acked-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20221124230313.923860399@linutronix.de
Diffstat (limited to 'kernel/irq')
-rw-r--r--kernel/irq/msi.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c
index c2bc94ee5c3e..de65acc5cfb0 100644
--- a/kernel/irq/msi.c
+++ b/kernel/irq/msi.c
@@ -220,6 +220,15 @@ int msi_setup_device_data(struct device *dev)
for (i = 0; i < MSI_MAX_DEVICE_IRQDOMAINS; i++)
xa_init(&md->__domains[i].store);
+ /*
+ * If @dev::msi::domain is set and is a global MSI domain, copy the
+ * pointer into the domain array so all code can operate on domain
+ * ids. The NULL pointer check is required to keep the legacy
+ * architecture specific PCI/MSI support working.
+ */
+ if (dev->msi.domain && !irq_domain_is_msi_parent(dev->msi.domain))
+ md->__domains[MSI_DEFAULT_DOMAIN].domain = dev->msi.domain;
+
mutex_init(&md->mutex);
dev->msi.data = md;
devres_add(dev, md);