PCI/MSI: Only use the generic MSI layer when domain is hierarchical

Since d8a1cb7575 ("PCI/MSI: Let pci_msi_get_domain use struct
device::msi_domain"), we use the MSI domain associated with the PCI device.

But finding an MSI domain doesn't mean that the domain is implemented using
the generic MSI domain API, and a number of MSI controllers are still using
arch_setup_msi_irq() and arch_teardown_msi_irqs().

Check that the domain we just obtained is hierarchical.  If it is, we can
use the new generic MSI stuff.  Otherwise we have to fall back to the old
arch_setup_msi_irq() and arch_teardown_msi_irqs() interfaces.

This avoids an oops in msi_domain_alloc_irqs() on systems with R-Car,
Tegra, Armada 370, and probably other DesignWare-based host controllers.

Fixes: d8a1cb7575 ("PCI/MSI: Let pci_msi_get_domain use struct device::msi_domain")
Reported-by: Phil Edworthy <[email protected]>
Tested-by: Phil Edworthy <[email protected]>
Signed-off-by: Marc Zyngier <[email protected]>
Signed-off-by: Bjorn Helgaas <[email protected]>
Acked-by: Thomas Gleixner <[email protected]>
CC: [email protected]	# v4.3+
This commit is contained in:
Marc Zyngier 2015-12-04 10:28:14 -06:00 • committed by Bjorn Helgaas
commit 3845d2953a

View file

@ -54,7 +54,7 @@ static int pci_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
struct irq_domain *domain;
domain = pci_msi_get_domain(dev);
if (domain)
if (domain && irq_domain_is_hierarchy(domain))
return pci_msi_domain_alloc_irqs(domain, dev, nvec, type);
return arch_setup_msi_irqs(dev, nvec, type);
@ -65,7 +65,7 @@ static void pci_msi_teardown_msi_irqs(struct pci_dev *dev)
struct irq_domain *domain;
domain = pci_msi_get_domain(dev);
if (domain)
if (domain && irq_domain_is_hierarchy(domain))
pci_msi_domain_free_irqs(domain, dev);
else
arch_teardown_msi_irqs(dev);