===================================================================
@@ -1632,18 +1632,17 @@ unsigned int pci_scan_child_bus(struct p
return max;
}
-struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
- struct pci_ops *ops, void *sysdata, struct list_head *resources)
+/**
+ * pci_alloc_root - Allocate memory for PCI root bus and bridge representations.
+ * @bus: Bus number of the root bus.
+ * @ops: Root bus operations.
+ * @sysdata: Architecture-specific data.
+ */
+struct pci_host_bridge *pci_alloc_root(int bus, struct pci_ops *ops,
+ void *sysdata)
{
- int error;
struct pci_host_bridge *bridge;
struct pci_bus *b, *b2;
- struct pci_host_bridge_window *window, *n;
- struct resource *res;
- resource_size_t offset;
- char bus_addr[64];
- char *fmt;
-
b = pci_alloc_bus();
if (!b)
@@ -1651,16 +1650,43 @@ struct pci_bus *pci_create_root_bus(stru
b->sysdata = sysdata;
b->ops = ops;
+ b->number = bus;
b2 = pci_find_bus(pci_domain_nr(b), bus);
if (b2) {
- /* If we already got to this bus through a different bridge, ignore it */
+ /*
+ * If we already got to this bus through a different bridge,
+ * ignore it.
+ */
dev_dbg(&b2->dev, "bus already known\n");
- goto err_out;
+ } else {
+ bridge = pci_alloc_host_bridge(b);
+ if (bridge)
+ return bridge;
}
- bridge = pci_alloc_host_bridge(b);
- if (!bridge)
- goto err_out;
+ kfree(b);
+ return NULL;
+}
+
+/**
+ * pci_add_root - Register PCI root bridge and root bus.
+ * @bridge: Bridge to register.
+ * @parent: Parent device of the bridge.
+ * @resources: Bridge resources.
+ *
+ * Register PCI root bridge and bus allocated by %pci_alloc_root().
+ */
+struct pci_bus *pci_add_root(struct pci_host_bridge *bridge,
+ struct device *parent, struct list_head *resources)
+{
+ int error;
+ struct pci_bus *b = bridge->bus;
+ struct pci_host_bridge_window *window, *n;
+ struct resource *res;
+ resource_size_t offset;
+ char bus_addr[64];
+ int bus = b->number;
+ char *fmt;
bridge->dev.parent = parent;
bridge->dev.release = pci_release_bus_bridge_dev;
@@ -1668,6 +1694,7 @@ struct pci_bus *pci_create_root_bus(stru
error = device_register(&bridge->dev);
if (error)
goto bridge_dev_reg_err;
+
b->bridge = get_device(&bridge->dev);
device_enable_async_suspend(b->bridge);
pci_set_bus_of_node(b);
@@ -1685,7 +1712,7 @@ struct pci_bus *pci_create_root_bus(stru
/* Create legacy_io and legacy_mem files for this bus */
pci_create_legacy_files(b);
- b->number = b->busn_res.start = bus;
+ b->busn_res.start = bus;
if (parent)
dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev));
@@ -1725,11 +1752,18 @@ class_dev_reg_err:
device_unregister(&bridge->dev);
bridge_dev_reg_err:
kfree(bridge);
-err_out:
kfree(b);
return NULL;
}
+struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
+ struct pci_ops *ops, void *sysdata, struct list_head *resources)
+{
+ struct pci_host_bridge *bridge = pci_alloc_root(bus, ops, sysdata);
+
+ return bridge ? pci_add_root(bridge, parent, resources) : NULL;
+}
+
int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int bus_max)
{
struct resource *res = &b->busn_res;
===================================================================
@@ -302,24 +302,6 @@ static int acpi_pci_find_device(struct d
return 0;
}
-static int acpi_pci_find_root_bridge(struct device *dev, acpi_handle *handle)
-{
- int num;
- unsigned int seg, bus;
-
- /*
- * The string should be the same as root bridge's name
- * Please look at 'pci_scan_bus_parented'
- */
- num = sscanf(dev_name(dev), "pci%04x:%02x", &seg, &bus);
- if (num != 2)
- return -ENODEV;
- *handle = acpi_get_pci_rootbridge_handle(seg, bus);
- if (!*handle)
- return -ENODEV;
- return 0;
-}
-
static void pci_acpi_setup(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
@@ -378,7 +360,6 @@ static void pci_acpi_cleanup(struct devi
static struct acpi_bus_type acpi_pci_bus = {
.bus = &pci_bus_type,
.find_device = acpi_pci_find_device,
- .find_bridge = acpi_pci_find_root_bridge,
.setup = pci_acpi_setup,
.cleanup = pci_acpi_cleanup,
};
===================================================================
@@ -107,24 +107,6 @@ void acpi_pci_unregister_driver(struct a
}
EXPORT_SYMBOL(acpi_pci_unregister_driver);
-acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus)
-{
- struct acpi_pci_root *root;
- acpi_handle handle = NULL;
-
- mutex_lock(&acpi_pci_root_lock);
- list_for_each_entry(root, &acpi_pci_roots, node)
- if ((root->segment == (u16) seg) &&
- (root->secondary.start == (u16) bus)) {
- handle = root->device->handle;
- break;
- }
- mutex_unlock(&acpi_pci_root_lock);
- return handle;
-}
-
-EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle);
-
/**
* acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root bridge
* @handle - the ACPI CA node in question.
===================================================================
@@ -443,7 +443,6 @@ struct acpi_pci_root {
/* helper */
acpi_handle acpi_get_child(acpi_handle, u64);
int acpi_is_root_bridge(acpi_handle);
-acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int);
struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle);
#define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)ACPI_HANDLE(dev))
===================================================================
@@ -700,6 +700,11 @@ void pci_bus_add_devices(const struct pc
struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus,
struct pci_ops *ops, void *sysdata);
struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata);
+struct pci_host_bridge *pci_alloc_root(int bus, struct pci_ops *ops,
+ void *sysdata);
+struct pci_bus *pci_add_root(struct pci_host_bridge *bridge,
+ struct device *parent,
+ struct list_head *resources);
struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
struct pci_ops *ops, void *sysdata,
struct list_head *resources);
===================================================================
@@ -551,9 +551,15 @@ struct pci_bus * __devinit pci_acpi_scan
}
if (!setup_mcfg_map(info, domain, (u8)root->secondary.start,
- (u8)root->secondary.end, root->mcfg_addr))
- bus = pci_create_root_bus(NULL, busnum, &pci_root_ops,
- sd, &resources);
+ (u8)root->secondary.end, root->mcfg_addr)) {
+ struct pci_host_bridge *bridge;
+
+ bridge = pci_alloc_root(busnum, &pci_root_ops, sd);
+ if (bridge) {
+ ACPI_HANDLE_SET(&bridge->dev, device->handle);
+ bus = pci_add_root(bridge, NULL, &resources);
+ }
+ }
if (bus) {
pci_scan_child_bus(bus);
===================================================================
@@ -333,6 +333,7 @@ pci_acpi_scan_root(struct acpi_pci_root
struct pci_controller *controller;
unsigned int windows = 0;
struct pci_root_info info;
+ struct pci_host_bridge *bridge;
struct pci_bus *pbus;
char *name;
int pxm;
@@ -378,8 +379,13 @@ pci_acpi_scan_root(struct acpi_pci_root
* should handle the case here, but it appears that IA64 hasn't
* such quirk. So we just ignore the case now.
*/
- pbus = pci_create_root_bus(NULL, bus, &pci_root_ops, controller,
- &info.resources);
+ bridge = pci_alloc_root(bus, &pci_root_ops, controller);
+ if (bridge) {
+ ACPI_HANDLE_SET(&bridge->dev, device->handle);
+ pbus = pci_add_root(bridge, NULL, &info.resources);
+ } else {
+ pbus = NULL;
+ }
if (!pbus) {
pci_free_resource_list(&info.resources);
return NULL;