summaryrefslogtreecommitdiffstats
path: root/arch/tile
diff options
context:
space:
mode:
authorLorenzo Pieralisi <lorenzo.pieralisi@arm.com>2017-07-31 12:37:54 -0400
committerBjorn Helgaas <bhelgaas@google.com>2017-08-03 17:28:56 -0400
commit98611dd735b472c23cc1e8cca90a997393a3a955 (patch)
treeafd91f5c81f7668de36e6b99cccc77799aa4004d /arch/tile
parent04c81c7293df875ca6a46e2c9a272c7ec72e5145 (diff)
tile/PCI: Replace pci_fixup_irqs() call with host bridge IRQ mapping hooks
The pci_fixup_irqs() function allocates IRQs for all PCI devices present in a system; those PCI devices possibly belong to different PCI bus trees (and possibly rooted at different host bridges) and may well be enabled (ie probed and bound to a driver) by the time pci_fixup_irqs() is called when probing a given host bridge driver. Furthermore, current kernel code relying on pci_fixup_irqs() to assign legacy PCI IRQs to devices does not work at all for hotplugged devices in that the code carrying out the IRQ fixup is called at host bridge driver probe time, which just cannot take into account devices hotplugged after the system has booted. The introduction of map/swizzle function hooks in struct pci_host_bridge allows us to define per-bridge map/swizzle functions that can be used at device probe time in PCI core code to allocate IRQs for a given device (through pci_assign_irq()). Convert PCI host bridge initialization code to the pci_scan_root_bus_bridge() API (that allows to pass a struct pci_host_bridge with initializedmap/swizzle pointers) and remove the pci_fixup_irqs() call from arch code. Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Cc: Chris Metcalf <cmetcalf@mellanox.com>
Diffstat (limited to 'arch/tile')
-rw-r--r--arch/tile/kernel/pci.c21
-rw-r--r--arch/tile/kernel/pci_gx.c21
2 files changed, 32 insertions, 10 deletions
diff --git a/arch/tile/kernel/pci.c b/arch/tile/kernel/pci.c
index bc6656b5708b..884826157765 100644
--- a/arch/tile/kernel/pci.c
+++ b/arch/tile/kernel/pci.c
@@ -274,6 +274,7 @@ static void fixup_read_and_payload_sizes(void)
274 */ 274 */
275int __init pcibios_init(void) 275int __init pcibios_init(void)
276{ 276{
277 struct pci_host_bridge *bridge;
277 int i; 278 int i;
278 279
279 pr_info("PCI: Probing PCI hardware\n"); 280 pr_info("PCI: Probing PCI hardware\n");
@@ -306,16 +307,26 @@ int __init pcibios_init(void)
306 307
307 pci_add_resource(&resources, &ioport_resource); 308 pci_add_resource(&resources, &ioport_resource);
308 pci_add_resource(&resources, &iomem_resource); 309 pci_add_resource(&resources, &iomem_resource);
309 bus = pci_scan_root_bus(NULL, 0, controller->ops, 310
310 controller, &resources); 311 bridge = pci_alloc_host_bridge(0);
312 if (!bridge)
313 break;
314
315 list_splice_init(&resources, &bridge->windows);
316 bridge->dev.parent = NULL;
317 bridge->sysdata = controller;
318 bridge->busnr = 0;
319 bridge->ops = controller->ops;
320 bridge->swizzle_irq = pci_common_swizzle;
321 bridge->map_irq = tile_map_irq;
322
323 pci_scan_root_bus_bridge(bridge);
324 bus = bridge->bus;
311 controller->root_bus = bus; 325 controller->root_bus = bus;
312 controller->last_busno = bus->busn_res.end; 326 controller->last_busno = bus->busn_res.end;
313 } 327 }
314 } 328 }
315 329
316 /* Do machine dependent PCI interrupt routing */
317 pci_fixup_irqs(pci_common_swizzle, tile_map_irq);
318
319 /* 330 /*
320 * This comes from the generic Linux PCI driver. 331 * This comes from the generic Linux PCI driver.
321 * 332 *
diff --git a/arch/tile/kernel/pci_gx.c b/arch/tile/kernel/pci_gx.c
index b554a68eea1b..e68317083ac7 100644
--- a/arch/tile/kernel/pci_gx.c
+++ b/arch/tile/kernel/pci_gx.c
@@ -669,6 +669,7 @@ int __init pcibios_init(void)
669 resource_size_t offset; 669 resource_size_t offset;
670 LIST_HEAD(resources); 670 LIST_HEAD(resources);
671 int next_busno; 671 int next_busno;
672 struct pci_host_bridge *bridge;
672 int i; 673 int i;
673 674
674 tile_pci_init(); 675 tile_pci_init();
@@ -881,15 +882,25 @@ int __init pcibios_init(void)
881 controller->mem_offset); 882 controller->mem_offset);
882 pci_add_resource(&resources, &controller->io_space); 883 pci_add_resource(&resources, &controller->io_space);
883 controller->first_busno = next_busno; 884 controller->first_busno = next_busno;
884 bus = pci_scan_root_bus(NULL, next_busno, controller->ops, 885
885 controller, &resources); 886 bridge = pci_alloc_host_bridge(0);
887 if (!bridge)
888 break;
889
890 list_splice_init(&resources, &bridge->windows);
891 bridge->dev.parent = NULL;
892 bridge->sysdata = controller;
893 bridge->busnr = next_busno;
894 bridge->ops = controller->ops;
895 bridge->swizzle_irq = pci_common_swizzle;
896 bridge->map_irq = tile_map_irq;
897
898 pci_scan_root_bus_bridge(bridge);
899 bus = bridge->bus;
886 controller->root_bus = bus; 900 controller->root_bus = bus;
887 next_busno = bus->busn_res.end + 1; 901 next_busno = bus->busn_res.end + 1;
888 } 902 }
889 903
890 /* Do machine dependent PCI interrupt routing */
891 pci_fixup_irqs(pci_common_swizzle, tile_map_irq);
892
893 /* 904 /*
894 * This comes from the generic Linux PCI driver. 905 * This comes from the generic Linux PCI driver.
895 * 906 *