diff options
-rw-r--r-- | drivers/acpi/bus.c | 6 | ||||
-rw-r--r-- | drivers/acpi/scan.c | 42 | ||||
-rw-r--r-- | include/acpi/acpi_bus.h | 2 |
3 files changed, 40 insertions, 10 deletions
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index fcb59c21c68d..c3237774632f 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -340,7 +340,7 @@ static void acpi_bus_osc_support(void) | |||
340 | */ | 340 | */ |
341 | static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) | 341 | static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) |
342 | { | 342 | { |
343 | struct acpi_device *device = NULL; | 343 | struct acpi_device *device; |
344 | struct acpi_driver *driver; | 344 | struct acpi_driver *driver; |
345 | 345 | ||
346 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Notification %#02x to handle %p\n", | 346 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Notification %#02x to handle %p\n", |
@@ -387,12 +387,14 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) | |||
387 | break; | 387 | break; |
388 | } | 388 | } |
389 | 389 | ||
390 | acpi_bus_get_device(handle, &device); | 390 | device = acpi_bus_get_acpi_device(handle); |
391 | if (device) { | 391 | if (device) { |
392 | driver = device->driver; | 392 | driver = device->driver; |
393 | if (driver && driver->ops.notify && | 393 | if (driver && driver->ops.notify && |
394 | (driver->flags & ACPI_DRIVER_ALL_NOTIFY_EVENTS)) | 394 | (driver->flags & ACPI_DRIVER_ALL_NOTIFY_EVENTS)) |
395 | driver->ops.notify(device, type); | 395 | driver->ops.notify(device, type); |
396 | |||
397 | acpi_bus_put_acpi_device(device); | ||
396 | } | 398 | } |
397 | } | 399 | } |
398 | 400 | ||
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 7384158c7f87..59eba29a6066 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -476,7 +476,7 @@ static void acpi_device_hotplug(void *data, u32 src) | |||
476 | 476 | ||
477 | out: | 477 | out: |
478 | acpi_evaluate_hotplug_ost(adev->handle, src, ost_code, NULL); | 478 | acpi_evaluate_hotplug_ost(adev->handle, src, ost_code, NULL); |
479 | put_device(&adev->dev); | 479 | acpi_bus_put_acpi_device(adev); |
480 | mutex_unlock(&acpi_scan_lock); | 480 | mutex_unlock(&acpi_scan_lock); |
481 | unlock_device_hotplug(); | 481 | unlock_device_hotplug(); |
482 | } | 482 | } |
@@ -488,9 +488,6 @@ static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data) | |||
488 | struct acpi_device *adev; | 488 | struct acpi_device *adev; |
489 | acpi_status status; | 489 | acpi_status status; |
490 | 490 | ||
491 | if (acpi_bus_get_device(handle, &adev)) | ||
492 | goto err_out; | ||
493 | |||
494 | switch (type) { | 491 | switch (type) { |
495 | case ACPI_NOTIFY_BUS_CHECK: | 492 | case ACPI_NOTIFY_BUS_CHECK: |
496 | acpi_handle_debug(handle, "ACPI_NOTIFY_BUS_CHECK event\n"); | 493 | acpi_handle_debug(handle, "ACPI_NOTIFY_BUS_CHECK event\n"); |
@@ -512,12 +509,15 @@ static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data) | |||
512 | /* non-hotplug event; possibly handled by other handler */ | 509 | /* non-hotplug event; possibly handled by other handler */ |
513 | return; | 510 | return; |
514 | } | 511 | } |
515 | get_device(&adev->dev); | 512 | adev = acpi_bus_get_acpi_device(handle); |
513 | if (!adev) | ||
514 | goto err_out; | ||
515 | |||
516 | status = acpi_hotplug_execute(acpi_device_hotplug, adev, type); | 516 | status = acpi_hotplug_execute(acpi_device_hotplug, adev, type); |
517 | if (ACPI_SUCCESS(status)) | 517 | if (ACPI_SUCCESS(status)) |
518 | return; | 518 | return; |
519 | 519 | ||
520 | put_device(&adev->dev); | 520 | acpi_bus_put_acpi_device(adev); |
521 | 521 | ||
522 | err_out: | 522 | err_out: |
523 | acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL); | 523 | acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL); |
@@ -1112,14 +1112,16 @@ static void acpi_scan_drop_device(acpi_handle handle, void *context) | |||
1112 | mutex_unlock(&acpi_device_del_lock); | 1112 | mutex_unlock(&acpi_device_del_lock); |
1113 | } | 1113 | } |
1114 | 1114 | ||
1115 | int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device) | 1115 | static int acpi_get_device_data(acpi_handle handle, struct acpi_device **device, |
1116 | void (*callback)(void *)) | ||
1116 | { | 1117 | { |
1117 | acpi_status status; | 1118 | acpi_status status; |
1118 | 1119 | ||
1119 | if (!device) | 1120 | if (!device) |
1120 | return -EINVAL; | 1121 | return -EINVAL; |
1121 | 1122 | ||
1122 | status = acpi_get_data(handle, acpi_scan_drop_device, (void **)device); | 1123 | status = acpi_get_data_full(handle, acpi_scan_drop_device, |
1124 | (void **)device, callback); | ||
1123 | if (ACPI_FAILURE(status) || !*device) { | 1125 | if (ACPI_FAILURE(status) || !*device) { |
1124 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No context for object [%p]\n", | 1126 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No context for object [%p]\n", |
1125 | handle)); | 1127 | handle)); |
@@ -1127,8 +1129,32 @@ int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device) | |||
1127 | } | 1129 | } |
1128 | return 0; | 1130 | return 0; |
1129 | } | 1131 | } |
1132 | |||
1133 | int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device) | ||
1134 | { | ||
1135 | return acpi_get_device_data(handle, device, NULL); | ||
1136 | } | ||
1130 | EXPORT_SYMBOL(acpi_bus_get_device); | 1137 | EXPORT_SYMBOL(acpi_bus_get_device); |
1131 | 1138 | ||
1139 | static void get_acpi_device(void *dev) | ||
1140 | { | ||
1141 | if (dev) | ||
1142 | get_device(&((struct acpi_device *)dev)->dev); | ||
1143 | } | ||
1144 | |||
1145 | struct acpi_device *acpi_bus_get_acpi_device(acpi_handle handle) | ||
1146 | { | ||
1147 | struct acpi_device *adev = NULL; | ||
1148 | |||
1149 | acpi_get_device_data(handle, &adev, get_acpi_device); | ||
1150 | return adev; | ||
1151 | } | ||
1152 | |||
1153 | void acpi_bus_put_acpi_device(struct acpi_device *adev) | ||
1154 | { | ||
1155 | put_device(&adev->dev); | ||
1156 | } | ||
1157 | |||
1132 | int acpi_device_add(struct acpi_device *device, | 1158 | int acpi_device_add(struct acpi_device *device, |
1133 | void (*release)(struct device *)) | 1159 | void (*release)(struct device *)) |
1134 | { | 1160 | { |
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 8256eb4ad057..94fd61a0456d 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
@@ -381,6 +381,8 @@ extern int unregister_acpi_notifier(struct notifier_block *); | |||
381 | */ | 381 | */ |
382 | 382 | ||
383 | int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device); | 383 | int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device); |
384 | struct acpi_device *acpi_bus_get_acpi_device(acpi_handle handle); | ||
385 | void acpi_bus_put_acpi_device(struct acpi_device *adev); | ||
384 | acpi_status acpi_bus_get_status_handle(acpi_handle handle, | 386 | acpi_status acpi_bus_get_status_handle(acpi_handle handle, |
385 | unsigned long long *sta); | 387 | unsigned long long *sta); |
386 | int acpi_bus_get_status(struct acpi_device *device); | 388 | int acpi_bus_get_status(struct acpi_device *device); |