diff options
author | Len Brown <len.brown@intel.com> | 2010-08-15 00:25:40 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2010-08-15 00:25:40 -0400 |
commit | c172cb73bc79fe69915b1a1a48e374aa4b1f8a59 (patch) | |
tree | eb3d6415914968441c063f7282e824b14b5a5edb /drivers/acpi/acpica/evgpe.c | |
parent | e8eb6228094bcf0c84d9aa32b6363e78da68e1f5 (diff) | |
parent | 28f4f8a9def2b1f3a6066bae791c77043ec49524 (diff) |
Merge branch 'acpica-gpe' into release
Diffstat (limited to 'drivers/acpi/acpica/evgpe.c')
-rw-r--r-- | drivers/acpi/acpica/evgpe.c | 142 |
1 files changed, 127 insertions, 15 deletions
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index 7c2c336006a1..f226eac314db 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c | |||
@@ -54,51 +54,159 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context); | |||
54 | 54 | ||
55 | /******************************************************************************* | 55 | /******************************************************************************* |
56 | * | 56 | * |
57 | * FUNCTION: acpi_ev_update_gpe_enable_masks | 57 | * FUNCTION: acpi_ev_update_gpe_enable_mask |
58 | * | 58 | * |
59 | * PARAMETERS: gpe_event_info - GPE to update | 59 | * PARAMETERS: gpe_event_info - GPE to update |
60 | * | 60 | * |
61 | * RETURN: Status | 61 | * RETURN: Status |
62 | * | 62 | * |
63 | * DESCRIPTION: Updates GPE register enable masks based upon whether there are | 63 | * DESCRIPTION: Updates GPE register enable mask based upon whether there are |
64 | * references (either wake or run) to this GPE | 64 | * runtime references to this GPE |
65 | * | 65 | * |
66 | ******************************************************************************/ | 66 | ******************************************************************************/ |
67 | 67 | ||
68 | acpi_status | 68 | acpi_status |
69 | acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info) | 69 | acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info) |
70 | { | 70 | { |
71 | struct acpi_gpe_register_info *gpe_register_info; | 71 | struct acpi_gpe_register_info *gpe_register_info; |
72 | u32 register_bit; | 72 | u32 register_bit; |
73 | 73 | ||
74 | ACPI_FUNCTION_TRACE(ev_update_gpe_enable_masks); | 74 | ACPI_FUNCTION_TRACE(ev_update_gpe_enable_mask); |
75 | 75 | ||
76 | gpe_register_info = gpe_event_info->register_info; | 76 | gpe_register_info = gpe_event_info->register_info; |
77 | if (!gpe_register_info) { | 77 | if (!gpe_register_info) { |
78 | return_ACPI_STATUS(AE_NOT_EXIST); | 78 | return_ACPI_STATUS(AE_NOT_EXIST); |
79 | } | 79 | } |
80 | 80 | ||
81 | register_bit = acpi_hw_gpe_register_bit(gpe_event_info, | 81 | register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info, |
82 | gpe_register_info); | 82 | gpe_register_info); |
83 | 83 | ||
84 | /* Clear the wake/run bits up front */ | 84 | /* Clear the run bit up front */ |
85 | 85 | ||
86 | ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake, register_bit); | ||
87 | ACPI_CLEAR_BIT(gpe_register_info->enable_for_run, register_bit); | 86 | ACPI_CLEAR_BIT(gpe_register_info->enable_for_run, register_bit); |
88 | 87 | ||
89 | /* Set the mask bits only if there are references to this GPE */ | 88 | /* Set the mask bit only if there are references to this GPE */ |
90 | 89 | ||
91 | if (gpe_event_info->runtime_count) { | 90 | if (gpe_event_info->runtime_count) { |
92 | ACPI_SET_BIT(gpe_register_info->enable_for_run, register_bit); | 91 | ACPI_SET_BIT(gpe_register_info->enable_for_run, (u8)register_bit); |
93 | } | 92 | } |
94 | 93 | ||
95 | if (gpe_event_info->wakeup_count) { | 94 | return_ACPI_STATUS(AE_OK); |
96 | ACPI_SET_BIT(gpe_register_info->enable_for_wake, register_bit); | 95 | } |
96 | |||
97 | /******************************************************************************* | ||
98 | * | ||
99 | * FUNCTION: acpi_ev_enable_gpe | ||
100 | * | ||
101 | * PARAMETERS: gpe_event_info - GPE to enable | ||
102 | * | ||
103 | * RETURN: Status | ||
104 | * | ||
105 | * DESCRIPTION: Clear the given GPE from stale events and enable it. | ||
106 | * | ||
107 | ******************************************************************************/ | ||
108 | acpi_status | ||
109 | acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) | ||
110 | { | ||
111 | acpi_status status; | ||
112 | |||
113 | ACPI_FUNCTION_TRACE(ev_enable_gpe); | ||
114 | |||
115 | /* | ||
116 | * We will only allow a GPE to be enabled if it has either an | ||
117 | * associated method (_Lxx/_Exx) or a handler. Otherwise, the | ||
118 | * GPE will be immediately disabled by acpi_ev_gpe_dispatch the | ||
119 | * first time it fires. | ||
120 | */ | ||
121 | if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)) { | ||
122 | return_ACPI_STATUS(AE_NO_HANDLER); | ||
97 | } | 123 | } |
98 | 124 | ||
99 | return_ACPI_STATUS(AE_OK); | 125 | /* Clear the GPE (of stale events) */ |
126 | status = acpi_hw_clear_gpe(gpe_event_info); | ||
127 | if (ACPI_FAILURE(status)) { | ||
128 | return_ACPI_STATUS(status); | ||
129 | } | ||
130 | |||
131 | /* Enable the requested GPE */ | ||
132 | status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE); | ||
133 | |||
134 | return_ACPI_STATUS(status); | ||
135 | } | ||
136 | |||
137 | |||
138 | /******************************************************************************* | ||
139 | * | ||
140 | * FUNCTION: acpi_raw_enable_gpe | ||
141 | * | ||
142 | * PARAMETERS: gpe_event_info - GPE to enable | ||
143 | * | ||
144 | * RETURN: Status | ||
145 | * | ||
146 | * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is | ||
147 | * hardware-enabled. | ||
148 | * | ||
149 | ******************************************************************************/ | ||
150 | |||
151 | acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) | ||
152 | { | ||
153 | acpi_status status = AE_OK; | ||
154 | |||
155 | if (gpe_event_info->runtime_count == ACPI_UINT8_MAX) { | ||
156 | return_ACPI_STATUS(AE_LIMIT); | ||
157 | } | ||
158 | |||
159 | gpe_event_info->runtime_count++; | ||
160 | if (gpe_event_info->runtime_count == 1) { | ||
161 | status = acpi_ev_update_gpe_enable_mask(gpe_event_info); | ||
162 | if (ACPI_SUCCESS(status)) { | ||
163 | status = acpi_ev_enable_gpe(gpe_event_info); | ||
164 | } | ||
165 | |||
166 | if (ACPI_FAILURE(status)) { | ||
167 | gpe_event_info->runtime_count--; | ||
168 | } | ||
169 | } | ||
170 | |||
171 | return_ACPI_STATUS(status); | ||
100 | } | 172 | } |
101 | 173 | ||
174 | /******************************************************************************* | ||
175 | * | ||
176 | * FUNCTION: acpi_raw_disable_gpe | ||
177 | * | ||
178 | * PARAMETERS: gpe_event_info - GPE to disable | ||
179 | * | ||
180 | * RETURN: Status | ||
181 | * | ||
182 | * DESCRIPTION: Remove a reference to a GPE. When the last reference is | ||
183 | * removed, the GPE is hardware-disabled. | ||
184 | * | ||
185 | ******************************************************************************/ | ||
186 | |||
187 | acpi_status acpi_raw_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) | ||
188 | { | ||
189 | acpi_status status = AE_OK; | ||
190 | |||
191 | if (!gpe_event_info->runtime_count) { | ||
192 | return_ACPI_STATUS(AE_LIMIT); | ||
193 | } | ||
194 | |||
195 | gpe_event_info->runtime_count--; | ||
196 | if (!gpe_event_info->runtime_count) { | ||
197 | status = acpi_ev_update_gpe_enable_mask(gpe_event_info); | ||
198 | if (ACPI_SUCCESS(status)) { | ||
199 | status = acpi_hw_low_set_gpe(gpe_event_info, | ||
200 | ACPI_GPE_DISABLE); | ||
201 | } | ||
202 | |||
203 | if (ACPI_FAILURE(status)) { | ||
204 | gpe_event_info->runtime_count++; | ||
205 | } | ||
206 | } | ||
207 | |||
208 | return_ACPI_STATUS(status); | ||
209 | } | ||
102 | 210 | ||
103 | /******************************************************************************* | 211 | /******************************************************************************* |
104 | * | 212 | * |
@@ -417,8 +525,12 @@ static void acpi_ev_asynch_enable_gpe(void *context) | |||
417 | } | 525 | } |
418 | } | 526 | } |
419 | 527 | ||
420 | /* Enable this GPE */ | 528 | /* |
421 | (void)acpi_hw_write_gpe_enable_reg(gpe_event_info); | 529 | * Enable this GPE, conditionally. This means that the GPE will only be |
530 | * physically enabled if the enable_for_run bit is set in the event_info | ||
531 | */ | ||
532 | (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_COND_ENABLE); | ||
533 | |||
422 | return_VOID; | 534 | return_VOID; |
423 | } | 535 | } |
424 | 536 | ||