aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/evxfevnt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/acpica/evxfevnt.c')
-rw-r--r--drivers/acpi/acpica/evxfevnt.c59
1 files changed, 53 insertions, 6 deletions
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c
index 7c7bbb4d402c..e3d9f5c8e53d 100644
--- a/drivers/acpi/acpica/evxfevnt.c
+++ b/drivers/acpi/acpica/evxfevnt.c
@@ -201,6 +201,44 @@ ACPI_EXPORT_SYMBOL(acpi_enable_event)
201 201
202/******************************************************************************* 202/*******************************************************************************
203 * 203 *
204 * FUNCTION: acpi_clear_and_enable_gpe
205 *
206 * PARAMETERS: gpe_event_info - GPE to enable
207 *
208 * RETURN: Status
209 *
210 * DESCRIPTION: Clear the given GPE from stale events and enable it.
211 *
212 ******************************************************************************/
213static acpi_status
214acpi_clear_and_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
215{
216 acpi_status status;
217
218 /*
219 * We will only allow a GPE to be enabled if it has either an
220 * associated method (_Lxx/_Exx) or a handler. Otherwise, the
221 * GPE will be immediately disabled by acpi_ev_gpe_dispatch the
222 * first time it fires.
223 */
224 if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)) {
225 return_ACPI_STATUS(AE_NO_HANDLER);
226 }
227
228 /* Clear the GPE (of stale events) */
229 status = acpi_hw_clear_gpe(gpe_event_info);
230 if (ACPI_FAILURE(status)) {
231 return_ACPI_STATUS(status);
232 }
233
234 /* Enable the requested GPE */
235 status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE);
236
237 return_ACPI_STATUS(status);
238}
239
240/*******************************************************************************
241 *
204 * FUNCTION: acpi_set_gpe 242 * FUNCTION: acpi_set_gpe
205 * 243 *
206 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 244 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
@@ -240,11 +278,11 @@ acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action)
240 278
241 switch (action) { 279 switch (action) {
242 case ACPI_GPE_ENABLE: 280 case ACPI_GPE_ENABLE:
243 status = acpi_ev_enable_gpe(gpe_event_info); 281 status = acpi_clear_and_enable_gpe(gpe_event_info);
244 break; 282 break;
245 283
246 case ACPI_GPE_DISABLE: 284 case ACPI_GPE_DISABLE:
247 status = acpi_ev_disable_gpe(gpe_event_info); 285 status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
248 break; 286 break;
249 287
250 default: 288 default:
@@ -307,7 +345,11 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type)
307 345
308 gpe_event_info->runtime_count++; 346 gpe_event_info->runtime_count++;
309 if (gpe_event_info->runtime_count == 1) { 347 if (gpe_event_info->runtime_count == 1) {
310 status = acpi_ev_enable_gpe(gpe_event_info); 348 status = acpi_ev_update_gpe_enable_masks(gpe_event_info);
349 if (ACPI_SUCCESS(status)) {
350 status = acpi_clear_and_enable_gpe(gpe_event_info);
351 }
352
311 if (ACPI_FAILURE(status)) { 353 if (ACPI_FAILURE(status)) {
312 gpe_event_info->runtime_count--; 354 gpe_event_info->runtime_count--;
313 goto unlock_and_exit; 355 goto unlock_and_exit;
@@ -334,7 +376,7 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type)
334 */ 376 */
335 gpe_event_info->wakeup_count++; 377 gpe_event_info->wakeup_count++;
336 if (gpe_event_info->wakeup_count == 1) { 378 if (gpe_event_info->wakeup_count == 1) {
337 (void)acpi_ev_update_gpe_enable_masks(gpe_event_info); 379 status = acpi_ev_update_gpe_enable_masks(gpe_event_info);
338 } 380 }
339 } 381 }
340 382
@@ -394,7 +436,12 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type
394 436
395 gpe_event_info->runtime_count--; 437 gpe_event_info->runtime_count--;
396 if (!gpe_event_info->runtime_count) { 438 if (!gpe_event_info->runtime_count) {
397 status = acpi_ev_disable_gpe(gpe_event_info); 439 status = acpi_ev_update_gpe_enable_masks(gpe_event_info);
440 if (ACPI_SUCCESS(status)) {
441 status = acpi_hw_low_set_gpe(gpe_event_info,
442 ACPI_GPE_DISABLE);
443 }
444
398 if (ACPI_FAILURE(status)) { 445 if (ACPI_FAILURE(status)) {
399 gpe_event_info->runtime_count++; 446 gpe_event_info->runtime_count++;
400 goto unlock_and_exit; 447 goto unlock_and_exit;
@@ -415,7 +462,7 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type
415 462
416 gpe_event_info->wakeup_count--; 463 gpe_event_info->wakeup_count--;
417 if (!gpe_event_info->wakeup_count) { 464 if (!gpe_event_info->wakeup_count) {
418 (void)acpi_ev_update_gpe_enable_masks(gpe_event_info); 465 status = acpi_ev_update_gpe_enable_masks(gpe_event_info);
419 } 466 }
420 } 467 }
421 468