aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLorenzo Pieralisi <lorenzo.pieralisi@arm.com>2017-07-31 12:37:55 -0400
committerBjorn Helgaas <bhelgaas@google.com>2017-08-03 17:29:34 -0400
commit0d368cb06eb109ad754643f666590f8c0b1c3149 (patch)
tree4aaa1121684a701b3fbf5005ad8dd349a714bbf7
parent98611dd735b472c23cc1e8cca90a997393a3a955 (diff)
unicore32/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 initialized map/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: Guan Xuetao <gxt@mprc.pku.edu.cn>
-rw-r--r--arch/unicore32/kernel/pci.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/arch/unicore32/kernel/pci.c b/arch/unicore32/kernel/pci.c
index 1053bca1f8aa..9f26840e41b1 100644
--- a/arch/unicore32/kernel/pci.c
+++ b/arch/unicore32/kernel/pci.c
@@ -101,7 +101,7 @@ void pci_puv3_preinit(void)
101 writel(readl(PCIBRI_CMD) | PCIBRI_CMD_IO | PCIBRI_CMD_MEM, PCIBRI_CMD); 101 writel(readl(PCIBRI_CMD) | PCIBRI_CMD_IO | PCIBRI_CMD_MEM, PCIBRI_CMD);
102} 102}
103 103
104static int __init pci_puv3_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) 104static int pci_puv3_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
105{ 105{
106 if (dev->bus->number == 0) { 106 if (dev->bus->number == 0) {
107#ifdef CONFIG_ARCH_FPGA /* 4 pci slots */ 107#ifdef CONFIG_ARCH_FPGA /* 4 pci slots */
@@ -252,19 +252,46 @@ void pcibios_fixup_bus(struct pci_bus *bus)
252} 252}
253EXPORT_SYMBOL(pcibios_fixup_bus); 253EXPORT_SYMBOL(pcibios_fixup_bus);
254 254
255static struct resource busn_resource = {
256 .name = "PCI busn",
257 .start = 0,
258 .end = 255,
259 .flags = IORESOURCE_BUS,
260};
261
255static int __init pci_common_init(void) 262static int __init pci_common_init(void)
256{ 263{
257 struct pci_bus *puv3_bus; 264 struct pci_bus *puv3_bus;
265 struct pci_host_bridge *bridge;
266 int ret;
267
268 bridge = pci_alloc_host_bridge(0);
269 if (!bridge)
270 return -ENOMEM;
258 271
259 pci_puv3_preinit(); 272 pci_puv3_preinit();
260 273
261 puv3_bus = pci_scan_bus(0, &pci_puv3_ops, NULL); 274 pci_add_resource(&bridge->windows, &ioport_resource);
275 pci_add_resource(&bridge->windows, &iomem_resource);
276 pci_add_resource(&bridge->windows, &busn_resource);
277 bridge->sysdata = NULL;
278 bridge->busnr = 0;
279 bridge->ops = &pci_puv3_ops;
280 bridge->swizzle_irq = pci_common_swizzle;
281 bridge->map_irq = pci_puv3_map_irq;
282
283 /* Scan our single hose. */
284 ret = pci_scan_root_bus_bridge(bridge);
285 if (ret) {
286 pci_free_host_bridge(bridge);
287 return;
288 }
289
290 puv3_bus = bridge->bus;
262 291
263 if (!puv3_bus) 292 if (!puv3_bus)
264 panic("PCI: unable to scan bus!"); 293 panic("PCI: unable to scan bus!");
265 294
266 pci_fixup_irqs(pci_common_swizzle, pci_puv3_map_irq);
267
268 pci_bus_size_bridges(puv3_bus); 295 pci_bus_size_bridges(puv3_bus);
269 pci_bus_assign_resources(puv3_bus); 296 pci_bus_assign_resources(puv3_bus);
270 pci_bus_add_devices(puv3_bus); 297 pci_bus_add_devices(puv3_bus);