diff options
Diffstat (limited to 'drivers/pci/probe.c')
-rw-r--r-- | drivers/pci/probe.c | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 6b0056e9c..bf8405fb4 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -15,7 +15,7 @@ #include <linux/pci-aspm.h> #include <linux/aer.h> #include <linux/acpi.h> -#include <asm-generic/pci-bridge.h> +#include <linux/irqdomain.h> #include "pci.h" #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ @@ -179,9 +179,6 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, u16 orig_cmd; struct pci_bus_region region, inverted_region; - if (dev->non_compliant_bars) - return 0; - mask = type ? PCI_ROM_ADDRESS_MASK : ~0; /* No printks while decoding is disabled! */ @@ -322,6 +319,9 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) { unsigned int pos, reg; + if (dev->non_compliant_bars) + return; + for (pos = 0; pos < howmany; pos++) { struct resource *res = &dev->resource[pos]; reg = PCI_BASE_ADDRESS_0 + (pos << 2); @@ -678,6 +678,20 @@ static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus) if (!d) d = pci_host_bridge_acpi_msi_domain(bus); +#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN + /* + * If no IRQ domain was found via the OF tree, try looking it up + * directly through the fwnode_handle. + */ + if (!d) { + struct fwnode_handle *fwnode = pci_root_bus_fwnode(bus); + + if (fwnode) + d = irq_find_matching_fwnode(fwnode, + DOMAIN_BUS_PCI_MSI); + } +#endif + return d; } @@ -761,6 +775,12 @@ add_dev: pcibios_add_bus(child); + if (child->ops->add_bus) { + ret = child->ops->add_bus(child); + if (WARN_ON(ret < 0)) + dev_err(&child->dev, "failed to add bus: %d\n", ret); + } + /* Create legacy_io and legacy_mem files for this bus */ pci_create_legacy_files(child); @@ -1622,7 +1642,7 @@ static void pci_init_capabilities(struct pci_dev *dev) pci_pm_init(dev); /* Vital Product Data */ - pci_vpd_pci22_init(dev); + pci_vpd_init(dev); /* Alternative Routing-ID Forwarding */ pci_configure_ari(dev); @@ -1817,6 +1837,13 @@ static int only_one_child(struct pci_bus *bus) return 0; if (pci_pcie_type(parent) == PCI_EXP_TYPE_ROOT_PORT) return 1; + + /* + * PCIe downstream ports are bridges that normally lead to only a + * device 0, but if PCI_SCAN_ALL_PCIE_DEVS is set, scan all + * possible devices, not just device 0. See PCIe spec r3.0, + * sec 7.3.1. + */ if (parent->has_secondary_link && !pci_has_flag(PCI_SCAN_ALL_PCIE_DEVS)) return 1; |