diff options
author | Alexey Starikovskiy <astarikovskiy@suse.de> | 2007-11-13 05:05:45 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2007-12-06 21:54:43 -0500 |
commit | 17bc54eef91df29f0a22e8a1562a404cf7a68e74 (patch) | |
tree | 48f6f26a243789582721e2a3419346ea22a6dcc9 /drivers/acpi/osl.c | |
parent | f194d132e4971111f85c18c96067acffb13cee6d (diff) |
ACPI: Defer enabling of level GPE until all pending notifies done
Level GPE should not be enabled until all work caused by it is done,
e.g. all Notify() methods are completed.
This can be accomplished by appending enable_gpe function to the end
of notify queue.
Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
Acked-by: Shaohua Li <shaohua.li@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/osl.c')
-rw-r--r-- | drivers/acpi/osl.c | 42 |
1 files changed, 8 insertions, 34 deletions
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index e3a673a00845..21d34595dbae 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -618,25 +618,6 @@ static void acpi_os_execute_deferred(struct work_struct *work) | |||
618 | dpc->function(dpc->context); | 618 | dpc->function(dpc->context); |
619 | kfree(dpc); | 619 | kfree(dpc); |
620 | 620 | ||
621 | /* Yield cpu to notify thread */ | ||
622 | cond_resched(); | ||
623 | |||
624 | return; | ||
625 | } | ||
626 | |||
627 | static void acpi_os_execute_notify(struct work_struct *work) | ||
628 | { | ||
629 | struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work); | ||
630 | |||
631 | if (!dpc) { | ||
632 | printk(KERN_ERR PREFIX "Invalid (NULL) context\n"); | ||
633 | return; | ||
634 | } | ||
635 | |||
636 | dpc->function(dpc->context); | ||
637 | |||
638 | kfree(dpc); | ||
639 | |||
640 | return; | 621 | return; |
641 | } | 622 | } |
642 | 623 | ||
@@ -660,7 +641,7 @@ acpi_status acpi_os_execute(acpi_execute_type type, | |||
660 | { | 641 | { |
661 | acpi_status status = AE_OK; | 642 | acpi_status status = AE_OK; |
662 | struct acpi_os_dpc *dpc; | 643 | struct acpi_os_dpc *dpc; |
663 | 644 | struct workqueue_struct *queue; | |
664 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 645 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
665 | "Scheduling function [%p(%p)] for deferred execution.\n", | 646 | "Scheduling function [%p(%p)] for deferred execution.\n", |
666 | function, context)); | 647 | function, context)); |
@@ -684,20 +665,13 @@ acpi_status acpi_os_execute(acpi_execute_type type, | |||
684 | dpc->function = function; | 665 | dpc->function = function; |
685 | dpc->context = context; | 666 | dpc->context = context; |
686 | 667 | ||
687 | if (type == OSL_NOTIFY_HANDLER) { | 668 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); |
688 | INIT_WORK(&dpc->work, acpi_os_execute_notify); | 669 | queue = (type == OSL_NOTIFY_HANDLER) ? kacpi_notify_wq : kacpid_wq; |
689 | if (!queue_work(kacpi_notify_wq, &dpc->work)) { | 670 | if (!queue_work(queue, &dpc->work)) { |
690 | status = AE_ERROR; | 671 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
691 | kfree(dpc); | 672 | "Call to queue_work() failed.\n")); |
692 | } | 673 | status = AE_ERROR; |
693 | } else { | 674 | kfree(dpc); |
694 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); | ||
695 | if (!queue_work(kacpid_wq, &dpc->work)) { | ||
696 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
697 | "Call to queue_work() failed.\n")); | ||
698 | status = AE_ERROR; | ||
699 | kfree(dpc); | ||
700 | } | ||
701 | } | 675 | } |
702 | return_ACPI_STATUS(status); | 676 | return_ACPI_STATUS(status); |
703 | } | 677 | } |