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.c172
1 files changed, 100 insertions, 72 deletions
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c
index c25999546c8c..2dbca95979ce 100644
--- a/drivers/acpi/acpica/evgpe.c
+++ b/drivers/acpi/acpica/evgpe.c
@@ -115,12 +115,13 @@ acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
115 ACPI_FUNCTION_TRACE(ev_enable_gpe); 115 ACPI_FUNCTION_TRACE(ev_enable_gpe);
116 116
117 /* 117 /*
118 * We will only allow a GPE to be enabled if it has either an 118 * We will only allow a GPE to be enabled if it has either an associated
119 * associated method (_Lxx/_Exx) or a handler. Otherwise, the 119 * method (_Lxx/_Exx) or a handler, or is using the implicit notify
120 * GPE will be immediately disabled by acpi_ev_gpe_dispatch the 120 * feature. Otherwise, the GPE will be immediately disabled by
121 * first time it fires. 121 * acpi_ev_gpe_dispatch the first time it fires.
122 */ 122 */
123 if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)) { 123 if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
124 ACPI_GPE_DISPATCH_NONE) {
124 return_ACPI_STATUS(AE_NO_HANDLER); 125 return_ACPI_STATUS(AE_NO_HANDLER);
125 } 126 }
126 127
@@ -486,12 +487,26 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
486 return_VOID; 487 return_VOID;
487 } 488 }
488 489
489 /* 490 /* Do the correct dispatch - normal method or implicit notify */
490 * Must check for control method type dispatch one more time to avoid a 491
491 * race with ev_gpe_install_handler 492 switch (local_gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) {
492 */ 493 case ACPI_GPE_DISPATCH_NOTIFY:
493 if ((local_gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == 494
494 ACPI_GPE_DISPATCH_METHOD) { 495 /*
496 * Implicit notify.
497 * Dispatch a DEVICE_WAKE notify to the appropriate handler.
498 * NOTE: the request is queued for execution after this method
499 * completes. The notify handlers are NOT invoked synchronously
500 * from this thread -- because handlers may in turn run other
501 * control methods.
502 */
503 status =
504 acpi_ev_queue_notify_request(local_gpe_event_info->dispatch.
505 device_node,
506 ACPI_NOTIFY_DEVICE_WAKE);
507 break;
508
509 case ACPI_GPE_DISPATCH_METHOD:
495 510
496 /* Allocate the evaluation information block */ 511 /* Allocate the evaluation information block */
497 512
@@ -518,6 +533,11 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
518 (local_gpe_event_info->dispatch. 533 (local_gpe_event_info->dispatch.
519 method_node))); 534 method_node)));
520 } 535 }
536
537 break;
538
539 default:
540 return_VOID; /* Should never happen */
521 } 541 }
522 542
523 /* Defer enabling of GPE until all notify handlers are done */ 543 /* Defer enabling of GPE until all notify handlers are done */
@@ -531,6 +551,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
531 return_VOID; 551 return_VOID;
532} 552}
533 553
554
534/******************************************************************************* 555/*******************************************************************************
535 * 556 *
536 * FUNCTION: acpi_ev_asynch_enable_gpe 557 * FUNCTION: acpi_ev_asynch_enable_gpe
@@ -541,38 +562,60 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
541 * RETURN: None 562 * RETURN: None
542 * 563 *
543 * DESCRIPTION: Asynchronous clear/enable for GPE. This allows the GPE to 564 * DESCRIPTION: Asynchronous clear/enable for GPE. This allows the GPE to
544 * complete. 565 * complete (i.e., finish execution of Notify)
545 * 566 *
546 ******************************************************************************/ 567 ******************************************************************************/
547 568
548static void ACPI_SYSTEM_XFACE acpi_ev_asynch_enable_gpe(void *context) 569static void ACPI_SYSTEM_XFACE acpi_ev_asynch_enable_gpe(void *context)
549{ 570{
550 struct acpi_gpe_event_info *gpe_event_info = context; 571 struct acpi_gpe_event_info *gpe_event_info = context;
572
573 (void)acpi_ev_finish_gpe(gpe_event_info);
574
575 ACPI_FREE(gpe_event_info);
576 return;
577}
578
579
580/*******************************************************************************
581 *
582 * FUNCTION: acpi_ev_finish_gpe
583 *
584 * PARAMETERS: gpe_event_info - Info for this GPE
585 *
586 * RETURN: Status
587 *
588 * DESCRIPTION: Clear/Enable a GPE. Common code that is used after execution
589 * of a GPE method or a synchronous or asynchronous GPE handler.
590 *
591 ******************************************************************************/
592
593acpi_status acpi_ev_finish_gpe(struct acpi_gpe_event_info *gpe_event_info)
594{
551 acpi_status status; 595 acpi_status status;
552 596
553 if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) == 597 if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
554 ACPI_GPE_LEVEL_TRIGGERED) { 598 ACPI_GPE_LEVEL_TRIGGERED) {
555 /* 599 /*
556 * GPE is level-triggered, we clear the GPE status bit after handling 600 * GPE is level-triggered, we clear the GPE status bit after
557 * the event. 601 * handling the event.
558 */ 602 */
559 status = acpi_hw_clear_gpe(gpe_event_info); 603 status = acpi_hw_clear_gpe(gpe_event_info);
560 if (ACPI_FAILURE(status)) { 604 if (ACPI_FAILURE(status)) {
561 goto exit; 605 return (status);
562 } 606 }
563 } 607 }
564 608
565 /* 609 /*
566 * Enable this GPE, conditionally. This means that the GPE will only be 610 * Enable this GPE, conditionally. This means that the GPE will
567 * physically enabled if the enable_for_run bit is set in the event_info 611 * only be physically enabled if the enable_for_run bit is set
612 * in the event_info.
568 */ 613 */
569 (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_CONDITIONAL_ENABLE); 614 (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_CONDITIONAL_ENABLE);
570 615 return (AE_OK);
571exit:
572 ACPI_FREE(gpe_event_info);
573 return;
574} 616}
575 617
618
576/******************************************************************************* 619/*******************************************************************************
577 * 620 *
578 * FUNCTION: acpi_ev_gpe_dispatch 621 * FUNCTION: acpi_ev_gpe_dispatch
@@ -595,6 +638,7 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
595 struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) 638 struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
596{ 639{
597 acpi_status status; 640 acpi_status status;
641 u32 return_value;
598 642
599 ACPI_FUNCTION_TRACE(ev_gpe_dispatch); 643 ACPI_FUNCTION_TRACE(ev_gpe_dispatch);
600 644
@@ -616,54 +660,49 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
616 } 660 }
617 661
618 /* 662 /*
619 * Dispatch the GPE to either an installed handler, or the control method 663 * Always disable the GPE so that it does not keep firing before
620 * associated with this GPE (_Lxx or _Exx). If a handler exists, we invoke 664 * any asynchronous activity completes (either from the execution
621 * it and do not attempt to run the method. If there is neither a handler 665 * of a GPE method or an asynchronous GPE handler.)
622 * nor a method, we disable this GPE to prevent further such pointless 666 *
623 * events from firing. 667 * If there is no handler or method to run, just disable the
668 * GPE and leave it disabled permanently to prevent further such
669 * pointless events from firing.
670 */
671 status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
672 if (ACPI_FAILURE(status)) {
673 ACPI_EXCEPTION((AE_INFO, status,
674 "Unable to disable GPE%02X", gpe_number));
675 return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
676 }
677
678 /*
679 * Dispatch the GPE to either an installed handler or the control
680 * method associated with this GPE (_Lxx or _Exx). If a handler
681 * exists, we invoke it and do not attempt to run the method.
682 * If there is neither a handler nor a method, leave the GPE
683 * disabled.
624 */ 684 */
625 switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) { 685 switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) {
626 case ACPI_GPE_DISPATCH_HANDLER: 686 case ACPI_GPE_DISPATCH_HANDLER:
627 687
628 /* 688 /* Invoke the installed handler (at interrupt level) */
629 * Invoke the installed handler (at interrupt level) 689
630 * Ignore return status for now. 690 return_value =
631 * TBD: leave GPE disabled on error? 691 gpe_event_info->dispatch.handler->address(gpe_device,
632 */ 692 gpe_number,
633 (void)gpe_event_info->dispatch.handler->address(gpe_device, 693 gpe_event_info->
634 gpe_number, 694 dispatch.handler->
635 gpe_event_info-> 695 context);
636 dispatch. 696
637 handler-> 697 /* If requested, clear (if level-triggered) and reenable the GPE */
638 context); 698
639 699 if (return_value & ACPI_REENABLE_GPE) {
640 /* It is now safe to clear level-triggered events. */ 700 (void)acpi_ev_finish_gpe(gpe_event_info);
641
642 if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
643 ACPI_GPE_LEVEL_TRIGGERED) {
644 status = acpi_hw_clear_gpe(gpe_event_info);
645 if (ACPI_FAILURE(status)) {
646 ACPI_EXCEPTION((AE_INFO, status,
647 "Unable to clear GPE[0x%2X]",
648 gpe_number));
649 return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
650 }
651 } 701 }
652 break; 702 break;
653 703
654 case ACPI_GPE_DISPATCH_METHOD: 704 case ACPI_GPE_DISPATCH_METHOD:
655 705 case ACPI_GPE_DISPATCH_NOTIFY:
656 /*
657 * Disable the GPE, so it doesn't keep firing before the method has a
658 * chance to run (it runs asynchronously with interrupts enabled).
659 */
660 status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
661 if (ACPI_FAILURE(status)) {
662 ACPI_EXCEPTION((AE_INFO, status,
663 "Unable to disable GPE[0x%2X]",
664 gpe_number));
665 return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
666 }
667 706
668 /* 707 /*
669 * Execute the method associated with the GPE 708 * Execute the method associated with the GPE
@@ -690,17 +729,6 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
690 "No handler or method for GPE[0x%2X], disabling event", 729 "No handler or method for GPE[0x%2X], disabling event",
691 gpe_number)); 730 gpe_number));
692 731
693 /*
694 * Disable the GPE. The GPE will remain disabled a handler
695 * is installed or ACPICA is restarted.
696 */
697 status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
698 if (ACPI_FAILURE(status)) {
699 ACPI_EXCEPTION((AE_INFO, status,
700 "Unable to disable GPE[0x%2X]",
701 gpe_number));
702 return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
703 }
704 break; 732 break;
705 } 733 }
706 734