diff options
| -rw-r--r-- | drivers/acpi/pci_bind.c | 40 | ||||
| -rw-r--r-- | drivers/acpi/pci_root.c | 24 | ||||
| -rw-r--r-- | drivers/acpi/scan.c | 33 | ||||
| -rw-r--r-- | include/acpi/acpi_drivers.h | 1 |
4 files changed, 43 insertions, 55 deletions
diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c index aa05e92464e6..1e2ae6e7a7e4 100644 --- a/drivers/acpi/pci_bind.c +++ b/drivers/acpi/pci_bind.c | |||
| @@ -223,6 +223,8 @@ int acpi_pci_bind(struct acpi_device *device) | |||
| 223 | data->id.segment, data->id.bus, | 223 | data->id.segment, data->id.bus, |
| 224 | data->id.device, data->id.function)); | 224 | data->id.device, data->id.function)); |
| 225 | data->bus = data->dev->subordinate; | 225 | data->bus = data->dev->subordinate; |
| 226 | device->ops.bind = acpi_pci_bind; | ||
| 227 | device->ops.unbind = acpi_pci_unbind; | ||
| 226 | } | 228 | } |
| 227 | 229 | ||
| 228 | /* | 230 | /* |
| @@ -352,6 +354,8 @@ acpi_pci_bind_root(struct acpi_device *device, | |||
| 352 | 354 | ||
| 353 | data->id = *id; | 355 | data->id = *id; |
| 354 | data->bus = bus; | 356 | data->bus = bus; |
| 357 | device->ops.bind = acpi_pci_bind; | ||
| 358 | device->ops.unbind = acpi_pci_unbind; | ||
| 355 | 359 | ||
| 356 | acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer); | 360 | acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer); |
| 357 | 361 | ||
| @@ -374,39 +378,3 @@ acpi_pci_bind_root(struct acpi_device *device, | |||
| 374 | 378 | ||
| 375 | return result; | 379 | return result; |
| 376 | } | 380 | } |
| 377 | |||
| 378 | #define ACPI_PCI_BRIDGE_DRIVER_NAME "ACPI PCI Bridge Driver" | ||
| 379 | |||
| 380 | static int acpi_pci_bridge_add(struct acpi_device *device); | ||
| 381 | static int acpi_pci_bridge_remove(struct acpi_device *device, int type); | ||
| 382 | |||
| 383 | static struct acpi_driver acpi_pci_bridge_driver = { | ||
| 384 | .name = ACPI_PCI_BRIDGE_DRIVER_NAME, | ||
| 385 | .ids = ACPI_PCI_BRIDGE_HID, | ||
| 386 | .ops = { | ||
| 387 | .add = acpi_pci_bridge_add, | ||
| 388 | .remove = acpi_pci_bridge_remove, | ||
| 389 | }, | ||
| 390 | }; | ||
| 391 | |||
| 392 | static int acpi_pci_bridge_add(struct acpi_device *device) | ||
| 393 | { | ||
| 394 | return acpi_pci_bind(device); | ||
| 395 | } | ||
| 396 | |||
| 397 | static int acpi_pci_bridge_remove(struct acpi_device *device, int type) | ||
| 398 | { | ||
| 399 | return acpi_pci_unbind(device); | ||
| 400 | } | ||
| 401 | |||
| 402 | static int __init acpi_pci_bridge_init(void) | ||
| 403 | { | ||
| 404 | if (acpi_pci_disabled) | ||
| 405 | return 0; | ||
| 406 | if (acpi_bus_register_driver(&acpi_pci_bridge_driver) < 0) | ||
| 407 | return -ENODEV; | ||
| 408 | return 0; | ||
| 409 | } | ||
| 410 | |||
| 411 | /* Should be called after ACPI pci root driver */ | ||
| 412 | subsys_initcall(acpi_pci_bridge_init); | ||
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 9cfc74192419..2e1a74a967bb 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
| @@ -151,6 +151,21 @@ static acpi_status try_get_root_bridge_busnr(acpi_handle handle, int *busnum) | |||
| 151 | return AE_OK; | 151 | return AE_OK; |
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | static void acpi_pci_bridge_scan(struct acpi_device *device) | ||
| 155 | { | ||
| 156 | int status; | ||
| 157 | struct acpi_device *child = NULL; | ||
| 158 | |||
| 159 | if (device->flags.bus_address) | ||
| 160 | if (device->parent && device->parent->ops.bind) { | ||
| 161 | status = device->parent->ops.bind(device); | ||
| 162 | if (!status) { | ||
| 163 | list_for_each_entry(child, &device->children, node) | ||
| 164 | acpi_pci_bridge_scan(child); | ||
| 165 | } | ||
| 166 | } | ||
| 167 | } | ||
| 168 | |||
| 154 | static int acpi_pci_root_add(struct acpi_device *device) | 169 | static int acpi_pci_root_add(struct acpi_device *device) |
| 155 | { | 170 | { |
| 156 | int result = 0; | 171 | int result = 0; |
| @@ -159,6 +174,7 @@ static int acpi_pci_root_add(struct acpi_device *device) | |||
| 159 | acpi_status status = AE_OK; | 174 | acpi_status status = AE_OK; |
| 160 | unsigned long value = 0; | 175 | unsigned long value = 0; |
| 161 | acpi_handle handle = NULL; | 176 | acpi_handle handle = NULL; |
| 177 | struct acpi_device *child; | ||
| 162 | 178 | ||
| 163 | 179 | ||
| 164 | if (!device) | 180 | if (!device) |
| @@ -175,6 +191,8 @@ static int acpi_pci_root_add(struct acpi_device *device) | |||
| 175 | strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); | 191 | strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); |
| 176 | acpi_driver_data(device) = root; | 192 | acpi_driver_data(device) = root; |
| 177 | 193 | ||
| 194 | device->ops.bind = acpi_pci_bind; | ||
| 195 | |||
| 178 | /* | 196 | /* |
| 179 | * Segment | 197 | * Segment |
| 180 | * ------- | 198 | * ------- |
| @@ -294,6 +312,12 @@ static int acpi_pci_root_add(struct acpi_device *device) | |||
| 294 | result = acpi_pci_irq_add_prt(device->handle, root->id.segment, | 312 | result = acpi_pci_irq_add_prt(device->handle, root->id.segment, |
| 295 | root->id.bus); | 313 | root->id.bus); |
| 296 | 314 | ||
| 315 | /* | ||
| 316 | * Scan and bind all _ADR-Based Devices | ||
| 317 | */ | ||
| 318 | list_for_each_entry(child, &device->children, node) | ||
| 319 | acpi_pci_bridge_scan(child); | ||
| 320 | |||
| 297 | end: | 321 | end: |
| 298 | if (result) { | 322 | if (result) { |
| 299 | if (!list_empty(&root->node)) | 323 | if (!list_empty(&root->node)) |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 769e54bc9226..30a39baeac51 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
| @@ -837,20 +837,6 @@ acpi_video_bus_match(struct acpi_device *device) | |||
| 837 | return -ENODEV; | 837 | return -ENODEV; |
| 838 | } | 838 | } |
| 839 | 839 | ||
| 840 | static int acpi_pci_bridge_match(struct acpi_device *device) | ||
| 841 | { | ||
| 842 | acpi_status status; | ||
| 843 | acpi_handle handle; | ||
| 844 | |||
| 845 | /* pci bridge has _PRT but isn't PNP0A03 */ | ||
| 846 | status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle); | ||
| 847 | if (ACPI_FAILURE(status)) | ||
| 848 | return -ENODEV; | ||
| 849 | if (!acpi_match_ids(device, "PNP0A03")) | ||
| 850 | return -ENODEV; | ||
| 851 | return 0; | ||
| 852 | } | ||
| 853 | |||
| 854 | static void acpi_device_set_id(struct acpi_device *device, | 840 | static void acpi_device_set_id(struct acpi_device *device, |
| 855 | struct acpi_device *parent, acpi_handle handle, | 841 | struct acpi_device *parent, acpi_handle handle, |
| 856 | int type) | 842 | int type) |
| @@ -886,10 +872,6 @@ static void acpi_device_set_id(struct acpi_device *device, | |||
| 886 | status = acpi_video_bus_match(device); | 872 | status = acpi_video_bus_match(device); |
| 887 | if(ACPI_SUCCESS(status)) | 873 | if(ACPI_SUCCESS(status)) |
| 888 | hid = ACPI_VIDEO_HID; | 874 | hid = ACPI_VIDEO_HID; |
| 889 | |||
| 890 | status = acpi_pci_bridge_match(device); | ||
| 891 | if(ACPI_SUCCESS(status)) | ||
| 892 | hid = ACPI_PCI_BRIDGE_HID; | ||
| 893 | } | 875 | } |
| 894 | break; | 876 | break; |
| 895 | case ACPI_BUS_TYPE_POWER: | 877 | case ACPI_BUS_TYPE_POWER: |
| @@ -1021,6 +1003,13 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice) | |||
| 1021 | if (!rmdevice) | 1003 | if (!rmdevice) |
| 1022 | return 0; | 1004 | return 0; |
| 1023 | 1005 | ||
| 1006 | /* | ||
| 1007 | * unbind _ADR-Based Devices when hot removal | ||
| 1008 | */ | ||
| 1009 | if (dev->flags.bus_address) { | ||
| 1010 | if ((dev->parent) && (dev->parent->ops.unbind)) | ||
| 1011 | dev->parent->ops.unbind(dev); | ||
| 1012 | } | ||
| 1024 | acpi_device_unregister(dev, ACPI_BUS_REMOVAL_EJECT); | 1013 | acpi_device_unregister(dev, ACPI_BUS_REMOVAL_EJECT); |
| 1025 | 1014 | ||
| 1026 | return 0; | 1015 | return 0; |
| @@ -1137,6 +1126,14 @@ acpi_add_single_object(struct acpi_device **child, | |||
| 1137 | 1126 | ||
| 1138 | result = acpi_device_register(device, parent); | 1127 | result = acpi_device_register(device, parent); |
| 1139 | 1128 | ||
| 1129 | /* | ||
| 1130 | * Bind _ADR-Based Devices when hot add | ||
| 1131 | */ | ||
| 1132 | if (device->flags.bus_address) { | ||
| 1133 | if (device->parent && device->parent->ops.bind) | ||
| 1134 | device->parent->ops.bind(device); | ||
| 1135 | } | ||
| 1136 | |||
| 1140 | end: | 1137 | end: |
| 1141 | if (!result) | 1138 | if (!result) |
| 1142 | *child = device; | 1139 | *child = device; |
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h index be67750ec88b..2781e6628645 100644 --- a/include/acpi/acpi_drivers.h +++ b/include/acpi/acpi_drivers.h | |||
| @@ -44,7 +44,6 @@ | |||
| 44 | #define ACPI_BUTTON_HID_SLEEPF "ACPI_FSB" | 44 | #define ACPI_BUTTON_HID_SLEEPF "ACPI_FSB" |
| 45 | 45 | ||
| 46 | #define ACPI_VIDEO_HID "ACPI_VID" | 46 | #define ACPI_VIDEO_HID "ACPI_VID" |
| 47 | #define ACPI_PCI_BRIDGE_HID "ACPI_PCI" | ||
| 48 | /* -------------------------------------------------------------------------- | 47 | /* -------------------------------------------------------------------------- |
| 49 | PCI | 48 | PCI |
| 50 | -------------------------------------------------------------------------- */ | 49 | -------------------------------------------------------------------------- */ |
