diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 4befe09053c1..476f4b1a2727 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -37,11 +37,23 @@ struct irq_domain * __weak arch_get_pci_msi_domain(struct pci_dev *dev) return pci_msi_default_domain; } +static struct irq_domain *pci_msi_get_domain(struct pci_dev *dev) +{ + struct irq_domain *domain = NULL; + + if (dev->bus->msi) + domain = dev->bus->msi->domain; + if (!domain) + domain = arch_get_pci_msi_domain(dev); + + return domain; +} + static int pci_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) { struct irq_domain *domain; - domain = arch_get_pci_msi_domain(dev); + domain = pci_msi_get_domain(dev); if (domain) return pci_msi_domain_alloc_irqs(domain, dev, nvec, type); @@ -52,7 +64,7 @@ static void pci_msi_teardown_msi_irqs(struct pci_dev *dev) { struct irq_domain *domain; - domain = arch_get_pci_msi_domain(dev); + domain = pci_msi_get_domain(dev); if (domain) pci_msi_domain_free_irqs(domain, dev); else diff --git a/include/linux/msi.h b/include/linux/msi.h index 692f217ae813..8ac4a68ffae2 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -108,6 +108,9 @@ struct msi_controller { struct device *dev; struct device_node *of_node; struct list_head list; +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + struct irq_domain *domain; +#endif int (*setup_irq)(struct msi_controller *chip, struct pci_dev *dev, struct msi_desc *desc);