summaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/bios32.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel/bios32.c')
-rw-r--r--arch/arm/kernel/bios32.c44
1 files changed, 28 insertions, 16 deletions
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index b259956365a0..56dc1a3a33b4 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) {
@@ -481,26 +484,37 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
break;
}
+ bridge->map_irq = pcibios_map_irq;
+ bridge->swizzle_irq = pcibios_swizzle;
+
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;
}
@@ -519,8 +533,6 @@ void pci_common_init_dev(struct device *parent, struct hw_pci *hw)
if (hw->postinit)
hw->postinit();
- pci_fixup_irqs(pcibios_swizzle, pcibios_map_irq);
-
list_for_each_entry(sys, &head, node) {
struct pci_bus *bus = sys->bus;