evgpe.c revision 206117
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 - 2010, 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 <contrib/dev/acpica/include/acpi.h> 117#include <contrib/dev/acpica/include/accommon.h> 118#include <contrib/dev/acpica/include/acevents.h> 119#include <contrib/dev/acpica/include/acnamesp.h> 120 121#define _COMPONENT ACPI_EVENTS 122 ACPI_MODULE_NAME ("evgpe") 123 124/* Local prototypes */ 125 126static void ACPI_SYSTEM_XFACE 127AcpiEvAsynchExecuteGpeMethod ( 128 void *Context); 129 130static void ACPI_SYSTEM_XFACE 131AcpiEvAsynchEnableGpe ( 132 void *Context); 133 134 135/******************************************************************************* 136 * 137 * FUNCTION: AcpiEvUpdateGpeEnableMasks 138 * 139 * PARAMETERS: GpeEventInfo - GPE to update 140 * 141 * RETURN: Status 142 * 143 * DESCRIPTION: Updates GPE register enable masks based upon whether there are 144 * references (either wake or run) to this GPE 145 * 146 ******************************************************************************/ 147 148ACPI_STATUS 149AcpiEvUpdateGpeEnableMasks ( 150 ACPI_GPE_EVENT_INFO *GpeEventInfo) 151{ 152 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo; 153 UINT8 RegisterBit; 154 155 156 ACPI_FUNCTION_TRACE (EvUpdateGpeEnableMasks); 157 158 159 GpeRegisterInfo = GpeEventInfo->RegisterInfo; 160 if (!GpeRegisterInfo) 161 { 162 return_ACPI_STATUS (AE_NOT_EXIST); 163 } 164 165 RegisterBit = (UINT8) 166 (1 << (GpeEventInfo->GpeNumber - GpeRegisterInfo->BaseGpeNumber)); 167 168 /* Clear the wake/run bits up front */ 169 170 ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, RegisterBit); 171 ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForRun, RegisterBit); 172 173 /* Set the mask bits only if there are references to this GPE */ 174 175 if (GpeEventInfo->RuntimeCount) 176 { 177 ACPI_SET_BIT (GpeRegisterInfo->EnableForRun, RegisterBit); 178 } 179 180 if (GpeEventInfo->WakeupCount) 181 { 182 ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, RegisterBit); 183 } 184 185 return_ACPI_STATUS (AE_OK); 186} 187 188 189/******************************************************************************* 190 * 191 * FUNCTION: AcpiEvEnableGpe 192 * 193 * PARAMETERS: GpeEventInfo - GPE to enable 194 * 195 * RETURN: Status 196 * 197 * DESCRIPTION: Hardware-enable a GPE. Always enables the GPE, regardless 198 * of type or number of references. 199 * 200 * Note: The GPE lock should be already acquired when this function is called. 201 * 202 ******************************************************************************/ 203 204ACPI_STATUS 205AcpiEvEnableGpe ( 206 ACPI_GPE_EVENT_INFO *GpeEventInfo) 207{ 208 ACPI_STATUS Status; 209 210 211 ACPI_FUNCTION_TRACE (EvEnableGpe); 212 213 214 /* 215 * We will only allow a GPE to be enabled if it has either an 216 * associated method (_Lxx/_Exx) or a handler. Otherwise, the 217 * GPE will be immediately disabled by AcpiEvGpeDispatch the 218 * first time it fires. 219 */ 220 if (!(GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK)) 221 { 222 return_ACPI_STATUS (AE_NO_HANDLER); 223 } 224 225 /* Ensure the HW enable masks are current */ 226 227 Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo); 228 if (ACPI_FAILURE (Status)) 229 { 230 return_ACPI_STATUS (Status); 231 } 232 233 /* Clear the GPE (of stale events) */ 234 235 Status = AcpiHwClearGpe (GpeEventInfo); 236 if (ACPI_FAILURE (Status)) 237 { 238 return_ACPI_STATUS (Status); 239 } 240 241 /* Enable the requested GPE */ 242 243 Status = AcpiHwWriteGpeEnableReg (GpeEventInfo); 244 return_ACPI_STATUS (Status); 245} 246 247 248/******************************************************************************* 249 * 250 * FUNCTION: AcpiEvDisableGpe 251 * 252 * PARAMETERS: GpeEventInfo - GPE to disable 253 * 254 * RETURN: Status 255 * 256 * DESCRIPTION: Hardware-disable a GPE. Always disables the requested GPE, 257 * regardless of the type or number of references. 258 * 259 * Note: The GPE lock should be already acquired when this function is called. 260 * 261 ******************************************************************************/ 262 263ACPI_STATUS 264AcpiEvDisableGpe ( 265 ACPI_GPE_EVENT_INFO *GpeEventInfo) 266{ 267 ACPI_STATUS Status; 268 269 270 ACPI_FUNCTION_TRACE (EvDisableGpe); 271 272 273 /* 274 * Note: Always disable the GPE, even if we think that that it is already 275 * disabled. It is possible that the AML or some other code has enabled 276 * the GPE behind our back. 277 */ 278 279 /* Ensure the HW enable masks are current */ 280 281 Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo); 282 if (ACPI_FAILURE (Status)) 283 { 284 return_ACPI_STATUS (Status); 285 } 286 287 /* 288 * Always H/W disable this GPE, even if we don't know the GPE type. 289 * Simply clear the enable bit for this particular GPE, but do not 290 * write out the current GPE enable mask since this may inadvertently 291 * enable GPEs too early. An example is a rogue GPE that has arrived 292 * during ACPICA initialization - possibly because AML or other code 293 * has enabled the GPE. 294 */ 295 Status = AcpiHwLowDisableGpe (GpeEventInfo); 296 return_ACPI_STATUS (Status); 297} 298 299 300/******************************************************************************* 301 * 302 * FUNCTION: AcpiEvLowGetGpeInfo 303 * 304 * PARAMETERS: GpeNumber - Raw GPE number 305 * GpeBlock - A GPE info block 306 * 307 * RETURN: A GPE EventInfo struct. NULL if not a valid GPE (The GpeNumber 308 * is not within the specified GPE block) 309 * 310 * DESCRIPTION: Returns the EventInfo struct associated with this GPE. This is 311 * the low-level implementation of EvGetGpeEventInfo. 312 * 313 ******************************************************************************/ 314 315ACPI_GPE_EVENT_INFO * 316AcpiEvLowGetGpeInfo ( 317 UINT32 GpeNumber, 318 ACPI_GPE_BLOCK_INFO *GpeBlock) 319{ 320 UINT32 GpeIndex; 321 322 323 /* 324 * Validate that the GpeNumber is within the specified GpeBlock. 325 * (Two steps) 326 */ 327 if (!GpeBlock || 328 (GpeNumber < GpeBlock->BlockBaseNumber)) 329 { 330 return (NULL); 331 } 332 333 GpeIndex = GpeNumber - GpeBlock->BlockBaseNumber; 334 if (GpeIndex >= GpeBlock->GpeCount) 335 { 336 return (NULL); 337 } 338 339 return (&GpeBlock->EventInfo[GpeIndex]); 340} 341 342 343/******************************************************************************* 344 * 345 * FUNCTION: AcpiEvGetGpeEventInfo 346 * 347 * PARAMETERS: GpeDevice - Device node. NULL for GPE0/GPE1 348 * GpeNumber - Raw GPE number 349 * 350 * RETURN: A GPE EventInfo struct. NULL if not a valid GPE 351 * 352 * DESCRIPTION: Returns the EventInfo struct associated with this GPE. 353 * Validates the GpeBlock and the GpeNumber 354 * 355 * Should be called only when the GPE lists are semaphore locked 356 * and not subject to change. 357 * 358 ******************************************************************************/ 359 360ACPI_GPE_EVENT_INFO * 361AcpiEvGetGpeEventInfo ( 362 ACPI_HANDLE GpeDevice, 363 UINT32 GpeNumber) 364{ 365 ACPI_OPERAND_OBJECT *ObjDesc; 366 ACPI_GPE_EVENT_INFO *GpeInfo; 367 UINT32 i; 368 369 370 ACPI_FUNCTION_ENTRY (); 371 372 373 /* A NULL GpeBlock means use the FADT-defined GPE block(s) */ 374 375 if (!GpeDevice) 376 { 377 /* Examine GPE Block 0 and 1 (These blocks are permanent) */ 378 379 for (i = 0; i < ACPI_MAX_GPE_BLOCKS; i++) 380 { 381 GpeInfo = AcpiEvLowGetGpeInfo (GpeNumber, 382 AcpiGbl_GpeFadtBlocks[i]); 383 if (GpeInfo) 384 { 385 return (GpeInfo); 386 } 387 } 388 389 /* The GpeNumber was not in the range of either FADT GPE block */ 390 391 return (NULL); 392 } 393 394 /* A Non-NULL GpeDevice means this is a GPE Block Device */ 395 396 ObjDesc = AcpiNsGetAttachedObject ((ACPI_NAMESPACE_NODE *) GpeDevice); 397 if (!ObjDesc || 398 !ObjDesc->Device.GpeBlock) 399 { 400 return (NULL); 401 } 402 403 return (AcpiEvLowGetGpeInfo (GpeNumber, ObjDesc->Device.GpeBlock)); 404} 405 406 407/******************************************************************************* 408 * 409 * FUNCTION: AcpiEvGpeDetect 410 * 411 * PARAMETERS: GpeXruptList - Interrupt block for this interrupt. 412 * Can have multiple GPE blocks attached. 413 * 414 * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED 415 * 416 * DESCRIPTION: Detect if any GP events have occurred. This function is 417 * executed at interrupt level. 418 * 419 ******************************************************************************/ 420 421UINT32 422AcpiEvGpeDetect ( 423 ACPI_GPE_XRUPT_INFO *GpeXruptList) 424{ 425 ACPI_STATUS Status; 426 ACPI_GPE_BLOCK_INFO *GpeBlock; 427 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo; 428 UINT32 IntStatus = ACPI_INTERRUPT_NOT_HANDLED; 429 UINT8 EnabledStatusByte; 430 UINT32 StatusReg; 431 UINT32 EnableReg; 432 ACPI_CPU_FLAGS Flags; 433 UINT32 i; 434 UINT32 j; 435 436 437 ACPI_FUNCTION_NAME (EvGpeDetect); 438 439 /* Check for the case where there are no GPEs */ 440 441 if (!GpeXruptList) 442 { 443 return (IntStatus); 444 } 445 446 /* 447 * We need to obtain the GPE lock for both the data structs and registers 448 * Note: Not necessary to obtain the hardware lock, since the GPE 449 * registers are owned by the GpeLock. 450 */ 451 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 452 453 /* Examine all GPE blocks attached to this interrupt level */ 454 455 GpeBlock = GpeXruptList->GpeBlockListHead; 456 while (GpeBlock) 457 { 458 /* 459 * Read all of the 8-bit GPE status and enable registers in this GPE 460 * block, saving all of them. Find all currently active GP events. 461 */ 462 for (i = 0; i < GpeBlock->RegisterCount; i++) 463 { 464 /* Get the next status/enable pair */ 465 466 GpeRegisterInfo = &GpeBlock->RegisterInfo[i]; 467 468 /* Read the Status Register */ 469 470 Status = AcpiHwRead (&StatusReg, &GpeRegisterInfo->StatusAddress); 471 if (ACPI_FAILURE (Status)) 472 { 473 goto UnlockAndExit; 474 } 475 476 /* Read the Enable Register */ 477 478 Status = AcpiHwRead (&EnableReg, &GpeRegisterInfo->EnableAddress); 479 if (ACPI_FAILURE (Status)) 480 { 481 goto UnlockAndExit; 482 } 483 484 ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS, 485 "Read GPE Register at GPE%X: Status=%02X, Enable=%02X\n", 486 GpeRegisterInfo->BaseGpeNumber, StatusReg, EnableReg)); 487 488 /* Check if there is anything active at all in this register */ 489 490 EnabledStatusByte = (UINT8) (StatusReg & EnableReg); 491 if (!EnabledStatusByte) 492 { 493 /* No active GPEs in this register, move on */ 494 495 continue; 496 } 497 498 /* Now look at the individual GPEs in this byte register */ 499 500 for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) 501 { 502 /* Examine one GPE bit */ 503 504 if (EnabledStatusByte & (1 << j)) 505 { 506 /* 507 * Found an active GPE. Dispatch the event to a handler 508 * or method. 509 */ 510 IntStatus |= AcpiEvGpeDispatch ( 511 &GpeBlock->EventInfo[((ACPI_SIZE) i * 512 ACPI_GPE_REGISTER_WIDTH) + j], 513 j + GpeRegisterInfo->BaseGpeNumber); 514 } 515 } 516 } 517 518 GpeBlock = GpeBlock->Next; 519 } 520 521UnlockAndExit: 522 523 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 524 return (IntStatus); 525} 526 527 528/******************************************************************************* 529 * 530 * FUNCTION: AcpiEvAsynchExecuteGpeMethod 531 * 532 * PARAMETERS: Context (GpeEventInfo) - Info for this GPE 533 * 534 * RETURN: None 535 * 536 * DESCRIPTION: Perform the actual execution of a GPE control method. This 537 * function is called from an invocation of AcpiOsExecute and 538 * therefore does NOT execute at interrupt level - so that 539 * the control method itself is not executed in the context of 540 * an interrupt handler. 541 * 542 ******************************************************************************/ 543 544static void ACPI_SYSTEM_XFACE 545AcpiEvAsynchExecuteGpeMethod ( 546 void *Context) 547{ 548 ACPI_GPE_EVENT_INFO *GpeEventInfo = Context; 549 ACPI_STATUS Status; 550 ACPI_GPE_EVENT_INFO *LocalGpeEventInfo; 551 ACPI_EVALUATE_INFO *Info; 552 553 554 ACPI_FUNCTION_TRACE (EvAsynchExecuteGpeMethod); 555 556 557 /* Allocate a local GPE block */ 558 559 LocalGpeEventInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_EVENT_INFO)); 560 if (!LocalGpeEventInfo) 561 { 562 ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY, 563 "while handling a GPE")); 564 return_VOID; 565 } 566 567 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 568 if (ACPI_FAILURE (Status)) 569 { 570 return_VOID; 571 } 572 573 /* Must revalidate the GpeNumber/GpeBlock */ 574 575 if (!AcpiEvValidGpeEvent (GpeEventInfo)) 576 { 577 Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 578 return_VOID; 579 } 580 581 /* Update the GPE register masks for return to enabled state */ 582 583 (void) AcpiEvUpdateGpeEnableMasks (GpeEventInfo); 584 585 /* 586 * Take a snapshot of the GPE info for this level - we copy the info to 587 * prevent a race condition with RemoveHandler/RemoveBlock. 588 */ 589 ACPI_MEMCPY (LocalGpeEventInfo, GpeEventInfo, 590 sizeof (ACPI_GPE_EVENT_INFO)); 591 592 Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 593 if (ACPI_FAILURE (Status)) 594 { 595 return_VOID; 596 } 597 598 /* 599 * Must check for control method type dispatch one more time to avoid a 600 * race with EvGpeInstallHandler 601 */ 602 if ((LocalGpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == 603 ACPI_GPE_DISPATCH_METHOD) 604 { 605 /* Allocate the evaluation information block */ 606 607 Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO)); 608 if (!Info) 609 { 610 Status = AE_NO_MEMORY; 611 } 612 else 613 { 614 /* 615 * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx 616 * control method that corresponds to this GPE 617 */ 618 Info->PrefixNode = LocalGpeEventInfo->Dispatch.MethodNode; 619 Info->Flags = ACPI_IGNORE_RETURN_VALUE; 620 621 Status = AcpiNsEvaluate (Info); 622 ACPI_FREE (Info); 623 } 624 625 if (ACPI_FAILURE (Status)) 626 { 627 ACPI_EXCEPTION ((AE_INFO, Status, 628 "while evaluating GPE method [%4.4s]", 629 AcpiUtGetNodeName (LocalGpeEventInfo->Dispatch.MethodNode))); 630 } 631 } 632 633 /* Defer enabling of GPE until all notify handlers are done */ 634 635 Status = AcpiOsExecute (OSL_NOTIFY_HANDLER, 636 AcpiEvAsynchEnableGpe, LocalGpeEventInfo); 637 if (ACPI_FAILURE (Status)) 638 { 639 ACPI_FREE (LocalGpeEventInfo); 640 } 641 return_VOID; 642} 643 644 645/******************************************************************************* 646 * 647 * FUNCTION: AcpiEvAsynchEnableGpe 648 * 649 * PARAMETERS: Context (GpeEventInfo) - Info for this GPE 650 * 651 * RETURN: None 652 * 653 * DESCRIPTION: Asynchronous clear/enable for GPE. This allows the GPE to 654 * complete (i.e., finish execution of Notify) 655 * 656 ******************************************************************************/ 657 658static void ACPI_SYSTEM_XFACE 659AcpiEvAsynchEnableGpe ( 660 void *Context) 661{ 662 ACPI_GPE_EVENT_INFO *GpeEventInfo = Context; 663 ACPI_STATUS Status; 664 665 666 if ((GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK) == 667 ACPI_GPE_LEVEL_TRIGGERED) 668 { 669 /* 670 * GPE is level-triggered, we clear the GPE status bit after handling 671 * the event. 672 */ 673 Status = AcpiHwClearGpe (GpeEventInfo); 674 if (ACPI_FAILURE (Status)) 675 { 676 goto Exit; 677 } 678 } 679 680 /* Enable this GPE */ 681 682 (void) AcpiHwWriteGpeEnableReg (GpeEventInfo); 683 684Exit: 685 ACPI_FREE (GpeEventInfo); 686 return; 687} 688 689 690/******************************************************************************* 691 * 692 * FUNCTION: AcpiEvGpeDispatch 693 * 694 * PARAMETERS: GpeEventInfo - Info for this GPE 695 * GpeNumber - Number relative to the parent GPE block 696 * 697 * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED 698 * 699 * DESCRIPTION: Dispatch a General Purpose Event to either a function (e.g. EC) 700 * or method (e.g. _Lxx/_Exx) handler. 701 * 702 * This function executes at interrupt level. 703 * 704 ******************************************************************************/ 705 706UINT32 707AcpiEvGpeDispatch ( 708 ACPI_GPE_EVENT_INFO *GpeEventInfo, 709 UINT32 GpeNumber) 710{ 711 ACPI_STATUS Status; 712 713 714 ACPI_FUNCTION_TRACE (EvGpeDispatch); 715 716 717 AcpiGpeCount++; 718 719 /* 720 * If edge-triggered, clear the GPE status bit now. Note that 721 * level-triggered events are cleared after the GPE is serviced. 722 */ 723 if ((GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK) == 724 ACPI_GPE_EDGE_TRIGGERED) 725 { 726 Status = AcpiHwClearGpe (GpeEventInfo); 727 if (ACPI_FAILURE (Status)) 728 { 729 ACPI_EXCEPTION ((AE_INFO, Status, 730 "Unable to clear GPE[0x%2X]", GpeNumber)); 731 return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED); 732 } 733 } 734 735 /* 736 * Dispatch the GPE to either an installed handler, or the control method 737 * associated with this GPE (_Lxx or _Exx). If a handler exists, we invoke 738 * it and do not attempt to run the method. If there is neither a handler 739 * nor a method, we disable this GPE to prevent further such pointless 740 * events from firing. 741 */ 742 switch (GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) 743 { 744 case ACPI_GPE_DISPATCH_HANDLER: 745 746 /* 747 * Invoke the installed handler (at interrupt level) 748 * Ignore return status for now. 749 * TBD: leave GPE disabled on error? 750 */ 751 (void) GpeEventInfo->Dispatch.Handler->Address ( 752 GpeEventInfo->Dispatch.Handler->Context); 753 754 /* It is now safe to clear level-triggered events. */ 755 756 if ((GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK) == 757 ACPI_GPE_LEVEL_TRIGGERED) 758 { 759 Status = AcpiHwClearGpe (GpeEventInfo); 760 if (ACPI_FAILURE (Status)) 761 { 762 ACPI_EXCEPTION ((AE_INFO, Status, 763 "Unable to clear GPE[0x%2X]", GpeNumber)); 764 return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED); 765 } 766 } 767 break; 768 769 case ACPI_GPE_DISPATCH_METHOD: 770 771 /* 772 * Disable the GPE, so it doesn't keep firing before the method has a 773 * chance to run (it runs asynchronously with interrupts enabled). 774 */ 775 Status = AcpiEvDisableGpe (GpeEventInfo); 776 if (ACPI_FAILURE (Status)) 777 { 778 ACPI_EXCEPTION ((AE_INFO, Status, 779 "Unable to disable GPE[0x%2X]", GpeNumber)); 780 return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED); 781 } 782 783 /* 784 * Execute the method associated with the GPE 785 * NOTE: Level-triggered GPEs are cleared after the method completes. 786 */ 787 Status = AcpiOsExecute (OSL_GPE_HANDLER, 788 AcpiEvAsynchExecuteGpeMethod, GpeEventInfo); 789 if (ACPI_FAILURE (Status)) 790 { 791 ACPI_EXCEPTION ((AE_INFO, Status, 792 "Unable to queue handler for GPE[0x%2X] - event disabled", 793 GpeNumber)); 794 } 795 break; 796 797 default: 798 799 /* 800 * No handler or method to run! 801 * 03/2010: This case should no longer be possible. We will not allow 802 * a GPE to be enabled if it has no handler or method. 803 */ 804 ACPI_ERROR ((AE_INFO, 805 "No handler or method for GPE[0x%2X], disabling event", 806 GpeNumber)); 807 808 /* 809 * Disable the GPE. The GPE will remain disabled a handler 810 * is installed or ACPICA is restarted. 811 */ 812 Status = AcpiEvDisableGpe (GpeEventInfo); 813 if (ACPI_FAILURE (Status)) 814 { 815 ACPI_EXCEPTION ((AE_INFO, Status, 816 "Unable to disable GPE[0x%2X]", GpeNumber)); 817 return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED); 818 } 819 break; 820 } 821 822 return_UINT32 (ACPI_INTERRUPT_HANDLED); 823} 824 825