Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:02

0001 /******************************************************************************
0002  *
0003  * Module Name: evxface - External interfaces for ACPI events
0004  *
0005  *****************************************************************************/
0006 
0007 /******************************************************************************
0008  *
0009  * 1. Copyright Notice
0010  *
0011  * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp.
0012  * All rights reserved.
0013  *
0014  * 2. License
0015  *
0016  * 2.1. This is your license from Intel Corp. under its intellectual property
0017  * rights. You may have additional license terms from the party that provided
0018  * you this software, covering your right to use that party's intellectual
0019  * property rights.
0020  *
0021  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
0022  * copy of the source code appearing in this file ("Covered Code") an
0023  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
0024  * base code distributed originally by Intel ("Original Intel Code") to copy,
0025  * make derivatives, distribute, use and display any portion of the Covered
0026  * Code in any form, with the right to sublicense such rights; and
0027  *
0028  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
0029  * license (with the right to sublicense), under only those claims of Intel
0030  * patents that are infringed by the Original Intel Code, to make, use, sell,
0031  * offer to sell, and import the Covered Code and derivative works thereof
0032  * solely to the minimum extent necessary to exercise the above copyright
0033  * license, and in no event shall the patent license extend to any additions
0034  * to or modifications of the Original Intel Code. No other license or right
0035  * is granted directly or by implication, estoppel or otherwise;
0036  *
0037  * The above copyright and patent license is granted only if the following
0038  * conditions are met:
0039  *
0040  * 3. Conditions
0041  *
0042  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
0043  * Redistribution of source code of any substantial portion of the Covered
0044  * Code or modification with rights to further distribute source must include
0045  * the above Copyright Notice, the above License, this list of Conditions,
0046  * and the following Disclaimer and Export Compliance provision. In addition,
0047  * Licensee must cause all Covered Code to which Licensee contributes to
0048  * contain a file documenting the changes Licensee made to create that Covered
0049  * Code and the date of any change. Licensee must include in that file the
0050  * documentation of any changes made by any predecessor Licensee. Licensee
0051  * must include a prominent statement that the modification is derived,
0052  * directly or indirectly, from Original Intel Code.
0053  *
0054  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
0055  * Redistribution of source code of any substantial portion of the Covered
0056  * Code or modification without rights to further distribute source must
0057  * include the following Disclaimer and Export Compliance provision in the
0058  * documentation and/or other materials provided with distribution. In
0059  * addition, Licensee may not authorize further sublicense of source of any
0060  * portion of the Covered Code, and must include terms to the effect that the
0061  * license from Licensee to its licensee is limited to the intellectual
0062  * property embodied in the software Licensee provides to its licensee, and
0063  * not to intellectual property embodied in modifications its licensee may
0064  * make.
0065  *
0066  * 3.3. Redistribution of Executable. Redistribution in executable form of any
0067  * substantial portion of the Covered Code or modification must reproduce the
0068  * above Copyright Notice, and the following Disclaimer and Export Compliance
0069  * provision in the documentation and/or other materials provided with the
0070  * distribution.
0071  *
0072  * 3.4. Intel retains all right, title, and interest in and to the Original
0073  * Intel Code.
0074  *
0075  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
0076  * Intel shall be used in advertising or otherwise to promote the sale, use or
0077  * other dealings in products derived from or relating to the Covered Code
0078  * without prior written authorization from Intel.
0079  *
0080  * 4. Disclaimer and Export Compliance
0081  *
0082  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
0083  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
0084  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
0085  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
0086  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
0087  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
0088  * PARTICULAR PURPOSE.
0089  *
0090  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
0091  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
0092  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
0093  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
0094  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
0095  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
0096  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
0097  * LIMITED REMEDY.
0098  *
0099  * 4.3. Licensee shall not export, either directly or indirectly, any of this
0100  * software or system incorporating such software without first obtaining any
0101  * required license or other approval from the U. S. Department of Commerce or
0102  * any other agency or department of the United States Government. In the
0103  * event Licensee exports any such software from the United States or
0104  * re-exports any such software from a foreign destination, Licensee shall
0105  * ensure that the distribution and export/re-export of the software is in
0106  * compliance with all laws, regulations, orders, or other restrictions of the
0107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
0108  * any of its subsidiaries will export/re-export any technical data, process,
0109  * software, or service, directly or indirectly, to any country for which the
0110  * United States government or any agency thereof requires an export license,
0111  * other governmental approval, or letter of assurance, without first obtaining
0112  * such license, approval or letter.
0113  *
0114  *****************************************************************************
0115  *
0116  * Alternatively, you may choose to be licensed under the terms of the
0117  * following license:
0118  *
0119  * Redistribution and use in source and binary forms, with or without
0120  * modification, are permitted provided that the following conditions
0121  * are met:
0122  * 1. Redistributions of source code must retain the above copyright
0123  *    notice, this list of conditions, and the following disclaimer,
0124  *    without modification.
0125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
0126  *    substantially similar to the "NO WARRANTY" disclaimer below
0127  *    ("Disclaimer") and any redistribution must be conditioned upon
0128  *    including a substantially similar Disclaimer requirement for further
0129  *    binary redistribution.
0130  * 3. Neither the names of the above-listed copyright holders nor the names
0131  *    of any contributors may be used to endorse or promote products derived
0132  *    from this software without specific prior written permission.
0133  *
0134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0145  *
0146  * Alternatively, you may choose to be licensed under the terms of the
0147  * GNU General Public License ("GPL") version 2 as published by the Free
0148  * Software Foundation.
0149  *
0150  *****************************************************************************/
0151 
0152 #define EXPORT_ACPI_INTERFACES
0153 
0154 #include "acpi.h"
0155 #include "accommon.h"
0156 #include "acnamesp.h"
0157 #include "acevents.h"
0158 #include "acinterp.h"
0159 
0160 #define _COMPONENT          ACPI_EVENTS
0161         ACPI_MODULE_NAME    ("evxface")
0162 
0163 #if (!ACPI_REDUCED_HARDWARE)
0164 
0165 /* Local prototypes */
0166 
0167 static ACPI_STATUS
0168 AcpiEvInstallGpeHandler (
0169     ACPI_HANDLE             GpeDevice,
0170     UINT32                  GpeNumber,
0171     UINT32                  Type,
0172     BOOLEAN                 IsRawHandler,
0173     ACPI_GPE_HANDLER        Address,
0174     void                    *Context);
0175 
0176 #endif
0177 
0178 
0179 /*******************************************************************************
0180  *
0181  * FUNCTION:    AcpiInstallNotifyHandler
0182  *
0183  * PARAMETERS:  Device          - The device for which notifies will be handled
0184  *              HandlerType     - The type of handler:
0185  *                                  ACPI_SYSTEM_NOTIFY: System Handler (00-7F)
0186  *                                  ACPI_DEVICE_NOTIFY: Device Handler (80-FF)
0187  *                                  ACPI_ALL_NOTIFY:    Both System and Device
0188  *              Handler         - Address of the handler
0189  *              Context         - Value passed to the handler on each GPE
0190  *
0191  * RETURN:      Status
0192  *
0193  * DESCRIPTION: Install a handler for notifications on an ACPI Device,
0194  *              ThermalZone, or Processor object.
0195  *
0196  * NOTES:       The Root namespace object may have only one handler for each
0197  *              type of notify (System/Device). Device/Thermal/Processor objects
0198  *              may have one device notify handler, and multiple system notify
0199  *              handlers.
0200  *
0201  ******************************************************************************/
0202 
0203 ACPI_STATUS
0204 AcpiInstallNotifyHandler (
0205     ACPI_HANDLE             Device,
0206     UINT32                  HandlerType,
0207     ACPI_NOTIFY_HANDLER     Handler,
0208     void                    *Context)
0209 {
0210     ACPI_NAMESPACE_NODE     *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device);
0211     ACPI_OPERAND_OBJECT     *ObjDesc;
0212     ACPI_OPERAND_OBJECT     *HandlerObj;
0213     ACPI_STATUS             Status;
0214     UINT32                  i;
0215 
0216 
0217     ACPI_FUNCTION_TRACE (AcpiInstallNotifyHandler);
0218 
0219 
0220     /* Parameter validation */
0221 
0222     if ((!Device) || (!Handler) || (!HandlerType) ||
0223         (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
0224     {
0225         return_ACPI_STATUS (AE_BAD_PARAMETER);
0226     }
0227 
0228     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
0229     if (ACPI_FAILURE (Status))
0230     {
0231         return_ACPI_STATUS (Status);
0232     }
0233 
0234     /*
0235      * Root Object:
0236      * Registering a notify handler on the root object indicates that the
0237      * caller wishes to receive notifications for all objects. Note that
0238      * only one global handler can be registered per notify type.
0239      * Ensure that a handler is not already installed.
0240      */
0241     if (Device == ACPI_ROOT_OBJECT)
0242     {
0243         for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
0244         {
0245             if (HandlerType & (i+1))
0246             {
0247                 if (AcpiGbl_GlobalNotify[i].Handler)
0248                 {
0249                     Status = AE_ALREADY_EXISTS;
0250                     goto UnlockAndExit;
0251                 }
0252 
0253                 AcpiGbl_GlobalNotify[i].Handler = Handler;
0254                 AcpiGbl_GlobalNotify[i].Context = Context;
0255             }
0256         }
0257 
0258         goto UnlockAndExit; /* Global notify handler installed, all done */
0259     }
0260 
0261     /*
0262      * All Other Objects:
0263      * Caller will only receive notifications specific to the target
0264      * object. Note that only certain object types are allowed to
0265      * receive notifications.
0266      */
0267 
0268     /* Are Notifies allowed on this object? */
0269 
0270     if (!AcpiEvIsNotifyObject (Node))
0271     {
0272         Status = AE_TYPE;
0273         goto UnlockAndExit;
0274     }
0275 
0276     /* Check for an existing internal object, might not exist */
0277 
0278     ObjDesc = AcpiNsGetAttachedObject (Node);
0279     if (!ObjDesc)
0280     {
0281         /* Create a new object */
0282 
0283         ObjDesc = AcpiUtCreateInternalObject (Node->Type);
0284         if (!ObjDesc)
0285         {
0286             Status = AE_NO_MEMORY;
0287             goto UnlockAndExit;
0288         }
0289 
0290         /* Attach new object to the Node, remove local reference */
0291 
0292         Status = AcpiNsAttachObject (Device, ObjDesc, Node->Type);
0293         AcpiUtRemoveReference (ObjDesc);
0294         if (ACPI_FAILURE (Status))
0295         {
0296             goto UnlockAndExit;
0297         }
0298     }
0299 
0300     /* Ensure that the handler is not already installed in the lists */
0301 
0302     for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
0303     {
0304         if (HandlerType & (i+1))
0305         {
0306             HandlerObj = ObjDesc->CommonNotify.NotifyList[i];
0307             while (HandlerObj)
0308             {
0309                 if (HandlerObj->Notify.Handler == Handler)
0310                 {
0311                     Status = AE_ALREADY_EXISTS;
0312                     goto UnlockAndExit;
0313                 }
0314 
0315                 HandlerObj = HandlerObj->Notify.Next[i];
0316             }
0317         }
0318     }
0319 
0320     /* Create and populate a new notify handler object */
0321 
0322     HandlerObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_NOTIFY);
0323     if (!HandlerObj)
0324     {
0325         Status = AE_NO_MEMORY;
0326         goto UnlockAndExit;
0327     }
0328 
0329     HandlerObj->Notify.Node = Node;
0330     HandlerObj->Notify.HandlerType = HandlerType;
0331     HandlerObj->Notify.Handler = Handler;
0332     HandlerObj->Notify.Context = Context;
0333 
0334     /* Install the handler at the list head(s) */
0335 
0336     for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
0337     {
0338         if (HandlerType & (i+1))
0339         {
0340             HandlerObj->Notify.Next[i] =
0341                 ObjDesc->CommonNotify.NotifyList[i];
0342 
0343             ObjDesc->CommonNotify.NotifyList[i] = HandlerObj;
0344         }
0345     }
0346 
0347     /* Add an extra reference if handler was installed in both lists */
0348 
0349     if (HandlerType == ACPI_ALL_NOTIFY)
0350     {
0351         AcpiUtAddReference (HandlerObj);
0352     }
0353 
0354 
0355 UnlockAndExit:
0356     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
0357     return_ACPI_STATUS (Status);
0358 }
0359 
0360 ACPI_EXPORT_SYMBOL (AcpiInstallNotifyHandler)
0361 
0362 
0363 /*******************************************************************************
0364  *
0365  * FUNCTION:    AcpiRemoveNotifyHandler
0366  *
0367  * PARAMETERS:  Device          - The device for which the handler is installed
0368  *              HandlerType     - The type of handler:
0369  *                                  ACPI_SYSTEM_NOTIFY: System Handler (00-7F)
0370  *                                  ACPI_DEVICE_NOTIFY: Device Handler (80-FF)
0371  *                                  ACPI_ALL_NOTIFY:    Both System and Device
0372  *              Handler         - Address of the handler
0373  *
0374  * RETURN:      Status
0375  *
0376  * DESCRIPTION: Remove a handler for notifies on an ACPI device
0377  *
0378  ******************************************************************************/
0379 
0380 ACPI_STATUS
0381 AcpiRemoveNotifyHandler (
0382     ACPI_HANDLE             Device,
0383     UINT32                  HandlerType,
0384     ACPI_NOTIFY_HANDLER     Handler)
0385 {
0386     ACPI_NAMESPACE_NODE     *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device);
0387     ACPI_OPERAND_OBJECT     *ObjDesc;
0388     ACPI_OPERAND_OBJECT     *HandlerObj;
0389     ACPI_OPERAND_OBJECT     *PreviousHandlerObj;
0390     ACPI_STATUS             Status = AE_OK;
0391     UINT32                  i;
0392 
0393 
0394     ACPI_FUNCTION_TRACE (AcpiRemoveNotifyHandler);
0395 
0396 
0397     /* Parameter validation */
0398 
0399     if ((!Device) || (!Handler) || (!HandlerType) ||
0400         (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
0401     {
0402         return_ACPI_STATUS (AE_BAD_PARAMETER);
0403     }
0404 
0405     /* Root Object. Global handlers are removed here */
0406 
0407     if (Device == ACPI_ROOT_OBJECT)
0408     {
0409         for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
0410         {
0411             if (HandlerType & (i+1))
0412             {
0413                 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
0414                 if (ACPI_FAILURE (Status))
0415                 {
0416                     return_ACPI_STATUS (Status);
0417                 }
0418 
0419                 if (!AcpiGbl_GlobalNotify[i].Handler ||
0420                     (AcpiGbl_GlobalNotify[i].Handler != Handler))
0421                 {
0422                     Status = AE_NOT_EXIST;
0423                     goto UnlockAndExit;
0424                 }
0425 
0426                 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
0427                     "Removing global notify handler\n"));
0428 
0429                 AcpiGbl_GlobalNotify[i].Handler = NULL;
0430                 AcpiGbl_GlobalNotify[i].Context = NULL;
0431 
0432                 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
0433 
0434                 /* Make sure all deferred notify tasks are completed */
0435 
0436                 AcpiOsWaitEventsComplete ();
0437             }
0438         }
0439 
0440         return_ACPI_STATUS (AE_OK);
0441     }
0442 
0443     /* All other objects: Are Notifies allowed on this object? */
0444 
0445     if (!AcpiEvIsNotifyObject (Node))
0446     {
0447         return_ACPI_STATUS (AE_TYPE);
0448     }
0449 
0450     /* Must have an existing internal object */
0451 
0452     ObjDesc = AcpiNsGetAttachedObject (Node);
0453     if (!ObjDesc)
0454     {
0455         return_ACPI_STATUS (AE_NOT_EXIST);
0456     }
0457 
0458     /* Internal object exists. Find the handler and remove it */
0459 
0460     for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
0461     {
0462         if (HandlerType & (i+1))
0463         {
0464             Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
0465             if (ACPI_FAILURE (Status))
0466             {
0467                 return_ACPI_STATUS (Status);
0468             }
0469 
0470             HandlerObj = ObjDesc->CommonNotify.NotifyList[i];
0471             PreviousHandlerObj = NULL;
0472 
0473             /* Attempt to find the handler in the handler list */
0474 
0475             while (HandlerObj &&
0476                   (HandlerObj->Notify.Handler != Handler))
0477             {
0478                 PreviousHandlerObj = HandlerObj;
0479                 HandlerObj = HandlerObj->Notify.Next[i];
0480             }
0481 
0482             if (!HandlerObj)
0483             {
0484                 Status = AE_NOT_EXIST;
0485                 goto UnlockAndExit;
0486             }
0487 
0488             /* Remove the handler object from the list */
0489 
0490             if (PreviousHandlerObj) /* Handler is not at the list head */
0491             {
0492                 PreviousHandlerObj->Notify.Next[i] =
0493                     HandlerObj->Notify.Next[i];
0494             }
0495             else /* Handler is at the list head */
0496             {
0497                 ObjDesc->CommonNotify.NotifyList[i] =
0498                     HandlerObj->Notify.Next[i];
0499             }
0500 
0501             (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
0502 
0503             /* Make sure all deferred notify tasks are completed */
0504 
0505             AcpiOsWaitEventsComplete ();
0506             AcpiUtRemoveReference (HandlerObj);
0507         }
0508     }
0509 
0510     return_ACPI_STATUS (Status);
0511 
0512 
0513 UnlockAndExit:
0514     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
0515     return_ACPI_STATUS (Status);
0516 }
0517 
0518 ACPI_EXPORT_SYMBOL (AcpiRemoveNotifyHandler)
0519 
0520 
0521 /*******************************************************************************
0522  *
0523  * FUNCTION:    AcpiInstallExceptionHandler
0524  *
0525  * PARAMETERS:  Handler         - Pointer to the handler function for the
0526  *                                event
0527  *
0528  * RETURN:      Status
0529  *
0530  * DESCRIPTION: Saves the pointer to the handler function
0531  *
0532  ******************************************************************************/
0533 
0534 ACPI_STATUS
0535 AcpiInstallExceptionHandler (
0536     ACPI_EXCEPTION_HANDLER  Handler)
0537 {
0538     ACPI_STATUS             Status;
0539 
0540 
0541     ACPI_FUNCTION_TRACE (AcpiInstallExceptionHandler);
0542 
0543 
0544     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
0545     if (ACPI_FAILURE (Status))
0546     {
0547         return_ACPI_STATUS (Status);
0548     }
0549 
0550     /* Don't allow two handlers. */
0551 
0552     if (AcpiGbl_ExceptionHandler)
0553     {
0554         Status = AE_ALREADY_EXISTS;
0555         goto Cleanup;
0556     }
0557 
0558     /* Install the handler */
0559 
0560     AcpiGbl_ExceptionHandler = Handler;
0561 
0562 Cleanup:
0563     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
0564     return_ACPI_STATUS (Status);
0565 }
0566 
0567 ACPI_EXPORT_SYMBOL (AcpiInstallExceptionHandler)
0568 
0569 
0570 #if (!ACPI_REDUCED_HARDWARE)
0571 /*******************************************************************************
0572  *
0573  * FUNCTION:    AcpiInstallSciHandler
0574  *
0575  * PARAMETERS:  Address             - Address of the handler
0576  *              Context             - Value passed to the handler on each SCI
0577  *
0578  * RETURN:      Status
0579  *
0580  * DESCRIPTION: Install a handler for a System Control Interrupt.
0581  *
0582  ******************************************************************************/
0583 
0584 ACPI_STATUS
0585 AcpiInstallSciHandler (
0586     ACPI_SCI_HANDLER        Address,
0587     void                    *Context)
0588 {
0589     ACPI_SCI_HANDLER_INFO   *NewSciHandler;
0590     ACPI_SCI_HANDLER_INFO   *SciHandler;
0591     ACPI_CPU_FLAGS          Flags;
0592     ACPI_STATUS             Status;
0593 
0594 
0595     ACPI_FUNCTION_TRACE (AcpiInstallSciHandler);
0596 
0597 
0598     if (!Address)
0599     {
0600         return_ACPI_STATUS (AE_BAD_PARAMETER);
0601     }
0602 
0603     /* Allocate and init a handler object */
0604 
0605     NewSciHandler = ACPI_ALLOCATE (sizeof (ACPI_SCI_HANDLER_INFO));
0606     if (!NewSciHandler)
0607     {
0608         return_ACPI_STATUS (AE_NO_MEMORY);
0609     }
0610 
0611     NewSciHandler->Address = Address;
0612     NewSciHandler->Context = Context;
0613 
0614     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
0615     if (ACPI_FAILURE (Status))
0616     {
0617         goto Exit;
0618     }
0619 
0620     /* Lock list during installation */
0621 
0622     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
0623     SciHandler = AcpiGbl_SciHandlerList;
0624 
0625     /* Ensure handler does not already exist */
0626 
0627     while (SciHandler)
0628     {
0629         if (Address == SciHandler->Address)
0630         {
0631             Status = AE_ALREADY_EXISTS;
0632             goto UnlockAndExit;
0633         }
0634 
0635         SciHandler = SciHandler->Next;
0636     }
0637 
0638     /* Install the new handler into the global list (at head) */
0639 
0640     NewSciHandler->Next = AcpiGbl_SciHandlerList;
0641     AcpiGbl_SciHandlerList = NewSciHandler;
0642 
0643 
0644 UnlockAndExit:
0645 
0646     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
0647     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
0648 
0649 Exit:
0650     if (ACPI_FAILURE (Status))
0651     {
0652         ACPI_FREE (NewSciHandler);
0653     }
0654     return_ACPI_STATUS (Status);
0655 }
0656 
0657 ACPI_EXPORT_SYMBOL (AcpiInstallSciHandler)
0658 
0659 
0660 /*******************************************************************************
0661  *
0662  * FUNCTION:    AcpiRemoveSciHandler
0663  *
0664  * PARAMETERS:  Address             - Address of the handler
0665  *
0666  * RETURN:      Status
0667  *
0668  * DESCRIPTION: Remove a handler for a System Control Interrupt.
0669  *
0670  ******************************************************************************/
0671 
0672 ACPI_STATUS
0673 AcpiRemoveSciHandler (
0674     ACPI_SCI_HANDLER        Address)
0675 {
0676     ACPI_SCI_HANDLER_INFO   *PrevSciHandler;
0677     ACPI_SCI_HANDLER_INFO   *NextSciHandler;
0678     ACPI_CPU_FLAGS          Flags;
0679     ACPI_STATUS             Status;
0680 
0681 
0682     ACPI_FUNCTION_TRACE (AcpiRemoveSciHandler);
0683 
0684 
0685     if (!Address)
0686     {
0687         return_ACPI_STATUS (AE_BAD_PARAMETER);
0688     }
0689 
0690     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
0691     if (ACPI_FAILURE (Status))
0692     {
0693         return_ACPI_STATUS (Status);
0694     }
0695 
0696     /* Remove the SCI handler with lock */
0697 
0698     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
0699 
0700     PrevSciHandler = NULL;
0701     NextSciHandler = AcpiGbl_SciHandlerList;
0702     while (NextSciHandler)
0703     {
0704         if (NextSciHandler->Address == Address)
0705         {
0706             /* Unlink and free the SCI handler info block */
0707 
0708             if (PrevSciHandler)
0709             {
0710                 PrevSciHandler->Next = NextSciHandler->Next;
0711             }
0712             else
0713             {
0714                 AcpiGbl_SciHandlerList = NextSciHandler->Next;
0715             }
0716 
0717             AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
0718             ACPI_FREE (NextSciHandler);
0719             goto UnlockAndExit;
0720         }
0721 
0722         PrevSciHandler = NextSciHandler;
0723         NextSciHandler = NextSciHandler->Next;
0724     }
0725 
0726     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
0727     Status = AE_NOT_EXIST;
0728 
0729 
0730 UnlockAndExit:
0731     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
0732     return_ACPI_STATUS (Status);
0733 }
0734 
0735 ACPI_EXPORT_SYMBOL (AcpiRemoveSciHandler)
0736 
0737 
0738 /*******************************************************************************
0739  *
0740  * FUNCTION:    AcpiInstallGlobalEventHandler
0741  *
0742  * PARAMETERS:  Handler         - Pointer to the global event handler function
0743  *              Context         - Value passed to the handler on each event
0744  *
0745  * RETURN:      Status
0746  *
0747  * DESCRIPTION: Saves the pointer to the handler function. The global handler
0748  *              is invoked upon each incoming GPE and Fixed Event. It is
0749  *              invoked at interrupt level at the time of the event dispatch.
0750  *              Can be used to update event counters, etc.
0751  *
0752  ******************************************************************************/
0753 
0754 ACPI_STATUS
0755 AcpiInstallGlobalEventHandler (
0756     ACPI_GBL_EVENT_HANDLER  Handler,
0757     void                    *Context)
0758 {
0759     ACPI_STATUS             Status;
0760 
0761 
0762     ACPI_FUNCTION_TRACE (AcpiInstallGlobalEventHandler);
0763 
0764 
0765     /* Parameter validation */
0766 
0767     if (!Handler)
0768     {
0769         return_ACPI_STATUS (AE_BAD_PARAMETER);
0770     }
0771 
0772     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
0773     if (ACPI_FAILURE (Status))
0774     {
0775         return_ACPI_STATUS (Status);
0776     }
0777 
0778     /* Don't allow two handlers. */
0779 
0780     if (AcpiGbl_GlobalEventHandler)
0781     {
0782         Status = AE_ALREADY_EXISTS;
0783         goto Cleanup;
0784     }
0785 
0786     AcpiGbl_GlobalEventHandler = Handler;
0787     AcpiGbl_GlobalEventHandlerContext = Context;
0788 
0789 
0790 Cleanup:
0791     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
0792     return_ACPI_STATUS (Status);
0793 }
0794 
0795 ACPI_EXPORT_SYMBOL (AcpiInstallGlobalEventHandler)
0796 
0797 
0798 /*******************************************************************************
0799  *
0800  * FUNCTION:    AcpiInstallFixedEventHandler
0801  *
0802  * PARAMETERS:  Event           - Event type to enable.
0803  *              Handler         - Pointer to the handler function for the
0804  *                                event
0805  *              Context         - Value passed to the handler on each GPE
0806  *
0807  * RETURN:      Status
0808  *
0809  * DESCRIPTION: Saves the pointer to the handler function and then enables the
0810  *              event.
0811  *
0812  ******************************************************************************/
0813 
0814 ACPI_STATUS
0815 AcpiInstallFixedEventHandler (
0816     UINT32                  Event,
0817     ACPI_EVENT_HANDLER      Handler,
0818     void                    *Context)
0819 {
0820     ACPI_STATUS             Status;
0821 
0822 
0823     ACPI_FUNCTION_TRACE (AcpiInstallFixedEventHandler);
0824 
0825 
0826     /* Parameter validation */
0827 
0828     if (Event > ACPI_EVENT_MAX)
0829     {
0830         return_ACPI_STATUS (AE_BAD_PARAMETER);
0831     }
0832 
0833     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
0834     if (ACPI_FAILURE (Status))
0835     {
0836         return_ACPI_STATUS (Status);
0837     }
0838 
0839     /* Do not allow multiple handlers */
0840 
0841     if (AcpiGbl_FixedEventHandlers[Event].Handler)
0842     {
0843         Status = AE_ALREADY_EXISTS;
0844         goto Cleanup;
0845     }
0846 
0847     /* Install the handler before enabling the event */
0848 
0849     AcpiGbl_FixedEventHandlers[Event].Handler = Handler;
0850     AcpiGbl_FixedEventHandlers[Event].Context = Context;
0851 
0852     Status = AcpiEnableEvent (Event, 0);
0853     if (ACPI_FAILURE (Status))
0854     {
0855         ACPI_WARNING ((AE_INFO,
0856             "Could not enable fixed event - %s (%u)",
0857             AcpiUtGetEventName (Event), Event));
0858 
0859         /* Remove the handler */
0860 
0861         AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
0862         AcpiGbl_FixedEventHandlers[Event].Context = NULL;
0863     }
0864     else
0865     {
0866         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
0867             "Enabled fixed event %s (%X), Handler=%p\n",
0868             AcpiUtGetEventName (Event), Event, Handler));
0869     }
0870 
0871 
0872 Cleanup:
0873     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
0874     return_ACPI_STATUS (Status);
0875 }
0876 
0877 ACPI_EXPORT_SYMBOL (AcpiInstallFixedEventHandler)
0878 
0879 
0880 /*******************************************************************************
0881  *
0882  * FUNCTION:    AcpiRemoveFixedEventHandler
0883  *
0884  * PARAMETERS:  Event           - Event type to disable.
0885  *              Handler         - Address of the handler
0886  *
0887  * RETURN:      Status
0888  *
0889  * DESCRIPTION: Disables the event and unregisters the event handler.
0890  *
0891  ******************************************************************************/
0892 
0893 ACPI_STATUS
0894 AcpiRemoveFixedEventHandler (
0895     UINT32                  Event,
0896     ACPI_EVENT_HANDLER      Handler)
0897 {
0898     ACPI_STATUS             Status = AE_OK;
0899 
0900 
0901     ACPI_FUNCTION_TRACE (AcpiRemoveFixedEventHandler);
0902 
0903 
0904     /* Parameter validation */
0905 
0906     if (Event > ACPI_EVENT_MAX)
0907     {
0908         return_ACPI_STATUS (AE_BAD_PARAMETER);
0909     }
0910 
0911     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
0912     if (ACPI_FAILURE (Status))
0913     {
0914         return_ACPI_STATUS (Status);
0915     }
0916 
0917     /* Disable the event before removing the handler */
0918 
0919     Status = AcpiDisableEvent (Event, 0);
0920 
0921     /* Always Remove the handler */
0922 
0923     AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
0924     AcpiGbl_FixedEventHandlers[Event].Context = NULL;
0925 
0926     if (ACPI_FAILURE (Status))
0927     {
0928         ACPI_WARNING ((AE_INFO,
0929             "Could not disable fixed event - %s (%u)",
0930             AcpiUtGetEventName (Event), Event));
0931     }
0932     else
0933     {
0934         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
0935             "Disabled fixed event - %s (%X)\n",
0936             AcpiUtGetEventName (Event), Event));
0937     }
0938 
0939     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
0940     return_ACPI_STATUS (Status);
0941 }
0942 
0943 ACPI_EXPORT_SYMBOL (AcpiRemoveFixedEventHandler)
0944 
0945 
0946 /*******************************************************************************
0947  *
0948  * FUNCTION:    AcpiEvInstallGpeHandler
0949  *
0950  * PARAMETERS:  GpeDevice       - Namespace node for the GPE (NULL for FADT
0951  *                                defined GPEs)
0952  *              GpeNumber       - The GPE number within the GPE block
0953  *              Type            - Whether this GPE should be treated as an
0954  *                                edge- or level-triggered interrupt.
0955  *              IsRawHandler    - Whether this GPE should be handled using
0956  *                                the special GPE handler mode.
0957  *              Address         - Address of the handler
0958  *              Context         - Value passed to the handler on each GPE
0959  *
0960  * RETURN:      Status
0961  *
0962  * DESCRIPTION: Internal function to install a handler for a General Purpose
0963  *              Event.
0964  *
0965  ******************************************************************************/
0966 
0967 static ACPI_STATUS
0968 AcpiEvInstallGpeHandler (
0969     ACPI_HANDLE             GpeDevice,
0970     UINT32                  GpeNumber,
0971     UINT32                  Type,
0972     BOOLEAN                 IsRawHandler,
0973     ACPI_GPE_HANDLER        Address,
0974     void                    *Context)
0975 {
0976     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
0977     ACPI_GPE_HANDLER_INFO   *Handler;
0978     ACPI_STATUS             Status;
0979     ACPI_CPU_FLAGS          Flags;
0980 
0981 
0982     ACPI_FUNCTION_TRACE (EvInstallGpeHandler);
0983 
0984 
0985     /* Parameter validation */
0986 
0987     if ((!Address) || (Type & ~ACPI_GPE_XRUPT_TYPE_MASK))
0988     {
0989         return_ACPI_STATUS (AE_BAD_PARAMETER);
0990     }
0991 
0992     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
0993     if (ACPI_FAILURE (Status))
0994     {
0995         return_ACPI_STATUS (Status);
0996     }
0997 
0998     /* Allocate and init handler object (before lock) */
0999 
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 */