evgpe.c revision 126372
1114239Snjl/****************************************************************************** 2114239Snjl * 3114239Snjl * Module Name: evgpe - General Purpose Event handling and dispatch 4126372Snjl * $Revision: 33 $ 5114239Snjl * 6114239Snjl *****************************************************************************/ 7114239Snjl 8114239Snjl/****************************************************************************** 9114239Snjl * 10114239Snjl * 1. Copyright Notice 11114239Snjl * 12126372Snjl * Some or all of this work - Copyright (c) 1999 - 2004, Intel Corp. 13114239Snjl * All rights reserved. 14114239Snjl * 15114239Snjl * 2. License 16114239Snjl * 17114239Snjl * 2.1. This is your license from Intel Corp. under its intellectual property 18114239Snjl * rights. You may have additional license terms from the party that provided 19114239Snjl * you this software, covering your right to use that party's intellectual 20114239Snjl * property rights. 21114239Snjl * 22114239Snjl * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23114239Snjl * copy of the source code appearing in this file ("Covered Code") an 24114239Snjl * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25114239Snjl * base code distributed originally by Intel ("Original Intel Code") to copy, 26114239Snjl * make derivatives, distribute, use and display any portion of the Covered 27114239Snjl * Code in any form, with the right to sublicense such rights; and 28114239Snjl * 29114239Snjl * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30114239Snjl * license (with the right to sublicense), under only those claims of Intel 31114239Snjl * patents that are infringed by the Original Intel Code, to make, use, sell, 32114239Snjl * offer to sell, and import the Covered Code and derivative works thereof 33114239Snjl * solely to the minimum extent necessary to exercise the above copyright 34114239Snjl * license, and in no event shall the patent license extend to any additions 35114239Snjl * to or modifications of the Original Intel Code. No other license or right 36114239Snjl * is granted directly or by implication, estoppel or otherwise; 37114239Snjl * 38114239Snjl * The above copyright and patent license is granted only if the following 39114239Snjl * conditions are met: 40114239Snjl * 41114239Snjl * 3. Conditions 42114239Snjl * 43114239Snjl * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44114239Snjl * Redistribution of source code of any substantial portion of the Covered 45114239Snjl * Code or modification with rights to further distribute source must include 46114239Snjl * the above Copyright Notice, the above License, this list of Conditions, 47114239Snjl * and the following Disclaimer and Export Compliance provision. In addition, 48114239Snjl * Licensee must cause all Covered Code to which Licensee contributes to 49114239Snjl * contain a file documenting the changes Licensee made to create that Covered 50114239Snjl * Code and the date of any change. Licensee must include in that file the 51114239Snjl * documentation of any changes made by any predecessor Licensee. Licensee 52114239Snjl * must include a prominent statement that the modification is derived, 53114239Snjl * directly or indirectly, from Original Intel Code. 54114239Snjl * 55114239Snjl * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56114239Snjl * Redistribution of source code of any substantial portion of the Covered 57114239Snjl * Code or modification without rights to further distribute source must 58114239Snjl * include the following Disclaimer and Export Compliance provision in the 59114239Snjl * documentation and/or other materials provided with distribution. In 60114239Snjl * addition, Licensee may not authorize further sublicense of source of any 61114239Snjl * portion of the Covered Code, and must include terms to the effect that the 62114239Snjl * license from Licensee to its licensee is limited to the intellectual 63114239Snjl * property embodied in the software Licensee provides to its licensee, and 64114239Snjl * not to intellectual property embodied in modifications its licensee may 65114239Snjl * make. 66114239Snjl * 67114239Snjl * 3.3. Redistribution of Executable. Redistribution in executable form of any 68114239Snjl * substantial portion of the Covered Code or modification must reproduce the 69114239Snjl * above Copyright Notice, and the following Disclaimer and Export Compliance 70114239Snjl * provision in the documentation and/or other materials provided with the 71114239Snjl * distribution. 72114239Snjl * 73114239Snjl * 3.4. Intel retains all right, title, and interest in and to the Original 74114239Snjl * Intel Code. 75114239Snjl * 76114239Snjl * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77114239Snjl * Intel shall be used in advertising or otherwise to promote the sale, use or 78114239Snjl * other dealings in products derived from or relating to the Covered Code 79114239Snjl * without prior written authorization from Intel. 80114239Snjl * 81114239Snjl * 4. Disclaimer and Export Compliance 82114239Snjl * 83114239Snjl * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84114239Snjl * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85114239Snjl * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86114239Snjl * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87114239Snjl * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 88114239Snjl * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89114239Snjl * PARTICULAR PURPOSE. 90114239Snjl * 91114239Snjl * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92114239Snjl * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93114239Snjl * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94114239Snjl * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95114239Snjl * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96114239Snjl * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97114239Snjl * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98114239Snjl * LIMITED REMEDY. 99114239Snjl * 100114239Snjl * 4.3. Licensee shall not export, either directly or indirectly, any of this 101114239Snjl * software or system incorporating such software without first obtaining any 102114239Snjl * required license or other approval from the U. S. Department of Commerce or 103114239Snjl * any other agency or department of the United States Government. In the 104114239Snjl * event Licensee exports any such software from the United States or 105114239Snjl * re-exports any such software from a foreign destination, Licensee shall 106114239Snjl * ensure that the distribution and export/re-export of the software is in 107114239Snjl * compliance with all laws, regulations, orders, or other restrictions of the 108114239Snjl * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109114239Snjl * any of its subsidiaries will export/re-export any technical data, process, 110114239Snjl * software, or service, directly or indirectly, to any country for which the 111114239Snjl * United States government or any agency thereof requires an export license, 112114239Snjl * other governmental approval, or letter of assurance, without first obtaining 113114239Snjl * such license, approval or letter. 114114239Snjl * 115114239Snjl *****************************************************************************/ 116114239Snjl 117114239Snjl#include "acpi.h" 118114239Snjl#include "acevents.h" 119114239Snjl#include "acnamesp.h" 120114239Snjl 121114239Snjl#define _COMPONENT ACPI_EVENTS 122114239Snjl ACPI_MODULE_NAME ("evgpe") 123114239Snjl 124114239Snjl 125114239Snjl/******************************************************************************* 126114239Snjl * 127114239Snjl * FUNCTION: AcpiEvGetGpeEventInfo 128114239Snjl * 129117521Snjl * PARAMETERS: GpeDevice - Device node. NULL for GPE0/GPE1 130117521Snjl * GpeNumber - Raw GPE number 131114239Snjl * 132117521Snjl * RETURN: A GPE EventInfo struct. NULL if not a valid GPE 133114239Snjl * 134117521Snjl * DESCRIPTION: Returns the EventInfo struct associated with this GPE. 135117521Snjl * Validates the GpeBlock and the GpeNumber 136114239Snjl * 137117521Snjl * Should be called only when the GPE lists are semaphore locked 138117521Snjl * and not subject to change. 139114239Snjl * 140114239Snjl ******************************************************************************/ 141114239Snjl 142114239SnjlACPI_GPE_EVENT_INFO * 143114239SnjlAcpiEvGetGpeEventInfo ( 144117521Snjl ACPI_HANDLE GpeDevice, 145114239Snjl UINT32 GpeNumber) 146114239Snjl{ 147117521Snjl ACPI_OPERAND_OBJECT *ObjDesc; 148114239Snjl ACPI_GPE_BLOCK_INFO *GpeBlock; 149117521Snjl ACPI_NATIVE_UINT i; 150114239Snjl 151114239Snjl 152117521Snjl ACPI_FUNCTION_ENTRY (); 153114239Snjl 154117521Snjl 155117521Snjl /* A NULL GpeBlock means use the FADT-defined GPE block(s) */ 156117521Snjl 157117521Snjl if (!GpeDevice) 158114239Snjl { 159117521Snjl /* Examine GPE Block 0 and 1 (These blocks are permanent) */ 160117521Snjl 161117521Snjl for (i = 0; i < ACPI_MAX_GPE_BLOCKS; i++) 162117521Snjl { 163117521Snjl GpeBlock = AcpiGbl_GpeFadtBlocks[i]; 164117521Snjl if (GpeBlock) 165117521Snjl { 166117521Snjl if ((GpeNumber >= GpeBlock->BlockBaseNumber) && 167117521Snjl (GpeNumber < GpeBlock->BlockBaseNumber + (GpeBlock->RegisterCount * 8))) 168117521Snjl { 169117521Snjl return (&GpeBlock->EventInfo[GpeNumber - GpeBlock->BlockBaseNumber]); 170117521Snjl } 171117521Snjl } 172117521Snjl } 173117521Snjl 174117521Snjl /* The GpeNumber was not in the range of either FADT GPE block */ 175117521Snjl 176114239Snjl return (NULL); 177114239Snjl } 178114239Snjl 179117521Snjl /* 180117521Snjl * A Non-null GpeDevice means this is a GPE Block Device. 181117521Snjl */ 182117521Snjl ObjDesc = AcpiNsGetAttachedObject ((ACPI_NAMESPACE_NODE *) GpeDevice); 183117521Snjl if (!ObjDesc || 184117521Snjl !ObjDesc->Device.GpeBlock) 185114239Snjl { 186117521Snjl return (NULL); 187114239Snjl } 188114239Snjl 189117521Snjl GpeBlock = ObjDesc->Device.GpeBlock; 190114239Snjl 191114239Snjl if ((GpeNumber >= GpeBlock->BlockBaseNumber) && 192114239Snjl (GpeNumber < GpeBlock->BlockBaseNumber + (GpeBlock->RegisterCount * 8))) 193114239Snjl { 194114239Snjl return (&GpeBlock->EventInfo[GpeNumber - GpeBlock->BlockBaseNumber]); 195114239Snjl } 196114239Snjl 197114239Snjl return (NULL); 198114239Snjl} 199114239Snjl 200117521Snjl 201114239Snjl/******************************************************************************* 202114239Snjl * 203114239Snjl * FUNCTION: AcpiEvGpeDetect 204114239Snjl * 205117521Snjl * PARAMETERS: GpeXruptList - Interrupt block for this interrupt. 206117521Snjl * Can have multiple GPE blocks attached. 207114239Snjl * 208114239Snjl * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED 209114239Snjl * 210114239Snjl * DESCRIPTION: Detect if any GP events have occurred. This function is 211114239Snjl * executed at interrupt level. 212114239Snjl * 213114239Snjl ******************************************************************************/ 214114239Snjl 215114239SnjlUINT32 216117521SnjlAcpiEvGpeDetect ( 217117521Snjl ACPI_GPE_XRUPT_INFO *GpeXruptList) 218114239Snjl{ 219114239Snjl UINT32 IntStatus = ACPI_INTERRUPT_NOT_HANDLED; 220114239Snjl UINT8 EnabledStatusByte; 221114239Snjl ACPI_GPE_REGISTER_INFO *GpeRegisterInfo; 222114239Snjl UINT32 InValue; 223114239Snjl ACPI_STATUS Status; 224114239Snjl ACPI_GPE_BLOCK_INFO *GpeBlock; 225117521Snjl UINT32 i; 226117521Snjl UINT32 j; 227114239Snjl 228114239Snjl 229114239Snjl ACPI_FUNCTION_NAME ("EvGpeDetect"); 230114239Snjl 231114239Snjl 232114239Snjl /* Examine all GPE blocks attached to this interrupt level */ 233114239Snjl 234117521Snjl AcpiOsAcquireLock (AcpiGbl_GpeLock, ACPI_ISR); 235117521Snjl GpeBlock = GpeXruptList->GpeBlockListHead; 236114239Snjl while (GpeBlock) 237114239Snjl { 238114239Snjl /* 239114239Snjl * Read all of the 8-bit GPE status and enable registers 240114239Snjl * in this GPE block, saving all of them. 241114239Snjl * Find all currently active GP events. 242114239Snjl */ 243114239Snjl for (i = 0; i < GpeBlock->RegisterCount; i++) 244114239Snjl { 245114239Snjl /* Get the next status/enable pair */ 246114239Snjl 247114239Snjl GpeRegisterInfo = &GpeBlock->RegisterInfo[i]; 248114239Snjl 249117521Snjl /* Read the Status Register */ 250117521Snjl 251114239Snjl Status = AcpiHwLowLevelRead (ACPI_GPE_REGISTER_WIDTH, &InValue, 252117521Snjl &GpeRegisterInfo->StatusAddress); 253114239Snjl GpeRegisterInfo->Status = (UINT8) InValue; 254114239Snjl if (ACPI_FAILURE (Status)) 255114239Snjl { 256117521Snjl goto UnlockAndExit; 257114239Snjl } 258114239Snjl 259117521Snjl /* Read the Enable Register */ 260117521Snjl 261114239Snjl Status = AcpiHwLowLevelRead (ACPI_GPE_REGISTER_WIDTH, &InValue, 262117521Snjl &GpeRegisterInfo->EnableAddress); 263114239Snjl GpeRegisterInfo->Enable = (UINT8) InValue; 264114239Snjl if (ACPI_FAILURE (Status)) 265114239Snjl { 266117521Snjl goto UnlockAndExit; 267114239Snjl } 268114239Snjl 269114239Snjl ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS, 270117521Snjl "GPE pair: Status %8.8X%8.8X = %02X, Enable %8.8X%8.8X = %02X\n", 271123315Snjl ACPI_FORMAT_UINT64 (ACPI_GET_ADDRESS (GpeRegisterInfo->StatusAddress.Address)), 272117521Snjl GpeRegisterInfo->Status, 273123315Snjl ACPI_FORMAT_UINT64 (ACPI_GET_ADDRESS (GpeRegisterInfo->EnableAddress.Address)), 274117521Snjl GpeRegisterInfo->Enable)); 275114239Snjl 276114239Snjl /* First check if there is anything active at all in this register */ 277114239Snjl 278114239Snjl EnabledStatusByte = (UINT8) (GpeRegisterInfo->Status & 279114239Snjl GpeRegisterInfo->Enable); 280114239Snjl if (!EnabledStatusByte) 281114239Snjl { 282114239Snjl /* No active GPEs in this register, move on */ 283114239Snjl 284114239Snjl continue; 285114239Snjl } 286114239Snjl 287114239Snjl /* Now look at the individual GPEs in this byte register */ 288114239Snjl 289123315Snjl for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) 290114239Snjl { 291114239Snjl /* Examine one GPE bit */ 292114239Snjl 293123315Snjl if (EnabledStatusByte & AcpiGbl_DecodeTo8bit[j]) 294114239Snjl { 295114239Snjl /* 296114239Snjl * Found an active GPE. Dispatch the event to a handler 297114239Snjl * or method. 298114239Snjl */ 299114239Snjl IntStatus |= AcpiEvGpeDispatch ( 300123315Snjl &GpeBlock->EventInfo[(i * ACPI_GPE_REGISTER_WIDTH) + j], 301123315Snjl j + GpeRegisterInfo->BaseGpeNumber); 302114239Snjl } 303114239Snjl } 304114239Snjl } 305114239Snjl 306114239Snjl GpeBlock = GpeBlock->Next; 307114239Snjl } 308114239Snjl 309117521SnjlUnlockAndExit: 310117521Snjl 311117521Snjl AcpiOsReleaseLock (AcpiGbl_GpeLock, ACPI_ISR); 312114239Snjl return (IntStatus); 313114239Snjl} 314114239Snjl 315114239Snjl 316114239Snjl/******************************************************************************* 317114239Snjl * 318114239Snjl * FUNCTION: AcpiEvAsynchExecuteGpeMethod 319114239Snjl * 320117521Snjl * PARAMETERS: Context (GpeEventInfo) - Info for this GPE 321114239Snjl * 322114239Snjl * RETURN: None 323114239Snjl * 324114239Snjl * DESCRIPTION: Perform the actual execution of a GPE control method. This 325114239Snjl * function is called from an invocation of AcpiOsQueueForExecution 326114239Snjl * (and therefore does NOT execute at interrupt level) so that 327114239Snjl * the control method itself is not executed in the context of 328117521Snjl * an interrupt handler. 329114239Snjl * 330114239Snjl ******************************************************************************/ 331114239Snjl 332114239Snjlstatic void ACPI_SYSTEM_XFACE 333114239SnjlAcpiEvAsynchExecuteGpeMethod ( 334114239Snjl void *Context) 335114239Snjl{ 336114239Snjl ACPI_GPE_EVENT_INFO *GpeEventInfo = (void *) Context; 337114239Snjl UINT32 GpeNumber = 0; 338114239Snjl ACPI_STATUS Status; 339117521Snjl ACPI_GPE_EVENT_INFO LocalGpeEventInfo; 340114239Snjl 341114239Snjl 342114239Snjl ACPI_FUNCTION_TRACE ("EvAsynchExecuteGpeMethod"); 343114239Snjl 344114239Snjl 345114239Snjl Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 346114239Snjl if (ACPI_FAILURE (Status)) 347114239Snjl { 348114239Snjl return_VOID; 349114239Snjl } 350114239Snjl 351117521Snjl /* Must revalidate the GpeNumber/GpeBlock */ 352117521Snjl 353117521Snjl if (!AcpiEvValidGpeEvent (GpeEventInfo)) 354117521Snjl { 355117521Snjl Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 356117521Snjl return_VOID; 357117521Snjl } 358117521Snjl 359117521Snjl /* 360117521Snjl * Take a snapshot of the GPE info for this level - we copy the 361117521Snjl * info to prevent a race condition with RemoveHandler/RemoveBlock. 362117521Snjl */ 363117521Snjl ACPI_MEMCPY (&LocalGpeEventInfo, GpeEventInfo, sizeof (ACPI_GPE_EVENT_INFO)); 364117521Snjl 365114239Snjl Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 366114239Snjl if (ACPI_FAILURE (Status)) 367114239Snjl { 368114239Snjl return_VOID; 369114239Snjl } 370114239Snjl 371117521Snjl if (LocalGpeEventInfo.MethodNode) 372114239Snjl { 373114239Snjl /* 374114239Snjl * Invoke the GPE Method (_Lxx, _Exx): 375114239Snjl * (Evaluate the _Lxx/_Exx control method that corresponds to this GPE.) 376114239Snjl */ 377117521Snjl Status = AcpiNsEvaluateByHandle (LocalGpeEventInfo.MethodNode, NULL, NULL); 378114239Snjl if (ACPI_FAILURE (Status)) 379114239Snjl { 380117521Snjl ACPI_REPORT_ERROR (("%s while evaluating method [%4.4s] for GPE[%2X]\n", 381114239Snjl AcpiFormatException (Status), 382123315Snjl AcpiUtGetNodeName (LocalGpeEventInfo.MethodNode), GpeNumber)); 383114239Snjl } 384114239Snjl } 385114239Snjl 386117521Snjl if (LocalGpeEventInfo.Flags & ACPI_EVENT_LEVEL_TRIGGERED) 387114239Snjl { 388114239Snjl /* 389114239Snjl * GPE is level-triggered, we clear the GPE status bit after handling 390114239Snjl * the event. 391114239Snjl */ 392117521Snjl Status = AcpiHwClearGpe (&LocalGpeEventInfo); 393114239Snjl if (ACPI_FAILURE (Status)) 394114239Snjl { 395114239Snjl return_VOID; 396114239Snjl } 397114239Snjl } 398114239Snjl 399114239Snjl /* Enable this GPE */ 400114239Snjl 401117521Snjl (void) AcpiHwEnableGpe (&LocalGpeEventInfo); 402114239Snjl return_VOID; 403114239Snjl} 404114239Snjl 405114239Snjl 406114239Snjl/******************************************************************************* 407114239Snjl * 408114239Snjl * FUNCTION: AcpiEvGpeDispatch 409114239Snjl * 410117521Snjl * PARAMETERS: GpeEventInfo - info for this GPE 411117521Snjl * GpeNumber - Number relative to the parent GPE block 412114239Snjl * 413114239Snjl * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED 414114239Snjl * 415114239Snjl * DESCRIPTION: Dispatch a General Purpose Event to either a function (e.g. EC) 416117521Snjl * or method (e.g. _Lxx/_Exx) handler. 417114239Snjl * 418117521Snjl * This function executes at interrupt level. 419117521Snjl * 420114239Snjl ******************************************************************************/ 421114239Snjl 422114239SnjlUINT32 423114239SnjlAcpiEvGpeDispatch ( 424117521Snjl ACPI_GPE_EVENT_INFO *GpeEventInfo, 425117521Snjl UINT32 GpeNumber) 426114239Snjl{ 427114239Snjl ACPI_STATUS Status; 428114239Snjl 429114239Snjl 430114239Snjl ACPI_FUNCTION_TRACE ("EvGpeDispatch"); 431114239Snjl 432114239Snjl 433114239Snjl /* 434114239Snjl * If edge-triggered, clear the GPE status bit now. Note that 435114239Snjl * level-triggered events are cleared after the GPE is serviced. 436114239Snjl */ 437117521Snjl if (GpeEventInfo->Flags & ACPI_EVENT_EDGE_TRIGGERED) 438114239Snjl { 439114239Snjl Status = AcpiHwClearGpe (GpeEventInfo); 440114239Snjl if (ACPI_FAILURE (Status)) 441114239Snjl { 442117521Snjl ACPI_REPORT_ERROR (("AcpiEvGpeDispatch: Unable to clear GPE[%2X]\n", 443114239Snjl GpeNumber)); 444114239Snjl return_VALUE (ACPI_INTERRUPT_NOT_HANDLED); 445114239Snjl } 446114239Snjl } 447114239Snjl 448114239Snjl /* 449114239Snjl * Dispatch the GPE to either an installed handler, or the control 450114239Snjl * method associated with this GPE (_Lxx or _Exx). 451114239Snjl * If a handler exists, we invoke it and do not attempt to run the method. 452114239Snjl * If there is neither a handler nor a method, we disable the level to 453114239Snjl * prevent further events from coming in here. 454114239Snjl */ 455114239Snjl if (GpeEventInfo->Handler) 456114239Snjl { 457114239Snjl /* Invoke the installed handler (at interrupt level) */ 458114239Snjl 459114239Snjl GpeEventInfo->Handler (GpeEventInfo->Context); 460123315Snjl 461123315Snjl /* It is now safe to clear level-triggered events. */ 462123315Snjl 463123315Snjl if (GpeEventInfo->Flags & ACPI_EVENT_LEVEL_TRIGGERED) 464123315Snjl { 465123315Snjl Status = AcpiHwClearGpe (GpeEventInfo); 466123315Snjl if (ACPI_FAILURE (Status)) 467123315Snjl { 468123315Snjl ACPI_REPORT_ERROR (( 469123315Snjl "AcpiEvGpeDispatch: Unable to clear GPE[%2X]\n", 470123315Snjl GpeNumber)); 471123315Snjl return_VALUE (ACPI_INTERRUPT_NOT_HANDLED); 472123315Snjl } 473123315Snjl } 474114239Snjl } 475114239Snjl else if (GpeEventInfo->MethodNode) 476114239Snjl { 477114239Snjl /* 478114239Snjl * Disable GPE, so it doesn't keep firing before the method has a 479114239Snjl * chance to run. 480114239Snjl */ 481114239Snjl Status = AcpiHwDisableGpe (GpeEventInfo); 482114239Snjl if (ACPI_FAILURE (Status)) 483114239Snjl { 484123315Snjl ACPI_REPORT_ERROR (( 485123315Snjl "AcpiEvGpeDispatch: Unable to disable GPE[%2X]\n", 486114239Snjl GpeNumber)); 487114239Snjl return_VALUE (ACPI_INTERRUPT_NOT_HANDLED); 488114239Snjl } 489114239Snjl 490126372Snjl /* 491123315Snjl * Execute the method associated with the GPE 492123315Snjl * NOTE: Level-triggered GPEs are cleared after the method completes. 493123315Snjl */ 494114239Snjl if (ACPI_FAILURE (AcpiOsQueueForExecution (OSD_PRIORITY_GPE, 495114239Snjl AcpiEvAsynchExecuteGpeMethod, 496114239Snjl GpeEventInfo))) 497114239Snjl { 498114239Snjl ACPI_REPORT_ERROR (( 499117521Snjl "AcpiEvGpeDispatch: Unable to queue handler for GPE[%2X], event is disabled\n", 500114239Snjl GpeNumber)); 501114239Snjl } 502114239Snjl } 503114239Snjl else 504114239Snjl { 505114239Snjl /* No handler or method to run! */ 506114239Snjl 507114239Snjl ACPI_REPORT_ERROR (( 508117521Snjl "AcpiEvGpeDispatch: No handler or method for GPE[%2X], disabling event\n", 509114239Snjl GpeNumber)); 510114239Snjl 511114239Snjl /* 512114239Snjl * Disable the GPE. The GPE will remain disabled until the ACPI 513123315Snjl * Core Subsystem is restarted, or a handler is installed. 514114239Snjl */ 515114239Snjl Status = AcpiHwDisableGpe (GpeEventInfo); 516114239Snjl if (ACPI_FAILURE (Status)) 517114239Snjl { 518123315Snjl ACPI_REPORT_ERROR (( 519123315Snjl "AcpiEvGpeDispatch: Unable to disable GPE[%2X]\n", 520114239Snjl GpeNumber)); 521114239Snjl return_VALUE (ACPI_INTERRUPT_NOT_HANDLED); 522114239Snjl } 523114239Snjl } 524114239Snjl 525114239Snjl return_VALUE (ACPI_INTERRUPT_HANDLED); 526114239Snjl} 527114239Snjl 528