aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/evgpe.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/acpica/evgpe.c')
-rw-r--r--drivers/acpi/acpica/evgpe.c164
1 files changed, 83 insertions, 81 deletions
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c
index aa70154cf4fa..5ed064e8673c 100644
--- a/drivers/acpi/acpica/evgpe.c
+++ b/drivers/acpi/acpica/evgpe.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2014, Intel Corp. 8 * Copyright (C) 2000 - 2015, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -114,17 +114,6 @@ acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
114 114
115 ACPI_FUNCTION_TRACE(ev_enable_gpe); 115 ACPI_FUNCTION_TRACE(ev_enable_gpe);
116 116
117 /*
118 * We will only allow a GPE to be enabled if it has either an associated
119 * method (_Lxx/_Exx) or a handler, or is using the implicit notify
120 * feature. Otherwise, the GPE will be immediately disabled by
121 * acpi_ev_gpe_dispatch the first time it fires.
122 */
123 if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
124 ACPI_GPE_DISPATCH_NONE) {
125 return_ACPI_STATUS(AE_NO_HANDLER);
126 }
127
128 /* Clear the GPE (of stale events) */ 117 /* Clear the GPE (of stale events) */
129 118
130 status = acpi_hw_clear_gpe(gpe_event_info); 119 status = acpi_hw_clear_gpe(gpe_event_info);
@@ -339,7 +328,11 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list)
339{ 328{
340 acpi_status status; 329 acpi_status status;
341 struct acpi_gpe_block_info *gpe_block; 330 struct acpi_gpe_block_info *gpe_block;
331 struct acpi_namespace_node *gpe_device;
342 struct acpi_gpe_register_info *gpe_register_info; 332 struct acpi_gpe_register_info *gpe_register_info;
333 struct acpi_gpe_event_info *gpe_event_info;
334 u32 gpe_number;
335 struct acpi_gpe_handler_info *gpe_handler_info;
343 u32 int_status = ACPI_INTERRUPT_NOT_HANDLED; 336 u32 int_status = ACPI_INTERRUPT_NOT_HANDLED;
344 u8 enabled_status_byte; 337 u8 enabled_status_byte;
345 u32 status_reg; 338 u32 status_reg;
@@ -367,6 +360,8 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list)
367 360
368 gpe_block = gpe_xrupt_list->gpe_block_list_head; 361 gpe_block = gpe_xrupt_list->gpe_block_list_head;
369 while (gpe_block) { 362 while (gpe_block) {
363 gpe_device = gpe_block->node;
364
370 /* 365 /*
371 * Read all of the 8-bit GPE status and enable registers in this GPE 366 * Read all of the 8-bit GPE status and enable registers in this GPE
372 * block, saving all of them. Find all currently active GP events. 367 * block, saving all of them. Find all currently active GP events.
@@ -442,16 +437,68 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list)
442 437
443 /* Examine one GPE bit */ 438 /* Examine one GPE bit */
444 439
440 gpe_event_info =
441 &gpe_block->
442 event_info[((acpi_size) i *
443 ACPI_GPE_REGISTER_WIDTH) + j];
444 gpe_number =
445 j + gpe_register_info->base_gpe_number;
446
445 if (enabled_status_byte & (1 << j)) { 447 if (enabled_status_byte & (1 << j)) {
446 /* 448
447 * Found an active GPE. Dispatch the event to a handler 449 /* Invoke global event handler if present */
448 * or method. 450
449 */ 451 acpi_gpe_count++;
450 int_status |= 452 if (acpi_gbl_global_event_handler) {
451 acpi_ev_gpe_dispatch(gpe_block-> 453 acpi_gbl_global_event_handler
452 node, 454 (ACPI_EVENT_TYPE_GPE,
453 &gpe_block-> 455 gpe_device, gpe_number,
454 event_info[((acpi_size) i * ACPI_GPE_REGISTER_WIDTH) + j], j + gpe_register_info->base_gpe_number); 456 acpi_gbl_global_event_handler_context);
457 }
458
459 /* Found an active GPE */
460
461 if (ACPI_GPE_DISPATCH_TYPE
462 (gpe_event_info->flags) ==
463 ACPI_GPE_DISPATCH_RAW_HANDLER) {
464
465 /* Dispatch the event to a raw handler */
466
467 gpe_handler_info =
468 gpe_event_info->dispatch.
469 handler;
470
471 /*
472 * There is no protection around the namespace node
473 * and the GPE handler to ensure a safe destruction
474 * because:
475 * 1. The namespace node is expected to always
476 * exist after loading a table.
477 * 2. The GPE handler is expected to be flushed by
478 * acpi_os_wait_events_complete() before the
479 * destruction.
480 */
481 acpi_os_release_lock
482 (acpi_gbl_gpe_lock, flags);
483 int_status |=
484 gpe_handler_info->
485 address(gpe_device,
486 gpe_number,
487 gpe_handler_info->
488 context);
489 flags =
490 acpi_os_acquire_lock
491 (acpi_gbl_gpe_lock);
492 } else {
493 /*
494 * Dispatch the event to a standard handler or
495 * method.
496 */
497 int_status |=
498 acpi_ev_gpe_dispatch
499 (gpe_device, gpe_event_info,
500 gpe_number);
501 }
455 } 502 }
456 } 503 }
457 } 504 }
@@ -484,52 +531,15 @@ unlock_and_exit:
484static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) 531static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
485{ 532{
486 struct acpi_gpe_event_info *gpe_event_info = context; 533 struct acpi_gpe_event_info *gpe_event_info = context;
487 acpi_status status; 534 acpi_status status = AE_OK;
488 struct acpi_gpe_event_info *local_gpe_event_info;
489 struct acpi_evaluate_info *info; 535 struct acpi_evaluate_info *info;
490 struct acpi_gpe_notify_info *notify; 536 struct acpi_gpe_notify_info *notify;
491 537
492 ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method); 538 ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method);
493 539
494 /* Allocate a local GPE block */
495
496 local_gpe_event_info =
497 ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_event_info));
498 if (!local_gpe_event_info) {
499 ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, "while handling a GPE"));
500 return_VOID;
501 }
502
503 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
504 if (ACPI_FAILURE(status)) {
505 ACPI_FREE(local_gpe_event_info);
506 return_VOID;
507 }
508
509 /* Must revalidate the gpe_number/gpe_block */
510
511 if (!acpi_ev_valid_gpe_event(gpe_event_info)) {
512 status = acpi_ut_release_mutex(ACPI_MTX_EVENTS);
513 ACPI_FREE(local_gpe_event_info);
514 return_VOID;
515 }
516
517 /*
518 * Take a snapshot of the GPE info for this level - we copy the info to
519 * prevent a race condition with remove_handler/remove_block.
520 */
521 ACPI_MEMCPY(local_gpe_event_info, gpe_event_info,
522 sizeof(struct acpi_gpe_event_info));
523
524 status = acpi_ut_release_mutex(ACPI_MTX_EVENTS);
525 if (ACPI_FAILURE(status)) {
526 ACPI_FREE(local_gpe_event_info);
527 return_VOID;
528 }
529
530 /* Do the correct dispatch - normal method or implicit notify */ 540 /* Do the correct dispatch - normal method or implicit notify */
531 541
532 switch (local_gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) { 542 switch (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags)) {
533 case ACPI_GPE_DISPATCH_NOTIFY: 543 case ACPI_GPE_DISPATCH_NOTIFY:
534 /* 544 /*
535 * Implicit notify. 545 * Implicit notify.
@@ -542,7 +552,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
542 * June 2012: Expand implicit notify mechanism to support 552 * June 2012: Expand implicit notify mechanism to support
543 * notifies on multiple device objects. 553 * notifies on multiple device objects.
544 */ 554 */
545 notify = local_gpe_event_info->dispatch.notify_list; 555 notify = gpe_event_info->dispatch.notify_list;
546 while (ACPI_SUCCESS(status) && notify) { 556 while (ACPI_SUCCESS(status) && notify) {
547 status = 557 status =
548 acpi_ev_queue_notify_request(notify->device_node, 558 acpi_ev_queue_notify_request(notify->device_node,
@@ -566,7 +576,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
566 * _Lxx/_Exx control method that corresponds to this GPE 576 * _Lxx/_Exx control method that corresponds to this GPE
567 */ 577 */
568 info->prefix_node = 578 info->prefix_node =
569 local_gpe_event_info->dispatch.method_node; 579 gpe_event_info->dispatch.method_node;
570 info->flags = ACPI_IGNORE_RETURN_VALUE; 580 info->flags = ACPI_IGNORE_RETURN_VALUE;
571 581
572 status = acpi_ns_evaluate(info); 582 status = acpi_ns_evaluate(info);
@@ -576,25 +586,27 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
576 if (ACPI_FAILURE(status)) { 586 if (ACPI_FAILURE(status)) {
577 ACPI_EXCEPTION((AE_INFO, status, 587 ACPI_EXCEPTION((AE_INFO, status,
578 "while evaluating GPE method [%4.4s]", 588 "while evaluating GPE method [%4.4s]",
579 acpi_ut_get_node_name 589 acpi_ut_get_node_name(gpe_event_info->
580 (local_gpe_event_info->dispatch. 590 dispatch.
581 method_node))); 591 method_node)));
582 } 592 }
583 break; 593 break;
584 594
585 default: 595 default:
586 596
587 return_VOID; /* Should never happen */ 597 goto error_exit; /* Should never happen */
588 } 598 }
589 599
590 /* Defer enabling of GPE until all notify handlers are done */ 600 /* Defer enabling of GPE until all notify handlers are done */
591 601
592 status = acpi_os_execute(OSL_NOTIFY_HANDLER, 602 status = acpi_os_execute(OSL_NOTIFY_HANDLER,
593 acpi_ev_asynch_enable_gpe, 603 acpi_ev_asynch_enable_gpe, gpe_event_info);
594 local_gpe_event_info); 604 if (ACPI_SUCCESS(status)) {
595 if (ACPI_FAILURE(status)) { 605 return_VOID;
596 ACPI_FREE(local_gpe_event_info);
597 } 606 }
607
608error_exit:
609 acpi_ev_asynch_enable_gpe(gpe_event_info);
598 return_VOID; 610 return_VOID;
599} 611}
600 612
@@ -622,7 +634,6 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_enable_gpe(void *context)
622 (void)acpi_ev_finish_gpe(gpe_event_info); 634 (void)acpi_ev_finish_gpe(gpe_event_info);
623 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 635 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
624 636
625 ACPI_FREE(gpe_event_info);
626 return; 637 return;
627} 638}
628 639
@@ -692,15 +703,6 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
692 703
693 ACPI_FUNCTION_TRACE(ev_gpe_dispatch); 704 ACPI_FUNCTION_TRACE(ev_gpe_dispatch);
694 705
695 /* Invoke global event handler if present */
696
697 acpi_gpe_count++;
698 if (acpi_gbl_global_event_handler) {
699 acpi_gbl_global_event_handler(ACPI_EVENT_TYPE_GPE, gpe_device,
700 gpe_number,
701 acpi_gbl_global_event_handler_context);
702 }
703
704 /* 706 /*
705 * Always disable the GPE so that it does not keep firing before 707 * Always disable the GPE so that it does not keep firing before
706 * any asynchronous activity completes (either from the execution 708 * any asynchronous activity completes (either from the execution
@@ -741,7 +743,7 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
741 * If there is neither a handler nor a method, leave the GPE 743 * If there is neither a handler nor a method, leave the GPE
742 * disabled. 744 * disabled.
743 */ 745 */
744 switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) { 746 switch (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags)) {
745 case ACPI_GPE_DISPATCH_HANDLER: 747 case ACPI_GPE_DISPATCH_HANDLER:
746 748
747 /* Invoke the installed handler (at interrupt level) */ 749 /* Invoke the installed handler (at interrupt level) */