aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/dock.c25
-rw-r--r--drivers/acpi/osl.c46
2 files changed, 65 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
751struct dock_data {
752 acpi_handle handle;
753 unsigned long event;
754 struct dock_station *ds;
755};
756
757static 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
751static int acpi_dock_notifier_call(struct notifier_block *this, 765static 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
685static 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
700acpi_status acpi_os_execute(acpi_execute_type type, 716static 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
765acpi_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}
740EXPORT_SYMBOL(acpi_os_execute); 770EXPORT_SYMBOL(acpi_os_execute);
741 771
772acpi_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
742void acpi_os_wait_events_complete(void *context) 778void acpi_os_wait_events_complete(void *context)
743{ 779{
744 flush_workqueue(kacpid_wq); 780 flush_workqueue(kacpid_wq);