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 - 2014, 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); 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 ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS, 507 "Ignore disabled registers for GPE %02X-%02X: " 508 "RunEnable=%02X, WakeEnable=%02X\n", 509 GpeRegisterInfo->BaseGpeNumber, 510 GpeRegisterInfo->BaseGpeNumber + (ACPI_GPE_REGISTER_WIDTH - 1), 511 GpeRegisterInfo->EnableForRun, 512 GpeRegisterInfo->EnableForWake)); 513 continue; 514 } 515 516 /* Read the Status Register */ 517 518 Status = AcpiHwRead (&StatusReg, &GpeRegisterInfo->StatusAddress); 519 if (ACPI_FAILURE (Status)) 520 { 521 goto UnlockAndExit; 522 } 523 524 /* Read the Enable Register */ 525 526 Status = AcpiHwRead (&EnableReg, &GpeRegisterInfo->EnableAddress); 527 if (ACPI_FAILURE (Status)) 528 { 529 goto UnlockAndExit; 530 } 531 532 ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS, 533 "Read registers for GPE %02X-%02X: Status=%02X, Enable=%02X, " 534 "RunEnable=%02X, WakeEnable=%02X\n", 535 GpeRegisterInfo->BaseGpeNumber, 536 GpeRegisterInfo->BaseGpeNumber + (ACPI_GPE_REGISTER_WIDTH - 1), 537 StatusReg, EnableReg, 538 GpeRegisterInfo->EnableForRun, 539 GpeRegisterInfo->EnableForWake)); 540 541 /* Check if there is anything active at all in this register */ 542 543 EnabledStatusByte = (UINT8) (StatusReg & EnableReg); 544 if (!EnabledStatusByte) 545 { 546 /* No active GPEs in this register, move on */ 547 548 continue; 549 } 550 551 /* Now look at the individual GPEs in this byte register */ 552 553 for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) 554 { 555 /* Examine one GPE bit */ 556 557 if (EnabledStatusByte & (1 << j)) 558 { 559 /* 560 * Found an active GPE. Dispatch the event to a handler 561 * or method. 562 */ 563 IntStatus |= AcpiEvGpeDispatch (GpeBlock->Node, 564 &GpeBlock->EventInfo[((ACPI_SIZE) i * 565 ACPI_GPE_REGISTER_WIDTH) + j], 566 j + GpeRegisterInfo->BaseGpeNumber); 567 } 568 } 569 } 570 571 GpeBlock = GpeBlock->Next; 572 } 573 574 UnlockAndExit: 575 576 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 577 return (IntStatus); 578 } 579 580 581 /******************************************************************************* 582 * 583 * FUNCTION: AcpiEvAsynchExecuteGpeMethod 584 * 585 * PARAMETERS: Context (GpeEventInfo) - Info for this GPE 586 * 587 * RETURN: None 588 * 589 * DESCRIPTION: Perform the actual execution of a GPE control method. This 590 * function is called from an invocation of AcpiOsExecute and 591 * therefore does NOT execute at interrupt level - so that 592 * the control method itself is not executed in the context of 593 * an interrupt handler. 594 * 595 ******************************************************************************/ 596 597 static void ACPI_SYSTEM_XFACE 598 AcpiEvAsynchExecuteGpeMethod ( 599 void *Context) 600 { 601 ACPI_GPE_EVENT_INFO *GpeEventInfo = Context; 602 ACPI_STATUS Status; 603 ACPI_GPE_EVENT_INFO *LocalGpeEventInfo; 604 ACPI_EVALUATE_INFO *Info; 605 ACPI_GPE_NOTIFY_INFO *Notify; 606 607 608 ACPI_FUNCTION_TRACE (EvAsynchExecuteGpeMethod); 609 610 611 /* Allocate a local GPE block */ 612 613 LocalGpeEventInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_EVENT_INFO)); 614 if (!LocalGpeEventInfo) 615 { 616 ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY, 617 "while handling a GPE")); 618 return_VOID; 619 } 620 621 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 622 if (ACPI_FAILURE (Status)) 623 { 624 ACPI_FREE (LocalGpeEventInfo); 625 return_VOID; 626 } 627 628 /* Must revalidate the GpeNumber/GpeBlock */ 629 630 if (!AcpiEvValidGpeEvent (GpeEventInfo)) 631 { 632 Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 633 ACPI_FREE (LocalGpeEventInfo); 634 return_VOID; 635 } 636 637 /* 638 * Take a snapshot of the GPE info for this level - we copy the info to 639 * prevent a race condition with RemoveHandler/RemoveBlock. 640 */ 641 ACPI_MEMCPY (LocalGpeEventInfo, GpeEventInfo, 642 sizeof (ACPI_GPE_EVENT_INFO)); 643 644 Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 645 if (ACPI_FAILURE (Status)) 646 { 647 ACPI_FREE (LocalGpeEventInfo); 648 return_VOID; 649 } 650 651 /* Do the correct dispatch - normal method or implicit notify */ 652 653 switch (LocalGpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) 654 { 655 case ACPI_GPE_DISPATCH_NOTIFY: 656 /* 657 * Implicit notify. 658 * Dispatch a DEVICE_WAKE notify to the appropriate handler. 659 * NOTE: the request is queued for execution after this method 660 * completes. The notify handlers are NOT invoked synchronously 661 * from this thread -- because handlers may in turn run other 662 * control methods. 663 * 664 * June 2012: Expand implicit notify mechanism to support 665 * notifies on multiple device objects. 666 */ 667 Notify = LocalGpeEventInfo->Dispatch.NotifyList; 668 while (ACPI_SUCCESS (Status) && Notify) 669 { 670 Status = AcpiEvQueueNotifyRequest (Notify->DeviceNode, 671 ACPI_NOTIFY_DEVICE_WAKE); 672 673 Notify = Notify->Next; 674 } 675 break; 676 677 case ACPI_GPE_DISPATCH_METHOD: 678 679 /* Allocate the evaluation information block */ 680 681 Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO)); 682 if (!Info) 683 { 684 Status = AE_NO_MEMORY; 685 } 686 else 687 { 688 /* 689 * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the 690 * _Lxx/_Exx control method that corresponds to this GPE 691 */ 692 Info->PrefixNode = LocalGpeEventInfo->Dispatch.MethodNode; 693 Info->Flags = ACPI_IGNORE_RETURN_VALUE; 694 695 Status = AcpiNsEvaluate (Info); 696 ACPI_FREE (Info); 697 } 698 699 if (ACPI_FAILURE (Status)) 700 { 701 ACPI_EXCEPTION ((AE_INFO, Status, 702 "while evaluating GPE method [%4.4s]", 703 AcpiUtGetNodeName (LocalGpeEventInfo->Dispatch.MethodNode))); 704 } 705 break; 706 707 default: 708 709 return_VOID; /* Should never happen */ 710 } 711 712 /* Defer enabling of GPE until all notify handlers are done */ 713 714 Status = AcpiOsExecute (OSL_NOTIFY_HANDLER, 715 AcpiEvAsynchEnableGpe, LocalGpeEventInfo); 716 if (ACPI_FAILURE (Status)) 717 { 718 ACPI_FREE (LocalGpeEventInfo); 719 } 720 return_VOID; 721 } 722 723 724 /******************************************************************************* 725 * 726 * FUNCTION: AcpiEvAsynchEnableGpe 727 * 728 * PARAMETERS: Context (GpeEventInfo) - Info for this GPE 729 * Callback from AcpiOsExecute 730 * 731 * RETURN: None 732 * 733 * DESCRIPTION: Asynchronous clear/enable for GPE. This allows the GPE to 734 * complete (i.e., finish execution of Notify) 735 * 736 ******************************************************************************/ 737 738 static void ACPI_SYSTEM_XFACE 739 AcpiEvAsynchEnableGpe ( 740 void *Context) 741 { 742 ACPI_GPE_EVENT_INFO *GpeEventInfo = Context; 743 744 745 (void) AcpiEvFinishGpe (GpeEventInfo); 746 747 ACPI_FREE (GpeEventInfo); 748 return; 749 } 750 751 752 /******************************************************************************* 753 * 754 * FUNCTION: AcpiEvFinishGpe 755 * 756 * PARAMETERS: GpeEventInfo - Info for this GPE 757 * 758 * RETURN: Status 759 * 760 * DESCRIPTION: Clear/Enable a GPE. Common code that is used after execution 761 * of a GPE method or a synchronous or asynchronous GPE handler. 762 * 763 ******************************************************************************/ 764 765 ACPI_STATUS 766 AcpiEvFinishGpe ( 767 ACPI_GPE_EVENT_INFO *GpeEventInfo) 768 { 769 ACPI_STATUS Status; 770 771 772 if ((GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK) == 773 ACPI_GPE_LEVEL_TRIGGERED) 774 { 775 /* 776 * GPE is level-triggered, we clear the GPE status bit after 777 * handling the event. 778 */ 779 Status = AcpiHwClearGpe (GpeEventInfo); 780 if (ACPI_FAILURE (Status)) 781 { 782 return (Status); 783 } 784 } 785 786 /* 787 * Enable this GPE, conditionally. This means that the GPE will 788 * only be physically enabled if the EnableForRun bit is set 789 * in the EventInfo. 790 */ 791 (void) AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_CONDITIONAL_ENABLE); 792 return (AE_OK); 793 } 794 795 796 /******************************************************************************* 797 * 798 * FUNCTION: AcpiEvGpeDispatch 799 * 800 * PARAMETERS: GpeDevice - Device node. NULL for GPE0/GPE1 801 * GpeEventInfo - Info for this GPE 802 * GpeNumber - Number relative to the parent GPE block 803 * 804 * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED 805 * 806 * DESCRIPTION: Dispatch a General Purpose Event to either a function (e.g. EC) 807 * or method (e.g. _Lxx/_Exx) handler. 808 * 809 * This function executes at interrupt level. 810 * 811 ******************************************************************************/ 812 813 UINT32 814 AcpiEvGpeDispatch ( 815 ACPI_NAMESPACE_NODE *GpeDevice, 816 ACPI_GPE_EVENT_INFO *GpeEventInfo, 817 UINT32 GpeNumber) 818 { 819 ACPI_STATUS Status; 820 UINT32 ReturnValue; 821 822 823 ACPI_FUNCTION_TRACE (EvGpeDispatch); 824 825 826 /* Invoke global event handler if present */ 827 828 AcpiGpeCount++; 829 if (AcpiGbl_GlobalEventHandler) 830 { 831 AcpiGbl_GlobalEventHandler (ACPI_EVENT_TYPE_GPE, GpeDevice, 832 GpeNumber, AcpiGbl_GlobalEventHandlerContext); 833 } 834 835 /* 836 * Always disable the GPE so that it does not keep firing before 837 * any asynchronous activity completes (either from the execution 838 * of a GPE method or an asynchronous GPE handler.) 839 * 840 * If there is no handler or method to run, just disable the 841 * GPE and leave it disabled permanently to prevent further such 842 * pointless events from firing. 843 */ 844 Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE); 845 if (ACPI_FAILURE (Status)) 846 { 847 ACPI_EXCEPTION ((AE_INFO, Status, 848 "Unable to disable GPE %02X", GpeNumber)); 849 return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED); 850 } 851 852 /* 853 * If edge-triggered, clear the GPE status bit now. Note that 854 * level-triggered events are cleared after the GPE is serviced. 855 */ 856 if ((GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK) == 857 ACPI_GPE_EDGE_TRIGGERED) 858 { 859 Status = AcpiHwClearGpe (GpeEventInfo); 860 if (ACPI_FAILURE (Status)) 861 { 862 ACPI_EXCEPTION ((AE_INFO, Status, 863 "Unable to clear GPE %02X", GpeNumber)); 864 (void) AcpiHwLowSetGpe (GpeEventInfo, 865 ACPI_GPE_CONDITIONAL_ENABLE); 866 return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED); 867 } 868 } 869 870 /* 871 * Dispatch the GPE to either an installed handler or the control 872 * method associated with this GPE (_Lxx or _Exx). If a handler 873 * exists, we invoke it and do not attempt to run the method. 874 * If there is neither a handler nor a method, leave the GPE 875 * disabled. 876 */ 877 switch (GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) 878 { 879 case ACPI_GPE_DISPATCH_HANDLER: 880 881 /* Invoke the installed handler (at interrupt level) */ 882 883 ReturnValue = GpeEventInfo->Dispatch.Handler->Address ( 884 GpeDevice, GpeNumber, 885 GpeEventInfo->Dispatch.Handler->Context); 886 887 /* If requested, clear (if level-triggered) and reenable the GPE */ 888 889 if (ReturnValue & ACPI_REENABLE_GPE) 890 { 891 (void) AcpiEvFinishGpe (GpeEventInfo); 892 } 893 break; 894 895 case ACPI_GPE_DISPATCH_METHOD: 896 case ACPI_GPE_DISPATCH_NOTIFY: 897 /* 898 * Execute the method associated with the GPE 899 * NOTE: Level-triggered GPEs are cleared after the method completes. 900 */ 901 Status = AcpiOsExecute (OSL_GPE_HANDLER, 902 AcpiEvAsynchExecuteGpeMethod, GpeEventInfo); 903 if (ACPI_FAILURE (Status)) 904 { 905 ACPI_EXCEPTION ((AE_INFO, Status, 906 "Unable to queue handler for GPE %02X - event disabled", 907 GpeNumber)); 908 } 909 break; 910 911 default: 912 /* 913 * No handler or method to run! 914 * 03/2010: This case should no longer be possible. We will not allow 915 * a GPE to be enabled if it has no handler or method. 916 */ 917 ACPI_ERROR ((AE_INFO, 918 "No handler or method for GPE %02X, disabling event", 919 GpeNumber)); 920 break; 921 } 922 923 return_UINT32 (ACPI_INTERRUPT_HANDLED); 924 } 925 926 #endif /* !ACPI_REDUCED_HARDWARE */ 927