Home | History | Annotate | Line # | Download | only in events
      1 /******************************************************************************
      2  *
      3  * Module Name: evxface - External interfaces for ACPI events
      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 "acnamesp.h"
    157 #include "acevents.h"
    158 #include "acinterp.h"
    159 
    160 #define _COMPONENT          ACPI_EVENTS
    161         ACPI_MODULE_NAME    ("evxface")
    162 
    163 #if (!ACPI_REDUCED_HARDWARE)
    164 
    165 /* Local prototypes */
    166 
    167 static ACPI_STATUS
    168 AcpiEvInstallGpeHandler (
    169     ACPI_HANDLE             GpeDevice,
    170     UINT32                  GpeNumber,
    171     UINT32                  Type,
    172     BOOLEAN                 IsRawHandler,
    173     ACPI_GPE_HANDLER        Address,
    174     void                    *Context);
    175 
    176 #endif
    177 
    178 
    179 /*******************************************************************************
    180  *
    181  * FUNCTION:    AcpiInstallNotifyHandler
    182  *
    183  * PARAMETERS:  Device          - The device for which notifies will be handled
    184  *              HandlerType     - The type of handler:
    185  *                                  ACPI_SYSTEM_NOTIFY: System Handler (00-7F)
    186  *                                  ACPI_DEVICE_NOTIFY: Device Handler (80-FF)
    187  *                                  ACPI_ALL_NOTIFY:    Both System and Device
    188  *              Handler         - Address of the handler
    189  *              Context         - Value passed to the handler on each GPE
    190  *
    191  * RETURN:      Status
    192  *
    193  * DESCRIPTION: Install a handler for notifications on an ACPI Device,
    194  *              ThermalZone, or Processor object.
    195  *
    196  * NOTES:       The Root namespace object may have only one handler for each
    197  *              type of notify (System/Device). Device/Thermal/Processor objects
    198  *              may have one device notify handler, and multiple system notify
    199  *              handlers.
    200  *
    201  ******************************************************************************/
    202 
    203 ACPI_STATUS
    204 AcpiInstallNotifyHandler (
    205     ACPI_HANDLE             Device,
    206     UINT32                  HandlerType,
    207     ACPI_NOTIFY_HANDLER     Handler,
    208     void                    *Context)
    209 {
    210     ACPI_NAMESPACE_NODE     *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device);
    211     ACPI_OPERAND_OBJECT     *ObjDesc;
    212     ACPI_OPERAND_OBJECT     *HandlerObj;
    213     ACPI_STATUS             Status;
    214     UINT32                  i;
    215 
    216 
    217     ACPI_FUNCTION_TRACE (AcpiInstallNotifyHandler);
    218 
    219 
    220     /* Parameter validation */
    221 
    222     if ((!Device) || (!Handler) || (!HandlerType) ||
    223         (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
    224     {
    225         return_ACPI_STATUS (AE_BAD_PARAMETER);
    226     }
    227 
    228     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
    229     if (ACPI_FAILURE (Status))
    230     {
    231         return_ACPI_STATUS (Status);
    232     }
    233 
    234     /*
    235      * Root Object:
    236      * Registering a notify handler on the root object indicates that the
    237      * caller wishes to receive notifications for all objects. Note that
    238      * only one global handler can be registered per notify type.
    239      * Ensure that a handler is not already installed.
    240      */
    241     if (Device == ACPI_ROOT_OBJECT)
    242     {
    243         for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
    244         {
    245             if (HandlerType & (i+1))
    246             {
    247                 if (AcpiGbl_GlobalNotify[i].Handler)
    248                 {
    249                     Status = AE_ALREADY_EXISTS;
    250                     goto UnlockAndExit;
    251                 }
    252 
    253                 AcpiGbl_GlobalNotify[i].Handler = Handler;
    254                 AcpiGbl_GlobalNotify[i].Context = Context;
    255             }
    256         }
    257 
    258         goto UnlockAndExit; /* Global notify handler installed, all done */
    259     }
    260 
    261     /*
    262      * All Other Objects:
    263      * Caller will only receive notifications specific to the target
    264      * object. Note that only certain object types are allowed to
    265      * receive notifications.
    266      */
    267 
    268     /* Are Notifies allowed on this object? */
    269 
    270     if (!AcpiEvIsNotifyObject (Node))
    271     {
    272         Status = AE_TYPE;
    273         goto UnlockAndExit;
    274     }
    275 
    276     /* Check for an existing internal object, might not exist */
    277 
    278     ObjDesc = AcpiNsGetAttachedObject (Node);
    279     if (!ObjDesc)
    280     {
    281         /* Create a new object */
    282 
    283         ObjDesc = AcpiUtCreateInternalObject (Node->Type);
    284         if (!ObjDesc)
    285         {
    286             Status = AE_NO_MEMORY;
    287             goto UnlockAndExit;
    288         }
    289 
    290         /* Attach new object to the Node, remove local reference */
    291 
    292         Status = AcpiNsAttachObject (Device, ObjDesc, Node->Type);
    293         AcpiUtRemoveReference (ObjDesc);
    294         if (ACPI_FAILURE (Status))
    295         {
    296             goto UnlockAndExit;
    297         }
    298     }
    299 
    300     /* Ensure that the handler is not already installed in the lists */
    301 
    302     for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
    303     {
    304         if (HandlerType & (i+1))
    305         {
    306             HandlerObj = ObjDesc->CommonNotify.NotifyList[i];
    307             while (HandlerObj)
    308             {
    309                 if (HandlerObj->Notify.Handler == Handler)
    310                 {
    311                     Status = AE_ALREADY_EXISTS;
    312                     goto UnlockAndExit;
    313                 }
    314 
    315                 HandlerObj = HandlerObj->Notify.Next[i];
    316             }
    317         }
    318     }
    319 
    320     /* Create and populate a new notify handler object */
    321 
    322     HandlerObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_NOTIFY);
    323     if (!HandlerObj)
    324     {
    325         Status = AE_NO_MEMORY;
    326         goto UnlockAndExit;
    327     }
    328 
    329     HandlerObj->Notify.Node = Node;
    330     HandlerObj->Notify.HandlerType = HandlerType;
    331     HandlerObj->Notify.Handler = Handler;
    332     HandlerObj->Notify.Context = Context;
    333 
    334     /* Install the handler at the list head(s) */
    335 
    336     for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
    337     {
    338         if (HandlerType & (i+1))
    339         {
    340             HandlerObj->Notify.Next[i] =
    341                 ObjDesc->CommonNotify.NotifyList[i];
    342 
    343             ObjDesc->CommonNotify.NotifyList[i] = HandlerObj;
    344         }
    345     }
    346 
    347     /* Add an extra reference if handler was installed in both lists */
    348 
    349     if (HandlerType == ACPI_ALL_NOTIFY)
    350     {
    351         AcpiUtAddReference (HandlerObj);
    352     }
    353 
    354 
    355 UnlockAndExit:
    356     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
    357     return_ACPI_STATUS (Status);
    358 }
    359 
    360 ACPI_EXPORT_SYMBOL (AcpiInstallNotifyHandler)
    361 
    362 
    363 /*******************************************************************************
    364  *
    365  * FUNCTION:    AcpiRemoveNotifyHandler
    366  *
    367  * PARAMETERS:  Device          - The device for which the handler is installed
    368  *              HandlerType     - The type of handler:
    369  *                                  ACPI_SYSTEM_NOTIFY: System Handler (00-7F)
    370  *                                  ACPI_DEVICE_NOTIFY: Device Handler (80-FF)
    371  *                                  ACPI_ALL_NOTIFY:    Both System and Device
    372  *              Handler         - Address of the handler
    373  *
    374  * RETURN:      Status
    375  *
    376  * DESCRIPTION: Remove a handler for notifies on an ACPI device
    377  *
    378  ******************************************************************************/
    379 
    380 ACPI_STATUS
    381 AcpiRemoveNotifyHandler (
    382     ACPI_HANDLE             Device,
    383     UINT32                  HandlerType,
    384     ACPI_NOTIFY_HANDLER     Handler)
    385 {
    386     ACPI_NAMESPACE_NODE     *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device);
    387     ACPI_OPERAND_OBJECT     *ObjDesc;
    388     ACPI_OPERAND_OBJECT     *HandlerObj;
    389     ACPI_OPERAND_OBJECT     *PreviousHandlerObj;
    390     ACPI_STATUS             Status = AE_OK;
    391     UINT32                  i;
    392 
    393 
    394     ACPI_FUNCTION_TRACE (AcpiRemoveNotifyHandler);
    395 
    396 
    397     /* Parameter validation */
    398 
    399     if ((!Device) || (!Handler) || (!HandlerType) ||
    400         (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
    401     {
    402         return_ACPI_STATUS (AE_BAD_PARAMETER);
    403     }
    404 
    405     /* Root Object. Global handlers are removed here */
    406 
    407     if (Device == ACPI_ROOT_OBJECT)
    408     {
    409         for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
    410         {
    411             if (HandlerType & (i+1))
    412             {
    413                 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
    414                 if (ACPI_FAILURE (Status))
    415                 {
    416                     return_ACPI_STATUS (Status);
    417                 }
    418 
    419                 if (!AcpiGbl_GlobalNotify[i].Handler ||
    420                     (AcpiGbl_GlobalNotify[i].Handler != Handler))
    421                 {
    422                     Status = AE_NOT_EXIST;
    423                     goto UnlockAndExit;
    424                 }
    425 
    426                 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
    427                     "Removing global notify handler\n"));
    428 
    429                 AcpiGbl_GlobalNotify[i].Handler = NULL;
    430                 AcpiGbl_GlobalNotify[i].Context = NULL;
    431 
    432                 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
    433 
    434                 /* Make sure all deferred notify tasks are completed */
    435 
    436                 AcpiOsWaitEventsComplete ();
    437             }
    438         }
    439 
    440         return_ACPI_STATUS (AE_OK);
    441     }
    442 
    443     /* All other objects: Are Notifies allowed on this object? */
    444 
    445     if (!AcpiEvIsNotifyObject (Node))
    446     {
    447         return_ACPI_STATUS (AE_TYPE);
    448     }
    449 
    450     /* Must have an existing internal object */
    451 
    452     ObjDesc = AcpiNsGetAttachedObject (Node);
    453     if (!ObjDesc)
    454     {
    455         return_ACPI_STATUS (AE_NOT_EXIST);
    456     }
    457 
    458     /* Internal object exists. Find the handler and remove it */
    459 
    460     for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
    461     {
    462         if (HandlerType & (i+1))
    463         {
    464             Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
    465             if (ACPI_FAILURE (Status))
    466             {
    467                 return_ACPI_STATUS (Status);
    468             }
    469 
    470             HandlerObj = ObjDesc->CommonNotify.NotifyList[i];
    471             PreviousHandlerObj = NULL;
    472 
    473             /* Attempt to find the handler in the handler list */
    474 
    475             while (HandlerObj &&
    476                   (HandlerObj->Notify.Handler != Handler))
    477             {
    478                 PreviousHandlerObj = HandlerObj;
    479                 HandlerObj = HandlerObj->Notify.Next[i];
    480             }
    481 
    482             if (!HandlerObj)
    483             {
    484                 Status = AE_NOT_EXIST;
    485                 goto UnlockAndExit;
    486             }
    487 
    488             /* Remove the handler object from the list */
    489 
    490             if (PreviousHandlerObj) /* Handler is not at the list head */
    491             {
    492                 PreviousHandlerObj->Notify.Next[i] =
    493                     HandlerObj->Notify.Next[i];
    494             }
    495             else /* Handler is at the list head */
    496             {
    497                 ObjDesc->CommonNotify.NotifyList[i] =
    498                     HandlerObj->Notify.Next[i];
    499             }
    500 
    501             (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
    502 
    503             /* Make sure all deferred notify tasks are completed */
    504 
    505             AcpiOsWaitEventsComplete ();
    506             AcpiUtRemoveReference (HandlerObj);
    507         }
    508     }
    509 
    510     return_ACPI_STATUS (Status);
    511 
    512 
    513 UnlockAndExit:
    514     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
    515     return_ACPI_STATUS (Status);
    516 }
    517 
    518 ACPI_EXPORT_SYMBOL (AcpiRemoveNotifyHandler)
    519 
    520 
    521 /*******************************************************************************
    522  *
    523  * FUNCTION:    AcpiInstallExceptionHandler
    524  *
    525  * PARAMETERS:  Handler         - Pointer to the handler function for the
    526  *                                event
    527  *
    528  * RETURN:      Status
    529  *
    530  * DESCRIPTION: Saves the pointer to the handler function
    531  *
    532  ******************************************************************************/
    533 
    534 ACPI_STATUS
    535 AcpiInstallExceptionHandler (
    536     ACPI_EXCEPTION_HANDLER  Handler)
    537 {
    538     ACPI_STATUS             Status;
    539 
    540 
    541     ACPI_FUNCTION_TRACE (AcpiInstallExceptionHandler);
    542 
    543 
    544     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    545     if (ACPI_FAILURE (Status))
    546     {
    547         return_ACPI_STATUS (Status);
    548     }
    549 
    550     /* Don't allow two handlers. */
    551 
    552     if (AcpiGbl_ExceptionHandler)
    553     {
    554         Status = AE_ALREADY_EXISTS;
    555         goto Cleanup;
    556     }
    557 
    558     /* Install the handler */
    559 
    560     AcpiGbl_ExceptionHandler = Handler;
    561 
    562 Cleanup:
    563     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    564     return_ACPI_STATUS (Status);
    565 }
    566 
    567 ACPI_EXPORT_SYMBOL (AcpiInstallExceptionHandler)
    568 
    569 
    570 #if (!ACPI_REDUCED_HARDWARE)
    571 /*******************************************************************************
    572  *
    573  * FUNCTION:    AcpiInstallSciHandler
    574  *
    575  * PARAMETERS:  Address             - Address of the handler
    576  *              Context             - Value passed to the handler on each SCI
    577  *
    578  * RETURN:      Status
    579  *
    580  * DESCRIPTION: Install a handler for a System Control Interrupt.
    581  *
    582  ******************************************************************************/
    583 
    584 ACPI_STATUS
    585 AcpiInstallSciHandler (
    586     ACPI_SCI_HANDLER        Address,
    587     void                    *Context)
    588 {
    589     ACPI_SCI_HANDLER_INFO   *NewSciHandler;
    590     ACPI_SCI_HANDLER_INFO   *SciHandler;
    591     ACPI_CPU_FLAGS          Flags;
    592     ACPI_STATUS             Status;
    593 
    594 
    595     ACPI_FUNCTION_TRACE (AcpiInstallSciHandler);
    596 
    597 
    598     if (!Address)
    599     {
    600         return_ACPI_STATUS (AE_BAD_PARAMETER);
    601     }
    602 
    603     /* Allocate and init a handler object */
    604 
    605     NewSciHandler = ACPI_ALLOCATE (sizeof (ACPI_SCI_HANDLER_INFO));
    606     if (!NewSciHandler)
    607     {
    608         return_ACPI_STATUS (AE_NO_MEMORY);
    609     }
    610 
    611     NewSciHandler->Address = Address;
    612     NewSciHandler->Context = Context;
    613 
    614     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    615     if (ACPI_FAILURE (Status))
    616     {
    617         goto Exit;
    618     }
    619 
    620     /* Lock list during installation */
    621 
    622     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
    623     SciHandler = AcpiGbl_SciHandlerList;
    624 
    625     /* Ensure handler does not already exist */
    626 
    627     while (SciHandler)
    628     {
    629         if (Address == SciHandler->Address)
    630         {
    631             Status = AE_ALREADY_EXISTS;
    632             goto UnlockAndExit;
    633         }
    634 
    635         SciHandler = SciHandler->Next;
    636     }
    637 
    638     /* Install the new handler into the global list (at head) */
    639 
    640     NewSciHandler->Next = AcpiGbl_SciHandlerList;
    641     AcpiGbl_SciHandlerList = NewSciHandler;
    642 
    643 
    644 UnlockAndExit:
    645 
    646     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    647     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    648 
    649 Exit:
    650     if (ACPI_FAILURE (Status))
    651     {
    652         ACPI_FREE (NewSciHandler);
    653     }
    654     return_ACPI_STATUS (Status);
    655 }
    656 
    657 ACPI_EXPORT_SYMBOL (AcpiInstallSciHandler)
    658 
    659 
    660 /*******************************************************************************
    661  *
    662  * FUNCTION:    AcpiRemoveSciHandler
    663  *
    664  * PARAMETERS:  Address             - Address of the handler
    665  *
    666  * RETURN:      Status
    667  *
    668  * DESCRIPTION: Remove a handler for a System Control Interrupt.
    669  *
    670  ******************************************************************************/
    671 
    672 ACPI_STATUS
    673 AcpiRemoveSciHandler (
    674     ACPI_SCI_HANDLER        Address)
    675 {
    676     ACPI_SCI_HANDLER_INFO   *PrevSciHandler;
    677     ACPI_SCI_HANDLER_INFO   *NextSciHandler;
    678     ACPI_CPU_FLAGS          Flags;
    679     ACPI_STATUS             Status;
    680 
    681 
    682     ACPI_FUNCTION_TRACE (AcpiRemoveSciHandler);
    683 
    684 
    685     if (!Address)
    686     {
    687         return_ACPI_STATUS (AE_BAD_PARAMETER);
    688     }
    689 
    690     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    691     if (ACPI_FAILURE (Status))
    692     {
    693         return_ACPI_STATUS (Status);
    694     }
    695 
    696     /* Remove the SCI handler with lock */
    697 
    698     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
    699 
    700     PrevSciHandler = NULL;
    701     NextSciHandler = AcpiGbl_SciHandlerList;
    702     while (NextSciHandler)
    703     {
    704         if (NextSciHandler->Address == Address)
    705         {
    706             /* Unlink and free the SCI handler info block */
    707 
    708             if (PrevSciHandler)
    709             {
    710                 PrevSciHandler->Next = NextSciHandler->Next;
    711             }
    712             else
    713             {
    714                 AcpiGbl_SciHandlerList = NextSciHandler->Next;
    715             }
    716 
    717             AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    718             ACPI_FREE (NextSciHandler);
    719             goto UnlockAndExit;
    720         }
    721 
    722         PrevSciHandler = NextSciHandler;
    723         NextSciHandler = NextSciHandler->Next;
    724     }
    725 
    726     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    727     Status = AE_NOT_EXIST;
    728 
    729 
    730 UnlockAndExit:
    731     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    732     return_ACPI_STATUS (Status);
    733 }
    734 
    735 ACPI_EXPORT_SYMBOL (AcpiRemoveSciHandler)
    736 
    737 
    738 /*******************************************************************************
    739  *
    740  * FUNCTION:    AcpiInstallGlobalEventHandler
    741  *
    742  * PARAMETERS:  Handler         - Pointer to the global event handler function
    743  *              Context         - Value passed to the handler on each event
    744  *
    745  * RETURN:      Status
    746  *
    747  * DESCRIPTION: Saves the pointer to the handler function. The global handler
    748  *              is invoked upon each incoming GPE and Fixed Event. It is
    749  *              invoked at interrupt level at the time of the event dispatch.
    750  *              Can be used to update event counters, etc.
    751  *
    752  ******************************************************************************/
    753 
    754 ACPI_STATUS
    755 AcpiInstallGlobalEventHandler (
    756     ACPI_GBL_EVENT_HANDLER  Handler,
    757     void                    *Context)
    758 {
    759     ACPI_STATUS             Status;
    760 
    761 
    762     ACPI_FUNCTION_TRACE (AcpiInstallGlobalEventHandler);
    763 
    764 
    765     /* Parameter validation */
    766 
    767     if (!Handler)
    768     {
    769         return_ACPI_STATUS (AE_BAD_PARAMETER);
    770     }
    771 
    772     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    773     if (ACPI_FAILURE (Status))
    774     {
    775         return_ACPI_STATUS (Status);
    776     }
    777 
    778     /* Don't allow two handlers. */
    779 
    780     if (AcpiGbl_GlobalEventHandler)
    781     {
    782         Status = AE_ALREADY_EXISTS;
    783         goto Cleanup;
    784     }
    785 
    786     AcpiGbl_GlobalEventHandler = Handler;
    787     AcpiGbl_GlobalEventHandlerContext = Context;
    788 
    789 
    790 Cleanup:
    791     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    792     return_ACPI_STATUS (Status);
    793 }
    794 
    795 ACPI_EXPORT_SYMBOL (AcpiInstallGlobalEventHandler)
    796 
    797 
    798 /*******************************************************************************
    799  *
    800  * FUNCTION:    AcpiInstallFixedEventHandler
    801  *
    802  * PARAMETERS:  Event           - Event type to enable.
    803  *              Handler         - Pointer to the handler function for the
    804  *                                event
    805  *              Context         - Value passed to the handler on each GPE
    806  *
    807  * RETURN:      Status
    808  *
    809  * DESCRIPTION: Saves the pointer to the handler function and then enables the
    810  *              event.
    811  *
    812  ******************************************************************************/
    813 
    814 ACPI_STATUS
    815 AcpiInstallFixedEventHandler (
    816     UINT32                  Event,
    817     ACPI_EVENT_HANDLER      Handler,
    818     void                    *Context)
    819 {
    820     ACPI_STATUS             Status;
    821 
    822 
    823     ACPI_FUNCTION_TRACE (AcpiInstallFixedEventHandler);
    824 
    825 
    826     /* Parameter validation */
    827 
    828     if (Event > ACPI_EVENT_MAX)
    829     {
    830         return_ACPI_STATUS (AE_BAD_PARAMETER);
    831     }
    832 
    833     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    834     if (ACPI_FAILURE (Status))
    835     {
    836         return_ACPI_STATUS (Status);
    837     }
    838 
    839     /* Do not allow multiple handlers */
    840 
    841     if (AcpiGbl_FixedEventHandlers[Event].Handler)
    842     {
    843         Status = AE_ALREADY_EXISTS;
    844         goto Cleanup;
    845     }
    846 
    847     /* Install the handler before enabling the event */
    848 
    849     AcpiGbl_FixedEventHandlers[Event].Handler = Handler;
    850     AcpiGbl_FixedEventHandlers[Event].Context = Context;
    851 
    852     Status = AcpiEnableEvent (Event, 0);
    853     if (ACPI_FAILURE (Status))
    854     {
    855         ACPI_WARNING ((AE_INFO,
    856             "Could not enable fixed event - %s (%u)",
    857             AcpiUtGetEventName (Event), Event));
    858 
    859         /* Remove the handler */
    860 
    861         AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
    862         AcpiGbl_FixedEventHandlers[Event].Context = NULL;
    863     }
    864     else
    865     {
    866         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
    867             "Enabled fixed event %s (%X), Handler=%p\n",
    868             AcpiUtGetEventName (Event), Event, Handler));
    869     }
    870 
    871 
    872 Cleanup:
    873     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    874     return_ACPI_STATUS (Status);
    875 }
    876 
    877 ACPI_EXPORT_SYMBOL (AcpiInstallFixedEventHandler)
    878 
    879 
    880 /*******************************************************************************
    881  *
    882  * FUNCTION:    AcpiRemoveFixedEventHandler
    883  *
    884  * PARAMETERS:  Event           - Event type to disable.
    885  *              Handler         - Address of the handler
    886  *
    887  * RETURN:      Status
    888  *
    889  * DESCRIPTION: Disables the event and unregisters the event handler.
    890  *
    891  ******************************************************************************/
    892 
    893 ACPI_STATUS
    894 AcpiRemoveFixedEventHandler (
    895     UINT32                  Event,
    896     ACPI_EVENT_HANDLER      Handler)
    897 {
    898     ACPI_STATUS             Status = AE_OK;
    899 
    900 
    901     ACPI_FUNCTION_TRACE (AcpiRemoveFixedEventHandler);
    902 
    903 
    904     /* Parameter validation */
    905 
    906     if (Event > ACPI_EVENT_MAX)
    907     {
    908         return_ACPI_STATUS (AE_BAD_PARAMETER);
    909     }
    910 
    911     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    912     if (ACPI_FAILURE (Status))
    913     {
    914         return_ACPI_STATUS (Status);
    915     }
    916 
    917     /* Disable the event before removing the handler */
    918 
    919     Status = AcpiDisableEvent (Event, 0);
    920 
    921     /* Always Remove the handler */
    922 
    923     AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
    924     AcpiGbl_FixedEventHandlers[Event].Context = NULL;
    925 
    926     if (ACPI_FAILURE (Status))
    927     {
    928         ACPI_WARNING ((AE_INFO,
    929             "Could not disable fixed event - %s (%u)",
    930             AcpiUtGetEventName (Event), Event));
    931     }
    932     else
    933     {
    934         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
    935             "Disabled fixed event - %s (%X)\n",
    936             AcpiUtGetEventName (Event), Event));
    937     }
    938 
    939     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    940     return_ACPI_STATUS (Status);
    941 }
    942 
    943 ACPI_EXPORT_SYMBOL (AcpiRemoveFixedEventHandler)
    944 
    945 
    946 /*******************************************************************************
    947  *
    948  * FUNCTION:    AcpiEvInstallGpeHandler
    949  *
    950  * PARAMETERS:  GpeDevice       - Namespace node for the GPE (NULL for FADT
    951  *                                defined GPEs)
    952  *              GpeNumber       - The GPE number within the GPE block
    953  *              Type            - Whether this GPE should be treated as an
    954  *                                edge- or level-triggered interrupt.
    955  *              IsRawHandler    - Whether this GPE should be handled using
    956  *                                the special GPE handler mode.
    957  *              Address         - Address of the handler
    958  *              Context         - Value passed to the handler on each GPE
    959  *
    960  * RETURN:      Status
    961  *
    962  * DESCRIPTION: Internal function to install a handler for a General Purpose
    963  *              Event.
    964  *
    965  ******************************************************************************/
    966 
    967 static ACPI_STATUS
    968 AcpiEvInstallGpeHandler (
    969     ACPI_HANDLE             GpeDevice,
    970     UINT32                  GpeNumber,
    971     UINT32                  Type,
    972     BOOLEAN                 IsRawHandler,
    973     ACPI_GPE_HANDLER        Address,
    974     void                    *Context)
    975 {
    976     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    977     ACPI_GPE_HANDLER_INFO   *Handler;
    978     ACPI_STATUS             Status;
    979     ACPI_CPU_FLAGS          Flags;
    980 
    981 
    982     ACPI_FUNCTION_TRACE (EvInstallGpeHandler);
    983 
    984 
    985     /* Parameter validation */
    986 
    987     if ((!Address) || (Type & ~ACPI_GPE_XRUPT_TYPE_MASK))
    988     {
    989         return_ACPI_STATUS (AE_BAD_PARAMETER);
    990     }
    991 
    992     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    993     if (ACPI_FAILURE (Status))
    994     {
    995         return_ACPI_STATUS (Status);
    996     }
    997 
    998     /* Allocate and init handler object (before lock) */
    999 
   1000     Handler = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_HANDLER_INFO));
   1001     if (!Handler)
   1002     {
   1003         Status = AE_NO_MEMORY;
   1004         goto UnlockAndExit;
   1005     }
   1006 
   1007     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
   1008 
   1009     /* Ensure that we have a valid GPE number */
   1010 
   1011     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
   1012     if (!GpeEventInfo)
   1013     {
   1014         Status = AE_BAD_PARAMETER;
   1015         goto FreeAndExit;
   1016     }
   1017 
   1018     /* Make sure that there isn't a handler there already */
   1019 
   1020     if ((ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
   1021             ACPI_GPE_DISPATCH_HANDLER) ||
   1022         (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
   1023             ACPI_GPE_DISPATCH_RAW_HANDLER))
   1024     {
   1025         Status = AE_ALREADY_EXISTS;
   1026         goto FreeAndExit;
   1027     }
   1028 
   1029     Handler->Address = Address;
   1030     Handler->Context = Context;
   1031     Handler->MethodNode = GpeEventInfo->Dispatch.MethodNode;
   1032     Handler->OriginalFlags = (UINT8) (GpeEventInfo->Flags &
   1033         (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK));
   1034 
   1035     /*
   1036      * If the GPE is associated with a method, it may have been enabled
   1037      * automatically during initialization, in which case it has to be
   1038      * disabled now to avoid spurious execution of the handler.
   1039      */
   1040     if (((ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) ==
   1041             ACPI_GPE_DISPATCH_METHOD) ||
   1042          (ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) ==
   1043             ACPI_GPE_DISPATCH_NOTIFY)) &&
   1044         GpeEventInfo->RuntimeCount)
   1045     {
   1046         Handler->OriginallyEnabled = TRUE;
   1047         (void) AcpiEvRemoveGpeReference (GpeEventInfo);
   1048 
   1049         /* Sanity check of original type against new type */
   1050 
   1051         if (Type != (UINT32) (GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK))
   1052         {
   1053             ACPI_WARNING ((AE_INFO, "GPE type mismatch (level/edge)"));
   1054         }
   1055     }
   1056 
   1057     /* Install the handler */
   1058 
   1059     GpeEventInfo->Dispatch.Handler = Handler;
   1060 
   1061     /* Setup up dispatch flags to indicate handler (vs. method/notify) */
   1062 
   1063     GpeEventInfo->Flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
   1064     GpeEventInfo->Flags |= (UINT8) (Type | (IsRawHandler ?
   1065         ACPI_GPE_DISPATCH_RAW_HANDLER : ACPI_GPE_DISPATCH_HANDLER));
   1066 
   1067     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
   1068 
   1069 
   1070 UnlockAndExit:
   1071     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
   1072     return_ACPI_STATUS (Status);
   1073 
   1074 FreeAndExit:
   1075     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
   1076     ACPI_FREE (Handler);
   1077     goto UnlockAndExit;
   1078 }
   1079 
   1080 
   1081 /*******************************************************************************
   1082  *
   1083  * FUNCTION:    AcpiInstallGpeHandler
   1084  *
   1085  * PARAMETERS:  GpeDevice       - Namespace node for the GPE (NULL for FADT
   1086  *                                defined GPEs)
   1087  *              GpeNumber       - The GPE number within the GPE block
   1088  *              Type            - Whether this GPE should be treated as an
   1089  *                                edge- or level-triggered interrupt.
   1090  *              Address         - Address of the handler
   1091  *              Context         - Value passed to the handler on each GPE
   1092  *
   1093  * RETURN:      Status
   1094  *
   1095  * DESCRIPTION: Install a handler for a General Purpose Event.
   1096  *
   1097  ******************************************************************************/
   1098 
   1099 ACPI_STATUS
   1100 AcpiInstallGpeHandler (
   1101     ACPI_HANDLE             GpeDevice,
   1102     UINT32                  GpeNumber,
   1103     UINT32                  Type,
   1104     ACPI_GPE_HANDLER        Address,
   1105     void                    *Context)
   1106 {
   1107     ACPI_STATUS             Status;
   1108 
   1109 
   1110     ACPI_FUNCTION_TRACE (AcpiInstallGpeHandler);
   1111 
   1112 
   1113     Status = AcpiEvInstallGpeHandler (GpeDevice, GpeNumber, Type,
   1114         FALSE, Address, Context);
   1115 
   1116     return_ACPI_STATUS (Status);
   1117 }
   1118 
   1119 ACPI_EXPORT_SYMBOL (AcpiInstallGpeHandler)
   1120 
   1121 
   1122 /*******************************************************************************
   1123  *
   1124  * FUNCTION:    AcpiInstallGpeRawHandler
   1125  *
   1126  * PARAMETERS:  GpeDevice       - Namespace node for the GPE (NULL for FADT
   1127  *                                defined GPEs)
   1128  *              GpeNumber       - The GPE number within the GPE block
   1129  *              Type            - Whether this GPE should be treated as an
   1130  *                                edge- or level-triggered interrupt.
   1131  *              Address         - Address of the handler
   1132  *              Context         - Value passed to the handler on each GPE
   1133  *
   1134  * RETURN:      Status
   1135  *
   1136  * DESCRIPTION: Install a handler for a General Purpose Event.
   1137  *
   1138  ******************************************************************************/
   1139 
   1140 ACPI_STATUS
   1141 AcpiInstallGpeRawHandler (
   1142     ACPI_HANDLE             GpeDevice,
   1143     UINT32                  GpeNumber,
   1144     UINT32                  Type,
   1145     ACPI_GPE_HANDLER        Address,
   1146     void                    *Context)
   1147 {
   1148     ACPI_STATUS             Status;
   1149 
   1150 
   1151     ACPI_FUNCTION_TRACE (AcpiInstallGpeRawHandler);
   1152 
   1153 
   1154     Status = AcpiEvInstallGpeHandler (GpeDevice, GpeNumber, Type,
   1155         TRUE, Address, Context);
   1156 
   1157     return_ACPI_STATUS (Status);
   1158 }
   1159 
   1160 ACPI_EXPORT_SYMBOL (AcpiInstallGpeRawHandler)
   1161 
   1162 
   1163 /*******************************************************************************
   1164  *
   1165  * FUNCTION:    AcpiRemoveGpeHandler
   1166  *
   1167  * PARAMETERS:  GpeDevice       - Namespace node for the GPE (NULL for FADT
   1168  *                                defined GPEs)
   1169  *              GpeNumber       - The event to remove a handler
   1170  *              Address         - Address of the handler
   1171  *
   1172  * RETURN:      Status
   1173  *
   1174  * DESCRIPTION: Remove a handler for a General Purpose AcpiEvent.
   1175  *
   1176  ******************************************************************************/
   1177 
   1178 ACPI_STATUS
   1179 AcpiRemoveGpeHandler (
   1180     ACPI_HANDLE             GpeDevice,
   1181     UINT32                  GpeNumber,
   1182     ACPI_GPE_HANDLER        Address)
   1183 {
   1184     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
   1185     ACPI_GPE_HANDLER_INFO   *Handler;
   1186     ACPI_STATUS             Status;
   1187     ACPI_CPU_FLAGS          Flags;
   1188 
   1189 
   1190     ACPI_FUNCTION_TRACE (AcpiRemoveGpeHandler);
   1191 
   1192 
   1193     /* Parameter validation */
   1194 
   1195     if (!Address)
   1196     {
   1197         return_ACPI_STATUS (AE_BAD_PARAMETER);
   1198     }
   1199 
   1200     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
   1201     if (ACPI_FAILURE (Status))
   1202     {
   1203         return_ACPI_STATUS (Status);
   1204     }
   1205 
   1206     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
   1207 
   1208     /* Ensure that we have a valid GPE number */
   1209 
   1210     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
   1211     if (!GpeEventInfo)
   1212     {
   1213         Status = AE_BAD_PARAMETER;
   1214         goto UnlockAndExit;
   1215     }
   1216 
   1217     /* Make sure that a handler is indeed installed */
   1218 
   1219     if ((ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) !=
   1220             ACPI_GPE_DISPATCH_HANDLER) &&
   1221         (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) !=
   1222             ACPI_GPE_DISPATCH_RAW_HANDLER))
   1223     {
   1224         Status = AE_NOT_EXIST;
   1225         goto UnlockAndExit;
   1226     }
   1227 
   1228     /* Make sure that the installed handler is the same */
   1229 
   1230     if (GpeEventInfo->Dispatch.Handler->Address != Address)
   1231     {
   1232         Status = AE_BAD_PARAMETER;
   1233         goto UnlockAndExit;
   1234     }
   1235 
   1236     /* Remove the handler */
   1237 
   1238     Handler = GpeEventInfo->Dispatch.Handler;
   1239     GpeEventInfo->Dispatch.Handler = NULL;
   1240 
   1241     /* Restore Method node (if any), set dispatch flags */
   1242 
   1243     GpeEventInfo->Dispatch.MethodNode = Handler->MethodNode;
   1244     GpeEventInfo->Flags &=
   1245         ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
   1246     GpeEventInfo->Flags |= Handler->OriginalFlags;
   1247 
   1248     /*
   1249      * If the GPE was previously associated with a method and it was
   1250      * enabled, it should be enabled at this point to restore the
   1251      * post-initialization configuration.
   1252      */
   1253     if (((ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) ==
   1254             ACPI_GPE_DISPATCH_METHOD) ||
   1255          (ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) ==
   1256             ACPI_GPE_DISPATCH_NOTIFY)) &&
   1257         Handler->OriginallyEnabled)
   1258     {
   1259         (void) AcpiEvAddGpeReference (GpeEventInfo, FALSE);
   1260         if (ACPI_GPE_IS_POLLING_NEEDED (GpeEventInfo))
   1261         {
   1262             /* Poll edge triggered GPEs to handle existing events */
   1263 
   1264             AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
   1265             (void) AcpiEvDetectGpe (
   1266                 GpeDevice, GpeEventInfo, GpeNumber);
   1267             Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
   1268         }
   1269     }
   1270 
   1271     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
   1272     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
   1273 
   1274     /* Make sure all deferred GPE tasks are completed */
   1275 
   1276     AcpiOsWaitEventsComplete ();
   1277 
   1278     /* Now we can free the handler object */
   1279 
   1280     ACPI_FREE (Handler);
   1281     return_ACPI_STATUS (Status);
   1282 
   1283 UnlockAndExit:
   1284     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
   1285     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
   1286     return_ACPI_STATUS (Status);
   1287 }
   1288 
   1289 ACPI_EXPORT_SYMBOL (AcpiRemoveGpeHandler)
   1290 
   1291 
   1292 /*******************************************************************************
   1293  *
   1294  * FUNCTION:    AcpiAcquireGlobalLock
   1295  *
   1296  * PARAMETERS:  Timeout         - How long the caller is willing to wait
   1297  *              Handle          - Where the handle to the lock is returned
   1298  *                                (if acquired)
   1299  *
   1300  * RETURN:      Status
   1301  *
   1302  * DESCRIPTION: Acquire the ACPI Global Lock
   1303  *
   1304  * Note: Allows callers with the same thread ID to acquire the global lock
   1305  * multiple times. In other words, externally, the behavior of the global lock
   1306  * is identical to an AML mutex. On the first acquire, a new handle is
   1307  * returned. On any subsequent calls to acquire by the same thread, the same
   1308  * handle is returned.
   1309  *
   1310  ******************************************************************************/
   1311 
   1312 ACPI_STATUS
   1313 AcpiAcquireGlobalLock (
   1314     UINT16                  Timeout,
   1315     UINT32                  *Handle)
   1316 {
   1317     ACPI_STATUS             Status;
   1318 
   1319 
   1320     if (!Handle)
   1321     {
   1322         return (AE_BAD_PARAMETER);
   1323     }
   1324 
   1325     /* Must lock interpreter to prevent race conditions */
   1326 
   1327     AcpiExEnterInterpreter ();
   1328 
   1329     Status = AcpiExAcquireMutexObject (Timeout,
   1330         AcpiGbl_GlobalLockMutex, AcpiOsGetThreadId ());
   1331 
   1332     if (ACPI_SUCCESS (Status))
   1333     {
   1334         /* Return the global lock handle (updated in AcpiEvAcquireGlobalLock) */
   1335 
   1336         *Handle = AcpiGbl_GlobalLockHandle;
   1337     }
   1338 
   1339     AcpiExExitInterpreter ();
   1340     return (Status);
   1341 }
   1342 
   1343 ACPI_EXPORT_SYMBOL (AcpiAcquireGlobalLock)
   1344 
   1345 
   1346 /*******************************************************************************
   1347  *
   1348  * FUNCTION:    AcpiReleaseGlobalLock
   1349  *
   1350  * PARAMETERS:  Handle      - Returned from AcpiAcquireGlobalLock
   1351  *
   1352  * RETURN:      Status
   1353  *
   1354  * DESCRIPTION: Release the ACPI Global Lock. The handle must be valid.
   1355  *
   1356  ******************************************************************************/
   1357 
   1358 ACPI_STATUS
   1359 AcpiReleaseGlobalLock (
   1360     UINT32                  Handle)
   1361 {
   1362     ACPI_STATUS             Status;
   1363 
   1364 
   1365     if (!Handle || (Handle != AcpiGbl_GlobalLockHandle))
   1366     {
   1367         return (AE_NOT_ACQUIRED);
   1368     }
   1369 
   1370     Status = AcpiExReleaseMutexObject (AcpiGbl_GlobalLockMutex);
   1371     return (Status);
   1372 }
   1373 
   1374 ACPI_EXPORT_SYMBOL (AcpiReleaseGlobalLock)
   1375 
   1376 #endif /* !ACPI_REDUCED_HARDWARE */
   1377