Home | History | Annotate | Line # | Download | only in events
      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 - 2025, 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  * Alternatively, you may choose to be licensed under the terms of the
    117  * following license:
    118  *
    119  * Redistribution and use in source and binary forms, with or without
    120  * modification, are permitted provided that the following conditions
    121  * are met:
    122  * 1. Redistributions of source code must retain the above copyright
    123  *    notice, this list of conditions, and the following disclaimer,
    124  *    without modification.
    125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
    126  *    substantially similar to the "NO WARRANTY" disclaimer below
    127  *    ("Disclaimer") and any redistribution must be conditioned upon
    128  *    including a substantially similar Disclaimer requirement for further
    129  *    binary redistribution.
    130  * 3. Neither the names of the above-listed copyright holders nor the names
    131  *    of any contributors may be used to endorse or promote products derived
    132  *    from this software without specific prior written permission.
    133  *
    134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    145  *
    146  * Alternatively, you may choose to be licensed under the terms of the
    147  * GNU General Public License ("GPL") version 2 as published by the Free
    148  * Software Foundation.
    149  *
    150  *****************************************************************************/
    151 
    152 #include "acpi.h"
    153 #include "accommon.h"
    154 #include "acevents.h"
    155 #include "acnamesp.h"
    156 
    157 #define _COMPONENT          ACPI_EVENTS
    158         ACPI_MODULE_NAME    ("evgpeblk")
    159 
    160 #if (!ACPI_REDUCED_HARDWARE) /* Entire module */
    161 
    162 /* Local prototypes */
    163 
    164 static ACPI_STATUS
    165 AcpiEvInstallGpeBlock (
    166     ACPI_GPE_BLOCK_INFO     *GpeBlock,
    167     UINT32                  InterruptNumber);
    168 
    169 static ACPI_STATUS
    170 AcpiEvCreateGpeInfoBlocks (
    171     ACPI_GPE_BLOCK_INFO     *GpeBlock);
    172 
    173 
    174 /*******************************************************************************
    175  *
    176  * FUNCTION:    AcpiEvInstallGpeBlock
    177  *
    178  * PARAMETERS:  GpeBlock                - New GPE block
    179  *              InterruptNumber         - Xrupt to be associated with this
    180  *                                        GPE block
    181  *
    182  * RETURN:      Status
    183  *
    184  * DESCRIPTION: Install new GPE block with mutex support
    185  *
    186  ******************************************************************************/
    187 
    188 static ACPI_STATUS
    189 AcpiEvInstallGpeBlock (
    190     ACPI_GPE_BLOCK_INFO     *GpeBlock,
    191     UINT32                  InterruptNumber)
    192 {
    193     ACPI_GPE_BLOCK_INFO     *NextGpeBlock;
    194     ACPI_GPE_XRUPT_INFO     *GpeXruptBlock;
    195     ACPI_STATUS             Status;
    196     ACPI_CPU_FLAGS          Flags;
    197 
    198 
    199     ACPI_FUNCTION_TRACE (EvInstallGpeBlock);
    200 
    201 
    202     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    203     if (ACPI_FAILURE (Status))
    204     {
    205         return_ACPI_STATUS (Status);
    206     }
    207 
    208     Status = AcpiEvGetGpeXruptBlock (InterruptNumber, &GpeXruptBlock);
    209     if (ACPI_FAILURE (Status))
    210     {
    211         goto UnlockAndExit;
    212     }
    213 
    214     /* Install the new block at the end of the list with lock */
    215 
    216     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
    217     if (GpeXruptBlock->GpeBlockListHead)
    218     {
    219         NextGpeBlock = GpeXruptBlock->GpeBlockListHead;
    220         while (NextGpeBlock->Next)
    221         {
    222             NextGpeBlock = NextGpeBlock->Next;
    223         }
    224 
    225         NextGpeBlock->Next = GpeBlock;
    226         GpeBlock->Previous = NextGpeBlock;
    227     }
    228     else
    229     {
    230         GpeXruptBlock->GpeBlockListHead = GpeBlock;
    231     }
    232 
    233     GpeBlock->XruptBlock = GpeXruptBlock;
    234     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    235 
    236 
    237 UnlockAndExit:
    238     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    239     return_ACPI_STATUS (Status);
    240 }
    241 
    242 
    243 /*******************************************************************************
    244  *
    245  * FUNCTION:    AcpiEvDeleteGpeBlock
    246  *
    247  * PARAMETERS:  GpeBlock            - Existing GPE block
    248  *
    249  * RETURN:      Status
    250  *
    251  * DESCRIPTION: Remove a GPE block
    252  *
    253  ******************************************************************************/
    254 
    255 ACPI_STATUS
    256 AcpiEvDeleteGpeBlock (
    257     ACPI_GPE_BLOCK_INFO     *GpeBlock)
    258 {
    259     ACPI_STATUS             Status;
    260     ACPI_CPU_FLAGS          Flags;
    261 
    262 
    263     ACPI_FUNCTION_TRACE (EvInstallGpeBlock);
    264 
    265 
    266     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    267     if (ACPI_FAILURE (Status))
    268     {
    269         return_ACPI_STATUS (Status);
    270     }
    271 
    272     /* Disable all GPEs in this block */
    273 
    274     Status = AcpiHwDisableGpeBlock (GpeBlock->XruptBlock, GpeBlock, NULL);
    275     if (ACPI_FAILURE (Status))
    276     {
    277         return_ACPI_STATUS (Status);
    278     }
    279 
    280     if (!GpeBlock->Previous && !GpeBlock->Next)
    281     {
    282         /* This is the last GpeBlock on this interrupt */
    283 
    284         Status = AcpiEvDeleteGpeXrupt (GpeBlock->XruptBlock);
    285         if (ACPI_FAILURE (Status))
    286         {
    287             goto UnlockAndExit;
    288         }
    289     }
    290     else
    291     {
    292         /* Remove the block on this interrupt with lock */
    293 
    294         Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
    295         if (GpeBlock->Previous)
    296         {
    297             GpeBlock->Previous->Next = GpeBlock->Next;
    298         }
    299         else
    300         {
    301             GpeBlock->XruptBlock->GpeBlockListHead = GpeBlock->Next;
    302         }
    303 
    304         if (GpeBlock->Next)
    305         {
    306             GpeBlock->Next->Previous = GpeBlock->Previous;
    307         }
    308 
    309         AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    310     }
    311 
    312     AcpiCurrentGpeCount -= GpeBlock->GpeCount;
    313 
    314     /* Free the GpeBlock */
    315 
    316     ACPI_FREE (GpeBlock->RegisterInfo);
    317     ACPI_FREE (GpeBlock->EventInfo);
    318     ACPI_FREE (GpeBlock);
    319 
    320 UnlockAndExit:
    321     Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    322     return_ACPI_STATUS (Status);
    323 }
    324 
    325 
    326 /*******************************************************************************
    327  *
    328  * FUNCTION:    AcpiEvCreateGpeInfoBlocks
    329  *
    330  * PARAMETERS:  GpeBlock    - New GPE block
    331  *
    332  * RETURN:      Status
    333  *
    334  * DESCRIPTION: Create the RegisterInfo and EventInfo blocks for this GPE block
    335  *
    336  ******************************************************************************/
    337 
    338 static ACPI_STATUS
    339 AcpiEvCreateGpeInfoBlocks (
    340     ACPI_GPE_BLOCK_INFO     *GpeBlock)
    341 {
    342     ACPI_GPE_REGISTER_INFO  *GpeRegisterInfo = NULL;
    343     ACPI_GPE_EVENT_INFO     *GpeEventInfo = NULL;
    344     ACPI_GPE_EVENT_INFO     *ThisEvent;
    345     ACPI_GPE_REGISTER_INFO  *ThisRegister;
    346     UINT32                  i;
    347     UINT32                  j;
    348     ACPI_STATUS             Status;
    349 
    350 
    351     ACPI_FUNCTION_TRACE (EvCreateGpeInfoBlocks);
    352 
    353 
    354     /* Allocate the GPE register information block */
    355 
    356     GpeRegisterInfo = ACPI_ALLOCATE_ZEROED (
    357         (ACPI_SIZE) GpeBlock->RegisterCount *
    358         sizeof (ACPI_GPE_REGISTER_INFO));
    359     if (!GpeRegisterInfo)
    360     {
    361         ACPI_ERROR ((AE_INFO,
    362             "Could not allocate the GpeRegisterInfo table"));
    363         return_ACPI_STATUS (AE_NO_MEMORY);
    364     }
    365 
    366     /*
    367      * Allocate the GPE EventInfo block. There are eight distinct GPEs
    368      * per register. Initialization to zeros is sufficient.
    369      */
    370     GpeEventInfo = ACPI_ALLOCATE_ZEROED ((ACPI_SIZE) GpeBlock->GpeCount *
    371         sizeof (ACPI_GPE_EVENT_INFO));
    372     if (!GpeEventInfo)
    373     {
    374         ACPI_ERROR ((AE_INFO,
    375             "Could not allocate the GpeEventInfo table"));
    376         Status = AE_NO_MEMORY;
    377         goto ErrorExit;
    378     }
    379 
    380     /* Save the new Info arrays in the GPE block */
    381 
    382     GpeBlock->RegisterInfo = GpeRegisterInfo;
    383     GpeBlock->EventInfo = GpeEventInfo;
    384 
    385     /*
    386      * Initialize the GPE Register and Event structures. A goal of these
    387      * tables is to hide the fact that there are two separate GPE register
    388      * sets in a given GPE hardware block, the status registers occupy the
    389      * first half, and the enable registers occupy the second half.
    390      */
    391     ThisRegister = GpeRegisterInfo;
    392     ThisEvent = GpeEventInfo;
    393 
    394     for (i = 0; i < GpeBlock->RegisterCount; i++)
    395     {
    396         /* Init the RegisterInfo for this GPE register (8 GPEs) */
    397 
    398         ThisRegister->BaseGpeNumber = (UINT16)
    399             (GpeBlock->BlockBaseNumber + (i * ACPI_GPE_REGISTER_WIDTH));
    400 
    401         ThisRegister->StatusAddress.Address =
    402             GpeBlock->Address + i;
    403 
    404         ThisRegister->EnableAddress.Address =
    405             GpeBlock->Address + i + GpeBlock->RegisterCount;
    406 
    407         ThisRegister->StatusAddress.SpaceId   = GpeBlock->SpaceId;
    408         ThisRegister->EnableAddress.SpaceId   = GpeBlock->SpaceId;
    409         ThisRegister->StatusAddress.BitWidth  = ACPI_GPE_REGISTER_WIDTH;
    410         ThisRegister->EnableAddress.BitWidth  = ACPI_GPE_REGISTER_WIDTH;
    411         ThisRegister->StatusAddress.BitOffset = 0;
    412         ThisRegister->EnableAddress.BitOffset = 0;
    413 
    414         /* Init the EventInfo for each GPE within this register */
    415 
    416         for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++)
    417         {
    418             ThisEvent->GpeNumber = (UINT8) (ThisRegister->BaseGpeNumber + j);
    419             ThisEvent->RegisterInfo = ThisRegister;
    420             ThisEvent++;
    421         }
    422 
    423         /* Disable all GPEs within this register */
    424 
    425         Status = AcpiHwWrite (0x00, &ThisRegister->EnableAddress);
    426         if (ACPI_FAILURE (Status))
    427         {
    428             goto ErrorExit;
    429         }
    430 
    431         /* Clear any pending GPE events within this register */
    432 
    433         Status = AcpiHwWrite (0xFF, &ThisRegister->StatusAddress);
    434         if (ACPI_FAILURE (Status))
    435         {
    436             goto ErrorExit;
    437         }
    438 
    439         ThisRegister++;
    440     }
    441 
    442     return_ACPI_STATUS (AE_OK);
    443 
    444 
    445 ErrorExit:
    446     if (GpeRegisterInfo)
    447     {
    448         ACPI_FREE (GpeRegisterInfo);
    449     }
    450     if (GpeEventInfo)
    451     {
    452         ACPI_FREE (GpeEventInfo);
    453     }
    454 
    455     return_ACPI_STATUS (Status);
    456 }
    457 
    458 
    459 /*******************************************************************************
    460  *
    461  * FUNCTION:    AcpiEvCreateGpeBlock
    462  *
    463  * PARAMETERS:  GpeDevice           - Handle to the parent GPE block
    464  *              GpeBlockAddress     - Address and SpaceID
    465  *              RegisterCount       - Number of GPE register pairs in the block
    466  *              GpeBlockBaseNumber  - Starting GPE number for the block
    467  *              InterruptNumber     - H/W interrupt for the block
    468  *              ReturnGpeBlock      - Where the new block descriptor is returned
    469  *
    470  * RETURN:      Status
    471  *
    472  * DESCRIPTION: Create and Install a block of GPE registers. All GPEs within
    473  *              the block are disabled at exit.
    474  *              Note: Assumes namespace is locked.
    475  *
    476  ******************************************************************************/
    477 
    478 ACPI_STATUS
    479 AcpiEvCreateGpeBlock (
    480     ACPI_NAMESPACE_NODE     *GpeDevice,
    481     UINT64                  Address,
    482     UINT8                   SpaceId,
    483     UINT32                  RegisterCount,
    484     UINT16                  GpeBlockBaseNumber,
    485     UINT32                  InterruptNumber,
    486     ACPI_GPE_BLOCK_INFO     **ReturnGpeBlock)
    487 {
    488     ACPI_STATUS             Status;
    489     ACPI_GPE_BLOCK_INFO     *GpeBlock;
    490     ACPI_GPE_WALK_INFO      WalkInfo;
    491 
    492 
    493     ACPI_FUNCTION_TRACE (EvCreateGpeBlock);
    494 
    495 
    496     if (!RegisterCount)
    497     {
    498         return_ACPI_STATUS (AE_OK);
    499     }
    500 
    501     /* Allocate a new GPE block */
    502 
    503     GpeBlock = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_BLOCK_INFO));
    504     if (!GpeBlock)
    505     {
    506         return_ACPI_STATUS (AE_NO_MEMORY);
    507     }
    508 
    509     /* Initialize the new GPE block */
    510 
    511     GpeBlock->Address = Address;
    512     GpeBlock->SpaceId = SpaceId;
    513     GpeBlock->Node = GpeDevice;
    514     GpeBlock->GpeCount = (UINT16) (RegisterCount * ACPI_GPE_REGISTER_WIDTH);
    515     GpeBlock->Initialized = FALSE;
    516     GpeBlock->RegisterCount = RegisterCount;
    517     GpeBlock->BlockBaseNumber = GpeBlockBaseNumber;
    518 
    519     /*
    520      * Create the RegisterInfo and EventInfo sub-structures
    521      * Note: disables and clears all GPEs in the block
    522      */
    523     Status = AcpiEvCreateGpeInfoBlocks (GpeBlock);
    524     if (ACPI_FAILURE (Status))
    525     {
    526         ACPI_FREE (GpeBlock);
    527         return_ACPI_STATUS (Status);
    528     }
    529 
    530     /* Install the new block in the global lists */
    531 
    532     Status = AcpiEvInstallGpeBlock (GpeBlock, InterruptNumber);
    533     if (ACPI_FAILURE (Status))
    534     {
    535         ACPI_FREE (GpeBlock->RegisterInfo);
    536         ACPI_FREE (GpeBlock->EventInfo);
    537         ACPI_FREE (GpeBlock);
    538         return_ACPI_STATUS (Status);
    539     }
    540 
    541     AcpiGbl_AllGpesInitialized = FALSE;
    542 
    543     /* Find all GPE methods (_Lxx or_Exx) for this block */
    544 
    545     WalkInfo.GpeBlock = GpeBlock;
    546     WalkInfo.GpeDevice = GpeDevice;
    547     WalkInfo.ExecuteByOwnerId = FALSE;
    548 
    549     (void) AcpiNsWalkNamespace (ACPI_TYPE_METHOD, GpeDevice,
    550         ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
    551         AcpiEvMatchGpeMethod, NULL, &WalkInfo, NULL);
    552 
    553     /* Return the new block */
    554 
    555     if (ReturnGpeBlock)
    556     {
    557         (*ReturnGpeBlock) = GpeBlock;
    558     }
    559 
    560     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
    561         "    Initialized GPE %02X to %02X [%4.4s] %u regs on interrupt 0x%X%s\n",
    562         (UINT32) GpeBlock->BlockBaseNumber,
    563         (UINT32) (GpeBlock->BlockBaseNumber + (GpeBlock->GpeCount - 1)),
    564         GpeDevice->Name.Ascii, GpeBlock->RegisterCount, InterruptNumber,
    565         InterruptNumber == AcpiGbl_FADT.SciInterrupt ? " (SCI)" : ""));
    566 
    567     /* Update global count of currently available GPEs */
    568 
    569     AcpiCurrentGpeCount += GpeBlock->GpeCount;
    570     return_ACPI_STATUS (AE_OK);
    571 }
    572 
    573 
    574 /*******************************************************************************
    575  *
    576  * FUNCTION:    AcpiEvInitializeGpeBlock
    577  *
    578  * PARAMETERS:  ACPI_GPE_CALLBACK
    579  *
    580  * RETURN:      Status
    581  *
    582  * DESCRIPTION: Initialize and enable a GPE block. Enable GPEs that have
    583  *              associated methods.
    584  *              Note: Assumes namespace is locked.
    585  *
    586  ******************************************************************************/
    587 
    588 ACPI_STATUS
    589 AcpiEvInitializeGpeBlock (
    590     ACPI_GPE_XRUPT_INFO     *GpeXruptInfo,
    591     ACPI_GPE_BLOCK_INFO     *GpeBlock,
    592     void                    *Context)
    593 {
    594     ACPI_STATUS             Status;
    595     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    596     UINT32                  GpeEnabledCount;
    597     UINT32                  GpeIndex;
    598     UINT32                  i;
    599     UINT32                  j;
    600     BOOLEAN                 *IsPollingNeeded = Context;
    601     ACPI_ERROR_ONLY (UINT32 GpeNumber);
    602 
    603 
    604     ACPI_FUNCTION_TRACE (EvInitializeGpeBlock);
    605 
    606 
    607     /*
    608      * Ignore a null GPE block (e.g., if no GPE block 1 exists), and
    609      * any GPE blocks that have been initialized already.
    610      */
    611     if (!GpeBlock || GpeBlock->Initialized)
    612     {
    613         return_ACPI_STATUS (AE_OK);
    614     }
    615 
    616     /*
    617      * Enable all GPEs that have a corresponding method and have the
    618      * ACPI_GPE_CAN_WAKE flag unset. Any other GPEs within this block
    619      * must be enabled via the acpi_enable_gpe() interface.
    620      */
    621     GpeEnabledCount = 0;
    622 
    623     for (i = 0; i < GpeBlock->RegisterCount; i++)
    624     {
    625         for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++)
    626         {
    627             /* Get the info block for this particular GPE */
    628 
    629             GpeIndex = (i * ACPI_GPE_REGISTER_WIDTH) + j;
    630             GpeEventInfo = &GpeBlock->EventInfo[GpeIndex];
    631             ACPI_ERROR_ONLY(GpeNumber = GpeBlock->BlockBaseNumber + GpeIndex);
    632             GpeEventInfo->Flags |= ACPI_GPE_INITIALIZED;
    633 
    634             /*
    635              * Ignore GPEs that have no corresponding _Lxx/_Exx method
    636              * and GPEs that are used to wake the system
    637              */
    638             if ((ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) != ACPI_GPE_DISPATCH_METHOD) ||
    639                 (GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE))
    640             {
    641                 continue;
    642             }
    643 
    644             Status = AcpiEvAddGpeReference (GpeEventInfo, FALSE);
    645             if (ACPI_FAILURE (Status))
    646             {
    647                 ACPI_EXCEPTION ((AE_INFO, Status,
    648                     "Could not enable GPE 0x%02X",
    649                     GpeNumber));
    650                 continue;
    651             }
    652 
    653             GpeEventInfo->Flags |= ACPI_GPE_AUTO_ENABLED;
    654 
    655             if (IsPollingNeeded &&
    656                 ACPI_GPE_IS_POLLING_NEEDED (GpeEventInfo))
    657             {
    658                 *IsPollingNeeded = TRUE;
    659             }
    660 
    661             GpeEnabledCount++;
    662         }
    663     }
    664 
    665     if (GpeEnabledCount)
    666     {
    667         ACPI_INFO ((
    668             "Enabled %u GPEs in block %02X to %02X", GpeEnabledCount,
    669             (UINT32) GpeBlock->BlockBaseNumber,
    670             (UINT32) (GpeBlock->BlockBaseNumber + (GpeBlock->GpeCount - 1))));
    671     }
    672 
    673     GpeBlock->Initialized = TRUE;
    674     return_ACPI_STATUS (AE_OK);
    675 }
    676 
    677 #endif /* !ACPI_REDUCED_HARDWARE */
    678