diff options
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/of.c | 25 | ||||
-rw-r--r-- | drivers/pci/probe.c | 5 |
2 files changed, 29 insertions, 1 deletions
diff --git a/drivers/pci/of.c b/drivers/pci/of.c index f0929934bb7a..85844d8c3efd 100644 --- a/drivers/pci/of.c +++ b/drivers/pci/of.c @@ -9,6 +9,7 @@ * 2 of the License, or (at your option) any later version. */ +#include <linux/irqdomain.h> #include <linux/kernel.h> #include <linux/pci.h> #include <linux/of.h> @@ -59,3 +60,27 @@ struct device_node * __weak pcibios_get_phb_of_node(struct pci_bus *bus) return of_node_get(bus->bridge->parent->of_node); return NULL; } + +struct irq_domain *pci_host_bridge_of_msi_domain(struct pci_bus *bus) +{ +#ifdef CONFIG_IRQ_DOMAIN + struct device_node *np; + struct irq_domain *d; + + if (!bus->dev.of_node) + return NULL; + + /* Start looking for a phandle to an MSI controller. */ + np = of_parse_phandle(bus->dev.of_node, "msi-parent", 0); + if (!np) + return NULL; + + d = irq_find_matching_host(np, DOMAIN_BUS_PCI_MSI); + if (d) + return d; + + return irq_find_host(np); +#else + return NULL; +#endif +} diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index c03ecbffc50b..a7afeacce7f1 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -663,12 +663,15 @@ static void pci_set_bus_speed(struct pci_bus *bus) static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus) { + struct irq_domain *d; + /* * Any firmware interface that can resolve the msi_domain * should be called from here. */ + d = pci_host_bridge_of_msi_domain(bus); - return NULL; + return d; } static void pci_set_bus_msi_domain(struct pci_bus *bus) |