Home | History | Annotate | Line # | Download | only in events
evgpe.c revision 1.1
      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 "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 /* Local prototypes */
    125 
    126 static void ACPI_SYSTEM_XFACE
    127 AcpiEvAsynchExecuteGpeMethod (
    128     void                    *Context);
    129 
    130 static void ACPI_SYSTEM_XFACE
    131 AcpiEvAsynchEnableGpe (
    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 
    148 ACPI_STATUS
    149 AcpiEvUpdateGpeEnableMasks (
    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 
    204 ACPI_STATUS
    205 AcpiEvEnableGpe (
    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 
    263 ACPI_STATUS
    264 AcpiEvDisableGpe (
    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 
    315 ACPI_GPE_EVENT_INFO *
    316 AcpiEvLowGetGpeInfo (
    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 
    360 ACPI_GPE_EVENT_INFO *
    361 AcpiEvGetGpeEventInfo (
    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 GpeDevice 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 
    421 UINT32
    422 AcpiEvGpeDetect (
    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 
    521 UnlockAndExit:
    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 
    544 static void ACPI_SYSTEM_XFACE
    545 AcpiEvAsynchExecuteGpeMethod (
    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 
    658 static void ACPI_SYSTEM_XFACE
    659 AcpiEvAsynchEnableGpe (
    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 
    684 Exit:
    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 
    706 UINT32
    707 AcpiEvGpeDispatch (
    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