From 902d886d4474a4d2661ae337f3c30dc7a8e59f28 Mon Sep 17 00:00:00 2001 From: Lorenzo Pieralisi Date: Mon, 10 Jul 2017 09:58:46 -0500 Subject: MIPS: PCI: Fix pcibios_scan_bus() NULL check code path If pci_scan_root_bus() fails (ie returns NULL) pcibios_scan_bus() must return immediately since the struct pci_bus pointer it returns is not valid and cannot be used. Move code checking the pci_scan_root_bus() return value to reinstate proper pcibios_scanbus() error path behaviour. Fixes: 88555b481958 ("MIPS: PCI: Support for CONFIG_PCI_DOMAINS_GENERIC") Signed-off-by: Lorenzo Pieralisi Signed-off-by: Bjorn Helgaas Cc: Ralf Baechle Cc: Paul Burton --- arch/mips/pci/pci-legacy.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/mips/pci/pci-legacy.c b/arch/mips/pci/pci-legacy.c index 174575a9a112..71d62f818d77 100644 --- a/arch/mips/pci/pci-legacy.c +++ b/arch/mips/pci/pci-legacy.c @@ -89,16 +89,16 @@ static void pcibios_scanbus(struct pci_controller *hose) pci_add_resource(&resources, hose->busn_resource); bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose, &resources); - hose->bus = bus; - - need_domain_info = need_domain_info || pci_domain_nr(bus); - set_pci_need_domain_info(hose, need_domain_info); - if (!bus) { pci_free_resource_list(&resources); return; } + hose->bus = bus; + + need_domain_info = need_domain_info || pci_domain_nr(bus); + set_pci_need_domain_info(hose, need_domain_info); + next_busno = bus->busn_res.end + 1; /* Don't allow 8-bit bus number overflow inside the hose - reserve some space for bridges. */ -- cgit v1.2.3 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/arc/kernel/pcibios.c | 4 ---- arch/arm64/kernel/pci.c | 8 -------- arch/cris/arch-v32/drivers/pci/bios.c | 4 ---- arch/microblaze/pci/pci-common.c | 6 ------ arch/s390/pci/pci.c | 4 ---- arch/sh/drivers/pci/pci.c | 8 -------- arch/sparc/kernel/pci.c | 4 ---- arch/tile/kernel/pci.c | 8 -------- arch/tile/kernel/pci_gx.c | 5 ----- drivers/pci/probe.c | 9 +++++++++ 10 files changed, 9 insertions(+), 51 deletions(-) (limited to 'arch') diff --git a/arch/arc/kernel/pcibios.c b/arch/arc/kernel/pcibios.c index 72e1d73d0bd6..1c8df8fd5fed 100644 --- a/arch/arc/kernel/pcibios.c +++ b/arch/arc/kernel/pcibios.c @@ -16,7 +16,3 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res, { return res->start; } - -void pcibios_fixup_bus(struct pci_bus *bus) -{ -} diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c index e2b7e4f9cc31..d91051259bb2 100644 --- a/arch/arm64/kernel/pci.c +++ b/arch/arm64/kernel/pci.c @@ -22,14 +22,6 @@ #include #include -/* - * Called after each bus is probed, but before its children are examined - */ -void pcibios_fixup_bus(struct pci_bus *bus) -{ - /* nothing to do, expected to be removed in the future */ -} - /* * We don't have to worry about legacy ISA devices, so nothing to do here */ diff --git a/arch/cris/arch-v32/drivers/pci/bios.c b/arch/cris/arch-v32/drivers/pci/bios.c index 394c2a73d5e2..5cc622c0225e 100644 --- a/arch/cris/arch-v32/drivers/pci/bios.c +++ b/arch/cris/arch-v32/drivers/pci/bios.c @@ -2,10 +2,6 @@ #include #include -void pcibios_fixup_bus(struct pci_bus *b) -{ -} - void pcibios_set_master(struct pci_dev *dev) { u8 lat; diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index 404fb38d06b7..940f266e5d5c 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c @@ -810,12 +810,6 @@ void pcibios_setup_bus_devices(struct pci_bus *bus) } } -void pcibios_fixup_bus(struct pci_bus *bus) -{ - /* nothing to do */ -} -EXPORT_SYMBOL(pcibios_fixup_bus); - /* * We need to avoid collisions with `mirrored' VGA ports * and other strange ISA hardware, so we always want the diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 7b30af5da222..ddb9923fb45d 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -262,10 +262,6 @@ static int zpci_cfg_store(struct zpci_dev *zdev, int offset, u32 val, u8 len) return rc; } -void pcibios_fixup_bus(struct pci_bus *bus) -{ -} - resource_size_t pcibios_align_resource(void *data, const struct resource *res, resource_size_t size, resource_size_t align) 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 diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index 7eceaa10836f..78d3dc25e126 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -690,10 +690,6 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm, return bus; } -void pcibios_fixup_bus(struct pci_bus *pbus) -{ -} - resource_size_t pcibios_align_resource(void *data, const struct resource *res, resource_size_t size, resource_size_t align) { diff --git a/arch/tile/kernel/pci.c b/arch/tile/kernel/pci.c index bc6656b5708b..3113d4d5c329 100644 --- a/arch/tile/kernel/pci.c +++ b/arch/tile/kernel/pci.c @@ -369,14 +369,6 @@ int __init pcibios_init(void) } subsys_initcall(pcibios_init); -/* - * No bus fixups needed. - */ -void pcibios_fixup_bus(struct pci_bus *bus) -{ - /* Nothing needs to be done. */ -} - void pcibios_set_master(struct pci_dev *dev) { /* No special bus mastering setup handling. */ diff --git a/arch/tile/kernel/pci_gx.c b/arch/tile/kernel/pci_gx.c index b554a68eea1b..b89172b592cc 100644 --- a/arch/tile/kernel/pci_gx.c +++ b/arch/tile/kernel/pci_gx.c @@ -1038,11 +1038,6 @@ alloc_mem_map_failed: } subsys_initcall(pcibios_init); -/* No bus fixups needed. */ -void pcibios_fixup_bus(struct pci_bus *bus) -{ -} - /* Process any "pci=" kernel boot arguments. */ char *__init pcibios_setup(char *str) { diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index c31310db0404..376c61173b4e 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -2288,6 +2288,15 @@ void pcie_bus_configure_settings(struct pci_bus *bus) } EXPORT_SYMBOL_GPL(pcie_bus_configure_settings); +/* + * Called after each bus is probed, but before its children are examined. This + * is marked as __weak because multiple architectures define it. + */ +void __weak pcibios_fixup_bus(struct pci_bus *bus) +{ + /* nothing to do, expected to be removed in the future */ +} + unsigned int pci_scan_child_bus(struct pci_bus *bus) { unsigned int devfn, pass, max = bus->busn_res.start; -- cgit v1.2.3 From ecf677c8dcaa7bf13eee31b4d9e4639d559984ad Mon Sep 17 00:00:00 2001 From: Palmer Dabbelt Date: Wed, 2 Aug 2017 14:44:50 -0500 Subject: PCI: Add a generic weak pcibios_align_resource() Multiple architectures define this as a trivial function, and I'm adding another one as part of the RISC-V port. Add a __weak version of pcibios_align_resource() and delete the now-obselete ones in a handful of ports. The only functional change should be that a handful of ports used to export pcibios_fixup_bus(). Only some architectures export this, so I just dropped it. Signed-off-by: Palmer Dabbelt Signed-off-by: Bjorn Helgaas --- arch/arc/kernel/pcibios.c | 9 --------- arch/arm64/kernel/pci.c | 9 --------- arch/ia64/pci/pci.c | 7 ------- arch/microblaze/pci/pci-common.c | 7 ------- arch/sparc/kernel/leon_pci.c | 6 ------ arch/sparc/kernel/pci.c | 6 ------ arch/sparc/kernel/pcic.c | 6 ------ arch/tile/kernel/pci.c | 10 ---------- arch/tile/kernel/pci_gx.c | 9 --------- drivers/pci/setup-res.c | 13 +++++++++++++ 10 files changed, 13 insertions(+), 69 deletions(-) (limited to 'arch') diff --git a/arch/arc/kernel/pcibios.c b/arch/arc/kernel/pcibios.c index 1c8df8fd5fed..05aba5a7b5d2 100644 --- a/arch/arc/kernel/pcibios.c +++ b/arch/arc/kernel/pcibios.c @@ -7,12 +7,3 @@ */ #include - -/* - * We don't have to worry about legacy ISA devices, so nothing to do here - */ -resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t align) -{ - return res->start; -} diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c index d91051259bb2..0e2ea1c78542 100644 --- a/arch/arm64/kernel/pci.c +++ b/arch/arm64/kernel/pci.c @@ -22,15 +22,6 @@ #include #include -/* - * We don't have to worry about legacy ISA devices, so nothing to do here - */ -resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t align) -{ - return res->start; -} - #ifdef CONFIG_ACPI /* * Try to assign the IRQ number when probing a new device diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 4068bde623dc..f5ec736100ee 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -411,13 +411,6 @@ pcibios_disable_device (struct pci_dev *dev) acpi_pci_irq_disable(dev); } -resource_size_t -pcibios_align_resource (void *data, const struct resource *res, - resource_size_t size, resource_size_t align) -{ - return res->start; -} - /** * ia64_pci_get_legacy_mem - generic legacy mem routine * @bus: bus to get legacy memory base address for diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index 940f266e5d5c..5835c09c6e26 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c @@ -823,13 +823,6 @@ void pcibios_setup_bus_devices(struct pci_bus *bus) * but we want to try to avoid allocating at 0x2900-0x2bff * which might have be mirrored at 0x0100-0x03ff.. */ -resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t align) -{ - return res->start; -} -EXPORT_SYMBOL(pcibios_align_resource); - int pcibios_add_device(struct pci_dev *dev) { dev->irq = of_irq_parse_and_map_pci(dev, 0, 0); diff --git a/arch/sparc/kernel/leon_pci.c b/arch/sparc/kernel/leon_pci.c index 4371f72ff025..0eafdf3d036d 100644 --- a/arch/sparc/kernel/leon_pci.c +++ b/arch/sparc/kernel/leon_pci.c @@ -94,9 +94,3 @@ void pcibios_fixup_bus(struct pci_bus *pbus) } } } - -resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t align) -{ - return res->start; -} diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index 78d3dc25e126..3f8670c92951 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -690,12 +690,6 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm, return bus; } -resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t align) -{ - return res->start; -} - int pcibios_enable_device(struct pci_dev *dev, int mask) { u16 cmd, oldcmd; diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index a38787b84322..e038e343f2c1 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c @@ -746,12 +746,6 @@ static void watchdog_reset() { } #endif -resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t align) -{ - return res->start; -} - int pcibios_enable_device(struct pci_dev *pdev, int mask) { return 0; diff --git a/arch/tile/kernel/pci.c b/arch/tile/kernel/pci.c index 3113d4d5c329..8999a20ed9d1 100644 --- a/arch/tile/kernel/pci.c +++ b/arch/tile/kernel/pci.c @@ -66,16 +66,6 @@ static int pci_scan_flags[TILE_NUM_PCIE]; static struct pci_ops tile_cfg_ops; -/* - * We don't need to worry about the alignment of resources. - */ -resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t align) -{ - return res->start; -} -EXPORT_SYMBOL(pcibios_align_resource); - /* * Open a FD to the hypervisor PCI device. * diff --git a/arch/tile/kernel/pci_gx.c b/arch/tile/kernel/pci_gx.c index b89172b592cc..0a7642184a9a 100644 --- a/arch/tile/kernel/pci_gx.c +++ b/arch/tile/kernel/pci_gx.c @@ -108,15 +108,6 @@ static struct pci_ops tile_cfg_ops; /* Mask of CPUs that should receive PCIe interrupts. */ static struct cpumask intr_cpus_map; -/* We don't need to worry about the alignment of resources. */ -resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, - resource_size_t align) -{ - return res->start; -} -EXPORT_SYMBOL(pcibios_align_resource); - /* * Pick a CPU to receive and handle the PCIe interrupts, based on the IRQ #. * For now, we simply send interrupts to non-dataplane CPUs. diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 85774b7a316a..e576e1a8d978 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c @@ -234,6 +234,19 @@ static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev, return 0; } +/* + * We don't have to worry about legacy ISA devices, so nothing to do here. + * This is marked as __weak because multiple architectures define it; it should + * eventually go away. + */ +resource_size_t __weak pcibios_align_resource(void *data, + const struct resource *res, + resource_size_t size, + resource_size_t align) +{ + return res->start; +} + static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, int resno, resource_size_t size, resource_size_t align) { -- cgit v1.2.3 From 77f0c8bc7840a79a26dd4b6e33fce96edd7b1492 Mon Sep 17 00:00:00 2001 From: Palmer Dabbelt Date: Fri, 23 Jun 2017 18:50:44 -0700 Subject: ARC: Remove empty kernel/pcibios.c ARC requires no arch-specific pcibios hooks, so delete this empty file. Signed-off-by: Palmer Dabbelt Signed-off-by: Bjorn Helgaas --- arch/arc/kernel/Makefile | 1 - arch/arc/kernel/pcibios.c | 9 --------- 2 files changed, 10 deletions(-) delete mode 100644 arch/arc/kernel/pcibios.c (limited to 'arch') diff --git a/arch/arc/kernel/Makefile b/arch/arc/kernel/Makefile index 8942c5c3b4c5..2dc5f4296d44 100644 --- a/arch/arc/kernel/Makefile +++ b/arch/arc/kernel/Makefile @@ -12,7 +12,6 @@ obj-y := arcksyms.o setup.o irq.o reset.o ptrace.o process.o devtree.o obj-y += signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o obj-$(CONFIG_ISA_ARCOMPACT) += entry-compact.o intc-compact.o obj-$(CONFIG_ISA_ARCV2) += entry-arcv2.o intc-arcv2.o -obj-$(CONFIG_PCI) += pcibios.o obj-$(CONFIG_MODULES) += arcksyms.o module.o obj-$(CONFIG_SMP) += smp.o diff --git a/arch/arc/kernel/pcibios.c b/arch/arc/kernel/pcibios.c deleted file mode 100644 index 05aba5a7b5d2..000000000000 --- a/arch/arc/kernel/pcibios.c +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright (C) 2014-2015 Synopsys, Inc. (www.synopsys.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -- cgit v1.2.3 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') 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 v1.2.3 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') 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 v1.2.3 From 0e4c2eeb758a91e68b9eaf7a4bee9bd5ed97ff2b Mon Sep 17 00:00:00 2001 From: Lorenzo Pieralisi Date: Mon, 31 Jul 2017 17:37:51 +0100 Subject: alpha/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: Richard Henderson Cc: Ivan Kokshaysky --- arch/alpha/kernel/pci.c | 27 ++++++++++++++++++++------- arch/alpha/kernel/sys_nautilus.c | 31 +++++++++++++++++++++++++++---- 2 files changed, 47 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c index 5f387ee5b5c5..d558287c6133 100644 --- a/arch/alpha/kernel/pci.c +++ b/arch/alpha/kernel/pci.c @@ -312,8 +312,9 @@ common_init_pci(void) { struct pci_controller *hose; struct list_head resources; + struct pci_host_bridge *bridge; struct pci_bus *bus; - int next_busno; + int ret, next_busno; int need_domain_info = 0; u32 pci_mem_end; u32 sg_base; @@ -336,11 +337,25 @@ common_init_pci(void) pci_add_resource_offset(&resources, hose->mem_space, hose->mem_space->start); - bus = pci_scan_root_bus(NULL, next_busno, alpha_mv.pci_ops, - hose, &resources); - if (!bus) + bridge = pci_alloc_host_bridge(0); + if (!bridge) continue; - hose->bus = bus; + + list_splice_init(&resources, &bridge->windows); + bridge->dev.parent = NULL; + bridge->sysdata = hose; + bridge->busnr = next_busno; + bridge->ops = alpha_mv.pci_ops; + bridge->swizzle_irq = alpha_mv.pci_swizzle; + bridge->map_irq = alpha_mv.pci_map_irq; + + ret = pci_scan_root_bus_bridge(bridge); + if (ret) { + pci_free_host_bridge(bridge); + continue; + } + + bus = hose->bus = bridge->bus; hose->need_domain_info = need_domain_info; next_busno = bus->busn_res.end + 1; /* Don't allow 8-bit bus number overflow inside the hose - @@ -354,7 +369,6 @@ common_init_pci(void) pcibios_claim_console_setup(); pci_assign_unassigned_resources(); - pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq); for (hose = hose_head; hose; hose = hose->next) { bus = hose->bus; if (bus) @@ -362,7 +376,6 @@ common_init_pci(void) } } - struct pci_controller * __init alloc_pci_controller(void) { diff --git a/arch/alpha/kernel/sys_nautilus.c b/arch/alpha/kernel/sys_nautilus.c index 2cfaa0e5c577..8ae04a121186 100644 --- a/arch/alpha/kernel/sys_nautilus.c +++ b/arch/alpha/kernel/sys_nautilus.c @@ -194,22 +194,46 @@ static struct resource irongate_mem = { .name = "Irongate PCI MEM", .flags = IORESOURCE_MEM, }; +static struct resource busn_resource = { + .name = "PCI busn", + .start = 0, + .end = 255, + .flags = IORESOURCE_BUS, +}; void __init nautilus_init_pci(void) { struct pci_controller *hose = hose_head; + struct pci_host_bridge *bridge; struct pci_bus *bus; struct pci_dev *irongate; unsigned long bus_align, bus_size, pci_mem; unsigned long memtop = max_low_pfn << PAGE_SHIFT; + int ret; + + bridge = pci_alloc_host_bridge(0); + if (!bridge) + return; + + pci_add_resource(&bridge->windows, &ioport_resource); + pci_add_resource(&bridge->windows, &iomem_resource); + pci_add_resource(&bridge->windows, &busn_resource); + bridge->dev.parent = NULL; + bridge->sysdata = hose; + bridge->busnr = 0; + bridge->ops = alpha_mv.pci_ops; + bridge->swizzle_irq = alpha_mv.pci_swizzle; + bridge->map_irq = alpha_mv.pci_map_irq; /* Scan our single hose. */ - bus = pci_scan_bus(0, alpha_mv.pci_ops, hose); - if (!bus) + ret = pci_scan_root_bus_bridge(bridge); + if (ret) { + pci_free_host_bridge(bridge); return; + } - hose->bus = bus; + bus = hose->bus = bridge->bus; pcibios_claim_one_bus(bus); irongate = pci_get_bus_and_slot(0, 0); @@ -254,7 +278,6 @@ nautilus_init_pci(void) /* pci_common_swizzle() relies on bus->self being NULL for the root bus, so just clear it. */ bus->self = NULL; - pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq); pci_bus_add_devices(bus); } -- cgit v1.2.3 From 19cc4c843f40c6110dd07270414586e7fe4121b2 Mon Sep 17 00:00:00 2001 From: Lorenzo Pieralisi Date: Mon, 31 Jul 2017 17:37:52 +0100 Subject: m68k/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: Geert Uytterhoeven --- arch/m68k/coldfire/pci.c | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/m68k/coldfire/pci.c b/arch/m68k/coldfire/pci.c index 6a640be48568..3097fa2ca746 100644 --- a/arch/m68k/coldfire/pci.c +++ b/arch/m68k/coldfire/pci.c @@ -243,6 +243,13 @@ static struct resource mcf_pci_io = { .flags = IORESOURCE_IO, }; +static struct resource busn_resource = { + .name = "PCI busn", + .start = 0, + .end = 255, + .flags = IORESOURCE_BUS, +}; + /* * Interrupt mapping and setting. */ @@ -258,6 +265,13 @@ static int mcf_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) static int __init mcf_pci_init(void) { + struct pci_host_bridge *bridge; + int ret; + + bridge = pci_alloc_host_bridge(0); + if (!bridge) + return -ENOMEM; + pr_info("ColdFire: PCI bus initialization...\n"); /* Reset the external PCI bus */ @@ -312,14 +326,28 @@ static int __init mcf_pci_init(void) set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(msecs_to_jiffies(200)); - rootbus = pci_scan_bus(0, &mcf_pci_ops, NULL); - if (!rootbus) - return -ENODEV; + + pci_add_resource(&bridge->windows, &ioport_resource); + pci_add_resource(&bridge->windows, &iomem_resource); + pci_add_resource(&bridge->windows, &busn_resource); + bridge->dev.parent = NULL; + bridge->sysdata = NULL; + bridge->busnr = 0; + bridge->ops = &mcf_pci_ops; + bridge->swizzle_irq = pci_common_swizzle; + bridge->map_irq = mcf_pci_map_irq; + + ret = pci_scan_root_bus_bridge(bridge); + if (ret) { + pci_free_host_bridge(bridge); + return ret; + } + + rootbus = bridge->bus; rootbus->resource[0] = &mcf_pci_io; rootbus->resource[1] = &mcf_pci_mem; - pci_fixup_irqs(pci_common_swizzle, mcf_pci_map_irq); pci_bus_size_bridges(rootbus); pci_bus_assign_resources(rootbus); pci_bus_add_devices(rootbus); -- cgit v1.2.3 From 04c81c7293df875ca6a46e2c9a272c7ec72e5145 Mon Sep 17 00:00:00 2001 From: Lorenzo Pieralisi Date: Mon, 31 Jul 2017 17:37:53 +0100 Subject: MIPS: 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: Ralf Baechle Cc: Paul Burton --- arch/mips/pci/pci-legacy.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/mips/pci/pci-legacy.c b/arch/mips/pci/pci-legacy.c index 71d62f818d77..fc7726088103 100644 --- a/arch/mips/pci/pci-legacy.c +++ b/arch/mips/pci/pci-legacy.c @@ -78,6 +78,12 @@ static void pcibios_scanbus(struct pci_controller *hose) static int need_domain_info; LIST_HEAD(resources); struct pci_bus *bus; + struct pci_host_bridge *bridge; + int ret; + + bridge = pci_alloc_host_bridge(0); + if (!bridge) + return; if (hose->get_busno && pci_has_flag(PCI_PROBE_ONLY)) next_busno = (*hose->get_busno)(); @@ -87,14 +93,20 @@ static void pcibios_scanbus(struct pci_controller *hose) pci_add_resource_offset(&resources, hose->io_resource, hose->io_offset); pci_add_resource(&resources, hose->busn_resource); - bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose, - &resources); - if (!bus) { - pci_free_resource_list(&resources); + 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_irq; + ret = pci_scan_root_bus_bridge(bridge); + if (ret) { + pci_free_host_bridge(bridge); return; } - hose->bus = bus; + hose->bus = bus = bridge->bus; need_domain_info = need_domain_info || pci_domain_nr(bus); set_pci_need_domain_info(hose, need_domain_info); @@ -224,8 +236,6 @@ static int __init pcibios_init(void) list_for_each_entry(hose, &controllers, list) pcibios_scanbus(hose); - pci_fixup_irqs(pci_common_swizzle, pcibios_map_irq); - pci_initialized = 1; return 0; -- cgit v1.2.3 From 98611dd735b472c23cc1e8cca90a997393a3a955 Mon Sep 17 00:00:00 2001 From: Lorenzo Pieralisi Date: Mon, 31 Jul 2017 17:37:54 +0100 Subject: 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 Signed-off-by: Bjorn Helgaas Cc: Chris Metcalf --- arch/tile/kernel/pci.c | 21 ++++++++++++++++----- arch/tile/kernel/pci_gx.c | 21 ++++++++++++++++----- 2 files changed, 32 insertions(+), 10 deletions(-) (limited to 'arch') 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) */ int __init pcibios_init(void) { + struct pci_host_bridge *bridge; int i; pr_info("PCI: Probing PCI hardware\n"); @@ -306,16 +307,26 @@ int __init pcibios_init(void) pci_add_resource(&resources, &ioport_resource); pci_add_resource(&resources, &iomem_resource); - bus = pci_scan_root_bus(NULL, 0, controller->ops, - controller, &resources); + + bridge = pci_alloc_host_bridge(0); + if (!bridge) + break; + + list_splice_init(&resources, &bridge->windows); + bridge->dev.parent = NULL; + bridge->sysdata = controller; + bridge->busnr = 0; + bridge->ops = controller->ops; + bridge->swizzle_irq = pci_common_swizzle; + bridge->map_irq = tile_map_irq; + + pci_scan_root_bus_bridge(bridge); + bus = bridge->bus; controller->root_bus = bus; controller->last_busno = bus->busn_res.end; } } - /* Do machine dependent PCI interrupt routing */ - pci_fixup_irqs(pci_common_swizzle, tile_map_irq); - /* * This comes from the generic Linux PCI driver. * 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) resource_size_t offset; LIST_HEAD(resources); int next_busno; + struct pci_host_bridge *bridge; int i; tile_pci_init(); @@ -881,15 +882,25 @@ int __init pcibios_init(void) controller->mem_offset); pci_add_resource(&resources, &controller->io_space); controller->first_busno = next_busno; - bus = pci_scan_root_bus(NULL, next_busno, controller->ops, - controller, &resources); + + bridge = pci_alloc_host_bridge(0); + if (!bridge) + break; + + list_splice_init(&resources, &bridge->windows); + bridge->dev.parent = NULL; + bridge->sysdata = controller; + bridge->busnr = next_busno; + bridge->ops = controller->ops; + bridge->swizzle_irq = pci_common_swizzle; + bridge->map_irq = tile_map_irq; + + pci_scan_root_bus_bridge(bridge); + bus = bridge->bus; controller->root_bus = bus; next_busno = bus->busn_res.end + 1; } - /* Do machine dependent PCI interrupt routing */ - pci_fixup_irqs(pci_common_swizzle, tile_map_irq); - /* * This comes from the generic Linux PCI driver. * -- cgit v1.2.3 From 0d368cb06eb109ad754643f666590f8c0b1c3149 Mon Sep 17 00:00:00 2001 From: Lorenzo Pieralisi Date: Mon, 31 Jul 2017 17:37:55 +0100 Subject: 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 Signed-off-by: Bjorn Helgaas Cc: Guan Xuetao --- arch/unicore32/kernel/pci.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) (limited to 'arch') 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) writel(readl(PCIBRI_CMD) | PCIBRI_CMD_IO | PCIBRI_CMD_MEM, PCIBRI_CMD); } -static int __init pci_puv3_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +static int pci_puv3_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { if (dev->bus->number == 0) { #ifdef CONFIG_ARCH_FPGA /* 4 pci slots */ @@ -252,19 +252,46 @@ void pcibios_fixup_bus(struct pci_bus *bus) } EXPORT_SYMBOL(pcibios_fixup_bus); +static struct resource busn_resource = { + .name = "PCI busn", + .start = 0, + .end = 255, + .flags = IORESOURCE_BUS, +}; + static int __init pci_common_init(void) { struct pci_bus *puv3_bus; + struct pci_host_bridge *bridge; + int ret; + + bridge = pci_alloc_host_bridge(0); + if (!bridge) + return -ENOMEM; pci_puv3_preinit(); - puv3_bus = pci_scan_bus(0, &pci_puv3_ops, NULL); + pci_add_resource(&bridge->windows, &ioport_resource); + pci_add_resource(&bridge->windows, &iomem_resource); + pci_add_resource(&bridge->windows, &busn_resource); + bridge->sysdata = NULL; + bridge->busnr = 0; + bridge->ops = &pci_puv3_ops; + bridge->swizzle_irq = pci_common_swizzle; + bridge->map_irq = pci_puv3_map_irq; + + /* Scan our single hose. */ + ret = pci_scan_root_bus_bridge(bridge); + if (ret) { + pci_free_host_bridge(bridge); + return; + } + + puv3_bus = bridge->bus; if (!puv3_bus) panic("PCI: unable to scan bus!"); - pci_fixup_irqs(pci_common_swizzle, pci_puv3_map_irq); - pci_bus_size_bridges(puv3_bus); pci_bus_assign_resources(puv3_bus); pci_bus_add_devices(puv3_bus); -- cgit v1.2.3 From b483e3c19b2796cbdfbef218478762f2d948e899 Mon Sep 17 00:00:00 2001 From: Lorenzo Pieralisi Date: Mon, 31 Jul 2017 17:37:56 +0100 Subject: sparc/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: "David S. Miller" --- arch/sparc/kernel/leon_pci.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/sparc/kernel/leon_pci.c b/arch/sparc/kernel/leon_pci.c index 4371f72ff025..7b5c7072b006 100644 --- a/arch/sparc/kernel/leon_pci.c +++ b/arch/sparc/kernel/leon_pci.c @@ -25,6 +25,12 @@ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info) { LIST_HEAD(resources); struct pci_bus *root_bus; + struct pci_host_bridge *bridge; + int ret; + + bridge = pci_alloc_host_bridge(0); + if (!bridge) + return; pci_add_resource_offset(&resources, &info->io_space, info->io_space.start - 0x1000); @@ -32,15 +38,21 @@ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info) info->busn.flags = IORESOURCE_BUS; pci_add_resource(&resources, &info->busn); - root_bus = pci_scan_root_bus(&ofdev->dev, 0, info->ops, info, - &resources); - if (!root_bus) { - pci_free_resource_list(&resources); + list_splice_init(&resources, &bridge->windows); + bridge->dev.parent = &ofdev->dev; + bridge->sysdata = info; + bridge->busnr = 0; + bridge->ops = info->ops; + bridge->swizzle_irq = pci_common_swizzle; + bridge->map_irq = info->map_irq; + + ret = pci_scan_root_bus_bridge(bridge); + if (ret) { + pci_free_host_bridge(bridge); return; } - /* Setup IRQs of all devices using custom routines */ - pci_fixup_irqs(pci_common_swizzle, info->map_irq); + root_bus = bridge->bus; /* Assign devices with resources */ pci_assign_unassigned_resources(); -- cgit v1.2.3 From c775697b713b70293507573355aa8c8c177db35b Mon Sep 17 00:00:00 2001 From: Lorenzo Pieralisi Date: Thu, 10 Aug 2017 15:19:25 -0500 Subject: microblaze/PCI: Remove pcibios_setup_bus_{self/devices} dead code 01cf9d524ff0 ("microblaze/PCI: Support generic Xilinx AXI PCIe Host Bridge IP driver") removed pcibios calls to: pcibios_setup_bus_self() pcibios_setup_bus_devices() Given that pcibios_fixup_bus() was the only caller of those functions they have now become dead code (along with the functions they were calling in turn), so they can be removed. Signed-off-by: Lorenzo Pieralisi [bhelgaas: remove "Fixup resources of a PCI<->PCI bridge" comment] Signed-off-by: Bjorn Helgaas Acked-by: Michal Simek Cc: Bharat Kumar Gogada Cc: Ravi Kiran Gummaluri --- arch/microblaze/include/asm/pci.h | 3 - arch/microblaze/pci/pci-common.c | 132 -------------------------------------- 2 files changed, 135 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h index efd4983cb697..114b93488193 100644 --- a/arch/microblaze/include/asm/pci.h +++ b/arch/microblaze/include/asm/pci.h @@ -81,9 +81,6 @@ extern pgprot_t pci_phys_mem_access_prot(struct file *file, #define HAVE_ARCH_PCI_RESOURCE_TO_USER -extern void pcibios_setup_bus_devices(struct pci_bus *bus); -extern void pcibios_setup_bus_self(struct pci_bus *bus); - /* This part of code was originally in xilinx-pci.h */ #ifdef CONFIG_PCI_XILINX extern void __init xilinx_pci_init(void); diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index 5835c09c6e26..2b32c454a22e 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c @@ -678,138 +678,6 @@ static void pcibios_fixup_resources(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources); -/* This function tries to figure out if a bridge resource has been initialized - * by the firmware or not. It doesn't have to be absolutely bullet proof, but - * things go more smoothly when it gets it right. It should covers cases such - * as Apple "closed" bridge resources and bare-metal pSeries unassigned bridges - */ -static int pcibios_uninitialized_bridge_resource(struct pci_bus *bus, - struct resource *res) -{ - struct pci_controller *hose = pci_bus_to_host(bus); - struct pci_dev *dev = bus->self; - resource_size_t offset; - u16 command; - int i; - - /* Job is a bit different between memory and IO */ - if (res->flags & IORESOURCE_MEM) { - /* If the BAR is non-0 (res != pci_mem_offset) then it's - * probably been initialized by somebody - */ - if (res->start != hose->pci_mem_offset) - return 0; - - /* The BAR is 0, let's check if memory decoding is enabled on - * the bridge. If not, we consider it unassigned - */ - pci_read_config_word(dev, PCI_COMMAND, &command); - if ((command & PCI_COMMAND_MEMORY) == 0) - return 1; - - /* Memory decoding is enabled and the BAR is 0. If any of - * the bridge resources covers that starting address (0 then - * it's good enough for us for memory - */ - for (i = 0; i < 3; i++) { - if ((hose->mem_resources[i].flags & IORESOURCE_MEM) && - hose->mem_resources[i].start == hose->pci_mem_offset) - return 0; - } - - /* Well, it starts at 0 and we know it will collide so we may as - * well consider it as unassigned. That covers the Apple case. - */ - return 1; - } else { - /* If the BAR is non-0, then we consider it assigned */ - offset = (unsigned long)hose->io_base_virt - _IO_BASE; - if (((res->start - offset) & 0xfffffffful) != 0) - return 0; - - /* Here, we are a bit different than memory as typically IO - * space starting at low addresses -is- valid. What we do - * instead if that we consider as unassigned anything that - * doesn't have IO enabled in the PCI command register, - * and that's it. - */ - pci_read_config_word(dev, PCI_COMMAND, &command); - if (command & PCI_COMMAND_IO) - return 0; - - /* It's starting at 0 and IO is disabled in the bridge, consider - * it unassigned - */ - return 1; - } -} - -/* Fixup resources of a PCI<->PCI bridge */ -static void pcibios_fixup_bridge(struct pci_bus *bus) -{ - struct resource *res; - int i; - - struct pci_dev *dev = bus->self; - - pci_bus_for_each_resource(bus, res, i) { - if (!res) - continue; - if (!res->flags) - continue; - if (i >= 3 && bus->self->transparent) - continue; - - pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x] fixup...\n", - pci_name(dev), i, - (unsigned long long)res->start, - (unsigned long long)res->end, - (unsigned int)res->flags); - - /* Try to detect uninitialized P2P bridge resources, - * and clear them out so they get re-assigned later - */ - if (pcibios_uninitialized_bridge_resource(bus, res)) { - res->flags = 0; - pr_debug("PCI:%s (unassigned)\n", - pci_name(dev)); - } else { - pr_debug("PCI:%s %016llx-%016llx\n", - pci_name(dev), - (unsigned long long)res->start, - (unsigned long long)res->end); - } - } -} - -void pcibios_setup_bus_self(struct pci_bus *bus) -{ - /* Fix up the bus resources for P2P bridges */ - if (bus->self != NULL) - pcibios_fixup_bridge(bus); -} - -void pcibios_setup_bus_devices(struct pci_bus *bus) -{ - struct pci_dev *dev; - - pr_debug("PCI: Fixup bus devices %d (%s)\n", - bus->number, bus->self ? pci_name(bus->self) : "PHB"); - - list_for_each_entry(dev, &bus->devices, bus_list) { - /* Setup OF node pointer in archdata */ - dev->dev.of_node = pci_device_to_OF_node(dev); - - /* Fixup NUMA node as it may not be setup yet by the generic - * code and is needed by the DMA init - */ - set_dev_node(&dev->dev, pcibus_to_node(dev->bus)); - - /* Read default IRQs and fixup if necessary */ - dev->irq = of_irq_parse_and_map_pci(dev, 0, 0); - } -} - /* * We need to avoid collisions with `mirrored' VGA ports * and other strange ISA hardware, so we always want the -- cgit v1.2.3 From e9a60cac89ab75fad51c12912b489043087beb90 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Wed, 19 Jul 2017 17:57:56 +0800 Subject: arm64: dts: rockchip: convert PCIe to use per-lane PHYs for rk3339 Convert all RK3399 platforms to use per-lane PHY model in order to save more power by idling unused lane(s). Tested-by: Jeffy Chen Signed-off-by: Shawn Lin Signed-off-by: Bjorn Helgaas Reviewed-by: Brian Norris --- arch/arm64/boot/dts/rockchip/rk3399.dtsi | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi index 69c56f7316c4..5b78ce16a87e 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi @@ -238,8 +238,10 @@ linux,pci-domain = <0>; max-link-speed = <1>; msi-map = <0x0 &its 0x0 0x1000>; - phys = <&pcie_phy>; - phy-names = "pcie-phy"; + phys = <&pcie_phy 0>, <&pcie_phy 1>, + <&pcie_phy 2>, <&pcie_phy 3>; + phy-names = "pcie-phy-0", "pcie-phy-1", + "pcie-phy-2", "pcie-phy-3"; ranges = <0x83000000 0x0 0xfa000000 0x0 0xfa000000 0x0 0x1e00000 0x81000000 0x0 0xfbe00000 0x0 0xfbe00000 0x0 0x100000>; resets = <&cru SRST_PCIE_CORE>, <&cru SRST_PCIE_MGMT>, @@ -1295,7 +1297,7 @@ compatible = "rockchip,rk3399-pcie-phy"; clocks = <&cru SCLK_PCIEPHY_REF>; clock-names = "refclk"; - #phy-cells = <0>; + #phy-cells = <1>; resets = <&cru SRST_PCIEPHY>; reset-names = "phy"; status = "disabled"; -- cgit v1.2.3 From f1b0e54e16b3db7882b4158ab4a26b87841753fd Mon Sep 17 00:00:00 2001 From: Jon Derrick Date: Thu, 17 Aug 2017 12:10:12 -0600 Subject: x86/PCI: Move VMD quirk to x86 fixups VMD currently only exists for Intel x86 products, so move the VMD quirk to arch/x86. Signed-off-by: Jon Derrick Signed-off-by: Bjorn Helgaas --- arch/x86/pci/fixup.c | 17 +++++++++++++++++ drivers/pci/quirks.c | 17 ----------------- 2 files changed, 17 insertions(+), 17 deletions(-) (limited to 'arch') diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c index 11e407489db0..4c2e318845ba 100644 --- a/arch/x86/pci/fixup.c +++ b/arch/x86/pci/fixup.c @@ -618,3 +618,20 @@ static void quirk_apple_mbp_poweroff(struct pci_dev *pdev) dev_info(dev, "can't work around MacBook Pro poweroff issue\n"); } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x8c10, quirk_apple_mbp_poweroff); + +/* + * VMD-enabled root ports will change the source ID for all messages + * to the VMD device. Rather than doing device matching with the source + * ID, the AER driver should traverse the child device tree, reading + * AER registers to find the faulting device. + */ +static void quirk_no_aersid(struct pci_dev *pdev) +{ + /* VMD Domain */ + if (pdev->bus->sysdata && pci_domain_nr(pdev->bus) >= 0x10000) + pdev->bus->bus_flags |= PCI_BUS_FLAGS_NO_AERSID; +} +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2030, quirk_no_aersid); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2031, quirk_no_aersid); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2032, quirk_no_aersid); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2033, quirk_no_aersid); diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 6967c6b4cf6b..0b0a2ae9a853 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -4657,23 +4657,6 @@ static void quirk_intel_qat_vf_cap(struct pci_dev *pdev) } DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x443, quirk_intel_qat_vf_cap); -/* - * VMD-enabled root ports will change the source ID for all messages - * to the VMD device. Rather than doing device matching with the source - * ID, the AER driver should traverse the child device tree, reading - * AER registers to find the faulting device. - */ -static void quirk_no_aersid(struct pci_dev *pdev) -{ - /* VMD Domain */ - if (pdev->bus->sysdata && pci_domain_nr(pdev->bus) >= 0x10000) - pdev->bus->bus_flags |= PCI_BUS_FLAGS_NO_AERSID; -} -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2030, quirk_no_aersid); -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2031, quirk_no_aersid); -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2032, quirk_no_aersid); -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2033, quirk_no_aersid); - /* FLR may cause some 82579 devices to hang. */ static void quirk_intel_no_flr(struct pci_dev *dev) { -- cgit v1.2.3 From c37f23d44e866d079d30399cb358dd19617562a1 Mon Sep 17 00:00:00 2001 From: Jon Derrick Date: Thu, 17 Aug 2017 12:10:13 -0600 Subject: x86/PCI: Use is_vmd() rather than relying on the domain number Use the is_vmd() predicate to identify devices below a VMD host rather than relying on the domain number. Signed-off-by: Jon Derrick Signed-off-by: Bjorn Helgaas --- arch/x86/pci/fixup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c index 4c2e318845ba..f2228b150faa 100644 --- a/arch/x86/pci/fixup.c +++ b/arch/x86/pci/fixup.c @@ -628,7 +628,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x8c10, quirk_apple_mbp_poweroff); static void quirk_no_aersid(struct pci_dev *pdev) { /* VMD Domain */ - if (pdev->bus->sysdata && pci_domain_nr(pdev->bus) >= 0x10000) + if (is_vmd(pdev->bus)) pdev->bus->bus_flags |= PCI_BUS_FLAGS_NO_AERSID; } DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2030, quirk_no_aersid); -- cgit v1.2.3