diff options
Diffstat (limited to 'drivers/acpi/osl.c')
-rw-r--r-- | drivers/acpi/osl.c | 46 |
1 files changed, 41 insertions, 5 deletions
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 1420a9f69e5d..6234d3e7acd3 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 | printk(KERN_ERR PREFIX | 757 | printk(KERN_ERR PREFIX |
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); |