diff options
| -rw-r--r-- | drivers/acpi/dock.c | 25 | ||||
| -rw-r--r-- | drivers/acpi/osl.c | 46 | ||||
| -rw-r--r-- | include/acpi/acpiosxf.h | 3 |
3 files changed, 68 insertions, 6 deletions
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 2563bc62987d..4b395b1e61b2 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
| @@ -748,6 +748,20 @@ static void dock_notify(acpi_handle handle, u32 event, void *data) | |||
| 748 | } | 748 | } |
| 749 | } | 749 | } |
| 750 | 750 | ||
| 751 | struct dock_data { | ||
| 752 | acpi_handle handle; | ||
| 753 | unsigned long event; | ||
| 754 | struct dock_station *ds; | ||
| 755 | }; | ||
| 756 | |||
| 757 | static void acpi_dock_deferred_cb(void *context) | ||
| 758 | { | ||
| 759 | struct dock_data *data = (struct dock_data *)context; | ||
| 760 | |||
| 761 | dock_notify(data->handle, data->event, data->ds); | ||
| 762 | kfree(data); | ||
| 763 | } | ||
| 764 | |||
| 751 | static int acpi_dock_notifier_call(struct notifier_block *this, | 765 | static int acpi_dock_notifier_call(struct notifier_block *this, |
| 752 | unsigned long event, void *data) | 766 | unsigned long event, void *data) |
| 753 | { | 767 | { |
| @@ -759,7 +773,16 @@ static int acpi_dock_notifier_call(struct notifier_block *this, | |||
| 759 | return 0; | 773 | return 0; |
| 760 | list_for_each_entry(dock_station, &dock_stations, sibiling) { | 774 | list_for_each_entry(dock_station, &dock_stations, sibiling) { |
| 761 | if (dock_station->handle == handle) { | 775 | if (dock_station->handle == handle) { |
| 762 | dock_notify(handle, event, dock_station); | 776 | struct dock_data *dock_data; |
| 777 | |||
| 778 | dock_data = kmalloc(sizeof(*dock_data), GFP_KERNEL); | ||
| 779 | if (!dock_data) | ||
| 780 | return 0; | ||
| 781 | dock_data->handle = handle; | ||
| 782 | dock_data->event = event; | ||
| 783 | dock_data->ds = dock_station; | ||
| 784 | acpi_os_hotplug_execute(acpi_dock_deferred_cb, | ||
| 785 | dock_data); | ||
| 763 | return 0 ; | 786 | return 0 ; |
| 764 | } | 787 | } |
| 765 | } | 788 | } |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 235a1386888a..750e0df15604 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
| @@ -682,6 +682,22 @@ static void acpi_os_execute_deferred(struct work_struct *work) | |||
| 682 | return; | 682 | return; |
| 683 | } | 683 | } |
| 684 | 684 | ||
| 685 | static void acpi_os_execute_hp_deferred(struct work_struct *work) | ||
| 686 | { | ||
| 687 | struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work); | ||
| 688 | if (!dpc) { | ||
| 689 | printk(KERN_ERR PREFIX "Invalid (NULL) context\n"); | ||
| 690 | return; | ||
| 691 | } | ||
| 692 | |||
| 693 | acpi_os_wait_events_complete(NULL); | ||
| 694 | |||
| 695 | dpc->function(dpc->context); | ||
| 696 | kfree(dpc); | ||
| 697 | |||
| 698 | return; | ||
| 699 | } | ||
| 700 | |||
| 685 | /******************************************************************************* | 701 | /******************************************************************************* |
| 686 | * | 702 | * |
| 687 | * FUNCTION: acpi_os_execute | 703 | * FUNCTION: acpi_os_execute |
| @@ -697,12 +713,13 @@ static void acpi_os_execute_deferred(struct work_struct *work) | |||
| 697 | * | 713 | * |
| 698 | ******************************************************************************/ | 714 | ******************************************************************************/ |
| 699 | 715 | ||
| 700 | acpi_status acpi_os_execute(acpi_execute_type type, | 716 | static acpi_status __acpi_os_execute(acpi_execute_type type, |
| 701 | acpi_osd_exec_callback function, void *context) | 717 | acpi_osd_exec_callback function, void *context, int hp) |
| 702 | { | 718 | { |
| 703 | acpi_status status = AE_OK; | 719 | acpi_status status = AE_OK; |
| 704 | struct acpi_os_dpc *dpc; | 720 | struct acpi_os_dpc *dpc; |
| 705 | struct workqueue_struct *queue; | 721 | struct workqueue_struct *queue; |
| 722 | int ret; | ||
| 706 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 723 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
| 707 | "Scheduling function [%p(%p)] for deferred execution.\n", | 724 | "Scheduling function [%p(%p)] for deferred execution.\n", |
| 708 | function, context)); | 725 | function, context)); |
| @@ -726,9 +743,17 @@ acpi_status acpi_os_execute(acpi_execute_type type, | |||
| 726 | dpc->function = function; | 743 | dpc->function = function; |
| 727 | dpc->context = context; | 744 | dpc->context = context; |
| 728 | 745 | ||
| 729 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); | 746 | if (!hp) { |
| 730 | queue = (type == OSL_NOTIFY_HANDLER) ? kacpi_notify_wq : kacpid_wq; | 747 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); |
| 731 | if (!queue_work(queue, &dpc->work)) { | 748 | queue = (type == OSL_NOTIFY_HANDLER) ? |
| 749 | kacpi_notify_wq : kacpid_wq; | ||
| 750 | ret = queue_work(queue, &dpc->work); | ||
| 751 | } else { | ||
| 752 | INIT_WORK(&dpc->work, acpi_os_execute_hp_deferred); | ||
| 753 | ret = schedule_work(&dpc->work); | ||
| 754 | } | ||
| 755 | |||
| 756 | if (!ret) { | ||
| 732 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 757 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
| 733 | "Call to queue_work() failed.\n")); | 758 | "Call to queue_work() failed.\n")); |
| 734 | status = AE_ERROR; | 759 | status = AE_ERROR; |
| @@ -737,8 +762,19 @@ acpi_status acpi_os_execute(acpi_execute_type type, | |||
| 737 | return_ACPI_STATUS(status); | 762 | return_ACPI_STATUS(status); |
| 738 | } | 763 | } |
| 739 | 764 | ||
| 765 | acpi_status acpi_os_execute(acpi_execute_type type, | ||
| 766 | acpi_osd_exec_callback function, void *context) | ||
| 767 | { | ||
| 768 | return __acpi_os_execute(type, function, context, 0); | ||
| 769 | } | ||
| 740 | EXPORT_SYMBOL(acpi_os_execute); | 770 | EXPORT_SYMBOL(acpi_os_execute); |
| 741 | 771 | ||
| 772 | acpi_status acpi_os_hotplug_execute(acpi_osd_exec_callback function, | ||
| 773 | void *context) | ||
| 774 | { | ||
| 775 | return __acpi_os_execute(0, function, context, 1); | ||
| 776 | } | ||
| 777 | |||
| 742 | void acpi_os_wait_events_complete(void *context) | 778 | void acpi_os_wait_events_complete(void *context) |
| 743 | { | 779 | { |
| 744 | flush_workqueue(kacpid_wq); | 780 | flush_workqueue(kacpid_wq); |
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index 3f93a6b4e17f..b91440ac0d16 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h | |||
| @@ -193,6 +193,9 @@ acpi_status | |||
| 193 | acpi_os_execute(acpi_execute_type type, | 193 | acpi_os_execute(acpi_execute_type type, |
| 194 | acpi_osd_exec_callback function, void *context); | 194 | acpi_osd_exec_callback function, void *context); |
| 195 | 195 | ||
| 196 | acpi_status | ||
| 197 | acpi_os_hotplug_execute(acpi_osd_exec_callback function, void *context); | ||
| 198 | |||
| 196 | void acpi_os_wait_events_complete(void *context); | 199 | void acpi_os_wait_events_complete(void *context); |
| 197 | 200 | ||
| 198 | void acpi_os_sleep(acpi_integer milliseconds); | 201 | void acpi_os_sleep(acpi_integer milliseconds); |
