aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/evgpe.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/acpi/acpica/evgpe.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/acpi/acpica/evgpe.c')
-rw-r--r--drivers/acpi/acpica/evgpe.c287
1 files changed, 195 insertions, 92 deletions
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c
index f226eac314db..65c79add3b19 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 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, 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
@@ -52,6 +52,8 @@ ACPI_MODULE_NAME("evgpe")
52/* Local prototypes */ 52/* Local prototypes */
53static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context); 53static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context);
54 54
55static void ACPI_SYSTEM_XFACE acpi_ev_asynch_enable_gpe(void *context);
56
55/******************************************************************************* 57/*******************************************************************************
56 * 58 *
57 * FUNCTION: acpi_ev_update_gpe_enable_mask 59 * FUNCTION: acpi_ev_update_gpe_enable_mask
@@ -102,7 +104,7 @@ acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info)
102 * 104 *
103 * RETURN: Status 105 * RETURN: Status
104 * 106 *
105 * DESCRIPTION: Clear the given GPE from stale events and enable it. 107 * DESCRIPTION: Clear a GPE of stale events and enable it.
106 * 108 *
107 ******************************************************************************/ 109 ******************************************************************************/
108acpi_status 110acpi_status
@@ -113,12 +115,13 @@ acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
113 ACPI_FUNCTION_TRACE(ev_enable_gpe); 115 ACPI_FUNCTION_TRACE(ev_enable_gpe);
114 116
115 /* 117 /*
116 * 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
117 * associated method (_Lxx/_Exx) or a handler. Otherwise, the 119 * method (_Lxx/_Exx) or a handler, or is using the implicit notify
118 * GPE will be immediately disabled by acpi_ev_gpe_dispatch the 120 * feature. Otherwise, the GPE will be immediately disabled by
119 * first time it fires. 121 * acpi_ev_gpe_dispatch the first time it fires.
120 */ 122 */
121 if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)) { 123 if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
124 ACPI_GPE_DISPATCH_NONE) {
122 return_ACPI_STATUS(AE_NO_HANDLER); 125 return_ACPI_STATUS(AE_NO_HANDLER);
123 } 126 }
124 127
@@ -137,9 +140,9 @@ acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
137 140
138/******************************************************************************* 141/*******************************************************************************
139 * 142 *
140 * FUNCTION: acpi_raw_enable_gpe 143 * FUNCTION: acpi_ev_add_gpe_reference
141 * 144 *
142 * PARAMETERS: gpe_event_info - GPE to enable 145 * PARAMETERS: gpe_event_info - Add a reference to this GPE
143 * 146 *
144 * RETURN: Status 147 * RETURN: Status
145 * 148 *
@@ -148,16 +151,21 @@ acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
148 * 151 *
149 ******************************************************************************/ 152 ******************************************************************************/
150 153
151acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) 154acpi_status acpi_ev_add_gpe_reference(struct acpi_gpe_event_info *gpe_event_info)
152{ 155{
153 acpi_status status = AE_OK; 156 acpi_status status = AE_OK;
154 157
158 ACPI_FUNCTION_TRACE(ev_add_gpe_reference);
159
155 if (gpe_event_info->runtime_count == ACPI_UINT8_MAX) { 160 if (gpe_event_info->runtime_count == ACPI_UINT8_MAX) {
156 return_ACPI_STATUS(AE_LIMIT); 161 return_ACPI_STATUS(AE_LIMIT);
157 } 162 }
158 163
159 gpe_event_info->runtime_count++; 164 gpe_event_info->runtime_count++;
160 if (gpe_event_info->runtime_count == 1) { 165 if (gpe_event_info->runtime_count == 1) {
166
167 /* Enable on first reference */
168
161 status = acpi_ev_update_gpe_enable_mask(gpe_event_info); 169 status = acpi_ev_update_gpe_enable_mask(gpe_event_info);
162 if (ACPI_SUCCESS(status)) { 170 if (ACPI_SUCCESS(status)) {
163 status = acpi_ev_enable_gpe(gpe_event_info); 171 status = acpi_ev_enable_gpe(gpe_event_info);
@@ -173,9 +181,9 @@ acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
173 181
174/******************************************************************************* 182/*******************************************************************************
175 * 183 *
176 * FUNCTION: acpi_raw_disable_gpe 184 * FUNCTION: acpi_ev_remove_gpe_reference
177 * 185 *
178 * PARAMETERS: gpe_event_info - GPE to disable 186 * PARAMETERS: gpe_event_info - Remove a reference to this GPE
179 * 187 *
180 * RETURN: Status 188 * RETURN: Status
181 * 189 *
@@ -184,16 +192,21 @@ acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
184 * 192 *
185 ******************************************************************************/ 193 ******************************************************************************/
186 194
187acpi_status acpi_raw_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) 195acpi_status acpi_ev_remove_gpe_reference(struct acpi_gpe_event_info *gpe_event_info)
188{ 196{
189 acpi_status status = AE_OK; 197 acpi_status status = AE_OK;
190 198
199 ACPI_FUNCTION_TRACE(ev_remove_gpe_reference);
200
191 if (!gpe_event_info->runtime_count) { 201 if (!gpe_event_info->runtime_count) {
192 return_ACPI_STATUS(AE_LIMIT); 202 return_ACPI_STATUS(AE_LIMIT);
193 } 203 }
194 204
195 gpe_event_info->runtime_count--; 205 gpe_event_info->runtime_count--;
196 if (!gpe_event_info->runtime_count) { 206 if (!gpe_event_info->runtime_count) {
207
208 /* Disable on last reference */
209
197 status = acpi_ev_update_gpe_enable_mask(gpe_event_info); 210 status = acpi_ev_update_gpe_enable_mask(gpe_event_info);
198 if (ACPI_SUCCESS(status)) { 211 if (ACPI_SUCCESS(status)) {
199 status = acpi_hw_low_set_gpe(gpe_event_info, 212 status = acpi_hw_low_set_gpe(gpe_event_info,
@@ -360,6 +373,15 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
360 373
361 gpe_register_info = &gpe_block->register_info[i]; 374 gpe_register_info = &gpe_block->register_info[i];
362 375
376 /*
377 * Optimization: If there are no GPEs enabled within this
378 * register, we can safely ignore the entire register.
379 */
380 if (!(gpe_register_info->enable_for_run |
381 gpe_register_info->enable_for_wake)) {
382 continue;
383 }
384
363 /* Read the Status Register */ 385 /* Read the Status Register */
364 386
365 status = 387 status =
@@ -379,7 +401,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
379 } 401 }
380 402
381 ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS, 403 ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
382 "Read GPE Register at GPE%X: Status=%02X, Enable=%02X\n", 404 "Read GPE Register at GPE%02X: Status=%02X, Enable=%02X\n",
383 gpe_register_info->base_gpe_number, 405 gpe_register_info->base_gpe_number,
384 status_reg, enable_reg)); 406 status_reg, enable_reg));
385 407
@@ -405,7 +427,9 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
405 * or method. 427 * or method.
406 */ 428 */
407 int_status |= 429 int_status |=
408 acpi_ev_gpe_dispatch(&gpe_block-> 430 acpi_ev_gpe_dispatch(gpe_block->
431 node,
432 &gpe_block->
409 event_info[((acpi_size) i * ACPI_GPE_REGISTER_WIDTH) + j], j + gpe_register_info->base_gpe_number); 433 event_info[((acpi_size) i * ACPI_GPE_REGISTER_WIDTH) + j], j + gpe_register_info->base_gpe_number);
410 } 434 }
411 } 435 }
@@ -435,19 +459,29 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
435 * an interrupt handler. 459 * an interrupt handler.
436 * 460 *
437 ******************************************************************************/ 461 ******************************************************************************/
438static void acpi_ev_asynch_enable_gpe(void *context);
439 462
440static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) 463static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
441{ 464{
442 struct acpi_gpe_event_info *gpe_event_info = (void *)context; 465 struct acpi_gpe_event_info *gpe_event_info = context;
443 acpi_status status; 466 acpi_status status;
444 struct acpi_gpe_event_info local_gpe_event_info; 467 struct acpi_gpe_event_info *local_gpe_event_info;
445 struct acpi_evaluate_info *info; 468 struct acpi_evaluate_info *info;
469 struct acpi_gpe_notify_object *notify_object;
446 470
447 ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method); 471 ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method);
448 472
473 /* Allocate a local GPE block */
474
475 local_gpe_event_info =
476 ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_event_info));
477 if (!local_gpe_event_info) {
478 ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, "while handling a GPE"));
479 return_VOID;
480 }
481
449 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); 482 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
450 if (ACPI_FAILURE(status)) { 483 if (ACPI_FAILURE(status)) {
484 ACPI_FREE(local_gpe_event_info);
451 return_VOID; 485 return_VOID;
452 } 486 }
453 487
@@ -455,6 +489,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
455 489
456 if (!acpi_ev_valid_gpe_event(gpe_event_info)) { 490 if (!acpi_ev_valid_gpe_event(gpe_event_info)) {
457 status = acpi_ut_release_mutex(ACPI_MTX_EVENTS); 491 status = acpi_ut_release_mutex(ACPI_MTX_EVENTS);
492 ACPI_FREE(local_gpe_event_info);
458 return_VOID; 493 return_VOID;
459 } 494 }
460 495
@@ -462,7 +497,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
462 * Take a snapshot of the GPE info for this level - we copy the info to 497 * Take a snapshot of the GPE info for this level - we copy the info to
463 * prevent a race condition with remove_handler/remove_block. 498 * prevent a race condition with remove_handler/remove_block.
464 */ 499 */
465 ACPI_MEMCPY(&local_gpe_event_info, gpe_event_info, 500 ACPI_MEMCPY(local_gpe_event_info, gpe_event_info,
466 sizeof(struct acpi_gpe_event_info)); 501 sizeof(struct acpi_gpe_event_info));
467 502
468 status = acpi_ut_release_mutex(ACPI_MTX_EVENTS); 503 status = acpi_ut_release_mutex(ACPI_MTX_EVENTS);
@@ -470,12 +505,34 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
470 return_VOID; 505 return_VOID;
471 } 506 }
472 507
473 /* 508 /* Do the correct dispatch - normal method or implicit notify */
474 * Must check for control method type dispatch one more time to avoid a 509
475 * race with ev_gpe_install_handler 510 switch (local_gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) {
476 */ 511 case ACPI_GPE_DISPATCH_NOTIFY:
477 if ((local_gpe_event_info.flags & ACPI_GPE_DISPATCH_MASK) == 512
478 ACPI_GPE_DISPATCH_METHOD) { 513 /*
514 * Implicit notify.
515 * Dispatch a DEVICE_WAKE notify to the appropriate handler.
516 * NOTE: the request is queued for execution after this method
517 * completes. The notify handlers are NOT invoked synchronously
518 * from this thread -- because handlers may in turn run other
519 * control methods.
520 */
521 status = acpi_ev_queue_notify_request(
522 local_gpe_event_info->dispatch.device.node,
523 ACPI_NOTIFY_DEVICE_WAKE);
524
525 notify_object = local_gpe_event_info->dispatch.device.next;
526 while (ACPI_SUCCESS(status) && notify_object) {
527 status = acpi_ev_queue_notify_request(
528 notify_object->node,
529 ACPI_NOTIFY_DEVICE_WAKE);
530 notify_object = notify_object->next;
531 }
532
533 break;
534
535 case ACPI_GPE_DISPATCH_METHOD:
479 536
480 /* Allocate the evaluation information block */ 537 /* Allocate the evaluation information block */
481 538
@@ -488,7 +545,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
488 * control method that corresponds to this GPE 545 * control method that corresponds to this GPE
489 */ 546 */
490 info->prefix_node = 547 info->prefix_node =
491 local_gpe_event_info.dispatch.method_node; 548 local_gpe_event_info->dispatch.method_node;
492 info->flags = ACPI_IGNORE_RETURN_VALUE; 549 info->flags = ACPI_IGNORE_RETURN_VALUE;
493 550
494 status = acpi_ns_evaluate(info); 551 status = acpi_ns_evaluate(info);
@@ -499,46 +556,98 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
499 ACPI_EXCEPTION((AE_INFO, status, 556 ACPI_EXCEPTION((AE_INFO, status,
500 "while evaluating GPE method [%4.4s]", 557 "while evaluating GPE method [%4.4s]",
501 acpi_ut_get_node_name 558 acpi_ut_get_node_name
502 (local_gpe_event_info.dispatch. 559 (local_gpe_event_info->dispatch.
503 method_node))); 560 method_node)));
504 } 561 }
562
563 break;
564
565 default:
566 return_VOID; /* Should never happen */
505 } 567 }
568
506 /* Defer enabling of GPE until all notify handlers are done */ 569 /* Defer enabling of GPE until all notify handlers are done */
507 acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_asynch_enable_gpe, 570
508 gpe_event_info); 571 status = acpi_os_execute(OSL_NOTIFY_HANDLER,
572 acpi_ev_asynch_enable_gpe,
573 local_gpe_event_info);
574 if (ACPI_FAILURE(status)) {
575 ACPI_FREE(local_gpe_event_info);
576 }
509 return_VOID; 577 return_VOID;
510} 578}
511 579
512static void acpi_ev_asynch_enable_gpe(void *context) 580
581/*******************************************************************************
582 *
583 * FUNCTION: acpi_ev_asynch_enable_gpe
584 *
585 * PARAMETERS: Context (gpe_event_info) - Info for this GPE
586 * Callback from acpi_os_execute
587 *
588 * RETURN: None
589 *
590 * DESCRIPTION: Asynchronous clear/enable for GPE. This allows the GPE to
591 * complete (i.e., finish execution of Notify)
592 *
593 ******************************************************************************/
594
595static void ACPI_SYSTEM_XFACE acpi_ev_asynch_enable_gpe(void *context)
513{ 596{
514 struct acpi_gpe_event_info *gpe_event_info = context; 597 struct acpi_gpe_event_info *gpe_event_info = context;
598
599 (void)acpi_ev_finish_gpe(gpe_event_info);
600
601 ACPI_FREE(gpe_event_info);
602 return;
603}
604
605
606/*******************************************************************************
607 *
608 * FUNCTION: acpi_ev_finish_gpe
609 *
610 * PARAMETERS: gpe_event_info - Info for this GPE
611 *
612 * RETURN: Status
613 *
614 * DESCRIPTION: Clear/Enable a GPE. Common code that is used after execution
615 * of a GPE method or a synchronous or asynchronous GPE handler.
616 *
617 ******************************************************************************/
618
619acpi_status acpi_ev_finish_gpe(struct acpi_gpe_event_info *gpe_event_info)
620{
515 acpi_status status; 621 acpi_status status;
622
516 if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) == 623 if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
517 ACPI_GPE_LEVEL_TRIGGERED) { 624 ACPI_GPE_LEVEL_TRIGGERED) {
518 /* 625 /*
519 * GPE is level-triggered, we clear the GPE status bit after handling 626 * GPE is level-triggered, we clear the GPE status bit after
520 * the event. 627 * handling the event.
521 */ 628 */
522 status = acpi_hw_clear_gpe(gpe_event_info); 629 status = acpi_hw_clear_gpe(gpe_event_info);
523 if (ACPI_FAILURE(status)) { 630 if (ACPI_FAILURE(status)) {
524 return_VOID; 631 return (status);
525 } 632 }
526 } 633 }
527 634
528 /* 635 /*
529 * Enable this GPE, conditionally. This means that the GPE will only be 636 * Enable this GPE, conditionally. This means that the GPE will
530 * physically enabled if the enable_for_run bit is set in the event_info 637 * only be physically enabled if the enable_for_run bit is set
638 * in the event_info.
531 */ 639 */
532 (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_COND_ENABLE); 640 (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_CONDITIONAL_ENABLE);
533 641 return (AE_OK);
534 return_VOID;
535} 642}
536 643
644
537/******************************************************************************* 645/*******************************************************************************
538 * 646 *
539 * FUNCTION: acpi_ev_gpe_dispatch 647 * FUNCTION: acpi_ev_gpe_dispatch
540 * 648 *
541 * PARAMETERS: gpe_event_info - Info for this GPE 649 * PARAMETERS: gpe_device - Device node. NULL for GPE0/GPE1
650 * gpe_event_info - Info for this GPE
542 * gpe_number - Number relative to the parent GPE block 651 * gpe_number - Number relative to the parent GPE block
543 * 652 *
544 * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED 653 * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
@@ -551,13 +660,22 @@ static void acpi_ev_asynch_enable_gpe(void *context)
551 ******************************************************************************/ 660 ******************************************************************************/
552 661
553u32 662u32
554acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) 663acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
664 struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
555{ 665{
556 acpi_status status; 666 acpi_status status;
667 u32 return_value;
557 668
558 ACPI_FUNCTION_TRACE(ev_gpe_dispatch); 669 ACPI_FUNCTION_TRACE(ev_gpe_dispatch);
559 670
560 acpi_os_gpe_count(gpe_number); 671 /* Invoke global event handler if present */
672
673 acpi_gpe_count++;
674 if (acpi_gbl_global_event_handler) {
675 acpi_gbl_global_event_handler(ACPI_EVENT_TYPE_GPE, gpe_device,
676 gpe_number,
677 acpi_gbl_global_event_handler_context);
678 }
561 679
562 /* 680 /*
563 * If edge-triggered, clear the GPE status bit now. Note that 681 * If edge-triggered, clear the GPE status bit now. Note that
@@ -568,59 +686,55 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
568 status = acpi_hw_clear_gpe(gpe_event_info); 686 status = acpi_hw_clear_gpe(gpe_event_info);
569 if (ACPI_FAILURE(status)) { 687 if (ACPI_FAILURE(status)) {
570 ACPI_EXCEPTION((AE_INFO, status, 688 ACPI_EXCEPTION((AE_INFO, status,
571 "Unable to clear GPE[0x%2X]", 689 "Unable to clear GPE%02X", gpe_number));
572 gpe_number));
573 return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); 690 return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
574 } 691 }
575 } 692 }
576 693
577 /* 694 /*
578 * Dispatch the GPE to either an installed handler, or the control method 695 * Always disable the GPE so that it does not keep firing before
579 * associated with this GPE (_Lxx or _Exx). If a handler exists, we invoke 696 * any asynchronous activity completes (either from the execution
580 * it and do not attempt to run the method. If there is neither a handler 697 * of a GPE method or an asynchronous GPE handler.)
581 * nor a method, we disable this GPE to prevent further such pointless 698 *
582 * events from firing. 699 * If there is no handler or method to run, just disable the
700 * GPE and leave it disabled permanently to prevent further such
701 * pointless events from firing.
702 */
703 status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
704 if (ACPI_FAILURE(status)) {
705 ACPI_EXCEPTION((AE_INFO, status,
706 "Unable to disable GPE%02X", gpe_number));
707 return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
708 }
709
710 /*
711 * Dispatch the GPE to either an installed handler or the control
712 * method associated with this GPE (_Lxx or _Exx). If a handler
713 * exists, we invoke it and do not attempt to run the method.
714 * If there is neither a handler nor a method, leave the GPE
715 * disabled.
583 */ 716 */
584 switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) { 717 switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) {
585 case ACPI_GPE_DISPATCH_HANDLER: 718 case ACPI_GPE_DISPATCH_HANDLER:
586 719
587 /* 720 /* Invoke the installed handler (at interrupt level) */
588 * Invoke the installed handler (at interrupt level)
589 * Ignore return status for now.
590 * TBD: leave GPE disabled on error?
591 */
592 (void)gpe_event_info->dispatch.handler->address(gpe_event_info->
593 dispatch.
594 handler->
595 context);
596 721
597 /* It is now safe to clear level-triggered events. */ 722 return_value =
723 gpe_event_info->dispatch.handler->address(gpe_device,
724 gpe_number,
725 gpe_event_info->
726 dispatch.handler->
727 context);
598 728
599 if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) == 729 /* If requested, clear (if level-triggered) and reenable the GPE */
600 ACPI_GPE_LEVEL_TRIGGERED) { 730
601 status = acpi_hw_clear_gpe(gpe_event_info); 731 if (return_value & ACPI_REENABLE_GPE) {
602 if (ACPI_FAILURE(status)) { 732 (void)acpi_ev_finish_gpe(gpe_event_info);
603 ACPI_EXCEPTION((AE_INFO, status,
604 "Unable to clear GPE[0x%2X]",
605 gpe_number));
606 return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
607 }
608 } 733 }
609 break; 734 break;
610 735
611 case ACPI_GPE_DISPATCH_METHOD: 736 case ACPI_GPE_DISPATCH_METHOD:
612 737 case ACPI_GPE_DISPATCH_NOTIFY:
613 /*
614 * Disable the GPE, so it doesn't keep firing before the method has a
615 * chance to run (it runs asynchronously with interrupts enabled).
616 */
617 status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
618 if (ACPI_FAILURE(status)) {
619 ACPI_EXCEPTION((AE_INFO, status,
620 "Unable to disable GPE[0x%2X]",
621 gpe_number));
622 return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
623 }
624 738
625 /* 739 /*
626 * Execute the method associated with the GPE 740 * Execute the method associated with the GPE
@@ -631,7 +745,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
631 gpe_event_info); 745 gpe_event_info);
632 if (ACPI_FAILURE(status)) { 746 if (ACPI_FAILURE(status)) {
633 ACPI_EXCEPTION((AE_INFO, status, 747 ACPI_EXCEPTION((AE_INFO, status,
634 "Unable to queue handler for GPE[0x%2X] - event disabled", 748 "Unable to queue handler for GPE%2X - event disabled",
635 gpe_number)); 749 gpe_number));
636 } 750 }
637 break; 751 break;
@@ -644,20 +758,9 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
644 * a GPE to be enabled if it has no handler or method. 758 * a GPE to be enabled if it has no handler or method.
645 */ 759 */
646 ACPI_ERROR((AE_INFO, 760 ACPI_ERROR((AE_INFO,
647 "No handler or method for GPE[0x%2X], disabling event", 761 "No handler or method for GPE%02X, disabling event",
648 gpe_number)); 762 gpe_number));
649 763
650 /*
651 * Disable the GPE. The GPE will remain disabled a handler
652 * is installed or ACPICA is restarted.
653 */
654 status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
655 if (ACPI_FAILURE(status)) {
656 ACPI_EXCEPTION((AE_INFO, status,
657 "Unable to disable GPE[0x%2X]",
658 gpe_number));
659 return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
660 }
661 break; 764 break;
662 } 765 }
663 766