diff options
author | Bob Moore <robert.moore@intel.com> | 2007-02-02 11:48:19 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2007-02-02 21:14:22 -0500 |
commit | c5a7156959e89b32260ad6072bbf5077bcdfbeee (patch) | |
tree | a1baa9c45a3aa33e9858a9a1df6ad78805cc694d | |
parent | fdffb72d23172c91af56983f303d1986994df522 (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>
-rw-r--r-- | drivers/acpi/events/evgpe.c | 78 | ||||
-rw-r--r-- | include/acpi/acglobal.h | 68 | ||||
-rw-r--r-- | include/acpi/actypes.h | 6 |
3 files changed, 51 insertions, 101 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 | ||
diff --git a/include/acpi/acglobal.h b/include/acpi/acglobal.h index 715c4812fe71..b74cd9b670b5 100644 --- a/include/acpi/acglobal.h +++ b/include/acpi/acglobal.h | |||
@@ -58,41 +58,6 @@ | |||
58 | #define ACPI_INIT_GLOBAL(a,b) a | 58 | #define ACPI_INIT_GLOBAL(a,b) a |
59 | #endif | 59 | #endif |
60 | 60 | ||
61 | /* | ||
62 | * Keep local copies of these FADT-based registers. NOTE: These globals | ||
63 | * are first in this file for alignment reasons on 64-bit systems. | ||
64 | */ | ||
65 | ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_enable; | ||
66 | ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable; | ||
67 | |||
68 | /***************************************************************************** | ||
69 | * | ||
70 | * Debug support | ||
71 | * | ||
72 | ****************************************************************************/ | ||
73 | |||
74 | /* Runtime configuration of debug print levels */ | ||
75 | |||
76 | extern u32 acpi_dbg_level; | ||
77 | extern u32 acpi_dbg_layer; | ||
78 | |||
79 | /* Procedure nesting level for debug output */ | ||
80 | |||
81 | extern u32 acpi_gbl_nesting_level; | ||
82 | |||
83 | /* Event counters */ | ||
84 | |||
85 | ACPI_EXTERN u32 acpi_gpe_count; | ||
86 | |||
87 | /* Support for dynamic control method tracing mechanism */ | ||
88 | |||
89 | ACPI_EXTERN u32 acpi_gbl_original_dbg_level; | ||
90 | ACPI_EXTERN u32 acpi_gbl_original_dbg_layer; | ||
91 | ACPI_EXTERN acpi_name acpi_gbl_trace_method_name; | ||
92 | ACPI_EXTERN u32 acpi_gbl_trace_dbg_level; | ||
93 | ACPI_EXTERN u32 acpi_gbl_trace_dbg_layer; | ||
94 | ACPI_EXTERN u32 acpi_gbl_trace_flags; | ||
95 | |||
96 | /***************************************************************************** | 61 | /***************************************************************************** |
97 | * | 62 | * |
98 | * Runtime configuration (static defaults that can be overriden at runtime) | 63 | * Runtime configuration (static defaults that can be overriden at runtime) |
@@ -139,6 +104,34 @@ ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_leave_wake_gpes_disabled, TRUE); | |||
139 | 104 | ||
140 | /***************************************************************************** | 105 | /***************************************************************************** |
141 | * | 106 | * |
107 | * Debug support | ||
108 | * | ||
109 | ****************************************************************************/ | ||
110 | |||
111 | /* Runtime configuration of debug print levels */ | ||
112 | |||
113 | extern u32 acpi_dbg_level; | ||
114 | extern u32 acpi_dbg_layer; | ||
115 | |||
116 | /* Procedure nesting level for debug output */ | ||
117 | |||
118 | extern u32 acpi_gbl_nesting_level; | ||
119 | |||
120 | /* Event counters */ | ||
121 | |||
122 | ACPI_EXTERN u32 acpi_gpe_count; | ||
123 | |||
124 | /* Support for dynamic control method tracing mechanism */ | ||
125 | |||
126 | ACPI_EXTERN u32 acpi_gbl_original_dbg_level; | ||
127 | ACPI_EXTERN u32 acpi_gbl_original_dbg_layer; | ||
128 | ACPI_EXTERN acpi_name acpi_gbl_trace_method_name; | ||
129 | ACPI_EXTERN u32 acpi_gbl_trace_dbg_level; | ||
130 | ACPI_EXTERN u32 acpi_gbl_trace_dbg_layer; | ||
131 | ACPI_EXTERN u32 acpi_gbl_trace_flags; | ||
132 | |||
133 | /***************************************************************************** | ||
134 | * | ||
142 | * ACPI Table globals | 135 | * ACPI Table globals |
143 | * | 136 | * |
144 | ****************************************************************************/ | 137 | ****************************************************************************/ |
@@ -154,6 +147,11 @@ ACPI_EXTERN struct acpi_table_fadt acpi_gbl_FADT; | |||
154 | #define acpi_fadt acpi_gbl_FADT | 147 | #define acpi_fadt acpi_gbl_FADT |
155 | extern acpi_native_uint acpi_gbl_permanent_mmap; | 148 | extern acpi_native_uint acpi_gbl_permanent_mmap; |
156 | 149 | ||
150 | /* These addresses are calculated from FADT address values */ | ||
151 | |||
152 | ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_enable; | ||
153 | ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable; | ||
154 | |||
157 | /* | 155 | /* |
158 | * Handle both ACPI 1.0 and ACPI 2.0 Integer widths. The integer width is | 156 | * Handle both ACPI 1.0 and ACPI 2.0 Integer widths. The integer width is |
159 | * determined by the revision of the DSDT: If the DSDT revision is less than | 157 | * determined by the revision of the DSDT: If the DSDT revision is less than |
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index b0cdee69ff5d..fe9eb0ea32e4 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h | |||
@@ -592,7 +592,7 @@ typedef u32 acpi_event_status; | |||
592 | * | | | +--- Type of dispatch -- to method, handler, or none | 592 | * | | | +--- Type of dispatch -- to method, handler, or none |
593 | * | | +--- Enabled for runtime? | 593 | * | | +--- Enabled for runtime? |
594 | * | +--- Enabled for wake? | 594 | * | +--- Enabled for wake? |
595 | * +--- System state when GPE ocurred (running/waking) | 595 | * +--- Unused |
596 | */ | 596 | */ |
597 | #define ACPI_GPE_XRUPT_TYPE_MASK (u8) 0x01 | 597 | #define ACPI_GPE_XRUPT_TYPE_MASK (u8) 0x01 |
598 | #define ACPI_GPE_LEVEL_TRIGGERED (u8) 0x01 | 598 | #define ACPI_GPE_LEVEL_TRIGGERED (u8) 0x01 |
@@ -618,10 +618,6 @@ typedef u32 acpi_event_status; | |||
618 | 618 | ||
619 | #define ACPI_GPE_ENABLE_MASK (u8) 0x60 /* Both run/wake */ | 619 | #define ACPI_GPE_ENABLE_MASK (u8) 0x60 /* Both run/wake */ |
620 | 620 | ||
621 | #define ACPI_GPE_SYSTEM_MASK (u8) 0x80 | ||
622 | #define ACPI_GPE_SYSTEM_RUNNING (u8) 0x80 | ||
623 | #define ACPI_GPE_SYSTEM_WAKING (u8) 0x00 | ||
624 | |||
625 | /* | 621 | /* |
626 | * Flags for GPE and Lock interfaces | 622 | * Flags for GPE and Lock interfaces |
627 | */ | 623 | */ |