diff options
Diffstat (limited to 'drivers/acpi/events/evgpe.c')
-rw-r--r-- | drivers/acpi/events/evgpe.c | 78 |
1 files changed, 17 insertions, 61 deletions
diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c index d9f71dda278a..df92c9e8c5c4 100644 --- a/drivers/acpi/events/evgpe.c +++ b/drivers/acpi/events/evgpe.c | |||
@@ -635,20 +635,23 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) | |||
635 | } | 635 | } |
636 | } | 636 | } |
637 | 637 | ||
638 | /* Save current system state */ | 638 | if (!acpi_gbl_system_awake_and_running) { |
639 | 639 | /* | |
640 | if (acpi_gbl_system_awake_and_running) { | 640 | * We just woke up because of a wake GPE. Disable any further GPEs |
641 | ACPI_SET_BIT(gpe_event_info->flags, ACPI_GPE_SYSTEM_RUNNING); | 641 | * until we are fully up and running (Only wake GPEs should be enabled |
642 | } else { | 642 | * at this time, but we just brute-force disable them all.) |
643 | ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_SYSTEM_RUNNING); | 643 | * 1) We must disable this particular wake GPE so it won't fire again |
644 | * 2) We want to disable all wake GPEs, since we are now awake | ||
645 | */ | ||
646 | (void)acpi_hw_disable_all_gpes(); | ||
644 | } | 647 | } |
645 | 648 | ||
646 | /* | 649 | /* |
647 | * Dispatch the GPE to either an installed handler, or the control | 650 | * Dispatch the GPE to either an installed handler, or the control method |
648 | * method associated with this GPE (_Lxx or _Exx). | 651 | * associated with this GPE (_Lxx or _Exx). If a handler exists, we invoke |
649 | * If a handler exists, we invoke it and do not attempt to run the method. | 652 | * it and do not attempt to run the method. If there is neither a handler |
650 | * If there is neither a handler nor a method, we disable the level to | 653 | * nor a method, we disable this GPE to prevent further such pointless |
651 | * prevent further events from coming in here. | 654 | * events from firing. |
652 | */ | 655 | */ |
653 | switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) { | 656 | switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) { |
654 | case ACPI_GPE_DISPATCH_HANDLER: | 657 | case ACPI_GPE_DISPATCH_HANDLER: |
@@ -679,8 +682,8 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) | |||
679 | case ACPI_GPE_DISPATCH_METHOD: | 682 | case ACPI_GPE_DISPATCH_METHOD: |
680 | 683 | ||
681 | /* | 684 | /* |
682 | * Disable GPE, so it doesn't keep firing before the method has a | 685 | * Disable the GPE, so it doesn't keep firing before the method has a |
683 | * chance to run. | 686 | * chance to run (it runs asynchronously with interrupts enabled). |
684 | */ | 687 | */ |
685 | status = acpi_ev_disable_gpe(gpe_event_info); | 688 | status = acpi_ev_disable_gpe(gpe_event_info); |
686 | if (ACPI_FAILURE(status)) { | 689 | if (ACPI_FAILURE(status)) { |
@@ -713,7 +716,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) | |||
713 | gpe_number)); | 716 | gpe_number)); |
714 | 717 | ||
715 | /* | 718 | /* |
716 | * Disable the GPE. The GPE will remain disabled until the ACPI | 719 | * Disable the GPE. The GPE will remain disabled until the ACPI |
717 | * Core Subsystem is restarted, or a handler is installed. | 720 | * Core Subsystem is restarted, or a handler is installed. |
718 | */ | 721 | */ |
719 | status = acpi_ev_disable_gpe(gpe_event_info); | 722 | status = acpi_ev_disable_gpe(gpe_event_info); |
@@ -728,50 +731,3 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) | |||
728 | 731 | ||
729 | return_UINT32(ACPI_INTERRUPT_HANDLED); | 732 | return_UINT32(ACPI_INTERRUPT_HANDLED); |
730 | } | 733 | } |
731 | |||
732 | #ifdef ACPI_GPE_NOTIFY_CHECK | ||
733 | /******************************************************************************* | ||
734 | * TBD: NOT USED, PROTOTYPE ONLY AND WILL PROBABLY BE REMOVED | ||
735 | * | ||
736 | * FUNCTION: acpi_ev_check_for_wake_only_gpe | ||
737 | * | ||
738 | * PARAMETERS: gpe_event_info - info for this GPE | ||
739 | * | ||
740 | * RETURN: Status | ||
741 | * | ||
742 | * DESCRIPTION: Determine if a a GPE is "wake-only". | ||
743 | * | ||
744 | * Called from Notify() code in interpreter when a "DeviceWake" | ||
745 | * Notify comes in. | ||
746 | * | ||
747 | ******************************************************************************/ | ||
748 | |||
749 | acpi_status | ||
750 | acpi_ev_check_for_wake_only_gpe(struct acpi_gpe_event_info *gpe_event_info) | ||
751 | { | ||
752 | acpi_status status; | ||
753 | |||
754 | ACPI_FUNCTION_TRACE(ev_check_for_wake_only_gpe); | ||
755 | |||
756 | if ((gpe_event_info) && /* Only >0 for _Lxx/_Exx */ | ||
757 | ((gpe_event_info->flags & ACPI_GPE_SYSTEM_MASK) == ACPI_GPE_SYSTEM_RUNNING)) { /* System state at GPE time */ | ||
758 | /* This must be a wake-only GPE, disable it */ | ||
759 | |||
760 | status = acpi_ev_disable_gpe(gpe_event_info); | ||
761 | |||
762 | /* Set GPE to wake-only. Do not change wake disabled/enabled status */ | ||
763 | |||
764 | acpi_ev_set_gpe_type(gpe_event_info, ACPI_GPE_TYPE_WAKE); | ||
765 | |||
766 | ACPI_INFO((AE_INFO, | ||
767 | "GPE %p was updated from wake/run to wake-only", | ||
768 | gpe_event_info)); | ||
769 | |||
770 | /* This was a wake-only GPE */ | ||
771 | |||
772 | return_ACPI_STATUS(AE_WAKE_ONLY_GPE); | ||
773 | } | ||
774 | |||
775 | return_ACPI_STATUS(AE_OK); | ||
776 | } | ||
777 | #endif | ||