diff options
author | Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> | 2017-06-28 23:13:55 +0300 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2017-06-28 23:13:55 +0300 |
commit | 97ad2bdcbe8598a69ee1f372ed6c0fbdb2869218 (patch) | |
tree | b35c25eb4093c0d19f7b3fa6d8c17c0ff2fabdb5 /arch/arm/kernel | |
parent | cea9bc0be624fb0dc488cb10df40be1323b6b758 (diff) | |
download | linux-97ad2bdcbe8598a69ee1f372ed6c0fbdb2869218.tar.xz |
ARM/PCI: Convert PCI scan API to pci_scan_root_bus_bridge()
The introduction of pci_scan_root_bus_bridge() provides a PCI core API to
scan a PCI root bus backed by an already initialized struct pci_host_bridge
object, which simplifies the bus scan interface and makes the PCI scan root
bus interface easier to generalize as members are added to the struct
pci_host_bridge.
Convert ARM bios32 code to pci_scan_root_bus_bridge() to improve the PCI
root bus scanning interface.
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
[bhelgaas: fold in warning fix from Arnd Bergmann <arnd@arndb.de>:
http://lkml.kernel.org/r/20170621215323.3921382-1-arnd@arndb.de]
[bhelgaas: set bridge->ops for mv78xx0]
[bhelgaas: fold in fixes from Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>:
http://lkml.kernel.org/r/20170701135457.GB8977@red-moon]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Andrew Lunn <andrew@lunn.ch>
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r-- | arch/arm/kernel/bios32.c | 39 |
1 files changed, 25 insertions, 14 deletions
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index b259956365a0..4c7621ac389c 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -458,10 +458,14 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw, int nr, busnr; for (nr = busnr = 0; nr < hw->nr_controllers; nr++) { - sys = kzalloc(sizeof(struct pci_sys_data), GFP_KERNEL); - if (WARN(!sys, "PCI: unable to allocate sys data!")) + struct pci_host_bridge *bridge; + + bridge = pci_alloc_host_bridge(sizeof(struct pci_sys_data)); + if (WARN(!bridge, "PCI: unable to allocate bridge!")) break; + sys = pci_host_bridge_priv(bridge); + sys->busnr = busnr; sys->swizzle = hw->swizzle; sys->map_irq = hw->map_irq; @@ -473,7 +477,6 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw, ret = hw->setup(nr, sys); if (ret > 0) { - struct pci_host_bridge *host_bridge; ret = pcibios_init_resource(nr, sys, hw->io_optional); if (ret) { @@ -482,25 +485,33 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw, } if (hw->scan) - sys->bus = hw->scan(nr, sys); - else - sys->bus = pci_scan_root_bus_msi(parent, - sys->busnr, hw->ops, sys, - &sys->resources, hw->msi_ctrl); + ret = hw->scan(nr, bridge); + else { + list_splice_init(&sys->resources, + &bridge->windows); + bridge->dev.parent = parent; + bridge->sysdata = sys; + bridge->busnr = sys->busnr; + bridge->ops = hw->ops; + bridge->msi = hw->msi_ctrl; + bridge->align_resource = + hw->align_resource; + + ret = pci_scan_root_bus_bridge(bridge); + } - if (WARN(!sys->bus, "PCI: unable to scan bus!")) { - kfree(sys); + if (WARN(ret < 0, "PCI: unable to scan bus!")) { + pci_free_host_bridge(bridge); break; } + sys->bus = bridge->bus; + busnr = sys->bus->busn_res.end + 1; list_add(&sys->node, head); - - host_bridge = pci_find_host_bridge(sys->bus); - host_bridge->align_resource = hw->align_resource; } else { - kfree(sys); + pci_free_host_bridge(bridge); if (ret < 0) break; } |