diff options
Diffstat (limited to 'drivers/acpi/osl.c')
-rw-r--r-- | drivers/acpi/osl.c | 50 |
1 files changed, 43 insertions, 7 deletions
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index f58fcbbc810d..4be252145cb4 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -681,6 +681,22 @@ static void acpi_os_execute_deferred(struct work_struct *work) | |||
681 | return; | 681 | return; |
682 | } | 682 | } |
683 | 683 | ||
684 | static void acpi_os_execute_hp_deferred(struct work_struct *work) | ||
685 | { | ||
686 | struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work); | ||
687 | if (!dpc) { | ||
688 | printk(KERN_ERR PREFIX "Invalid (NULL) context\n"); | ||
689 | return; | ||
690 | } | ||
691 | |||
692 | acpi_os_wait_events_complete(NULL); | ||
693 | |||
694 | dpc->function(dpc->context); | ||
695 | kfree(dpc); | ||
696 | |||
697 | return; | ||
698 | } | ||
699 | |||
684 | /******************************************************************************* | 700 | /******************************************************************************* |
685 | * | 701 | * |
686 | * FUNCTION: acpi_os_execute | 702 | * FUNCTION: acpi_os_execute |
@@ -696,12 +712,13 @@ static void acpi_os_execute_deferred(struct work_struct *work) | |||
696 | * | 712 | * |
697 | ******************************************************************************/ | 713 | ******************************************************************************/ |
698 | 714 | ||
699 | acpi_status acpi_os_execute(acpi_execute_type type, | 715 | static acpi_status __acpi_os_execute(acpi_execute_type type, |
700 | acpi_osd_exec_callback function, void *context) | 716 | acpi_osd_exec_callback function, void *context, int hp) |
701 | { | 717 | { |
702 | acpi_status status = AE_OK; | 718 | acpi_status status = AE_OK; |
703 | struct acpi_os_dpc *dpc; | 719 | struct acpi_os_dpc *dpc; |
704 | struct workqueue_struct *queue; | 720 | struct workqueue_struct *queue; |
721 | int ret; | ||
705 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 722 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
706 | "Scheduling function [%p(%p)] for deferred execution.\n", | 723 | "Scheduling function [%p(%p)] for deferred execution.\n", |
707 | function, context)); | 724 | function, context)); |
@@ -725,19 +742,38 @@ acpi_status acpi_os_execute(acpi_execute_type type, | |||
725 | dpc->function = function; | 742 | dpc->function = function; |
726 | dpc->context = context; | 743 | dpc->context = context; |
727 | 744 | ||
728 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); | 745 | if (!hp) { |
729 | queue = (type == OSL_NOTIFY_HANDLER) ? kacpi_notify_wq : kacpid_wq; | 746 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); |
730 | if (!queue_work(queue, &dpc->work)) { | 747 | queue = (type == OSL_NOTIFY_HANDLER) ? |
731 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 748 | kacpi_notify_wq : kacpid_wq; |
732 | "Call to queue_work() failed.\n")); | 749 | ret = queue_work(queue, &dpc->work); |
750 | } else { | ||
751 | INIT_WORK(&dpc->work, acpi_os_execute_hp_deferred); | ||
752 | ret = schedule_work(&dpc->work); | ||
753 | } | ||
754 | |||
755 | if (!ret) { | ||
756 | printk(KERN_ERR PREFIX | ||
757 | "Call to queue_work() failed.\n"); | ||
733 | status = AE_ERROR; | 758 | status = AE_ERROR; |
734 | kfree(dpc); | 759 | kfree(dpc); |
735 | } | 760 | } |
736 | return_ACPI_STATUS(status); | 761 | return_ACPI_STATUS(status); |
737 | } | 762 | } |
738 | 763 | ||
764 | acpi_status acpi_os_execute(acpi_execute_type type, | ||
765 | acpi_osd_exec_callback function, void *context) | ||
766 | { | ||
767 | return __acpi_os_execute(type, function, context, 0); | ||
768 | } | ||
739 | EXPORT_SYMBOL(acpi_os_execute); | 769 | EXPORT_SYMBOL(acpi_os_execute); |
740 | 770 | ||
771 | acpi_status acpi_os_hotplug_execute(acpi_osd_exec_callback function, | ||
772 | void *context) | ||
773 | { | ||
774 | return __acpi_os_execute(0, function, context, 1); | ||
775 | } | ||
776 | |||
741 | void acpi_os_wait_events_complete(void *context) | 777 | void acpi_os_wait_events_complete(void *context) |
742 | { | 778 | { |
743 | flush_workqueue(kacpid_wq); | 779 | flush_workqueue(kacpid_wq); |