X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Facpi%2Fpci_root.c;h=c3fed31166b552761f2bb9c3b26ef2b7c3e47592;hb=8410565f540db87ca938f56f92780d251e4f157d;hp=b9c52cdbf6587bc641026b123cb0d82625b42493;hpb=9774f3384125912eb491ca77f77907324db3ed05;p=linux-2.6 diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index b9c52cdbf6..c3fed31166 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -36,19 +36,23 @@ #include #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_device_id root_device_ids[] = { + {"PNP0A03", 0}, + {"", 0}, +}; +MODULE_DEVICE_TABLE(acpi, root_device_ids); + 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, + .ids = root_device_ids, .ops = { .add = acpi_pci_root_add, .remove = acpi_pci_root_remove, @@ -117,6 +121,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,7 +169,22 @@ static acpi_status try_get_root_bridge_busnr(acpi_handle handle, int *busnum) return AE_OK; } -static int acpi_pci_root_add(struct acpi_device *device) +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 __devinit acpi_pci_root_add(struct acpi_device *device) { int result = 0; struct acpi_pci_root *root = NULL; @@ -160,15 +192,15 @@ 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) return -EINVAL; - root = kmalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); + root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); if (!root) return -ENOMEM; - memset(root, 0, sizeof(struct acpi_pci_root)); INIT_LIST_HEAD(&root->node); root->device = device; @@ -176,9 +208,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; /* @@ -300,6 +329,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))