aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2007-02-02 11:48:19 -0500
committerLen Brown <len.brown@intel.com>2007-02-02 21:14:22 -0500
commitc5a7156959e89b32260ad6072bbf5077bcdfbeee (patch)
treea1baa9c45a3aa33e9858a9a1df6ad78805cc694d /drivers/acpi
parentfdffb72d23172c91af56983f303d1986994df522 (diff)
ACPICA: Disable all wake GPEs after first one recieved
Change for GPE support: when a wake GPE is received, now all wake GPEs are immediately disabled to prevent the waking GPE from firing again, and to prevent other wake GPEs from interrupting the wake process. Signed-off-by: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/events/evgpe.c78
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
749acpi_status
750acpi_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