|
@@ -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;
|
|
|
}
|