diff options
-rw-r--r-- | drivers/acpi/dock.c | 25 | ||||
-rw-r--r-- | drivers/acpi/internal.h | 2 | ||||
-rw-r--r-- | drivers/acpi/osl.c | 96 | ||||
-rw-r--r-- | drivers/acpi/pci_root.c | 14 | ||||
-rw-r--r-- | drivers/acpi/scan.c | 43 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 18 | ||||
-rw-r--r-- | include/acpi/acpi_bus.h | 12 | ||||
-rw-r--r-- | include/acpi/acpiosxf.h | 3 |
8 files changed, 71 insertions, 142 deletions
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 05ea4be01a83..eab7d1145bfa 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
@@ -671,39 +671,20 @@ static void dock_notify(struct dock_station *ds, u32 event) | |||
671 | } | 671 | } |
672 | } | 672 | } |
673 | 673 | ||
674 | struct dock_data { | 674 | static void acpi_dock_deferred_cb(void *data, u32 event) |
675 | struct dock_station *ds; | ||
676 | u32 event; | ||
677 | }; | ||
678 | |||
679 | static void acpi_dock_deferred_cb(void *context) | ||
680 | { | 675 | { |
681 | struct dock_data *data = context; | ||
682 | |||
683 | acpi_scan_lock_acquire(); | 676 | acpi_scan_lock_acquire(); |
684 | dock_notify(data->ds, data->event); | 677 | dock_notify(data, event); |
685 | acpi_scan_lock_release(); | 678 | acpi_scan_lock_release(); |
686 | kfree(data); | ||
687 | } | 679 | } |
688 | 680 | ||
689 | static void dock_notify_handler(acpi_handle handle, u32 event, void *data) | 681 | static void dock_notify_handler(acpi_handle handle, u32 event, void *data) |
690 | { | 682 | { |
691 | struct dock_data *dd; | ||
692 | |||
693 | if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK | 683 | if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK |
694 | && event != ACPI_NOTIFY_EJECT_REQUEST) | 684 | && event != ACPI_NOTIFY_EJECT_REQUEST) |
695 | return; | 685 | return; |
696 | 686 | ||
697 | dd = kmalloc(sizeof(*dd), GFP_KERNEL); | 687 | acpi_hotplug_execute(acpi_dock_deferred_cb, data, event); |
698 | if (dd) { | ||
699 | acpi_status status; | ||
700 | |||
701 | dd->ds = data; | ||
702 | dd->event = event; | ||
703 | status = acpi_os_hotplug_execute(acpi_dock_deferred_cb, dd); | ||
704 | if (ACPI_FAILURE(status)) | ||
705 | kfree(dd); | ||
706 | } | ||
707 | } | 688 | } |
708 | 689 | ||
709 | /** | 690 | /** |
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 80cd1a10c4c3..c6db680c826c 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
@@ -87,7 +87,7 @@ void acpi_device_add_finalize(struct acpi_device *device); | |||
87 | void acpi_free_pnp_ids(struct acpi_device_pnp *pnp); | 87 | void acpi_free_pnp_ids(struct acpi_device_pnp *pnp); |
88 | int acpi_bind_one(struct device *dev, acpi_handle handle); | 88 | int acpi_bind_one(struct device *dev, acpi_handle handle); |
89 | int acpi_unbind_one(struct device *dev); | 89 | int acpi_unbind_one(struct device *dev); |
90 | void acpi_bus_device_eject(struct acpi_device *device, u32 ost_src); | 90 | void acpi_bus_device_eject(void *data, u32 ost_src); |
91 | 91 | ||
92 | /* -------------------------------------------------------------------------- | 92 | /* -------------------------------------------------------------------------- |
93 | Power Resource | 93 | Power Resource |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index e5f416c7f66e..cfc3e260a688 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -61,7 +61,6 @@ struct acpi_os_dpc { | |||
61 | acpi_osd_exec_callback function; | 61 | acpi_osd_exec_callback function; |
62 | void *context; | 62 | void *context; |
63 | struct work_struct work; | 63 | struct work_struct work; |
64 | int wait; | ||
65 | }; | 64 | }; |
66 | 65 | ||
67 | #ifdef CONFIG_ACPI_CUSTOM_DSDT | 66 | #ifdef CONFIG_ACPI_CUSTOM_DSDT |
@@ -1067,9 +1066,6 @@ static void acpi_os_execute_deferred(struct work_struct *work) | |||
1067 | { | 1066 | { |
1068 | struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work); | 1067 | struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work); |
1069 | 1068 | ||
1070 | if (dpc->wait) | ||
1071 | acpi_os_wait_events_complete(); | ||
1072 | |||
1073 | dpc->function(dpc->context); | 1069 | dpc->function(dpc->context); |
1074 | kfree(dpc); | 1070 | kfree(dpc); |
1075 | } | 1071 | } |
@@ -1089,8 +1085,8 @@ static void acpi_os_execute_deferred(struct work_struct *work) | |||
1089 | * | 1085 | * |
1090 | ******************************************************************************/ | 1086 | ******************************************************************************/ |
1091 | 1087 | ||
1092 | static acpi_status __acpi_os_execute(acpi_execute_type type, | 1088 | acpi_status acpi_os_execute(acpi_execute_type type, |
1093 | acpi_osd_exec_callback function, void *context, int hp) | 1089 | acpi_osd_exec_callback function, void *context) |
1094 | { | 1090 | { |
1095 | acpi_status status = AE_OK; | 1091 | acpi_status status = AE_OK; |
1096 | struct acpi_os_dpc *dpc; | 1092 | struct acpi_os_dpc *dpc; |
@@ -1117,20 +1113,11 @@ static acpi_status __acpi_os_execute(acpi_execute_type type, | |||
1117 | dpc->context = context; | 1113 | dpc->context = context; |
1118 | 1114 | ||
1119 | /* | 1115 | /* |
1120 | * We can't run hotplug code in keventd_wq/kacpid_wq/kacpid_notify_wq | ||
1121 | * because the hotplug code may call driver .remove() functions, | ||
1122 | * which invoke flush_scheduled_work/acpi_os_wait_events_complete | ||
1123 | * to flush these workqueues. | ||
1124 | * | ||
1125 | * To prevent lockdep from complaining unnecessarily, make sure that | 1116 | * To prevent lockdep from complaining unnecessarily, make sure that |
1126 | * there is a different static lockdep key for each workqueue by using | 1117 | * there is a different static lockdep key for each workqueue by using |
1127 | * INIT_WORK() for each of them separately. | 1118 | * INIT_WORK() for each of them separately. |
1128 | */ | 1119 | */ |
1129 | if (hp) { | 1120 | if (type == OSL_NOTIFY_HANDLER) { |
1130 | queue = kacpi_hotplug_wq; | ||
1131 | dpc->wait = 1; | ||
1132 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); | ||
1133 | } else if (type == OSL_NOTIFY_HANDLER) { | ||
1134 | queue = kacpi_notify_wq; | 1121 | queue = kacpi_notify_wq; |
1135 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); | 1122 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); |
1136 | } else { | 1123 | } else { |
@@ -1155,28 +1142,59 @@ static acpi_status __acpi_os_execute(acpi_execute_type type, | |||
1155 | } | 1142 | } |
1156 | return status; | 1143 | return status; |
1157 | } | 1144 | } |
1145 | EXPORT_SYMBOL(acpi_os_execute); | ||
1158 | 1146 | ||
1159 | acpi_status acpi_os_execute(acpi_execute_type type, | 1147 | void acpi_os_wait_events_complete(void) |
1160 | acpi_osd_exec_callback function, void *context) | ||
1161 | { | 1148 | { |
1162 | return __acpi_os_execute(type, function, context, 0); | 1149 | flush_workqueue(kacpid_wq); |
1150 | flush_workqueue(kacpi_notify_wq); | ||
1163 | } | 1151 | } |
1164 | EXPORT_SYMBOL(acpi_os_execute); | ||
1165 | 1152 | ||
1166 | acpi_status acpi_os_hotplug_execute(acpi_osd_exec_callback function, | 1153 | struct acpi_hp_work { |
1167 | void *context) | 1154 | struct work_struct work; |
1155 | acpi_hp_callback func; | ||
1156 | void *data; | ||
1157 | u32 src; | ||
1158 | }; | ||
1159 | |||
1160 | static void acpi_hotplug_work_fn(struct work_struct *work) | ||
1168 | { | 1161 | { |
1169 | return __acpi_os_execute(0, function, context, 1); | 1162 | struct acpi_hp_work *hpw = container_of(work, struct acpi_hp_work, work); |
1163 | |||
1164 | acpi_os_wait_events_complete(); | ||
1165 | hpw->func(hpw->data, hpw->src); | ||
1166 | kfree(hpw); | ||
1170 | } | 1167 | } |
1171 | EXPORT_SYMBOL(acpi_os_hotplug_execute); | ||
1172 | 1168 | ||
1173 | void acpi_os_wait_events_complete(void) | 1169 | acpi_status acpi_hotplug_execute(acpi_hp_callback func, void *data, u32 src) |
1174 | { | 1170 | { |
1175 | flush_workqueue(kacpid_wq); | 1171 | struct acpi_hp_work *hpw; |
1176 | flush_workqueue(kacpi_notify_wq); | 1172 | |
1173 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
1174 | "Scheduling function [%p(%p, %u)] for deferred execution.\n", | ||
1175 | func, data, src)); | ||
1176 | |||
1177 | hpw = kmalloc(sizeof(*hpw), GFP_KERNEL); | ||
1178 | if (!hpw) | ||
1179 | return AE_NO_MEMORY; | ||
1180 | |||
1181 | INIT_WORK(&hpw->work, acpi_hotplug_work_fn); | ||
1182 | hpw->func = func; | ||
1183 | hpw->data = data; | ||
1184 | hpw->src = src; | ||
1185 | /* | ||
1186 | * We can't run hotplug code in kacpid_wq/kacpid_notify_wq etc., because | ||
1187 | * the hotplug code may call driver .remove() functions, which may | ||
1188 | * invoke flush_scheduled_work()/acpi_os_wait_events_complete() to flush | ||
1189 | * these workqueues. | ||
1190 | */ | ||
1191 | if (!queue_work(kacpi_hotplug_wq, &hpw->work)) { | ||
1192 | kfree(hpw); | ||
1193 | return AE_ERROR; | ||
1194 | } | ||
1195 | return AE_OK; | ||
1177 | } | 1196 | } |
1178 | 1197 | ||
1179 | EXPORT_SYMBOL(acpi_os_wait_events_complete); | ||
1180 | 1198 | ||
1181 | acpi_status | 1199 | acpi_status |
1182 | acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle) | 1200 | acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle) |
@@ -1825,25 +1843,3 @@ void acpi_os_set_prepare_extended_sleep(int (*func)(u8 sleep_state, | |||
1825 | { | 1843 | { |
1826 | __acpi_os_prepare_extended_sleep = func; | 1844 | __acpi_os_prepare_extended_sleep = func; |
1827 | } | 1845 | } |
1828 | |||
1829 | |||
1830 | void alloc_acpi_hp_work(acpi_handle handle, u32 type, void *context, | ||
1831 | void (*func)(struct work_struct *work)) | ||
1832 | { | ||
1833 | struct acpi_hp_work *hp_work; | ||
1834 | int ret; | ||
1835 | |||
1836 | hp_work = kmalloc(sizeof(*hp_work), GFP_KERNEL); | ||
1837 | if (!hp_work) | ||
1838 | return; | ||
1839 | |||
1840 | hp_work->handle = handle; | ||
1841 | hp_work->type = type; | ||
1842 | hp_work->context = context; | ||
1843 | |||
1844 | INIT_WORK(&hp_work->work, func); | ||
1845 | ret = queue_work(kacpi_hotplug_wq, &hp_work->work); | ||
1846 | if (!ret) | ||
1847 | kfree(hp_work); | ||
1848 | } | ||
1849 | EXPORT_SYMBOL_GPL(alloc_acpi_hp_work); | ||
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index d77f0bf7eda0..417876bce854 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -592,17 +592,10 @@ static void handle_root_bridge_insertion(acpi_handle handle) | |||
592 | acpi_handle_err(handle, "cannot add bridge to acpi list\n"); | 592 | acpi_handle_err(handle, "cannot add bridge to acpi list\n"); |
593 | } | 593 | } |
594 | 594 | ||
595 | static void _handle_hotplug_event_root(struct work_struct *work) | 595 | static void hotplug_event_root(void *data, u32 type) |
596 | { | 596 | { |
597 | acpi_handle handle = data; | ||
597 | struct acpi_pci_root *root; | 598 | struct acpi_pci_root *root; |
598 | struct acpi_hp_work *hp_work; | ||
599 | acpi_handle handle; | ||
600 | u32 type; | ||
601 | |||
602 | hp_work = container_of(work, struct acpi_hp_work, work); | ||
603 | handle = hp_work->handle; | ||
604 | type = hp_work->type; | ||
605 | kfree(hp_work); /* allocated in handle_hotplug_event_bridge */ | ||
606 | 599 | ||
607 | acpi_scan_lock_acquire(); | 600 | acpi_scan_lock_acquire(); |
608 | 601 | ||
@@ -654,8 +647,7 @@ static void _handle_hotplug_event_root(struct work_struct *work) | |||
654 | static void handle_hotplug_event_root(acpi_handle handle, u32 type, | 647 | static void handle_hotplug_event_root(acpi_handle handle, u32 type, |
655 | void *context) | 648 | void *context) |
656 | { | 649 | { |
657 | alloc_acpi_hp_work(handle, type, context, | 650 | acpi_hotplug_execute(hotplug_event_root, handle, type); |
658 | _handle_hotplug_event_root); | ||
659 | } | 651 | } |
660 | 652 | ||
661 | static acpi_status __init | 653 | static acpi_status __init |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 5cd7f8c5666a..276cde70a514 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -285,8 +285,9 @@ static int acpi_scan_hot_remove(struct acpi_device *device) | |||
285 | return 0; | 285 | return 0; |
286 | } | 286 | } |
287 | 287 | ||
288 | void acpi_bus_device_eject(struct acpi_device *device, u32 ost_src) | 288 | void acpi_bus_device_eject(void *data, u32 ost_src) |
289 | { | 289 | { |
290 | struct acpi_device *device = data; | ||
290 | acpi_handle handle = device->handle; | 291 | acpi_handle handle = device->handle; |
291 | struct acpi_scan_handler *handler; | 292 | struct acpi_scan_handler *handler; |
292 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; | 293 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; |
@@ -327,8 +328,9 @@ void acpi_bus_device_eject(struct acpi_device *device, u32 ost_src) | |||
327 | goto out; | 328 | goto out; |
328 | } | 329 | } |
329 | 330 | ||
330 | static void acpi_scan_bus_device_check(acpi_handle handle, u32 ost_source) | 331 | static void acpi_scan_bus_device_check(void *data, u32 ost_source) |
331 | { | 332 | { |
333 | acpi_handle handle = data; | ||
332 | struct acpi_device *device = NULL; | 334 | struct acpi_device *device = NULL; |
333 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; | 335 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; |
334 | int error; | 336 | int error; |
@@ -363,18 +365,6 @@ static void acpi_scan_bus_device_check(acpi_handle handle, u32 ost_source) | |||
363 | unlock_device_hotplug(); | 365 | unlock_device_hotplug(); |
364 | } | 366 | } |
365 | 367 | ||
366 | static void acpi_scan_bus_check(void *context) | ||
367 | { | ||
368 | acpi_scan_bus_device_check((acpi_handle)context, | ||
369 | ACPI_NOTIFY_BUS_CHECK); | ||
370 | } | ||
371 | |||
372 | static void acpi_scan_device_check(void *context) | ||
373 | { | ||
374 | acpi_scan_bus_device_check((acpi_handle)context, | ||
375 | ACPI_NOTIFY_DEVICE_CHECK); | ||
376 | } | ||
377 | |||
378 | static void acpi_hotplug_unsupported(acpi_handle handle, u32 type) | 368 | static void acpi_hotplug_unsupported(acpi_handle handle, u32 type) |
379 | { | 369 | { |
380 | u32 ost_status; | 370 | u32 ost_status; |
@@ -403,18 +393,8 @@ static void acpi_hotplug_unsupported(acpi_handle handle, u32 type) | |||
403 | acpi_evaluate_hotplug_ost(handle, type, ost_status, NULL); | 393 | acpi_evaluate_hotplug_ost(handle, type, ost_status, NULL); |
404 | } | 394 | } |
405 | 395 | ||
406 | /** | ||
407 | * acpi_bus_hot_remove_device: Hot-remove a device and its children. | ||
408 | * @context: Address of the ACPI device object to hot-remove. | ||
409 | */ | ||
410 | static void acpi_bus_hot_remove_device(void *context) | ||
411 | { | ||
412 | acpi_bus_device_eject(context, ACPI_NOTIFY_EJECT_REQUEST); | ||
413 | } | ||
414 | |||
415 | static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data) | 396 | static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data) |
416 | { | 397 | { |
417 | acpi_osd_exec_callback callback; | ||
418 | struct acpi_scan_handler *handler = data; | 398 | struct acpi_scan_handler *handler = data; |
419 | struct acpi_device *adev; | 399 | struct acpi_device *adev; |
420 | acpi_status status; | 400 | acpi_status status; |
@@ -425,11 +405,9 @@ static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data) | |||
425 | switch (type) { | 405 | switch (type) { |
426 | case ACPI_NOTIFY_BUS_CHECK: | 406 | case ACPI_NOTIFY_BUS_CHECK: |
427 | acpi_handle_debug(handle, "ACPI_NOTIFY_BUS_CHECK event\n"); | 407 | acpi_handle_debug(handle, "ACPI_NOTIFY_BUS_CHECK event\n"); |
428 | callback = acpi_scan_bus_check; | ||
429 | break; | 408 | break; |
430 | case ACPI_NOTIFY_DEVICE_CHECK: | 409 | case ACPI_NOTIFY_DEVICE_CHECK: |
431 | acpi_handle_debug(handle, "ACPI_NOTIFY_DEVICE_CHECK event\n"); | 410 | acpi_handle_debug(handle, "ACPI_NOTIFY_DEVICE_CHECK event\n"); |
432 | callback = acpi_scan_device_check; | ||
433 | break; | 411 | break; |
434 | case ACPI_NOTIFY_EJECT_REQUEST: | 412 | case ACPI_NOTIFY_EJECT_REQUEST: |
435 | acpi_handle_debug(handle, "ACPI_NOTIFY_EJECT_REQUEST event\n"); | 413 | acpi_handle_debug(handle, "ACPI_NOTIFY_EJECT_REQUEST event\n"); |
@@ -438,8 +416,7 @@ static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data) | |||
438 | goto err_out; | 416 | goto err_out; |
439 | 417 | ||
440 | get_device(&adev->dev); | 418 | get_device(&adev->dev); |
441 | callback = acpi_bus_hot_remove_device; | 419 | status = acpi_hotplug_execute(acpi_bus_device_eject, adev, type); |
442 | status = acpi_os_hotplug_execute(callback, adev); | ||
443 | if (ACPI_SUCCESS(status)) | 420 | if (ACPI_SUCCESS(status)) |
444 | return; | 421 | return; |
445 | 422 | ||
@@ -449,7 +426,7 @@ static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data) | |||
449 | /* non-hotplug event; possibly handled by other handler */ | 426 | /* non-hotplug event; possibly handled by other handler */ |
450 | return; | 427 | return; |
451 | } | 428 | } |
452 | status = acpi_os_hotplug_execute(callback, handle); | 429 | status = acpi_hotplug_execute(acpi_scan_bus_device_check, handle, type); |
453 | if (ACPI_SUCCESS(status)) | 430 | if (ACPI_SUCCESS(status)) |
454 | return; | 431 | return; |
455 | 432 | ||
@@ -484,11 +461,6 @@ static ssize_t power_state_show(struct device *dev, | |||
484 | 461 | ||
485 | static DEVICE_ATTR(power_state, 0444, power_state_show, NULL); | 462 | static DEVICE_ATTR(power_state, 0444, power_state_show, NULL); |
486 | 463 | ||
487 | static void acpi_eject_store_work(void *context) | ||
488 | { | ||
489 | acpi_bus_device_eject(context, ACPI_OST_EC_OSPM_EJECT); | ||
490 | } | ||
491 | |||
492 | static ssize_t | 464 | static ssize_t |
493 | acpi_eject_store(struct device *d, struct device_attribute *attr, | 465 | acpi_eject_store(struct device *d, struct device_attribute *attr, |
494 | const char *buf, size_t count) | 466 | const char *buf, size_t count) |
@@ -511,7 +483,8 @@ acpi_eject_store(struct device *d, struct device_attribute *attr, | |||
511 | acpi_evaluate_hotplug_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT, | 483 | acpi_evaluate_hotplug_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT, |
512 | ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); | 484 | ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); |
513 | get_device(&acpi_device->dev); | 485 | get_device(&acpi_device->dev); |
514 | status = acpi_os_hotplug_execute(acpi_eject_store_work, acpi_device); | 486 | status = acpi_hotplug_execute(acpi_bus_device_eject, acpi_device, |
487 | ACPI_OST_EC_OSPM_EJECT); | ||
515 | if (ACPI_SUCCESS(status)) | 488 | if (ACPI_SUCCESS(status)) |
516 | return count; | 489 | return count; |
517 | 490 | ||
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 0b7d23b4ad95..5246ba297470 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -875,21 +875,17 @@ static void hotplug_event(acpi_handle handle, u32 type, void *data) | |||
875 | put_bridge(bridge); | 875 | put_bridge(bridge); |
876 | } | 876 | } |
877 | 877 | ||
878 | static void hotplug_event_work(struct work_struct *work) | 878 | static void hotplug_event_work(void *data, u32 type) |
879 | { | 879 | { |
880 | struct acpiphp_context *context; | 880 | struct acpiphp_context *context = data; |
881 | struct acpi_hp_work *hp_work; | 881 | acpi_handle handle = context->handle; |
882 | 882 | ||
883 | hp_work = container_of(work, struct acpi_hp_work, work); | ||
884 | context = hp_work->context; | ||
885 | acpi_scan_lock_acquire(); | 883 | acpi_scan_lock_acquire(); |
886 | 884 | ||
887 | hotplug_event(hp_work->handle, hp_work->type, context); | 885 | hotplug_event(handle, type, context); |
888 | 886 | ||
889 | acpi_scan_lock_release(); | 887 | acpi_scan_lock_release(); |
890 | acpi_evaluate_hotplug_ost(hp_work->handle, hp_work->type, | 888 | acpi_evaluate_hotplug_ost(handle, type, ACPI_OST_SC_SUCCESS, NULL); |
891 | ACPI_OST_SC_SUCCESS, NULL); | ||
892 | kfree(hp_work); /* allocated in handle_hotplug_event() */ | ||
893 | put_bridge(context->func.parent); | 889 | put_bridge(context->func.parent); |
894 | } | 890 | } |
895 | 891 | ||
@@ -940,10 +936,10 @@ static void handle_hotplug_event(acpi_handle handle, u32 type, void *data) | |||
940 | 936 | ||
941 | mutex_lock(&acpiphp_context_lock); | 937 | mutex_lock(&acpiphp_context_lock); |
942 | context = acpiphp_get_context(handle); | 938 | context = acpiphp_get_context(handle); |
943 | if (context) { | 939 | if (context && !WARN_ON(context->handle != handle)) { |
944 | get_bridge(context->func.parent); | 940 | get_bridge(context->func.parent); |
945 | acpiphp_put_context(context); | 941 | acpiphp_put_context(context); |
946 | alloc_acpi_hp_work(handle, type, context, hotplug_event_work); | 942 | acpi_hotplug_execute(hotplug_event_work, context, type); |
947 | mutex_unlock(&acpiphp_context_lock); | 943 | mutex_unlock(&acpiphp_context_lock); |
948 | return; | 944 | return; |
949 | } | 945 | } |
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index eb37a6fb8665..d64a3010332f 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
@@ -339,15 +339,6 @@ struct acpi_bus_event { | |||
339 | u32 data; | 339 | u32 data; |
340 | }; | 340 | }; |
341 | 341 | ||
342 | struct acpi_hp_work { | ||
343 | struct work_struct work; | ||
344 | acpi_handle handle; | ||
345 | u32 type; | ||
346 | void *context; | ||
347 | }; | ||
348 | void alloc_acpi_hp_work(acpi_handle handle, u32 type, void *context, | ||
349 | void (*func)(struct work_struct *work)); | ||
350 | |||
351 | extern struct kobject *acpi_kobj; | 342 | extern struct kobject *acpi_kobj; |
352 | extern int acpi_bus_generate_netlink_event(const char*, const char*, u8, int); | 343 | extern int acpi_bus_generate_netlink_event(const char*, const char*, u8, int); |
353 | void acpi_bus_private_data_handler(acpi_handle, void *); | 344 | void acpi_bus_private_data_handler(acpi_handle, void *); |
@@ -393,6 +384,9 @@ int acpi_match_device_ids(struct acpi_device *device, | |||
393 | int acpi_create_dir(struct acpi_device *); | 384 | int acpi_create_dir(struct acpi_device *); |
394 | void acpi_remove_dir(struct acpi_device *); | 385 | void acpi_remove_dir(struct acpi_device *); |
395 | 386 | ||
387 | typedef void (*acpi_hp_callback)(void *data, u32 src); | ||
388 | |||
389 | acpi_status acpi_hotplug_execute(acpi_hp_callback func, void *data, u32 src); | ||
396 | 390 | ||
397 | /** | 391 | /** |
398 | * module_acpi_driver(acpi_driver) - Helper macro for registering an ACPI driver | 392 | * module_acpi_driver(acpi_driver) - Helper macro for registering an ACPI driver |
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index 64b8c7639520..505cb4d59f23 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h | |||
@@ -200,9 +200,6 @@ acpi_status | |||
200 | acpi_os_execute(acpi_execute_type type, | 200 | acpi_os_execute(acpi_execute_type type, |
201 | acpi_osd_exec_callback function, void *context); | 201 | acpi_osd_exec_callback function, void *context); |
202 | 202 | ||
203 | acpi_status | ||
204 | acpi_os_hotplug_execute(acpi_osd_exec_callback function, void *context); | ||
205 | |||
206 | void acpi_os_wait_events_complete(void); | 203 | void acpi_os_wait_events_complete(void); |
207 | 204 | ||
208 | void acpi_os_sleep(u64 milliseconds); | 205 | void acpi_os_sleep(u64 milliseconds); |