summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/linux/msi.h3
-rw-r--r--kernel/irq/msi.c9
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);