Home | History | Annotate | Line # | Download | only in events
evgpeblk.c revision 1.1
      1 /******************************************************************************
      2  *
      3  * Module Name: evgpeblk - GPE block creation and initialization.
      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    ("evgpeblk")
    123 
    124 /* Local prototypes */
    125 
    126 static ACPI_STATUS
    127 AcpiEvInstallGpeBlock (
    128     ACPI_GPE_BLOCK_INFO     *GpeBlock,
    129     UINT32                  InterruptNumber);
    130 
    131 static ACPI_STATUS
    132 AcpiEvCreateGpeInfoBlocks (
    133     ACPI_GPE_BLOCK_INFO     *GpeBlock);
    134 
    135 
    136 /*******************************************************************************
    137  *
    138  * FUNCTION:    AcpiEvInstallGpeBlock
    139  *
    140  * PARAMETERS:  GpeBlock                - New GPE block
    141  *              InterruptNumber         - Xrupt to be associated with this
    142  *                                        GPE block
    143  *
    144  * RETURN:      Status
    145  *
    146  * DESCRIPTION: Install new GPE block with mutex support
    147  *
    148  ******************************************************************************/
    149 
    150 static ACPI_STATUS
    151 AcpiEvInstallGpeBlock (
    152     ACPI_GPE_BLOCK_INFO     *GpeBlock,
    153     UINT32                  InterruptNumber)
    154 {
    155     ACPI_GPE_BLOCK_INFO     *NextGpeBlock;
    156     ACPI_GPE_XRUPT_INFO     *GpeXruptBlock;
    157     ACPI_STATUS             Status;
    158     ACPI_CPU_FLAGS          Flags;
    159 
    160 
    161     ACPI_FUNCTION_TRACE (EvInstallGpeBlock);
    162 
    163 
    164     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    165     if (ACPI_FAILURE (Status))
    166     {
    167         return_ACPI_STATUS (Status);
    168     }
    169 
    170     GpeXruptBlock = AcpiEvGetGpeXruptBlock (InterruptNumber);
    171     if (!GpeXruptBlock)
    172     {
    173         Status = AE_NO_MEMORY;
    174         goto UnlockAndExit;
    175     }
    176 
    177     /* Install the new block at the end of the list with lock */
    178 
    179     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
    180     if (GpeXruptBlock->GpeBlockListHead)
    181     {
    182         NextGpeBlock = GpeXruptBlock->GpeBlockListHead;
    183         while (NextGpeBlock->Next)
    184         {
    185             NextGpeBlock = NextGpeBlock->Next;
    186         }
    187 
    188         NextGpeBlock->Next = GpeBlock;
    189         GpeBlock->Previous = NextGpeBlock;
    190     }
    191     else
    192     {
    193         GpeXruptBlock->GpeBlockListHead = GpeBlock;
    194     }
    195 
    196     GpeBlock->XruptBlock = GpeXruptBlock;
    197     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    198 
    199 
    200 UnlockAndExit:
    201     Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    202     return_ACPI_STATUS (Status);
    203 }
    204 
    205 
    206 /*******************************************************************************
    207  *
    208  * FUNCTION:    AcpiEvDeleteGpeBlock
    209  *
    210  * PARAMETERS:  GpeBlock            - Existing GPE block
    211  *
    212  * RETURN:      Status
    213  *
    214  * DESCRIPTION: Remove a GPE block
    215  *
    216  ******************************************************************************/
    217 
    218 ACPI_STATUS
    219 AcpiEvDeleteGpeBlock (
    220     ACPI_GPE_BLOCK_INFO     *GpeBlock)
    221 {
    222     ACPI_STATUS             Status;
    223     ACPI_CPU_FLAGS          Flags;
    224 
    225 
    226     ACPI_FUNCTION_TRACE (EvInstallGpeBlock);
    227 
    228 
    229     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    230     if (ACPI_FAILURE (Status))
    231     {
    232         return_ACPI_STATUS (Status);
    233     }
    234 
    235     /* Disable all GPEs in this block */
    236 
    237     Status = AcpiHwDisableGpeBlock (GpeBlock->XruptBlock, GpeBlock, NULL);
    238 
    239     if (!GpeBlock->Previous && !GpeBlock->Next)
    240     {
    241         /* This is the last GpeBlock on this interrupt */
    242 
    243         Status = AcpiEvDeleteGpeXrupt (GpeBlock->XruptBlock);
    244         if (ACPI_FAILURE (Status))
    245         {
    246             goto UnlockAndExit;
    247         }
    248     }
    249     else
    250     {
    251         /* Remove the block on this interrupt with lock */
    252 
    253         Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
    254         if (GpeBlock->Previous)
    255         {
    256             GpeBlock->Previous->Next = GpeBlock->Next;
    257         }
    258         else
    259         {
    260             GpeBlock->XruptBlock->GpeBlockListHead = GpeBlock->Next;
    261         }
    262 
    263         if (GpeBlock->Next)
    264         {
    265             GpeBlock->Next->Previous = GpeBlock->Previous;
    266         }
    267         AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    268     }
    269 
    270     AcpiCurrentGpeCount -= GpeBlock->GpeCount;
    271 
    272     /* Free the GpeBlock */
    273 
    274     ACPI_FREE (GpeBlock->RegisterInfo);
    275     ACPI_FREE (GpeBlock->EventInfo);
    276     ACPI_FREE (GpeBlock);
    277 
    278 UnlockAndExit:
    279     Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    280     return_ACPI_STATUS (Status);
    281 }
    282 
    283 
    284 /*******************************************************************************
    285  *
    286  * FUNCTION:    AcpiEvCreateGpeInfoBlocks
    287  *
    288  * PARAMETERS:  GpeBlock    - New GPE block
    289  *
    290  * RETURN:      Status
    291  *
    292  * DESCRIPTION: Create the RegisterInfo and EventInfo blocks for this GPE block
    293  *
    294  ******************************************************************************/
    295 
    296 static ACPI_STATUS
    297 AcpiEvCreateGpeInfoBlocks (
    298     ACPI_GPE_BLOCK_INFO     *GpeBlock)
    299 {
    300     ACPI_GPE_REGISTER_INFO  *GpeRegisterInfo = NULL;
    301     ACPI_GPE_EVENT_INFO     *GpeEventInfo = NULL;
    302     ACPI_GPE_EVENT_INFO     *ThisEvent;
    303     ACPI_GPE_REGISTER_INFO  *ThisRegister;
    304     UINT32                  i;
    305     UINT32                  j;
    306     ACPI_STATUS             Status;
    307 
    308 
    309     ACPI_FUNCTION_TRACE (EvCreateGpeInfoBlocks);
    310 
    311 
    312     /* Allocate the GPE register information block */
    313 
    314     GpeRegisterInfo = ACPI_ALLOCATE_ZEROED (
    315                         (ACPI_SIZE) GpeBlock->RegisterCount *
    316                         sizeof (ACPI_GPE_REGISTER_INFO));
    317     if (!GpeRegisterInfo)
    318     {
    319         ACPI_ERROR ((AE_INFO,
    320             "Could not allocate the GpeRegisterInfo table"));
    321         return_ACPI_STATUS (AE_NO_MEMORY);
    322     }
    323 
    324     /*
    325      * Allocate the GPE EventInfo block. There are eight distinct GPEs
    326      * per register. Initialization to zeros is sufficient.
    327      */
    328     GpeEventInfo = ACPI_ALLOCATE_ZEROED ((ACPI_SIZE) GpeBlock->GpeCount *
    329                     sizeof (ACPI_GPE_EVENT_INFO));
    330     if (!GpeEventInfo)
    331     {
    332         ACPI_ERROR ((AE_INFO,
    333             "Could not allocate the GpeEventInfo table"));
    334         Status = AE_NO_MEMORY;
    335         goto ErrorExit;
    336     }
    337 
    338     /* Save the new Info arrays in the GPE block */
    339 
    340     GpeBlock->RegisterInfo = GpeRegisterInfo;
    341     GpeBlock->EventInfo    = GpeEventInfo;
    342 
    343     /*
    344      * Initialize the GPE Register and Event structures. A goal of these
    345      * tables is to hide the fact that there are two separate GPE register
    346      * sets in a given GPE hardware block, the status registers occupy the
    347      * first half, and the enable registers occupy the second half.
    348      */
    349     ThisRegister = GpeRegisterInfo;
    350     ThisEvent    = GpeEventInfo;
    351 
    352     for (i = 0; i < GpeBlock->RegisterCount; i++)
    353     {
    354         /* Init the RegisterInfo for this GPE register (8 GPEs) */
    355 
    356         ThisRegister->BaseGpeNumber = (UINT8) (GpeBlock->BlockBaseNumber +
    357                                              (i * ACPI_GPE_REGISTER_WIDTH));
    358 
    359         ThisRegister->StatusAddress.Address =
    360             GpeBlock->BlockAddress.Address + i;
    361 
    362         ThisRegister->EnableAddress.Address =
    363             GpeBlock->BlockAddress.Address + i + GpeBlock->RegisterCount;
    364 
    365         ThisRegister->StatusAddress.SpaceId   = GpeBlock->BlockAddress.SpaceId;
    366         ThisRegister->EnableAddress.SpaceId   = GpeBlock->BlockAddress.SpaceId;
    367         ThisRegister->StatusAddress.BitWidth  = ACPI_GPE_REGISTER_WIDTH;
    368         ThisRegister->EnableAddress.BitWidth  = ACPI_GPE_REGISTER_WIDTH;
    369         ThisRegister->StatusAddress.BitOffset = 0;
    370         ThisRegister->EnableAddress.BitOffset = 0;
    371 
    372         /* Init the EventInfo for each GPE within this register */
    373 
    374         for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++)
    375         {
    376             ThisEvent->GpeNumber = (UINT8) (ThisRegister->BaseGpeNumber + j);
    377             ThisEvent->RegisterInfo = ThisRegister;
    378             ThisEvent++;
    379         }
    380 
    381         /* Disable all GPEs within this register */
    382 
    383         Status = AcpiHwWrite (0x00, &ThisRegister->EnableAddress);
    384         if (ACPI_FAILURE (Status))
    385         {
    386             goto ErrorExit;
    387         }
    388 
    389         /* Clear any pending GPE events within this register */
    390 
    391         Status = AcpiHwWrite (0xFF, &ThisRegister->StatusAddress);
    392         if (ACPI_FAILURE (Status))
    393         {
    394             goto ErrorExit;
    395         }
    396 
    397         ThisRegister++;
    398     }
    399 
    400     return_ACPI_STATUS (AE_OK);
    401 
    402 
    403 ErrorExit:
    404     if (GpeRegisterInfo)
    405     {
    406         ACPI_FREE (GpeRegisterInfo);
    407     }
    408     if (GpeEventInfo)
    409     {
    410         ACPI_FREE (GpeEventInfo);
    411     }
    412 
    413     return_ACPI_STATUS (Status);
    414 }
    415 
    416 
    417 /*******************************************************************************
    418  *
    419  * FUNCTION:    AcpiEvCreateGpeBlock
    420  *
    421  * PARAMETERS:  GpeDevice           - Handle to the parent GPE block
    422  *              GpeBlockAddress     - Address and SpaceID
    423  *              RegisterCount       - Number of GPE register pairs in the block
    424  *              GpeBlockBaseNumber  - Starting GPE number for the block
    425  *              InterruptNumber     - H/W interrupt for the block
    426  *              ReturnGpeBlock      - Where the new block descriptor is returned
    427  *
    428  * RETURN:      Status
    429  *
    430  * DESCRIPTION: Create and Install a block of GPE registers. All GPEs within
    431  *              the block are disabled at exit.
    432  *              Note: Assumes namespace is locked.
    433  *
    434  ******************************************************************************/
    435 
    436 ACPI_STATUS
    437 AcpiEvCreateGpeBlock (
    438     ACPI_NAMESPACE_NODE     *GpeDevice,
    439     ACPI_GENERIC_ADDRESS    *GpeBlockAddress,
    440     UINT32                  RegisterCount,
    441     UINT8                   GpeBlockBaseNumber,
    442     UINT32                  InterruptNumber,
    443     ACPI_GPE_BLOCK_INFO     **ReturnGpeBlock)
    444 {
    445     ACPI_STATUS             Status;
    446     ACPI_GPE_BLOCK_INFO     *GpeBlock;
    447     ACPI_GPE_WALK_INFO      WalkInfo;
    448 
    449 
    450     ACPI_FUNCTION_TRACE (EvCreateGpeBlock);
    451 
    452 
    453     if (!RegisterCount)
    454     {
    455         return_ACPI_STATUS (AE_OK);
    456     }
    457 
    458     /* Allocate a new GPE block */
    459 
    460     GpeBlock = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_BLOCK_INFO));
    461     if (!GpeBlock)
    462     {
    463         return_ACPI_STATUS (AE_NO_MEMORY);
    464     }
    465 
    466     /* Initialize the new GPE block */
    467 
    468     GpeBlock->Node = GpeDevice;
    469     GpeBlock->GpeCount = (UINT16) (RegisterCount * ACPI_GPE_REGISTER_WIDTH);
    470     GpeBlock->RegisterCount = RegisterCount;
    471     GpeBlock->BlockBaseNumber = GpeBlockBaseNumber;
    472 
    473     ACPI_MEMCPY (&GpeBlock->BlockAddress, GpeBlockAddress,
    474         sizeof (ACPI_GENERIC_ADDRESS));
    475 
    476     /*
    477      * Create the RegisterInfo and EventInfo sub-structures
    478      * Note: disables and clears all GPEs in the block
    479      */
    480     Status = AcpiEvCreateGpeInfoBlocks (GpeBlock);
    481     if (ACPI_FAILURE (Status))
    482     {
    483         ACPI_FREE (GpeBlock);
    484         return_ACPI_STATUS (Status);
    485     }
    486 
    487     /* Install the new block in the global lists */
    488 
    489     Status = AcpiEvInstallGpeBlock (GpeBlock, InterruptNumber);
    490     if (ACPI_FAILURE (Status))
    491     {
    492         ACPI_FREE (GpeBlock);
    493         return_ACPI_STATUS (Status);
    494     }
    495 
    496     /* Find all GPE methods (_Lxx or_Exx) for this block */
    497 
    498     WalkInfo.GpeBlock = GpeBlock;
    499     WalkInfo.GpeDevice = GpeDevice;
    500     WalkInfo.EnableThisGpe = FALSE;
    501     WalkInfo.ExecuteByOwnerId = FALSE;
    502 
    503     Status = AcpiNsWalkNamespace (ACPI_TYPE_METHOD, GpeDevice,
    504                 ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
    505                 AcpiEvMatchGpeMethod, NULL, &WalkInfo, NULL);
    506 
    507     /* Return the new block */
    508 
    509     if (ReturnGpeBlock)
    510     {
    511         (*ReturnGpeBlock) = GpeBlock;
    512     }
    513 
    514     ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
    515         "GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n",
    516         (UINT32) GpeBlock->BlockBaseNumber,
    517         (UINT32) (GpeBlock->BlockBaseNumber + (GpeBlock->GpeCount - 1)),
    518         GpeDevice->Name.Ascii, GpeBlock->RegisterCount,
    519         InterruptNumber));
    520 
    521     /* Update global count of currently available GPEs */
    522 
    523     AcpiCurrentGpeCount += GpeBlock->GpeCount;
    524     return_ACPI_STATUS (AE_OK);
    525 }
    526 
    527 
    528 /*******************************************************************************
    529  *
    530  * FUNCTION:    AcpiEvInitializeGpeBlock
    531  *
    532  * PARAMETERS:  GpeDevice           - Handle to the parent GPE block
    533  *              GpeBlock            - Gpe Block info
    534  *
    535  * RETURN:      Status
    536  *
    537  * DESCRIPTION: Initialize and enable a GPE block. First find and run any
    538  *              _PRT methods associated with the block, then enable the
    539  *              appropriate GPEs.
    540  *              Note: Assumes namespace is locked.
    541  *
    542  ******************************************************************************/
    543 
    544 ACPI_STATUS
    545 AcpiEvInitializeGpeBlock (
    546     ACPI_NAMESPACE_NODE     *GpeDevice,
    547     ACPI_GPE_BLOCK_INFO     *GpeBlock)
    548 {
    549     ACPI_STATUS             Status;
    550     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    551     ACPI_GPE_WALK_INFO      WalkInfo;
    552     UINT32                  WakeGpeCount;
    553     UINT32                  GpeEnabledCount;
    554     UINT32                  GpeIndex;
    555     UINT32                  GpeNumber;
    556     UINT32                  i;
    557     UINT32                  j;
    558 
    559 
    560     ACPI_FUNCTION_TRACE (EvInitializeGpeBlock);
    561 
    562 
    563     /* Ignore a null GPE block (e.g., if no GPE block 1 exists) */
    564 
    565     if (!GpeBlock)
    566     {
    567         return_ACPI_STATUS (AE_OK);
    568     }
    569 
    570     /*
    571      * Runtime option: Should wake GPEs be enabled at runtime?  The default
    572      * is no, they should only be enabled just as the machine goes to sleep.
    573      */
    574     if (AcpiGbl_LeaveWakeGpesDisabled)
    575     {
    576         /*
    577          * Differentiate runtime vs wake GPEs, via the _PRW control methods.
    578          * Each GPE that has one or more _PRWs that reference it is by
    579          * definition a wake GPE and will not be enabled while the machine
    580          * is running.
    581          */
    582         WalkInfo.GpeBlock = GpeBlock;
    583         WalkInfo.GpeDevice = GpeDevice;
    584         WalkInfo.ExecuteByOwnerId = FALSE;
    585 
    586         Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
    587                     ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
    588                     AcpiEvMatchPrwAndGpe, NULL, &WalkInfo, NULL);
    589         if (ACPI_FAILURE (Status))
    590         {
    591             ACPI_EXCEPTION ((AE_INFO, Status, "While executing _PRW methods"));
    592         }
    593     }
    594 
    595     /*
    596      * Enable all GPEs that have a corresponding method and are not
    597      * capable of generating wakeups. Any other GPEs within this block
    598      * must be enabled via the AcpiEnableGpe interface.
    599      */
    600     WakeGpeCount = 0;
    601     GpeEnabledCount = 0;
    602 
    603     if (GpeDevice == AcpiGbl_FadtGpeDevice)
    604     {
    605         GpeDevice = NULL;
    606     }
    607 
    608     for (i = 0; i < GpeBlock->RegisterCount; i++)
    609     {
    610         for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++)
    611         {
    612             /* Get the info block for this particular GPE */
    613 
    614             GpeIndex = (i * ACPI_GPE_REGISTER_WIDTH) + j;
    615             GpeEventInfo = &GpeBlock->EventInfo[GpeIndex];
    616 
    617             /* Ignore GPEs that can wake the system */
    618 
    619             if (GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE)
    620             {
    621                 WakeGpeCount++;
    622                 if (AcpiGbl_LeaveWakeGpesDisabled)
    623                 {
    624                     continue;
    625                 }
    626             }
    627 
    628             /* Ignore GPEs that have no corresponding _Lxx/_Exx method */
    629 
    630             if (!(GpeEventInfo->Flags & ACPI_GPE_DISPATCH_METHOD))
    631             {
    632                 continue;
    633             }
    634 
    635             /* Enable this GPE */
    636 
    637             GpeNumber = GpeIndex + GpeBlock->BlockBaseNumber;
    638             Status = AcpiEnableGpe (GpeDevice, GpeNumber,
    639                         ACPI_GPE_TYPE_RUNTIME);
    640             if (ACPI_FAILURE (Status))
    641             {
    642                 ACPI_EXCEPTION ((AE_INFO, Status,
    643                     "Could not enable GPE 0x%02X", GpeNumber));
    644                 continue;
    645             }
    646 
    647             GpeEnabledCount++;
    648         }
    649     }
    650 
    651     if (GpeEnabledCount || WakeGpeCount)
    652     {
    653         ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
    654             "Enabled %u Runtime GPEs, added %u Wake GPEs in this block\n",
    655             GpeEnabledCount, WakeGpeCount));
    656     }
    657 
    658     return_ACPI_STATUS (AE_OK);
    659 }
    660 
    661