path: root/drivers/pci
diff options
authorJean-Philippe Brucker <>2021-05-10 19:31:30 +0200
committerBjorn Helgaas <>2021-05-25 18:37:37 -0500
commit85aabbd7b315c65673084b6227bee92c00405239 (patch)
tree63b2c9b396ffd828691891afcc552163f46edfe9 /drivers/pci
parent2ee4c8a268764e751ee44dfffa76c813cfc27aee (diff)
PCI/MSI: Fix MSIs for generic hosts that use device-tree's "msi-map"
Since commit 9ec37efb8783 ("PCI/MSI: Make pci_host_common_probe() declare its reliance on MSI domains"), platforms that rely on the "msi-map" device-tree property don't get MSIs anymore. On the Arm Fast Model for example [1], the host bridge doesn't have a "msi-parent" property since it doesn't itself generate MSIs, and so doesn't get a MSI domain. It has an "msi-map" property instead to describe MSI controllers of child devices. As a result, due to the new msi_domain check in pci_register_host_bridge(), the whole bus gets PCI_BUS_FLAGS_NO_MSI. Check whether the root complex has an "msi-map" property before giving up on MSIs. [1] arch/arm64/boot/dts/arm/fvp-base-revc.dts Fixes: 9ec37efb8783 ("PCI/MSI: Make pci_host_common_probe() declare its reliance on MSI domains") Link: Signed-off-by: Jean-Philippe Brucker <> Signed-off-by: Bjorn Helgaas <> Acked-by: Marc Zyngier <>
Diffstat (limited to 'drivers/pci')
2 files changed, 9 insertions, 1 deletions
diff --git a/drivers/pci/of.c b/drivers/pci/of.c
index da5b414d585a..85dcb7097da4 100644
--- a/drivers/pci/of.c
+++ b/drivers/pci/of.c
@@ -103,6 +103,13 @@ struct irq_domain *pci_host_bridge_of_msi_domain(struct pci_bus *bus)
+bool pci_host_of_has_msi_map(struct device *dev)
+ if (dev && dev->of_node)
+ return of_get_property(dev->of_node, "msi-map", NULL);
+ return false;
static inline int __of_pci_pci_compare(struct device_node *node,
unsigned int data)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 3a62d09b8869..275204646c68 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -925,7 +925,8 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
- if (bridge->msi_domain && !dev_get_msi_domain(&bus->dev))
+ if (bridge->msi_domain && !dev_get_msi_domain(&bus->dev) &&
+ !pci_host_of_has_msi_map(parent))
bus->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
if (!parent)