1 /****************************************************************************** 2 * 3 * Module Name: evgpe - General Purpose Event handling and dispatch 4 * 5 *****************************************************************************/ 6 7 /****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2012, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 *****************************************************************************/ 115 116 #include "acpi.h" 117 #include "accommon.h" 118 #include "acevents.h" 119 #include "acnamesp.h" 120 121 #define _COMPONENT ACPI_EVENTS 122 ACPI_MODULE_NAME ("evgpe") 123 124 #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ 125 126 /* Local prototypes */ 127 128 static void ACPI_SYSTEM_XFACE 129 AcpiEvAsynchExecuteGpeMethod ( 130 void *Context); 131 132 static void ACPI_SYSTEM_XFACE 133 AcpiEvAsynchEnableGpe ( 134 void *Context); 135 136 137 /******************************************************************************* 138 * 139 * FUNCTION: AcpiEvUpdateGpeEnableMask 140 * 141 * PARAMETERS: GpeEventInfo - GPE to update 142 * 143 * RETURN: Status 144 * 145 * DESCRIPTION: Updates GPE register enable mask based upon whether there are 146 * runtime references to this GPE 147 * 148 ******************************************************************************/ 149 150 ACPI_STATUS 151 AcpiEvUpdateGpeEnableMask ( 152 ACPI_GPE_EVENT_INFO *GpeEventInfo) 153 { 154 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo; 155 UINT32 RegisterBit; 156 157 158 ACPI_FUNCTION_TRACE (EvUpdateGpeEnableMask); 159 160 161 GpeRegisterInfo = GpeEventInfo->RegisterInfo; 162 if (!GpeRegisterInfo) 163 { 164 return_ACPI_STATUS (AE_NOT_EXIST); 165 } 166 167 RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo, GpeRegisterInfo); 168 169 /* Clear the run bit up front */ 170 171 ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForRun, RegisterBit); 172 173 /* Set the mask bit only if there are references to this GPE */ 174 175 if (GpeEventInfo->RuntimeCount) 176 { 177 ACPI_SET_BIT (GpeRegisterInfo->EnableForRun, (UINT8) RegisterBit); 178 } 179 180 return_ACPI_STATUS (AE_OK); 181 } 182 183 184 /******************************************************************************* 185 * 186 * FUNCTION: AcpiEvEnableGpe 187 * 188 * PARAMETERS: GpeEventInfo - GPE to enable 189 * 190 * RETURN: Status 191 * 192 * DESCRIPTION: Clear a GPE of stale events and enable it. 193 * 194 ******************************************************************************/ 195 196 ACPI_STATUS 197 AcpiEvEnableGpe ( 198 ACPI_GPE_EVENT_INFO *GpeEventInfo) 199 { 200 ACPI_STATUS Status; 201 202 203 ACPI_FUNCTION_TRACE (EvEnableGpe); 204 205 206 /* 207 * We will only allow a GPE to be enabled if it has either an associated 208 * method (_Lxx/_Exx) or a handler, or is using the implicit notify 209 * feature. Otherwise, the GPE will be immediately disabled by 210 * AcpiEvGpeDispatch the first time it fires. 211 */ 212 if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == 213 ACPI_GPE_DISPATCH_NONE) 214 { 215 return_ACPI_STATUS (AE_NO_HANDLER); 216 } 217 218 /* Clear the GPE (of stale events) */ 219 220 Status = AcpiHwClearGpe (GpeEventInfo); 221 if (ACPI_FAILURE (Status)) 222 { 223 return_ACPI_STATUS (Status); 224 } 225 226 /* Enable the requested GPE */ 227 228 Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE); 229 return_ACPI_STATUS (Status); 230 } 231 232 233 /******************************************************************************* 234 * 235 * FUNCTION: AcpiEvAddGpeReference 236 * 237 * PARAMETERS: GpeEventInfo - Add a reference to this GPE 238 * 239 * RETURN: Status 240 * 241 * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is 242 * hardware-enabled. 243 * 244 ******************************************************************************/ 245 246 ACPI_STATUS 247 AcpiEvAddGpeReference ( 248 ACPI_GPE_EVENT_INFO *GpeEventInfo) 249 { 250 ACPI_STATUS Status = AE_OK; 251 252 253 ACPI_FUNCTION_TRACE (EvAddGpeReference); 254 255 256 if (GpeEventInfo->RuntimeCount == ACPI_UINT8_MAX) 257 { 258 return_ACPI_STATUS (AE_LIMIT); 259 } 260 261 GpeEventInfo->RuntimeCount++; 262 if (GpeEventInfo->RuntimeCount == 1) 263 { 264 /* Enable on first reference */ 265 266 Status = AcpiEvUpdateGpeEnableMask (GpeEventInfo); 267 if (ACPI_SUCCESS (Status)) 268 { 269 Status = AcpiEvEnableGpe (GpeEventInfo); 270 } 271 272 if (ACPI_FAILURE (Status)) 273 { 274 GpeEventInfo->RuntimeCount--; 275 } 276 } 277 278 return_ACPI_STATUS (Status); 279 } 280 281 282 /******************************************************************************* 283 * 284 * FUNCTION: AcpiEvRemoveGpeReference 285 * 286 * PARAMETERS: GpeEventInfo - Remove a reference to this GPE 287 * 288 * RETURN: Status 289 * 290 * DESCRIPTION: Remove a reference to a GPE. When the last reference is 291 * removed, the GPE is hardware-disabled. 292 * 293 ******************************************************************************/ 294 295 ACPI_STATUS 296 AcpiEvRemoveGpeReference ( 297 ACPI_GPE_EVENT_INFO *GpeEventInfo) 298 { 299 ACPI_STATUS Status = AE_OK; 300 301 302 ACPI_FUNCTION_TRACE (EvRemoveGpeReference); 303 304 305 if (!GpeEventInfo->RuntimeCount) 306 { 307 return_ACPI_STATUS (AE_LIMIT); 308 } 309 310 GpeEventInfo->RuntimeCount--; 311 if (!GpeEventInfo->RuntimeCount) 312 { 313 /* Disable on last reference */ 314 315 Status = AcpiEvUpdateGpeEnableMask (GpeEventInfo); 316 if (ACPI_SUCCESS (Status)) 317 { 318 Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE); 319 } 320 321 if (ACPI_FAILURE (Status)) 322 { 323 GpeEventInfo->RuntimeCount++; 324 } 325 } 326 327 return_ACPI_STATUS (Status); 328 } 329 330 331 /******************************************************************************* 332 * 333 * FUNCTION: AcpiEvLowGetGpeInfo 334 * 335 * PARAMETERS: GpeNumber - Raw GPE number 336 * GpeBlock - A GPE info block 337 * 338 * RETURN: A GPE EventInfo struct. NULL if not a valid GPE (The GpeNumber 339 * is not within the specified GPE block) 340 * 341 * DESCRIPTION: Returns the EventInfo struct associated with this GPE. This is 342 * the low-level implementation of EvGetGpeEventInfo. 343 * 344 ******************************************************************************/ 345 346 ACPI_GPE_EVENT_INFO * 347 AcpiEvLowGetGpeInfo ( 348 UINT32 GpeNumber, 349 ACPI_GPE_BLOCK_INFO *GpeBlock) 350 { 351 UINT32 GpeIndex; 352 353 354 /* 355 * Validate that the GpeNumber is within the specified GpeBlock. 356 * (Two steps) 357 */ 358 if (!GpeBlock || 359 (GpeNumber < GpeBlock->BlockBaseNumber)) 360 { 361 return (NULL); 362 } 363 364 GpeIndex = GpeNumber - GpeBlock->BlockBaseNumber; 365 if (GpeIndex >= GpeBlock->GpeCount) 366 { 367 return (NULL); 368 } 369 370 return (&GpeBlock->EventInfo[GpeIndex]); 371 } 372 373 374 /******************************************************************************* 375 * 376 * FUNCTION: AcpiEvGetGpeEventInfo 377 * 378 * PARAMETERS: GpeDevice - Device node. NULL for GPE0/GPE1 379 * GpeNumber - Raw GPE number 380 * 381 * RETURN: A GPE EventInfo struct. NULL if not a valid GPE 382 * 383 * DESCRIPTION: Returns the EventInfo struct associated with this GPE. 384 * Validates the GpeBlock and the GpeNumber 385 * 386 * Should be called only when the GPE lists are semaphore locked 387 * and not subject to change. 388 * 389 ******************************************************************************/ 390 391 ACPI_GPE_EVENT_INFO * 392 AcpiEvGetGpeEventInfo ( 393 ACPI_HANDLE GpeDevice, 394 UINT32 GpeNumber) 395 { 396 ACPI_OPERAND_OBJECT *ObjDesc; 397 ACPI_GPE_EVENT_INFO *GpeInfo; 398 UINT32 i; 399 400 401 ACPI_FUNCTION_ENTRY (); 402 403 404 /* A NULL GpeDevice means use the FADT-defined GPE block(s) */ 405 406 if (!GpeDevice) 407 { 408 /* Examine GPE Block 0 and 1 (These blocks are permanent) */ 409 410 for (i = 0; i < ACPI_MAX_GPE_BLOCKS; i++) 411 { 412 GpeInfo = AcpiEvLowGetGpeInfo (GpeNumber, 413 AcpiGbl_GpeFadtBlocks[i]); 414 if (GpeInfo) 415 { 416 return (GpeInfo); 417 } 418 } 419 420 /* The GpeNumber was not in the range of either FADT GPE block */ 421 422 return (NULL); 423 } 424 425 /* A Non-NULL GpeDevice means this is a GPE Block Device */ 426 427 ObjDesc = AcpiNsGetAttachedObject ((ACPI_NAMESPACE_NODE *) GpeDevice); 428 if (!ObjDesc || 429 !ObjDesc->Device.GpeBlock) 430 { 431 return (NULL); 432 } 433 434 return (AcpiEvLowGetGpeInfo (GpeNumber, ObjDesc->Device.GpeBlock)); 435 } 436 437 438 /******************************************************************************* 439 * 440 * FUNCTION: AcpiEvGpeDetect 441 * 442 * PARAMETERS: GpeXruptList - Interrupt block for this interrupt. 443 * Can have multiple GPE blocks attached. 444 * 445 * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED 446 * 447 * DESCRIPTION: Detect if any GP events have occurred. This function is 448 * executed at interrupt level. 449 * 450 ******************************************************************************/ 451 452 UINT32 453 AcpiEvGpeDetect ( 454 ACPI_GPE_XRUPT_INFO *GpeXruptList) 455 { 456 ACPI_STATUS Status; 457 ACPI_GPE_BLOCK_INFO *GpeBlock; 458 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo; 459 UINT32 IntStatus = ACPI_INTERRUPT_NOT_HANDLED; 460 UINT8 EnabledStatusByte; 461 UINT32 StatusReg; 462 UINT32 EnableReg; 463 ACPI_CPU_FLAGS Flags; 464 UINT32 i; 465 UINT32 j; 466 467 468 ACPI_FUNCTION_NAME (EvGpeDetect); 469 470 /* Check for the case where there are no GPEs */ 471 472 if (!GpeXruptList) 473 { 474 return (IntStatus); 475 } 476 477 /* 478 * We need to obtain the GPE lock for both the data structs and registers 479 * Note: Not necessary to obtain the hardware lock, since the GPE 480 * registers are owned by the GpeLock. 481 */ 482 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 483 484 /* Examine all GPE blocks attached to this interrupt level */ 485 486 GpeBlock = GpeXruptList->GpeBlockListHead; 487 while (GpeBlock) 488 { 489 /* 490 * Read all of the 8-bit GPE status and enable registers in this GPE 491 * block, saving all of them. Find all currently active GP events. 492 */ 493 for (i = 0; i < GpeBlock->RegisterCount; i++) 494 { 495 /* Get the next status/enable pair */ 496 497 GpeRegisterInfo = &GpeBlock->RegisterInfo[i]; 498 499 /* 500 * Optimization: If there are no GPEs enabled within this 501 * register, we can safely ignore the entire register. 502 */ 503 if (!(GpeRegisterInfo->EnableForRun | 504 GpeRegisterInfo->EnableForWake)) 505 { 506 continue; 507 } 508 509 /* Read the Status Register */ 510 511 Status = AcpiHwRead (&StatusReg, &GpeRegisterInfo->StatusAddress); 512 if (ACPI_FAILURE (Status)) 513 { 514 goto UnlockAndExit; 515 } 516 517 /* Read the Enable Register */ 518 519 Status = AcpiHwRead (&EnableReg, &GpeRegisterInfo->EnableAddress); 520 if (ACPI_FAILURE (Status)) 521 { 522 goto UnlockAndExit; 523 } 524 525 ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS, 526 "Read GPE Register at GPE%02X: Status=%02X, Enable=%02X\n", 527 GpeRegisterInfo->BaseGpeNumber, StatusReg, EnableReg)); 528 529 /* Check if there is anything active at all in this register */ 530 531 EnabledStatusByte = (UINT8) (StatusReg & EnableReg); 532 if (!EnabledStatusByte) 533 { 534 /* No active GPEs in this register, move on */ 535 536 continue; 537 } 538 539 /* Now look at the individual GPEs in this byte register */ 540 541 for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) 542 { 543 /* Examine one GPE bit */ 544 545 if (EnabledStatusByte & (1 << j)) 546 { 547 /* 548 * Found an active GPE. Dispatch the event to a handler 549 * or method. 550 */ 551 IntStatus |= AcpiEvGpeDispatch (GpeBlock->Node, 552 &GpeBlock->EventInfo[((ACPI_SIZE) i * 553 ACPI_GPE_REGISTER_WIDTH) + j], 554 j + GpeRegisterInfo->BaseGpeNumber); 555 } 556 } 557 } 558 559 GpeBlock = GpeBlock->Next; 560 } 561 562 UnlockAndExit: 563 564 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 565 return (IntStatus); 566 } 567 568 569 /******************************************************************************* 570 * 571 * FUNCTION: AcpiEvAsynchExecuteGpeMethod 572 * 573 * PARAMETERS: Context (GpeEventInfo) - Info for this GPE 574 * 575 * RETURN: None 576 * 577 * DESCRIPTION: Perform the actual execution of a GPE control method. This 578 * function is called from an invocation of AcpiOsExecute and 579 * therefore does NOT execute at interrupt level - so that 580 * the control method itself is not executed in the context of 581 * an interrupt handler. 582 * 583 ******************************************************************************/ 584 585 static void ACPI_SYSTEM_XFACE 586 AcpiEvAsynchExecuteGpeMethod ( 587 void *Context) 588 { 589 ACPI_GPE_EVENT_INFO *GpeEventInfo = Context; 590 ACPI_STATUS Status; 591 ACPI_GPE_EVENT_INFO *LocalGpeEventInfo; 592 ACPI_EVALUATE_INFO *Info; 593 ACPI_GPE_NOTIFY_INFO *Notify; 594 595 596 ACPI_FUNCTION_TRACE (EvAsynchExecuteGpeMethod); 597 598 599 /* Allocate a local GPE block */ 600 601 LocalGpeEventInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_EVENT_INFO)); 602 if (!LocalGpeEventInfo) 603 { 604 ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY, 605 "while handling a GPE")); 606 return_VOID; 607 } 608 609 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 610 if (ACPI_FAILURE (Status)) 611 { 612 return_VOID; 613 } 614 615 /* Must revalidate the GpeNumber/GpeBlock */ 616 617 if (!AcpiEvValidGpeEvent (GpeEventInfo)) 618 { 619 Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 620 return_VOID; 621 } 622 623 /* 624 * Take a snapshot of the GPE info for this level - we copy the info to 625 * prevent a race condition with RemoveHandler/RemoveBlock. 626 */ 627 ACPI_MEMCPY (LocalGpeEventInfo, GpeEventInfo, 628 sizeof (ACPI_GPE_EVENT_INFO)); 629 630 Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 631 if (ACPI_FAILURE (Status)) 632 { 633 return_VOID; 634 } 635 636 /* Do the correct dispatch - normal method or implicit notify */ 637 638 switch (LocalGpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) 639 { 640 case ACPI_GPE_DISPATCH_NOTIFY: 641 642 /* 643 * Implicit notify. 644 * Dispatch a DEVICE_WAKE notify to the appropriate handler. 645 * NOTE: the request is queued for execution after this method 646 * completes. The notify handlers are NOT invoked synchronously 647 * from this thread -- because handlers may in turn run other 648 * control methods. 649 * 650 * June 2012: Expand implicit notify mechanism to support 651 * notifies on multiple device objects. 652 */ 653 Notify = LocalGpeEventInfo->Dispatch.NotifyList; 654 while (ACPI_SUCCESS (Status) && Notify) 655 { 656 Status = AcpiEvQueueNotifyRequest (Notify->DeviceNode, 657 ACPI_NOTIFY_DEVICE_WAKE); 658 659 Notify = Notify->Next; 660 } 661 break; 662 663 case ACPI_GPE_DISPATCH_METHOD: 664 665 /* Allocate the evaluation information block */ 666 667 Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO)); 668 if (!Info) 669 { 670 Status = AE_NO_MEMORY; 671 } 672 else 673 { 674 /* 675 * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the 676 * _Lxx/_Exx control method that corresponds to this GPE 677 */ 678 Info->PrefixNode = LocalGpeEventInfo->Dispatch.MethodNode; 679 Info->Flags = ACPI_IGNORE_RETURN_VALUE; 680 681 Status = AcpiNsEvaluate (Info); 682 ACPI_FREE (Info); 683 } 684 685 if (ACPI_FAILURE (Status)) 686 { 687 ACPI_EXCEPTION ((AE_INFO, Status, 688 "while evaluating GPE method [%4.4s]", 689 AcpiUtGetNodeName (LocalGpeEventInfo->Dispatch.MethodNode))); 690 } 691 692 break; 693 694 default: 695 return_VOID; /* Should never happen */ 696 } 697 698 /* Defer enabling of GPE until all notify handlers are done */ 699 700 Status = AcpiOsExecute (OSL_NOTIFY_HANDLER, 701 AcpiEvAsynchEnableGpe, LocalGpeEventInfo); 702 if (ACPI_FAILURE (Status)) 703 { 704 ACPI_FREE (LocalGpeEventInfo); 705 } 706 return_VOID; 707 } 708 709 710 /******************************************************************************* 711 * 712 * FUNCTION: AcpiEvAsynchEnableGpe 713 * 714 * PARAMETERS: Context (GpeEventInfo) - Info for this GPE 715 * Callback from AcpiOsExecute 716 * 717 * RETURN: None 718 * 719 * DESCRIPTION: Asynchronous clear/enable for GPE. This allows the GPE to 720 * complete (i.e., finish execution of Notify) 721 * 722 ******************************************************************************/ 723 724 static void ACPI_SYSTEM_XFACE 725 AcpiEvAsynchEnableGpe ( 726 void *Context) 727 { 728 ACPI_GPE_EVENT_INFO *GpeEventInfo = Context; 729 730 731 (void) AcpiEvFinishGpe (GpeEventInfo); 732 733 ACPI_FREE (GpeEventInfo); 734 return; 735 } 736 737 738 /******************************************************************************* 739 * 740 * FUNCTION: AcpiEvFinishGpe 741 * 742 * PARAMETERS: GpeEventInfo - Info for this GPE 743 * 744 * RETURN: Status 745 * 746 * DESCRIPTION: Clear/Enable a GPE. Common code that is used after execution 747 * of a GPE method or a synchronous or asynchronous GPE handler. 748 * 749 ******************************************************************************/ 750 751 ACPI_STATUS 752 AcpiEvFinishGpe ( 753 ACPI_GPE_EVENT_INFO *GpeEventInfo) 754 { 755 ACPI_STATUS Status; 756 757 758 if ((GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK) == 759 ACPI_GPE_LEVEL_TRIGGERED) 760 { 761 /* 762 * GPE is level-triggered, we clear the GPE status bit after 763 * handling the event. 764 */ 765 Status = AcpiHwClearGpe (GpeEventInfo); 766 if (ACPI_FAILURE (Status)) 767 { 768 return (Status); 769 } 770 } 771 772 /* 773 * Enable this GPE, conditionally. This means that the GPE will 774 * only be physically enabled if the EnableForRun bit is set 775 * in the EventInfo. 776 */ 777 (void) AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_CONDITIONAL_ENABLE); 778 return (AE_OK); 779 } 780 781 782 /******************************************************************************* 783 * 784 * FUNCTION: AcpiEvGpeDispatch 785 * 786 * PARAMETERS: GpeDevice - Device node. NULL for GPE0/GPE1 787 * GpeEventInfo - Info for this GPE 788 * GpeNumber - Number relative to the parent GPE block 789 * 790 * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED 791 * 792 * DESCRIPTION: Dispatch a General Purpose Event to either a function (e.g. EC) 793 * or method (e.g. _Lxx/_Exx) handler. 794 * 795 * This function executes at interrupt level. 796 * 797 ******************************************************************************/ 798 799 UINT32 800 AcpiEvGpeDispatch ( 801 ACPI_NAMESPACE_NODE *GpeDevice, 802 ACPI_GPE_EVENT_INFO *GpeEventInfo, 803 UINT32 GpeNumber) 804 { 805 ACPI_STATUS Status; 806 UINT32 ReturnValue; 807 808 809 ACPI_FUNCTION_TRACE (EvGpeDispatch); 810 811 812 /* Invoke global event handler if present */ 813 814 AcpiGpeCount++; 815 if (AcpiGbl_GlobalEventHandler) 816 { 817 AcpiGbl_GlobalEventHandler (ACPI_EVENT_TYPE_GPE, GpeDevice, 818 GpeNumber, AcpiGbl_GlobalEventHandlerContext); 819 } 820 821 /* 822 * If edge-triggered, clear the GPE status bit now. Note that 823 * level-triggered events are cleared after the GPE is serviced. 824 */ 825 if ((GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK) == 826 ACPI_GPE_EDGE_TRIGGERED) 827 { 828 Status = AcpiHwClearGpe (GpeEventInfo); 829 if (ACPI_FAILURE (Status)) 830 { 831 ACPI_EXCEPTION ((AE_INFO, Status, 832 "Unable to clear GPE%02X", GpeNumber)); 833 return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED); 834 } 835 } 836 837 /* 838 * Always disable the GPE so that it does not keep firing before 839 * any asynchronous activity completes (either from the execution 840 * of a GPE method or an asynchronous GPE handler.) 841 * 842 * If there is no handler or method to run, just disable the 843 * GPE and leave it disabled permanently to prevent further such 844 * pointless events from firing. 845 */ 846 Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE); 847 if (ACPI_FAILURE (Status)) 848 { 849 ACPI_EXCEPTION ((AE_INFO, Status, 850 "Unable to disable GPE%02X", GpeNumber)); 851 return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED); 852 } 853 854 /* 855 * Dispatch the GPE to either an installed handler or the control 856 * method associated with this GPE (_Lxx or _Exx). If a handler 857 * exists, we invoke it and do not attempt to run the method. 858 * If there is neither a handler nor a method, leave the GPE 859 * disabled. 860 */ 861 switch (GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) 862 { 863 case ACPI_GPE_DISPATCH_HANDLER: 864 865 /* Invoke the installed handler (at interrupt level) */ 866 867 ReturnValue = GpeEventInfo->Dispatch.Handler->Address ( 868 GpeDevice, GpeNumber, 869 GpeEventInfo->Dispatch.Handler->Context); 870 871 /* If requested, clear (if level-triggered) and reenable the GPE */ 872 873 if (ReturnValue & ACPI_REENABLE_GPE) 874 { 875 (void) AcpiEvFinishGpe (GpeEventInfo); 876 } 877 break; 878 879 case ACPI_GPE_DISPATCH_METHOD: 880 case ACPI_GPE_DISPATCH_NOTIFY: 881 882 /* 883 * Execute the method associated with the GPE 884 * NOTE: Level-triggered GPEs are cleared after the method completes. 885 */ 886 Status = AcpiOsExecute (OSL_GPE_HANDLER, 887 AcpiEvAsynchExecuteGpeMethod, GpeEventInfo); 888 if (ACPI_FAILURE (Status)) 889 { 890 ACPI_EXCEPTION ((AE_INFO, Status, 891 "Unable to queue handler for GPE%02X - event disabled", 892 GpeNumber)); 893 } 894 break; 895 896 default: 897 898 /* 899 * No handler or method to run! 900 * 03/2010: This case should no longer be possible. We will not allow 901 * a GPE to be enabled if it has no handler or method. 902 */ 903 ACPI_ERROR ((AE_INFO, 904 "No handler or method for GPE%02X, disabling event", 905 GpeNumber)); 906 break; 907 } 908 909 return_UINT32 (ACPI_INTERRUPT_HANDLED); 910 } 911 912 #endif /* !ACPI_REDUCED_HARDWARE */ 913