From bccf90d6e063d278b9ddc78dd266d0adef29886c Mon Sep 17 00:00:00 2001 From: Palmer Dabbelt Date: Fri, 23 Jun 2017 18:50:42 -0700 Subject: PCI: Add a generic weak pcibios_fixup_bus() Multiple architectures define this as an empty function, and I'm adding another one as part of the RISC-V port. Add a __weak version of pcibios_fixup_bus() and delete the now-obselete ones in a handful of ports. The only functional change should be that microblaze used to export pcibios_fixup_bus(). None of the other architectures exports this, so I just dropped it. Signed-off-by: Palmer Dabbelt Signed-off-by: Bjorn Helgaas --- arch/sh/drivers/pci/pci.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index c99ee286b69f..749642e1272e 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -154,14 +154,6 @@ static int __init pcibios_init(void) } subsys_initcall(pcibios_init); -/* - * Called after each bus is probed, but before its children - * are examined. - */ -void pcibios_fixup_bus(struct pci_bus *bus) -{ -} - /* * We need to avoid collisions with `mirrored' VGA ports * and other strange ISA hardware, so we always want the -- cgit From 2b8ff9f2769135a08fc7b9c989560f759b80cc1a Mon Sep 17 00:00:00 2001 From: Matthew Minter Date: Mon, 31 Jul 2017 17:37:49 +0100 Subject: sh/PCI: Remove __init optimisations from IRQ mapping functions/data Currently many IRQ mapping functions and data structures use the __init and __initdata optimisations. These result in the relevant functions being innaccessible after boot time. However for deferred IRQ assignment it is important to have access to these functions at PCI device enable time. Therefore, remove the optimisation from the relevant data structures and functions to prepare for deferred IRQ assignment. Signed-off-by: Matthew Minter Signed-off-by: Bjorn Helgaas Cc: Rich Felker Cc: Yoshinori Sato --- arch/sh/drivers/pci/fixups-cayman.c | 2 +- arch/sh/drivers/pci/fixups-dreamcast.c | 2 +- arch/sh/drivers/pci/fixups-r7780rp.c | 2 +- arch/sh/drivers/pci/fixups-rts7751r2d.c | 6 +++--- arch/sh/drivers/pci/fixups-sdk7780.c | 4 ++-- arch/sh/drivers/pci/fixups-se7751.c | 2 +- arch/sh/drivers/pci/fixups-sh03.c | 2 +- arch/sh/drivers/pci/fixups-snapgear.c | 2 +- arch/sh/drivers/pci/fixups-titan.c | 4 ++-- arch/sh/drivers/pci/pcie-sh7786.c | 2 +- 10 files changed, 14 insertions(+), 14 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/drivers/pci/fixups-cayman.c b/arch/sh/drivers/pci/fixups-cayman.c index edc2fb7a5bb2..32467884d6f7 100644 --- a/arch/sh/drivers/pci/fixups-cayman.c +++ b/arch/sh/drivers/pci/fixups-cayman.c @@ -5,7 +5,7 @@ #include #include "pci-sh5.h" -int __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int result = -1; diff --git a/arch/sh/drivers/pci/fixups-dreamcast.c b/arch/sh/drivers/pci/fixups-dreamcast.c index 1d1c5a227e50..9d597f7ab8dd 100644 --- a/arch/sh/drivers/pci/fixups-dreamcast.c +++ b/arch/sh/drivers/pci/fixups-dreamcast.c @@ -76,7 +76,7 @@ static void gapspci_fixup_resources(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, gapspci_fixup_resources); -int __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin) { /* * The interrupt routing semantics here are quite trivial. diff --git a/arch/sh/drivers/pci/fixups-r7780rp.c b/arch/sh/drivers/pci/fixups-r7780rp.c index 57ed3f09d0c2..2c9b58f848dd 100644 --- a/arch/sh/drivers/pci/fixups-r7780rp.c +++ b/arch/sh/drivers/pci/fixups-r7780rp.c @@ -15,7 +15,7 @@ #include #include "pci-sh4.h" -int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) +int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) { return evt2irq(0xa20) + slot; } diff --git a/arch/sh/drivers/pci/fixups-rts7751r2d.c b/arch/sh/drivers/pci/fixups-rts7751r2d.c index eaddb56c45c6..358ac104f08c 100644 --- a/arch/sh/drivers/pci/fixups-rts7751r2d.c +++ b/arch/sh/drivers/pci/fixups-rts7751r2d.c @@ -20,18 +20,18 @@ #define PCIMCR_MRSET_OFF 0xBFFFFFFF #define PCIMCR_RFSH_OFF 0xFFFFFFFB -static u8 rts7751r2d_irq_tab[] __initdata = { +static u8 rts7751r2d_irq_tab[] = { IRQ_PCI_INTA, IRQ_PCI_INTB, IRQ_PCI_INTC, IRQ_PCI_INTD, }; -static char lboxre2_irq_tab[] __initdata = { +static char lboxre2_irq_tab[] = { IRQ_ETH0, IRQ_ETH1, IRQ_INTA, IRQ_INTD, }; -int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) +int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) { if (mach_is_lboxre2()) return lboxre2_irq_tab[slot]; diff --git a/arch/sh/drivers/pci/fixups-sdk7780.c b/arch/sh/drivers/pci/fixups-sdk7780.c index c0a015ae6ecf..24e96dfbdb22 100644 --- a/arch/sh/drivers/pci/fixups-sdk7780.c +++ b/arch/sh/drivers/pci/fixups-sdk7780.c @@ -22,7 +22,7 @@ #define IRQ_INTD evt2irq(0xa80) /* IDSEL [16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31] */ -static char sdk7780_irq_tab[4][16] __initdata = { +static char sdk7780_irq_tab[4][16] = { /* INTA */ { IRQ_INTA, IRQ_INTD, IRQ_INTC, IRQ_INTD, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, @@ -37,7 +37,7 @@ static char sdk7780_irq_tab[4][16] __initdata = { -1, -1, -1 }, }; -int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) +int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) { return sdk7780_irq_tab[pin-1][slot]; } diff --git a/arch/sh/drivers/pci/fixups-se7751.c b/arch/sh/drivers/pci/fixups-se7751.c index 84a88ca92008..1cb8d0ac4fdb 100644 --- a/arch/sh/drivers/pci/fixups-se7751.c +++ b/arch/sh/drivers/pci/fixups-se7751.c @@ -7,7 +7,7 @@ #include #include "pci-sh4.h" -int __init pcibios_map_platform_irq(const struct pci_dev *, u8 slot, u8 pin) +int pcibios_map_platform_irq(const struct pci_dev *, u8 slot, u8 pin) { switch (slot) { case 0: return evt2irq(0x3a0); diff --git a/arch/sh/drivers/pci/fixups-sh03.c b/arch/sh/drivers/pci/fixups-sh03.c index 16207bef9f52..55ac1ba2c74f 100644 --- a/arch/sh/drivers/pci/fixups-sh03.c +++ b/arch/sh/drivers/pci/fixups-sh03.c @@ -4,7 +4,7 @@ #include #include -int __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq; diff --git a/arch/sh/drivers/pci/fixups-snapgear.c b/arch/sh/drivers/pci/fixups-snapgear.c index 6e33ba4cd076..a931e5928f58 100644 --- a/arch/sh/drivers/pci/fixups-snapgear.c +++ b/arch/sh/drivers/pci/fixups-snapgear.c @@ -19,7 +19,7 @@ #include #include "pci-sh4.h" -int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) +int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) { int irq = -1; diff --git a/arch/sh/drivers/pci/fixups-titan.c b/arch/sh/drivers/pci/fixups-titan.c index bd1addb1b8be..a9d563e479d5 100644 --- a/arch/sh/drivers/pci/fixups-titan.c +++ b/arch/sh/drivers/pci/fixups-titan.c @@ -19,7 +19,7 @@ #include #include "pci-sh4.h" -static char titan_irq_tab[] __initdata = { +static char titan_irq_tab[] = { TITAN_IRQ_WAN, TITAN_IRQ_LAN, TITAN_IRQ_MPCIA, @@ -27,7 +27,7 @@ static char titan_irq_tab[] __initdata = { TITAN_IRQ_USB, }; -int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) +int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) { int irq = titan_irq_tab[slot]; diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c index a162a7f86b2e..0167a7352719 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.c +++ b/arch/sh/drivers/pci/pcie-sh7786.c @@ -467,7 +467,7 @@ static int __init pcie_init(struct sh7786_pcie_port *port) return 0; } -int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) +int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) { return evt2irq(0xae0); } -- cgit From 20d693225ab78f0651b0e116b74196aaf8a950bb Mon Sep 17 00:00:00 2001 From: Lorenzo Pieralisi Date: Mon, 31 Jul 2017 17:37:50 +0100 Subject: sh/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 Signed-off-by: Bjorn Helgaas Cc: Rich Felker Cc: Yoshinori Sato --- arch/sh/drivers/pci/pci.c | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index c99ee286b69f..357278c88e98 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -39,8 +39,12 @@ static void pcibios_scanbus(struct pci_channel *hose) LIST_HEAD(resources); struct resource *res; resource_size_t offset; - int i; - struct pci_bus *bus; + int i, ret; + struct pci_host_bridge *bridge; + + bridge = pci_alloc_host_bridge(0); + if (!bridge) + return; for (i = 0; i < hose->nr_resources; i++) { res = hose->resources + i; @@ -52,19 +56,26 @@ static void pcibios_scanbus(struct pci_channel *hose) pci_add_resource_offset(&resources, res, offset); } - bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose, - &resources); - hose->bus = bus; + list_splice_init(&resources, &bridge->windows); + bridge->dev.parent = NULL; + bridge->sysdata = hose; + bridge->busnr = next_busno; + bridge->ops = hose->pci_ops; + bridge->swizzle_irq = pci_common_swizzle; + bridge->map_irq = pcibios_map_platform_irq; + + ret = pci_scan_root_bus_bridge(bridge); + if (ret) { + pci_free_host_bridge(bridge); + return; + } + + hose->bus = bridge->bus; need_domain_info = need_domain_info || hose->index; hose->need_domain_info = need_domain_info; - if (!bus) { - pci_free_resource_list(&resources); - return; - } - - next_busno = bus->busn_res.end + 1; + next_busno = hose->bus->busn_res.end + 1; /* Don't allow 8-bit bus number overflow inside the hose - reserve some space for bridges. */ if (next_busno > 224) { @@ -72,9 +83,9 @@ static void pcibios_scanbus(struct pci_channel *hose) need_domain_info = 1; } - pci_bus_size_bridges(bus); - pci_bus_assign_resources(bus); - pci_bus_add_devices(bus); + pci_bus_size_bridges(hose->bus); + pci_bus_assign_resources(hose->bus); + pci_bus_add_devices(hose->bus); } /* @@ -144,8 +155,6 @@ static int __init pcibios_init(void) for (hose = hose_head; hose; hose = hose->next) pcibios_scanbus(hose); - pci_fixup_irqs(pci_common_swizzle, pcibios_map_platform_irq); - dma_debug_add_bus(&pci_bus_type); pci_initialized = 1; -- cgit