Merge branch 'drm-patches' of master.kernel.org:/pub/scm/linux/kernel/git/airlied...
[powerpc.git] / drivers / acpi / pci_root.c
index a860efa..ad4145a 100644 (file)
 #include <acpi/acpi_drivers.h>
 
 #define _COMPONENT             ACPI_PCI_COMPONENT
-ACPI_MODULE_NAME("pci_root")
+ACPI_MODULE_NAME("pci_root");
 #define ACPI_PCI_ROOT_CLASS            "pci_bridge"
 #define ACPI_PCI_ROOT_HID              "PNP0A03"
-#define ACPI_PCI_ROOT_DRIVER_NAME      "ACPI PCI Root Bridge Driver"
 #define ACPI_PCI_ROOT_DEVICE_NAME      "PCI Root Bridge"
 static int acpi_pci_root_add(struct acpi_device *device);
 static int acpi_pci_root_remove(struct acpi_device *device, int type);
 static int acpi_pci_root_start(struct acpi_device *device);
 
 static struct acpi_driver acpi_pci_root_driver = {
-       .name = ACPI_PCI_ROOT_DRIVER_NAME,
+       .name = "pci_root",
        .class = ACPI_PCI_ROOT_CLASS,
        .ids = ACPI_PCI_ROOT_HID,
        .ops = {
@@ -117,6 +116,19 @@ void acpi_pci_unregister_driver(struct acpi_pci_driver *driver)
 
 EXPORT_SYMBOL(acpi_pci_unregister_driver);
 
+acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus)
+{
+       struct acpi_pci_root *tmp;
+       
+       list_for_each_entry(tmp, &acpi_pci_roots, node) {
+               if ((tmp->id.segment == (u16) seg) && (tmp->id.bus == (u16) bus))
+                       return tmp->device->handle;
+       }
+       return NULL;            
+}
+
+EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle);
+
 static acpi_status
 get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
 {
@@ -152,6 +164,21 @@ static acpi_status try_get_root_bridge_busnr(acpi_handle handle, int *busnum)
        return AE_OK;
 }
 
+static void acpi_pci_bridge_scan(struct acpi_device *device)
+{
+       int status;
+       struct acpi_device *child = NULL;
+
+       if (device->flags.bus_address)
+               if (device->parent && device->parent->ops.bind) {
+                       status = device->parent->ops.bind(device);
+                       if (!status) {
+                               list_for_each_entry(child, &device->children, node)
+                                       acpi_pci_bridge_scan(child);
+                       }
+               }
+}
+
 static int acpi_pci_root_add(struct acpi_device *device)
 {
        int result = 0;
@@ -160,6 +187,7 @@ static int acpi_pci_root_add(struct acpi_device *device)
        acpi_status status = AE_OK;
        unsigned long value = 0;
        acpi_handle handle = NULL;
+       struct acpi_device *child;
 
 
        if (!device)
@@ -175,9 +203,6 @@ static int acpi_pci_root_add(struct acpi_device *device)
        strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS);
        acpi_driver_data(device) = root;
 
-       /*
-        * TBD: Doesn't the bus driver automatically set this?
-        */
        device->ops.bind = acpi_pci_bind;
 
        /* 
@@ -299,6 +324,12 @@ static int acpi_pci_root_add(struct acpi_device *device)
                result = acpi_pci_irq_add_prt(device->handle, root->id.segment,
                                              root->id.bus);
 
+       /*
+        * Scan and bind all _ADR-Based Devices
+        */
+       list_for_each_entry(child, &device->children, node)
+               acpi_pci_bridge_scan(child);
+
       end:
        if (result) {
                if (!list_empty(&root->node))