diff options
-rw-r--r-- | include/linux/msi.h | 3 | ||||
-rw-r--r-- | kernel/irq/msi.c | 9 |
2 files changed, 12 insertions, 0 deletions
diff --git a/include/linux/msi.h b/include/linux/msi.h index f7b9c41a4f54..fdbc80d81e26 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -77,6 +77,7 @@ struct msi_desc; struct pci_dev; struct platform_msi_priv_data; struct device_attribute; +struct irq_domain; void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg); #ifdef CONFIG_GENERIC_MSI_IRQ @@ -177,9 +178,11 @@ enum msi_desc_filter { /** * struct msi_dev_domain - The internals of MSI domain info per device * @store: Xarray for storing MSI descriptor pointers + * @irqdomain: Pointer to a per device interrupt domain */ struct msi_dev_domain { struct xarray store; + struct irq_domain *domain; }; /** 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); |