Home | History | Annotate | Line # | Download | only in events
      1 /******************************************************************************
      2  *
      3  * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs)
      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 #define EXPORT_ACPI_INTERFACES
    153 
    154 #include "acpi.h"
    155 #include "accommon.h"
    156 #include "acevents.h"
    157 #include "acnamesp.h"
    158 
    159 #define _COMPONENT          ACPI_EVENTS
    160         ACPI_MODULE_NAME    ("evxfgpe")
    161 
    162 
    163 #if (!ACPI_REDUCED_HARDWARE) /* Entire module */
    164 /*******************************************************************************
    165  *
    166  * FUNCTION:    AcpiUpdateAllGpes
    167  *
    168  * PARAMETERS:  None
    169  *
    170  * RETURN:      Status
    171  *
    172  * DESCRIPTION: Complete GPE initialization and enable all GPEs that have
    173  *              associated _Lxx or _Exx methods and are not pointed to by any
    174  *              device _PRW methods (this indicates that these GPEs are
    175  *              generally intended for system or device wakeup. Such GPEs
    176  *              have to be enabled directly when the devices whose _PRW
    177  *              methods point to them are set up for wakeup signaling.)
    178  *
    179  * NOTE: Should be called after any GPEs are added to the system. Primarily,
    180  * after the system _PRW methods have been run, but also after a GPE Block
    181  * Device has been added or if any new GPE methods have been added via a
    182  * dynamic table load.
    183  *
    184  ******************************************************************************/
    185 
    186 ACPI_STATUS
    187 AcpiUpdateAllGpes (
    188     void)
    189 {
    190     ACPI_STATUS             Status;
    191     BOOLEAN                 IsPollingNeeded = FALSE;
    192 
    193 
    194     ACPI_FUNCTION_TRACE (AcpiUpdateAllGpes);
    195 
    196 
    197     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    198     if (ACPI_FAILURE (Status))
    199     {
    200         return_ACPI_STATUS (Status);
    201     }
    202 
    203     if (AcpiGbl_AllGpesInitialized)
    204     {
    205         goto UnlockAndExit;
    206     }
    207 
    208     Status = AcpiEvWalkGpeList (AcpiEvInitializeGpeBlock,
    209         &IsPollingNeeded);
    210     if (ACPI_SUCCESS (Status))
    211     {
    212         AcpiGbl_AllGpesInitialized = TRUE;
    213     }
    214 
    215 UnlockAndExit:
    216     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    217 
    218     if (IsPollingNeeded && AcpiGbl_AllGpesInitialized)
    219     {
    220         /* Poll GPEs to handle already triggered events */
    221 
    222         AcpiEvGpeDetect (AcpiGbl_GpeXruptListHead);
    223     }
    224     return_ACPI_STATUS (Status);
    225 }
    226 
    227 ACPI_EXPORT_SYMBOL (AcpiUpdateAllGpes)
    228 
    229 
    230 /*******************************************************************************
    231  *
    232  * FUNCTION:    AcpiEnableGpe
    233  *
    234  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
    235  *              GpeNumber           - GPE level within the GPE block
    236  *
    237  * RETURN:      Status
    238  *
    239  * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
    240  *              hardware-enabled.
    241  *
    242  ******************************************************************************/
    243 
    244 ACPI_STATUS
    245 AcpiEnableGpe (
    246     ACPI_HANDLE             GpeDevice,
    247     UINT32                  GpeNumber)
    248 {
    249     ACPI_STATUS             Status = AE_BAD_PARAMETER;
    250     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    251     ACPI_CPU_FLAGS          Flags;
    252 
    253 
    254     ACPI_FUNCTION_TRACE (AcpiEnableGpe);
    255 
    256 
    257     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
    258 
    259     /*
    260      * Ensure that we have a valid GPE number and that there is some way
    261      * of handling the GPE (handler or a GPE method). In other words, we
    262      * won't allow a valid GPE to be enabled if there is no way to handle it.
    263      */
    264     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
    265     if (GpeEventInfo)
    266     {
    267         if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) !=
    268             ACPI_GPE_DISPATCH_NONE)
    269         {
    270             Status = AcpiEvAddGpeReference (GpeEventInfo, TRUE);
    271             if (ACPI_SUCCESS (Status) &&
    272                 ACPI_GPE_IS_POLLING_NEEDED (GpeEventInfo))
    273             {
    274                 /* Poll edge-triggered GPEs to handle existing events */
    275 
    276                 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    277                 (void) AcpiEvDetectGpe (
    278                     GpeDevice, GpeEventInfo, GpeNumber);
    279                 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
    280             }
    281         }
    282         else
    283         {
    284             Status = AE_NO_HANDLER;
    285         }
    286     }
    287 
    288     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    289     return_ACPI_STATUS (Status);
    290 }
    291 
    292 ACPI_EXPORT_SYMBOL (AcpiEnableGpe)
    293 
    294 
    295 /*******************************************************************************
    296  *
    297  * FUNCTION:    AcpiDisableGpe
    298  *
    299  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
    300  *              GpeNumber           - GPE level within the GPE block
    301  *
    302  * RETURN:      Status
    303  *
    304  * DESCRIPTION: Remove a reference to a GPE. When the last reference is
    305  *              removed, only then is the GPE disabled (for runtime GPEs), or
    306  *              the GPE mask bit disabled (for wake GPEs)
    307  *
    308  ******************************************************************************/
    309 
    310 ACPI_STATUS
    311 AcpiDisableGpe (
    312     ACPI_HANDLE             GpeDevice,
    313     UINT32                  GpeNumber)
    314 {
    315     ACPI_STATUS             Status = AE_BAD_PARAMETER;
    316     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    317     ACPI_CPU_FLAGS          Flags;
    318 
    319 
    320     ACPI_FUNCTION_TRACE (AcpiDisableGpe);
    321 
    322 
    323     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
    324 
    325     /* Ensure that we have a valid GPE number */
    326 
    327     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
    328     if (GpeEventInfo)
    329     {
    330         Status = AcpiEvRemoveGpeReference (GpeEventInfo);
    331     }
    332 
    333     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    334     return_ACPI_STATUS (Status);
    335 }
    336 
    337 ACPI_EXPORT_SYMBOL (AcpiDisableGpe)
    338 
    339 
    340 /*******************************************************************************
    341  *
    342  * FUNCTION:    AcpiSetGpe
    343  *
    344  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
    345  *              GpeNumber           - GPE level within the GPE block
    346  *              Action              - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
    347  *
    348  * RETURN:      Status
    349  *
    350  * DESCRIPTION: Enable or disable an individual GPE. This function bypasses
    351  *              the reference count mechanism used in the AcpiEnableGpe(),
    352  *              AcpiDisableGpe() interfaces.
    353  *              This API is typically used by the GPE raw handler mode driver
    354  *              to switch between the polling mode and the interrupt mode after
    355  *              the driver has enabled the GPE.
    356  *              The APIs should be invoked in this order:
    357  *               AcpiEnableGpe()              <- Ensure the reference count > 0
    358  *               AcpiSetGpe(ACPI_GPE_DISABLE) <- Enter polling mode
    359  *               AcpiSetGpe(ACPI_GPE_ENABLE)  <- Leave polling mode
    360  *               AcpiDisableGpe()             <- Decrease the reference count
    361  *
    362  * Note: If a GPE is shared by 2 silicon components, then both the drivers
    363  *       should support GPE polling mode or disabling the GPE for long period
    364  *       for one driver may break the other. So use it with care since all
    365  *       firmware _Lxx/_Exx handlers currently rely on the GPE interrupt mode.
    366  *
    367  ******************************************************************************/
    368 
    369 ACPI_STATUS
    370 AcpiSetGpe (
    371     ACPI_HANDLE             GpeDevice,
    372     UINT32                  GpeNumber,
    373     UINT8                   Action)
    374 {
    375     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    376     ACPI_STATUS             Status;
    377     ACPI_CPU_FLAGS          Flags;
    378 
    379 
    380     ACPI_FUNCTION_TRACE (AcpiSetGpe);
    381 
    382 
    383     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
    384 
    385     /* Ensure that we have a valid GPE number */
    386 
    387     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
    388     if (!GpeEventInfo)
    389     {
    390         Status = AE_BAD_PARAMETER;
    391         goto UnlockAndExit;
    392     }
    393 
    394     /* Perform the action */
    395 
    396     switch (Action)
    397     {
    398     case ACPI_GPE_ENABLE:
    399 
    400         Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE);
    401         GpeEventInfo->DisableForDispatch = FALSE;
    402         break;
    403 
    404     case ACPI_GPE_DISABLE:
    405 
    406         Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
    407         GpeEventInfo->DisableForDispatch = TRUE;
    408         break;
    409 
    410     default:
    411 
    412         Status = AE_BAD_PARAMETER;
    413         break;
    414     }
    415 
    416 UnlockAndExit:
    417     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    418     return_ACPI_STATUS (Status);
    419 }
    420 
    421 ACPI_EXPORT_SYMBOL (AcpiSetGpe)
    422 
    423 
    424 /*******************************************************************************
    425  *
    426  * FUNCTION:    AcpiMaskGpe
    427  *
    428  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
    429  *              GpeNumber           - GPE level within the GPE block
    430  *              IsMasked            - Whether the GPE is masked or not
    431  *
    432  * RETURN:      Status
    433  *
    434  * DESCRIPTION: Unconditionally mask/unmask the an individual GPE, ex., to
    435  *              prevent a GPE flooding.
    436  *
    437  ******************************************************************************/
    438 
    439 ACPI_STATUS
    440 AcpiMaskGpe (
    441     ACPI_HANDLE             GpeDevice,
    442     UINT32                  GpeNumber,
    443     BOOLEAN                 IsMasked)
    444 {
    445     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    446     ACPI_STATUS             Status;
    447     ACPI_CPU_FLAGS          Flags;
    448 
    449 
    450     ACPI_FUNCTION_TRACE (AcpiMaskGpe);
    451 
    452 
    453     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
    454 
    455     /* Ensure that we have a valid GPE number */
    456 
    457     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
    458     if (!GpeEventInfo)
    459     {
    460         Status = AE_BAD_PARAMETER;
    461         goto UnlockAndExit;
    462     }
    463 
    464     Status = AcpiEvMaskGpe (GpeEventInfo, IsMasked);
    465 
    466 UnlockAndExit:
    467     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    468     return_ACPI_STATUS (Status);
    469 }
    470 
    471 ACPI_EXPORT_SYMBOL (AcpiMaskGpe)
    472 
    473 
    474 /*******************************************************************************
    475  *
    476  * FUNCTION:    AcpiMarkGpeForWake
    477  *
    478  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
    479  *              GpeNumber           - GPE level within the GPE block
    480  *
    481  * RETURN:      Status
    482  *
    483  * DESCRIPTION: Mark a GPE as having the ability to wake the system. Simply
    484  *              sets the ACPI_GPE_CAN_WAKE flag.
    485  *
    486  * Some potential callers of AcpiSetupGpeForWake may know in advance that
    487  * there won't be any notify handlers installed for device wake notifications
    488  * from the given GPE (one example is a button GPE in Linux). For these cases,
    489  * AcpiMarkGpeForWake should be used instead of AcpiSetupGpeForWake.
    490  * This will set the ACPI_GPE_CAN_WAKE flag for the GPE without trying to
    491  * setup implicit wake notification for it (since there's no handler method).
    492  *
    493  ******************************************************************************/
    494 
    495 ACPI_STATUS
    496 AcpiMarkGpeForWake (
    497     ACPI_HANDLE             GpeDevice,
    498     UINT32                  GpeNumber)
    499 {
    500     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    501     ACPI_STATUS             Status = AE_BAD_PARAMETER;
    502     ACPI_CPU_FLAGS          Flags;
    503 
    504 
    505     ACPI_FUNCTION_TRACE (AcpiMarkGpeForWake);
    506 
    507 
    508     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
    509 
    510     /* Ensure that we have a valid GPE number */
    511 
    512     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
    513     if (GpeEventInfo)
    514     {
    515         /* Mark the GPE as a possible wake event */
    516 
    517         GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
    518         Status = AE_OK;
    519     }
    520 
    521     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    522     return_ACPI_STATUS (Status);
    523 }
    524 
    525 ACPI_EXPORT_SYMBOL (AcpiMarkGpeForWake)
    526 
    527 
    528 /*******************************************************************************
    529  *
    530  * FUNCTION:    AcpiSetupGpeForWake
    531  *
    532  * PARAMETERS:  WakeDevice          - Device associated with the GPE (via _PRW)
    533  *              GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
    534  *              GpeNumber           - GPE level within the GPE block
    535  *
    536  * RETURN:      Status
    537  *
    538  * DESCRIPTION: Mark a GPE as having the ability to wake the system. This
    539  *              interface is intended to be used as the host executes the
    540  *              _PRW methods (Power Resources for Wake) in the system tables.
    541  *              Each _PRW appears under a Device Object (The WakeDevice), and
    542  *              contains the info for the wake GPE associated with the
    543  *              WakeDevice.
    544  *
    545  ******************************************************************************/
    546 
    547 ACPI_STATUS
    548 AcpiSetupGpeForWake (
    549     ACPI_HANDLE             WakeDevice,
    550     ACPI_HANDLE             GpeDevice,
    551     UINT32                  GpeNumber)
    552 {
    553     ACPI_STATUS             Status;
    554     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    555     ACPI_NAMESPACE_NODE     *DeviceNode;
    556     ACPI_GPE_NOTIFY_INFO    *Notify;
    557     ACPI_GPE_NOTIFY_INFO    *NewNotify;
    558     ACPI_CPU_FLAGS          Flags;
    559 
    560 
    561     ACPI_FUNCTION_TRACE (AcpiSetupGpeForWake);
    562 
    563 
    564     /* Parameter Validation */
    565 
    566     if (!WakeDevice)
    567     {
    568         /*
    569          * By forcing WakeDevice to be valid, we automatically enable the
    570          * implicit notify feature on all hosts.
    571          */
    572         return_ACPI_STATUS (AE_BAD_PARAMETER);
    573     }
    574 
    575     /* Handle root object case */
    576 
    577     if (WakeDevice == ACPI_ROOT_OBJECT)
    578     {
    579         DeviceNode = AcpiGbl_RootNode;
    580     }
    581     else
    582     {
    583         DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, WakeDevice);
    584     }
    585 
    586     /* Validate WakeDevice is of type Device */
    587 
    588     if (DeviceNode->Type != ACPI_TYPE_DEVICE)
    589     {
    590         return_ACPI_STATUS (AE_BAD_PARAMETER);
    591     }
    592 
    593     /*
    594      * Allocate a new notify object up front, in case it is needed.
    595      * Memory allocation while holding a spinlock is a big no-no
    596      * on some hosts.
    597      */
    598     NewNotify = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_NOTIFY_INFO));
    599     if (!NewNotify)
    600     {
    601         return_ACPI_STATUS (AE_NO_MEMORY);
    602     }
    603 
    604     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
    605 
    606     /* Ensure that we have a valid GPE number */
    607 
    608     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
    609     if (!GpeEventInfo)
    610     {
    611         Status = AE_BAD_PARAMETER;
    612         goto UnlockAndExit;
    613     }
    614 
    615     /*
    616      * If there is no method or handler for this GPE, then the
    617      * WakeDevice will be notified whenever this GPE fires. This is
    618      * known as an "implicit notify". Note: The GPE is assumed to be
    619      * level-triggered (for windows compatibility).
    620      */
    621     if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
    622         ACPI_GPE_DISPATCH_NONE)
    623     {
    624         /*
    625          * This is the first device for implicit notify on this GPE.
    626          * Just set the flags here, and enter the NOTIFY block below.
    627          */
    628         GpeEventInfo->Flags =
    629             (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED);
    630     }
    631     else if (GpeEventInfo->Flags & ACPI_GPE_AUTO_ENABLED)
    632     {
    633         /*
    634          * A reference to this GPE has been added during the GPE block
    635          * initialization, so drop it now to prevent the GPE from being
    636          * permanently enabled and clear its ACPI_GPE_AUTO_ENABLED flag.
    637          */
    638         (void) AcpiEvRemoveGpeReference (GpeEventInfo);
    639         GpeEventInfo->Flags &= ~ACPI_GPE_AUTO_ENABLED;
    640     }
    641 
    642     /*
    643      * If we already have an implicit notify on this GPE, add
    644      * this device to the notify list.
    645      */
    646     if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
    647         ACPI_GPE_DISPATCH_NOTIFY)
    648     {
    649         /* Ensure that the device is not already in the list */
    650 
    651         Notify = GpeEventInfo->Dispatch.NotifyList;
    652         while (Notify)
    653         {
    654             if (Notify->DeviceNode == DeviceNode)
    655             {
    656                 Status = AE_ALREADY_EXISTS;
    657                 goto UnlockAndExit;
    658             }
    659             Notify = Notify->Next;
    660         }
    661 
    662         /* Add this device to the notify list for this GPE */
    663 
    664         NewNotify->DeviceNode = DeviceNode;
    665         NewNotify->Next = GpeEventInfo->Dispatch.NotifyList;
    666         GpeEventInfo->Dispatch.NotifyList = NewNotify;
    667         NewNotify = NULL;
    668     }
    669 
    670     /* Mark the GPE as a possible wake event */
    671 
    672     GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
    673     Status = AE_OK;
    674 
    675 
    676 UnlockAndExit:
    677     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    678 
    679     /* Delete the notify object if it was not used above */
    680 
    681     if (NewNotify)
    682     {
    683         ACPI_FREE (NewNotify);
    684     }
    685     return_ACPI_STATUS (Status);
    686 }
    687 
    688 ACPI_EXPORT_SYMBOL (AcpiSetupGpeForWake)
    689 
    690 
    691 /*******************************************************************************
    692  *
    693  * FUNCTION:    AcpiSetGpeWakeMask
    694  *
    695  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
    696  *              GpeNumber           - GPE level within the GPE block
    697  *              Action              - Enable or Disable
    698  *
    699  * RETURN:      Status
    700  *
    701  * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must
    702  *              already be marked as a WAKE GPE.
    703  *
    704  ******************************************************************************/
    705 
    706 ACPI_STATUS
    707 AcpiSetGpeWakeMask (
    708     ACPI_HANDLE             GpeDevice,
    709     UINT32                  GpeNumber,
    710     UINT8                   Action)
    711 {
    712     ACPI_STATUS             Status = AE_OK;
    713     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    714     ACPI_GPE_REGISTER_INFO  *GpeRegisterInfo;
    715     ACPI_CPU_FLAGS          Flags;
    716     UINT32                  RegisterBit;
    717 
    718 
    719     ACPI_FUNCTION_TRACE (AcpiSetGpeWakeMask);
    720 
    721 
    722     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
    723 
    724     /*
    725      * Ensure that we have a valid GPE number and that this GPE is in
    726      * fact a wake GPE
    727      */
    728     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
    729     if (!GpeEventInfo)
    730     {
    731         Status = AE_BAD_PARAMETER;
    732         goto UnlockAndExit;
    733     }
    734 
    735     if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE))
    736     {
    737         Status = AE_TYPE;
    738         goto UnlockAndExit;
    739     }
    740 
    741     GpeRegisterInfo = GpeEventInfo->RegisterInfo;
    742     if (!GpeRegisterInfo)
    743     {
    744         Status = AE_NOT_EXIST;
    745         goto UnlockAndExit;
    746     }
    747 
    748     RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo);
    749 
    750     /* Perform the action */
    751 
    752     switch (Action)
    753     {
    754     case ACPI_GPE_ENABLE:
    755 
    756         ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
    757         break;
    758 
    759     case ACPI_GPE_DISABLE:
    760 
    761         ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
    762         break;
    763 
    764     default:
    765 
    766         ACPI_ERROR ((AE_INFO, "%u, Invalid action", Action));
    767         Status = AE_BAD_PARAMETER;
    768         break;
    769     }
    770 
    771 UnlockAndExit:
    772     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    773     return_ACPI_STATUS (Status);
    774 }
    775 
    776 ACPI_EXPORT_SYMBOL (AcpiSetGpeWakeMask)
    777 
    778 
    779 /*******************************************************************************
    780  *
    781  * FUNCTION:    AcpiClearGpe
    782  *
    783  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
    784  *              GpeNumber           - GPE level within the GPE block
    785  *
    786  * RETURN:      Status
    787  *
    788  * DESCRIPTION: Clear an ACPI event (general purpose)
    789  *
    790  ******************************************************************************/
    791 
    792 ACPI_STATUS
    793 AcpiClearGpe (
    794     ACPI_HANDLE             GpeDevice,
    795     UINT32                  GpeNumber)
    796 {
    797     ACPI_STATUS             Status = AE_OK;
    798     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    799     ACPI_CPU_FLAGS          Flags;
    800 
    801 
    802     ACPI_FUNCTION_TRACE (AcpiClearGpe);
    803 
    804 
    805     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
    806 
    807     /* Ensure that we have a valid GPE number */
    808 
    809     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
    810     if (!GpeEventInfo)
    811     {
    812         Status = AE_BAD_PARAMETER;
    813         goto UnlockAndExit;
    814     }
    815 
    816     Status = AcpiHwClearGpe (GpeEventInfo);
    817 
    818 UnlockAndExit:
    819     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    820     return_ACPI_STATUS (Status);
    821 }
    822 
    823 ACPI_EXPORT_SYMBOL (AcpiClearGpe)
    824 
    825 
    826 /*******************************************************************************
    827  *
    828  * FUNCTION:    AcpiGetGpeStatus
    829  *
    830  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
    831  *              GpeNumber           - GPE level within the GPE block
    832  *              EventStatus         - Where the current status of the event
    833  *                                    will be returned
    834  *
    835  * RETURN:      Status
    836  *
    837  * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled)
    838  *
    839  ******************************************************************************/
    840 
    841 ACPI_STATUS
    842 AcpiGetGpeStatus (
    843     ACPI_HANDLE             GpeDevice,
    844     UINT32                  GpeNumber,
    845     ACPI_EVENT_STATUS       *EventStatus)
    846 {
    847     ACPI_STATUS             Status = AE_OK;
    848     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    849     ACPI_CPU_FLAGS          Flags;
    850 
    851 
    852     ACPI_FUNCTION_TRACE (AcpiGetGpeStatus);
    853 
    854 
    855     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
    856 
    857     /* Ensure that we have a valid GPE number */
    858 
    859     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
    860     if (!GpeEventInfo)
    861     {
    862         Status = AE_BAD_PARAMETER;
    863         goto UnlockAndExit;
    864     }
    865 
    866     /* Obtain status on the requested GPE number */
    867 
    868     Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus);
    869 
    870 UnlockAndExit:
    871     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    872     return_ACPI_STATUS (Status);
    873 }
    874 
    875 ACPI_EXPORT_SYMBOL (AcpiGetGpeStatus)
    876 
    877 
    878 /*******************************************************************************
    879  *
    880  * FUNCTION:    AcpiDispatchGpe
    881  *
    882  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
    883  *              GpeNumber           - GPE level within the GPE block
    884  *
    885  * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
    886  *
    887  * DESCRIPTION: Detect and dispatch a General Purpose Event to either a function
    888  *              (e.g. EC) or method (e.g. _Lxx/_Exx) handler.
    889  *
    890  ******************************************************************************/
    891 
    892 UINT32
    893 AcpiDispatchGpe(
    894     ACPI_HANDLE             GpeDevice,
    895     UINT32                  GpeNumber)
    896 {
    897     ACPI_FUNCTION_TRACE(acpi_dispatch_gpe);
    898 
    899     return (AcpiEvDetectGpe (GpeDevice, NULL, GpeNumber));
    900 }
    901 
    902 ACPI_EXPORT_SYMBOL (AcpiDispatchGpe)
    903 
    904 
    905 /*******************************************************************************
    906  *
    907  * FUNCTION:    AcpiFinishGpe
    908  *
    909  * PARAMETERS:  GpeDevice           - Namespace node for the GPE Block
    910  *                                    (NULL for FADT defined GPEs)
    911  *              GpeNumber           - GPE level within the GPE block
    912  *
    913  * RETURN:      Status
    914  *
    915  * DESCRIPTION: Clear and conditionally re-enable a GPE. This completes the GPE
    916  *              processing. Intended for use by asynchronous host-installed
    917  *              GPE handlers. The GPE is only re-enabled if the EnableForRun bit
    918  *              is set in the GPE info.
    919  *
    920  ******************************************************************************/
    921 
    922 ACPI_STATUS
    923 AcpiFinishGpe (
    924     ACPI_HANDLE             GpeDevice,
    925     UINT32                  GpeNumber)
    926 {
    927     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    928     ACPI_STATUS             Status;
    929     ACPI_CPU_FLAGS          Flags;
    930 
    931 
    932     ACPI_FUNCTION_TRACE (AcpiFinishGpe);
    933 
    934 
    935     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
    936 
    937     /* Ensure that we have a valid GPE number */
    938 
    939     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
    940     if (!GpeEventInfo)
    941     {
    942         Status = AE_BAD_PARAMETER;
    943         goto UnlockAndExit;
    944     }
    945 
    946     Status = AcpiEvFinishGpe (GpeEventInfo);
    947 
    948 UnlockAndExit:
    949     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    950     return_ACPI_STATUS (Status);
    951 }
    952 
    953 ACPI_EXPORT_SYMBOL (AcpiFinishGpe)
    954 
    955 
    956 /******************************************************************************
    957  *
    958  * FUNCTION:    AcpiDisableAllGpes
    959  *
    960  * PARAMETERS:  None
    961  *
    962  * RETURN:      Status
    963  *
    964  * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
    965  *
    966  ******************************************************************************/
    967 
    968 ACPI_STATUS
    969 AcpiDisableAllGpes (
    970     void)
    971 {
    972     ACPI_STATUS             Status;
    973 
    974 
    975     ACPI_FUNCTION_TRACE (AcpiDisableAllGpes);
    976 
    977 
    978     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    979     if (ACPI_FAILURE (Status))
    980     {
    981         return_ACPI_STATUS (Status);
    982     }
    983 
    984     Status = AcpiHwDisableAllGpes ();
    985     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    986 
    987     return_ACPI_STATUS (Status);
    988 }
    989 
    990 ACPI_EXPORT_SYMBOL (AcpiDisableAllGpes)
    991 
    992 
    993 /******************************************************************************
    994  *
    995  * FUNCTION:    AcpiEnableAllRuntimeGpes
    996  *
    997  * PARAMETERS:  None
    998  *
    999  * RETURN:      Status
   1000  *
   1001  * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
   1002  *
   1003  ******************************************************************************/
   1004 
   1005 ACPI_STATUS
   1006 AcpiEnableAllRuntimeGpes (
   1007     void)
   1008 {
   1009     ACPI_STATUS             Status;
   1010 
   1011 
   1012     ACPI_FUNCTION_TRACE (AcpiEnableAllRuntimeGpes);
   1013 
   1014 
   1015     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
   1016     if (ACPI_FAILURE (Status))
   1017     {
   1018         return_ACPI_STATUS (Status);
   1019     }
   1020 
   1021     Status = AcpiHwEnableAllRuntimeGpes ();
   1022     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
   1023 
   1024     return_ACPI_STATUS (Status);
   1025 }
   1026 
   1027 ACPI_EXPORT_SYMBOL (AcpiEnableAllRuntimeGpes)
   1028 
   1029 
   1030 /******************************************************************************
   1031  *
   1032  * FUNCTION:    AcpiEnableAllWakeupGpes
   1033  *
   1034  * PARAMETERS:  None
   1035  *
   1036  * RETURN:      Status
   1037  *
   1038  * DESCRIPTION: Enable all "wakeup" GPEs and disable all of the other GPEs, in
   1039  *              all GPE blocks.
   1040  *
   1041  ******************************************************************************/
   1042 
   1043 ACPI_STATUS
   1044 AcpiEnableAllWakeupGpes (
   1045     void)
   1046 {
   1047     ACPI_STATUS             Status;
   1048 
   1049 
   1050     ACPI_FUNCTION_TRACE (AcpiEnableAllWakeupGpes);
   1051 
   1052 
   1053     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
   1054     if (ACPI_FAILURE (Status))
   1055     {
   1056         return_ACPI_STATUS (Status);
   1057     }
   1058 
   1059     Status = AcpiHwEnableAllWakeupGpes ();
   1060     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
   1061 
   1062     return_ACPI_STATUS (Status);
   1063 }
   1064 
   1065 ACPI_EXPORT_SYMBOL (AcpiEnableAllWakeupGpes)
   1066 
   1067 
   1068 /******************************************************************************
   1069  *
   1070  * FUNCTION:    AcpiAnyGpeStatusSet
   1071  *
   1072  * PARAMETERS:  None
   1073  *
   1074  * RETURN:      Whether or not the status bit is set for any GPE
   1075  *
   1076  * DESCRIPTION: Check the status bits of all enabled GPEs and return TRUE if any
   1077  *              of them is set or FALSE otherwise.
   1078  *
   1079  ******************************************************************************/
   1080 
   1081 UINT32
   1082 AcpiAnyGpeStatusSet (
   1083     void)
   1084 {
   1085     ACPI_STATUS                Status;
   1086     UINT8                      Ret;
   1087 
   1088 
   1089     ACPI_FUNCTION_TRACE (AcpiAnyGpeStatusSet);
   1090 
   1091     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
   1092     if (ACPI_FAILURE (Status))
   1093     {
   1094         return (FALSE);
   1095     }
   1096 
   1097     Ret = AcpiHwCheckAllGpes ();
   1098     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
   1099 
   1100     return (Ret);
   1101 }
   1102 
   1103 ACPI_EXPORT_SYMBOL(AcpiAnyGpeStatusSet)
   1104 
   1105 
   1106 /*******************************************************************************
   1107  *
   1108  * FUNCTION:    AcpiInstallGpeBlock
   1109  *
   1110  * PARAMETERS:  GpeDevice           - Handle to the parent GPE Block Device
   1111  *              GpeBlockAddress     - Address and SpaceID
   1112  *              RegisterCount       - Number of GPE register pairs in the block
   1113  *              InterruptNumber     - H/W interrupt for the block
   1114  *
   1115  * RETURN:      Status
   1116  *
   1117  * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not
   1118  *              enabled here.
   1119  *
   1120  ******************************************************************************/
   1121 
   1122 ACPI_STATUS
   1123 AcpiInstallGpeBlock (
   1124     ACPI_HANDLE             GpeDevice,
   1125     ACPI_GENERIC_ADDRESS    *GpeBlockAddress,
   1126     UINT32                  RegisterCount,
   1127     UINT32                  InterruptNumber)
   1128 {
   1129     ACPI_STATUS             Status;
   1130     ACPI_OPERAND_OBJECT     *ObjDesc;
   1131     ACPI_NAMESPACE_NODE     *Node;
   1132     ACPI_GPE_BLOCK_INFO     *GpeBlock;
   1133 
   1134 
   1135     ACPI_FUNCTION_TRACE (AcpiInstallGpeBlock);
   1136 
   1137 
   1138     if ((!GpeDevice)       ||
   1139         (!GpeBlockAddress) ||
   1140         (!RegisterCount))
   1141     {
   1142         return_ACPI_STATUS (AE_BAD_PARAMETER);
   1143     }
   1144 
   1145     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
   1146     if (ACPI_FAILURE (Status))
   1147     {
   1148         return_ACPI_STATUS (Status);
   1149     }
   1150 
   1151     Node = AcpiNsValidateHandle (GpeDevice);
   1152     if (!Node)
   1153     {
   1154         Status = AE_BAD_PARAMETER;
   1155         goto UnlockAndExit;
   1156     }
   1157 
   1158     /* Validate the parent device */
   1159 
   1160     if (Node->Type != ACPI_TYPE_DEVICE)
   1161     {
   1162         Status = AE_TYPE;
   1163         goto UnlockAndExit;
   1164     }
   1165 
   1166     if (Node->Object)
   1167     {
   1168         Status = AE_ALREADY_EXISTS;
   1169         goto UnlockAndExit;
   1170     }
   1171 
   1172     /*
   1173      * For user-installed GPE Block Devices, the GpeBlockBaseNumber
   1174      * is always zero
   1175      */
   1176     Status = AcpiEvCreateGpeBlock (Node, GpeBlockAddress->Address,
   1177         GpeBlockAddress->SpaceId, RegisterCount,
   1178         0, InterruptNumber, &GpeBlock);
   1179     if (ACPI_FAILURE (Status))
   1180     {
   1181         goto UnlockAndExit;
   1182     }
   1183 
   1184     /* Install block in the DeviceObject attached to the node */
   1185 
   1186     ObjDesc = AcpiNsGetAttachedObject (Node);
   1187     if (!ObjDesc)
   1188     {
   1189         /*
   1190          * No object, create a new one (Device nodes do not always have
   1191          * an attached object)
   1192          */
   1193         ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_DEVICE);
   1194         if (!ObjDesc)
   1195         {
   1196             Status = AE_NO_MEMORY;
   1197             goto UnlockAndExit;
   1198         }
   1199 
   1200         Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_DEVICE);
   1201 
   1202         /* Remove local reference to the object */
   1203 
   1204         AcpiUtRemoveReference (ObjDesc);
   1205         if (ACPI_FAILURE (Status))
   1206         {
   1207             goto UnlockAndExit;
   1208         }
   1209     }
   1210 
   1211     /* Now install the GPE block in the DeviceObject */
   1212 
   1213     ObjDesc->Device.GpeBlock = GpeBlock;
   1214 
   1215 
   1216 UnlockAndExit:
   1217     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
   1218     return_ACPI_STATUS (Status);
   1219 }
   1220 
   1221 ACPI_EXPORT_SYMBOL (AcpiInstallGpeBlock)
   1222 
   1223 
   1224 /*******************************************************************************
   1225  *
   1226  * FUNCTION:    AcpiRemoveGpeBlock
   1227  *
   1228  * PARAMETERS:  GpeDevice           - Handle to the parent GPE Block Device
   1229  *
   1230  * RETURN:      Status
   1231  *
   1232  * DESCRIPTION: Remove a previously installed block of GPE registers
   1233  *
   1234  ******************************************************************************/
   1235 
   1236 ACPI_STATUS
   1237 AcpiRemoveGpeBlock (
   1238     ACPI_HANDLE             GpeDevice)
   1239 {
   1240     ACPI_OPERAND_OBJECT     *ObjDesc;
   1241     ACPI_STATUS             Status;
   1242     ACPI_NAMESPACE_NODE     *Node;
   1243 
   1244 
   1245     ACPI_FUNCTION_TRACE (AcpiRemoveGpeBlock);
   1246 
   1247 
   1248     if (!GpeDevice)
   1249     {
   1250         return_ACPI_STATUS (AE_BAD_PARAMETER);
   1251     }
   1252 
   1253     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
   1254     if (ACPI_FAILURE (Status))
   1255     {
   1256         return_ACPI_STATUS (Status);
   1257     }
   1258 
   1259     Node = AcpiNsValidateHandle (GpeDevice);
   1260     if (!Node)
   1261     {
   1262         Status = AE_BAD_PARAMETER;
   1263         goto UnlockAndExit;
   1264     }
   1265 
   1266     /* Validate the parent device */
   1267 
   1268     if (Node->Type != ACPI_TYPE_DEVICE)
   1269     {
   1270         Status = AE_TYPE;
   1271         goto UnlockAndExit;
   1272     }
   1273 
   1274     /* Get the DeviceObject attached to the node */
   1275 
   1276     ObjDesc = AcpiNsGetAttachedObject (Node);
   1277     if (!ObjDesc ||
   1278         !ObjDesc->Device.GpeBlock)
   1279     {
   1280         return_ACPI_STATUS (AE_NULL_OBJECT);
   1281     }
   1282 
   1283     /* Delete the GPE block (but not the DeviceObject) */
   1284 
   1285     Status = AcpiEvDeleteGpeBlock (ObjDesc->Device.GpeBlock);
   1286     if (ACPI_SUCCESS (Status))
   1287     {
   1288         ObjDesc->Device.GpeBlock = NULL;
   1289     }
   1290 
   1291 UnlockAndExit:
   1292     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
   1293     return_ACPI_STATUS (Status);
   1294 }
   1295 
   1296 ACPI_EXPORT_SYMBOL (AcpiRemoveGpeBlock)
   1297 
   1298 
   1299 /*******************************************************************************
   1300  *
   1301  * FUNCTION:    AcpiGetGpeDevice
   1302  *
   1303  * PARAMETERS:  Index               - System GPE index (0-CurrentGpeCount)
   1304  *              GpeDevice           - Where the parent GPE Device is returned
   1305  *
   1306  * RETURN:      Status
   1307  *
   1308  * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
   1309  *              gpe device indicates that the gpe number is contained in one of
   1310  *              the FADT-defined gpe blocks. Otherwise, the GPE block device.
   1311  *
   1312  ******************************************************************************/
   1313 
   1314 ACPI_STATUS
   1315 AcpiGetGpeDevice (
   1316     UINT32                  Index,
   1317     ACPI_HANDLE             *GpeDevice)
   1318 {
   1319     ACPI_GPE_DEVICE_INFO    Info;
   1320     ACPI_STATUS             Status;
   1321 
   1322 
   1323     ACPI_FUNCTION_TRACE (AcpiGetGpeDevice);
   1324 
   1325 
   1326     if (!GpeDevice)
   1327     {
   1328         return_ACPI_STATUS (AE_BAD_PARAMETER);
   1329     }
   1330 
   1331     if (Index >= AcpiCurrentGpeCount)
   1332     {
   1333         return_ACPI_STATUS (AE_NOT_EXIST);
   1334     }
   1335 
   1336     /* Setup and walk the GPE list */
   1337 
   1338     Info.Index = Index;
   1339     Info.Status = AE_NOT_EXIST;
   1340     Info.GpeDevice = NULL;
   1341     Info.NextBlockBaseIndex = 0;
   1342 
   1343     Status = AcpiEvWalkGpeList (AcpiEvGetGpeDevice, &Info);
   1344     if (ACPI_FAILURE (Status))
   1345     {
   1346         return_ACPI_STATUS (Status);
   1347     }
   1348 
   1349     *GpeDevice = ACPI_CAST_PTR (ACPI_HANDLE, Info.GpeDevice);
   1350     return_ACPI_STATUS (Info.Status);
   1351 }
   1352 
   1353 ACPI_EXPORT_SYMBOL (AcpiGetGpeDevice)
   1354 
   1355 #endif /* !ACPI_REDUCED_HARDWARE */
   1356