xref: /minix3/minix/drivers/power/acpi/events/evxface.c (revision 29492bb71c7148a089a5afafa0c99409161218df)
1433d6423SLionel Sambuc /******************************************************************************
2433d6423SLionel Sambuc  *
3433d6423SLionel Sambuc  * Module Name: evxface - External interfaces for ACPI events
4433d6423SLionel Sambuc  *
5433d6423SLionel Sambuc  *****************************************************************************/
6433d6423SLionel Sambuc 
7*29492bb7SDavid van Moolenbroek /*
8*29492bb7SDavid van Moolenbroek  * Copyright (C) 2000 - 2014, Intel Corp.
9433d6423SLionel Sambuc  * All rights reserved.
10433d6423SLionel Sambuc  *
11*29492bb7SDavid van Moolenbroek  * Redistribution and use in source and binary forms, with or without
12*29492bb7SDavid van Moolenbroek  * modification, are permitted provided that the following conditions
13*29492bb7SDavid van Moolenbroek  * are met:
14*29492bb7SDavid van Moolenbroek  * 1. Redistributions of source code must retain the above copyright
15*29492bb7SDavid van Moolenbroek  *    notice, this list of conditions, and the following disclaimer,
16*29492bb7SDavid van Moolenbroek  *    without modification.
17*29492bb7SDavid van Moolenbroek  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18*29492bb7SDavid van Moolenbroek  *    substantially similar to the "NO WARRANTY" disclaimer below
19*29492bb7SDavid van Moolenbroek  *    ("Disclaimer") and any redistribution must be conditioned upon
20*29492bb7SDavid van Moolenbroek  *    including a substantially similar Disclaimer requirement for further
21*29492bb7SDavid van Moolenbroek  *    binary redistribution.
22*29492bb7SDavid van Moolenbroek  * 3. Neither the names of the above-listed copyright holders nor the names
23*29492bb7SDavid van Moolenbroek  *    of any contributors may be used to endorse or promote products derived
24*29492bb7SDavid van Moolenbroek  *    from this software without specific prior written permission.
25433d6423SLionel Sambuc  *
26*29492bb7SDavid van Moolenbroek  * Alternatively, this software may be distributed under the terms of the
27*29492bb7SDavid van Moolenbroek  * GNU General Public License ("GPL") version 2 as published by the Free
28*29492bb7SDavid van Moolenbroek  * Software Foundation.
29433d6423SLionel Sambuc  *
30*29492bb7SDavid van Moolenbroek  * NO WARRANTY
31*29492bb7SDavid van Moolenbroek  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32*29492bb7SDavid van Moolenbroek  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33*29492bb7SDavid van Moolenbroek  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34*29492bb7SDavid van Moolenbroek  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35*29492bb7SDavid van Moolenbroek  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36*29492bb7SDavid van Moolenbroek  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37*29492bb7SDavid van Moolenbroek  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38*29492bb7SDavid van Moolenbroek  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39*29492bb7SDavid van Moolenbroek  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40*29492bb7SDavid van Moolenbroek  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41*29492bb7SDavid van Moolenbroek  * POSSIBILITY OF SUCH DAMAGES.
42*29492bb7SDavid van Moolenbroek  */
43433d6423SLionel Sambuc 
44*29492bb7SDavid van Moolenbroek #define EXPORT_ACPI_INTERFACES
45433d6423SLionel Sambuc 
46433d6423SLionel Sambuc #include "acpi.h"
47433d6423SLionel Sambuc #include "accommon.h"
48433d6423SLionel Sambuc #include "acnamesp.h"
49433d6423SLionel Sambuc #include "acevents.h"
50433d6423SLionel Sambuc #include "acinterp.h"
51433d6423SLionel Sambuc 
52433d6423SLionel Sambuc #define _COMPONENT          ACPI_EVENTS
53433d6423SLionel Sambuc         ACPI_MODULE_NAME    ("evxface")
54433d6423SLionel Sambuc 
55433d6423SLionel Sambuc 
56433d6423SLionel Sambuc /*******************************************************************************
57433d6423SLionel Sambuc  *
58*29492bb7SDavid van Moolenbroek  * FUNCTION:    AcpiInstallNotifyHandler
59*29492bb7SDavid van Moolenbroek  *
60*29492bb7SDavid van Moolenbroek  * PARAMETERS:  Device          - The device for which notifies will be handled
61*29492bb7SDavid van Moolenbroek  *              HandlerType     - The type of handler:
62*29492bb7SDavid van Moolenbroek  *                                  ACPI_SYSTEM_NOTIFY: System Handler (00-7F)
63*29492bb7SDavid van Moolenbroek  *                                  ACPI_DEVICE_NOTIFY: Device Handler (80-FF)
64*29492bb7SDavid van Moolenbroek  *                                  ACPI_ALL_NOTIFY:    Both System and Device
65*29492bb7SDavid van Moolenbroek  *              Handler         - Address of the handler
66*29492bb7SDavid van Moolenbroek  *              Context         - Value passed to the handler on each GPE
67*29492bb7SDavid van Moolenbroek  *
68*29492bb7SDavid van Moolenbroek  * RETURN:      Status
69*29492bb7SDavid van Moolenbroek  *
70*29492bb7SDavid van Moolenbroek  * DESCRIPTION: Install a handler for notifications on an ACPI Device,
71*29492bb7SDavid van Moolenbroek  *              ThermalZone, or Processor object.
72*29492bb7SDavid van Moolenbroek  *
73*29492bb7SDavid van Moolenbroek  * NOTES:       The Root namespace object may have only one handler for each
74*29492bb7SDavid van Moolenbroek  *              type of notify (System/Device). Device/Thermal/Processor objects
75*29492bb7SDavid van Moolenbroek  *              may have one device notify handler, and multiple system notify
76*29492bb7SDavid van Moolenbroek  *              handlers.
77*29492bb7SDavid van Moolenbroek  *
78*29492bb7SDavid van Moolenbroek  ******************************************************************************/
79*29492bb7SDavid van Moolenbroek 
80*29492bb7SDavid van Moolenbroek ACPI_STATUS
AcpiInstallNotifyHandler(ACPI_HANDLE Device,UINT32 HandlerType,ACPI_NOTIFY_HANDLER Handler,void * Context)81*29492bb7SDavid van Moolenbroek AcpiInstallNotifyHandler (
82*29492bb7SDavid van Moolenbroek     ACPI_HANDLE             Device,
83*29492bb7SDavid van Moolenbroek     UINT32                  HandlerType,
84*29492bb7SDavid van Moolenbroek     ACPI_NOTIFY_HANDLER     Handler,
85*29492bb7SDavid van Moolenbroek     void                    *Context)
86*29492bb7SDavid van Moolenbroek {
87*29492bb7SDavid van Moolenbroek     ACPI_NAMESPACE_NODE     *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device);
88*29492bb7SDavid van Moolenbroek     ACPI_OPERAND_OBJECT     *ObjDesc;
89*29492bb7SDavid van Moolenbroek     ACPI_OPERAND_OBJECT     *HandlerObj;
90*29492bb7SDavid van Moolenbroek     ACPI_STATUS             Status;
91*29492bb7SDavid van Moolenbroek     UINT32                  i;
92*29492bb7SDavid van Moolenbroek 
93*29492bb7SDavid van Moolenbroek 
94*29492bb7SDavid van Moolenbroek     ACPI_FUNCTION_TRACE (AcpiInstallNotifyHandler);
95*29492bb7SDavid van Moolenbroek 
96*29492bb7SDavid van Moolenbroek 
97*29492bb7SDavid van Moolenbroek     /* Parameter validation */
98*29492bb7SDavid van Moolenbroek 
99*29492bb7SDavid van Moolenbroek     if ((!Device) || (!Handler) || (!HandlerType) ||
100*29492bb7SDavid van Moolenbroek         (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
101*29492bb7SDavid van Moolenbroek     {
102*29492bb7SDavid van Moolenbroek         return_ACPI_STATUS (AE_BAD_PARAMETER);
103*29492bb7SDavid van Moolenbroek     }
104*29492bb7SDavid van Moolenbroek 
105*29492bb7SDavid van Moolenbroek     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
106*29492bb7SDavid van Moolenbroek     if (ACPI_FAILURE (Status))
107*29492bb7SDavid van Moolenbroek     {
108*29492bb7SDavid van Moolenbroek         return_ACPI_STATUS (Status);
109*29492bb7SDavid van Moolenbroek     }
110*29492bb7SDavid van Moolenbroek 
111*29492bb7SDavid van Moolenbroek     /*
112*29492bb7SDavid van Moolenbroek      * Root Object:
113*29492bb7SDavid van Moolenbroek      * Registering a notify handler on the root object indicates that the
114*29492bb7SDavid van Moolenbroek      * caller wishes to receive notifications for all objects. Note that
115*29492bb7SDavid van Moolenbroek      * only one global handler can be registered per notify type.
116*29492bb7SDavid van Moolenbroek      * Ensure that a handler is not already installed.
117*29492bb7SDavid van Moolenbroek      */
118*29492bb7SDavid van Moolenbroek     if (Device == ACPI_ROOT_OBJECT)
119*29492bb7SDavid van Moolenbroek     {
120*29492bb7SDavid van Moolenbroek         for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
121*29492bb7SDavid van Moolenbroek         {
122*29492bb7SDavid van Moolenbroek             if (HandlerType & (i+1))
123*29492bb7SDavid van Moolenbroek             {
124*29492bb7SDavid van Moolenbroek                 if (AcpiGbl_GlobalNotify[i].Handler)
125*29492bb7SDavid van Moolenbroek                 {
126*29492bb7SDavid van Moolenbroek                     Status = AE_ALREADY_EXISTS;
127*29492bb7SDavid van Moolenbroek                     goto UnlockAndExit;
128*29492bb7SDavid van Moolenbroek                 }
129*29492bb7SDavid van Moolenbroek 
130*29492bb7SDavid van Moolenbroek                 AcpiGbl_GlobalNotify[i].Handler = Handler;
131*29492bb7SDavid van Moolenbroek                 AcpiGbl_GlobalNotify[i].Context = Context;
132*29492bb7SDavid van Moolenbroek             }
133*29492bb7SDavid van Moolenbroek         }
134*29492bb7SDavid van Moolenbroek 
135*29492bb7SDavid van Moolenbroek         goto UnlockAndExit; /* Global notify handler installed, all done */
136*29492bb7SDavid van Moolenbroek     }
137*29492bb7SDavid van Moolenbroek 
138*29492bb7SDavid van Moolenbroek     /*
139*29492bb7SDavid van Moolenbroek      * All Other Objects:
140*29492bb7SDavid van Moolenbroek      * Caller will only receive notifications specific to the target
141*29492bb7SDavid van Moolenbroek      * object. Note that only certain object types are allowed to
142*29492bb7SDavid van Moolenbroek      * receive notifications.
143*29492bb7SDavid van Moolenbroek      */
144*29492bb7SDavid van Moolenbroek 
145*29492bb7SDavid van Moolenbroek     /* Are Notifies allowed on this object? */
146*29492bb7SDavid van Moolenbroek 
147*29492bb7SDavid van Moolenbroek     if (!AcpiEvIsNotifyObject (Node))
148*29492bb7SDavid van Moolenbroek     {
149*29492bb7SDavid van Moolenbroek         Status = AE_TYPE;
150*29492bb7SDavid van Moolenbroek         goto UnlockAndExit;
151*29492bb7SDavid van Moolenbroek     }
152*29492bb7SDavid van Moolenbroek 
153*29492bb7SDavid van Moolenbroek     /* Check for an existing internal object, might not exist */
154*29492bb7SDavid van Moolenbroek 
155*29492bb7SDavid van Moolenbroek     ObjDesc = AcpiNsGetAttachedObject (Node);
156*29492bb7SDavid van Moolenbroek     if (!ObjDesc)
157*29492bb7SDavid van Moolenbroek     {
158*29492bb7SDavid van Moolenbroek         /* Create a new object */
159*29492bb7SDavid van Moolenbroek 
160*29492bb7SDavid van Moolenbroek         ObjDesc = AcpiUtCreateInternalObject (Node->Type);
161*29492bb7SDavid van Moolenbroek         if (!ObjDesc)
162*29492bb7SDavid van Moolenbroek         {
163*29492bb7SDavid van Moolenbroek             Status = AE_NO_MEMORY;
164*29492bb7SDavid van Moolenbroek             goto UnlockAndExit;
165*29492bb7SDavid van Moolenbroek         }
166*29492bb7SDavid van Moolenbroek 
167*29492bb7SDavid van Moolenbroek         /* Attach new object to the Node, remove local reference */
168*29492bb7SDavid van Moolenbroek 
169*29492bb7SDavid van Moolenbroek         Status = AcpiNsAttachObject (Device, ObjDesc, Node->Type);
170*29492bb7SDavid van Moolenbroek         AcpiUtRemoveReference (ObjDesc);
171*29492bb7SDavid van Moolenbroek         if (ACPI_FAILURE (Status))
172*29492bb7SDavid van Moolenbroek         {
173*29492bb7SDavid van Moolenbroek             goto UnlockAndExit;
174*29492bb7SDavid van Moolenbroek         }
175*29492bb7SDavid van Moolenbroek     }
176*29492bb7SDavid van Moolenbroek 
177*29492bb7SDavid van Moolenbroek     /* Ensure that the handler is not already installed in the lists */
178*29492bb7SDavid van Moolenbroek 
179*29492bb7SDavid van Moolenbroek     for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
180*29492bb7SDavid van Moolenbroek     {
181*29492bb7SDavid van Moolenbroek         if (HandlerType & (i+1))
182*29492bb7SDavid van Moolenbroek         {
183*29492bb7SDavid van Moolenbroek             HandlerObj = ObjDesc->CommonNotify.NotifyList[i];
184*29492bb7SDavid van Moolenbroek             while (HandlerObj)
185*29492bb7SDavid van Moolenbroek             {
186*29492bb7SDavid van Moolenbroek                 if (HandlerObj->Notify.Handler == Handler)
187*29492bb7SDavid van Moolenbroek                 {
188*29492bb7SDavid van Moolenbroek                     Status = AE_ALREADY_EXISTS;
189*29492bb7SDavid van Moolenbroek                     goto UnlockAndExit;
190*29492bb7SDavid van Moolenbroek                 }
191*29492bb7SDavid van Moolenbroek 
192*29492bb7SDavid van Moolenbroek                 HandlerObj = HandlerObj->Notify.Next[i];
193*29492bb7SDavid van Moolenbroek             }
194*29492bb7SDavid van Moolenbroek         }
195*29492bb7SDavid van Moolenbroek     }
196*29492bb7SDavid van Moolenbroek 
197*29492bb7SDavid van Moolenbroek     /* Create and populate a new notify handler object */
198*29492bb7SDavid van Moolenbroek 
199*29492bb7SDavid van Moolenbroek     HandlerObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_NOTIFY);
200*29492bb7SDavid van Moolenbroek     if (!HandlerObj)
201*29492bb7SDavid van Moolenbroek     {
202*29492bb7SDavid van Moolenbroek         Status = AE_NO_MEMORY;
203*29492bb7SDavid van Moolenbroek         goto UnlockAndExit;
204*29492bb7SDavid van Moolenbroek     }
205*29492bb7SDavid van Moolenbroek 
206*29492bb7SDavid van Moolenbroek     HandlerObj->Notify.Node = Node;
207*29492bb7SDavid van Moolenbroek     HandlerObj->Notify.HandlerType = HandlerType;
208*29492bb7SDavid van Moolenbroek     HandlerObj->Notify.Handler = Handler;
209*29492bb7SDavid van Moolenbroek     HandlerObj->Notify.Context = Context;
210*29492bb7SDavid van Moolenbroek 
211*29492bb7SDavid van Moolenbroek     /* Install the handler at the list head(s) */
212*29492bb7SDavid van Moolenbroek 
213*29492bb7SDavid van Moolenbroek     for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
214*29492bb7SDavid van Moolenbroek     {
215*29492bb7SDavid van Moolenbroek         if (HandlerType & (i+1))
216*29492bb7SDavid van Moolenbroek         {
217*29492bb7SDavid van Moolenbroek             HandlerObj->Notify.Next[i] =
218*29492bb7SDavid van Moolenbroek                 ObjDesc->CommonNotify.NotifyList[i];
219*29492bb7SDavid van Moolenbroek 
220*29492bb7SDavid van Moolenbroek             ObjDesc->CommonNotify.NotifyList[i] = HandlerObj;
221*29492bb7SDavid van Moolenbroek         }
222*29492bb7SDavid van Moolenbroek     }
223*29492bb7SDavid van Moolenbroek 
224*29492bb7SDavid van Moolenbroek     /* Add an extra reference if handler was installed in both lists */
225*29492bb7SDavid van Moolenbroek 
226*29492bb7SDavid van Moolenbroek     if (HandlerType == ACPI_ALL_NOTIFY)
227*29492bb7SDavid van Moolenbroek     {
228*29492bb7SDavid van Moolenbroek         AcpiUtAddReference (HandlerObj);
229*29492bb7SDavid van Moolenbroek     }
230*29492bb7SDavid van Moolenbroek 
231*29492bb7SDavid van Moolenbroek 
232*29492bb7SDavid van Moolenbroek UnlockAndExit:
233*29492bb7SDavid van Moolenbroek     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
234*29492bb7SDavid van Moolenbroek     return_ACPI_STATUS (Status);
235*29492bb7SDavid van Moolenbroek }
236*29492bb7SDavid van Moolenbroek 
ACPI_EXPORT_SYMBOL(AcpiInstallNotifyHandler)237*29492bb7SDavid van Moolenbroek ACPI_EXPORT_SYMBOL (AcpiInstallNotifyHandler)
238*29492bb7SDavid van Moolenbroek 
239*29492bb7SDavid van Moolenbroek 
240*29492bb7SDavid van Moolenbroek /*******************************************************************************
241*29492bb7SDavid van Moolenbroek  *
242*29492bb7SDavid van Moolenbroek  * FUNCTION:    AcpiRemoveNotifyHandler
243*29492bb7SDavid van Moolenbroek  *
244*29492bb7SDavid van Moolenbroek  * PARAMETERS:  Device          - The device for which the handler is installed
245*29492bb7SDavid van Moolenbroek  *              HandlerType     - The type of handler:
246*29492bb7SDavid van Moolenbroek  *                                  ACPI_SYSTEM_NOTIFY: System Handler (00-7F)
247*29492bb7SDavid van Moolenbroek  *                                  ACPI_DEVICE_NOTIFY: Device Handler (80-FF)
248*29492bb7SDavid van Moolenbroek  *                                  ACPI_ALL_NOTIFY:    Both System and Device
249*29492bb7SDavid van Moolenbroek  *              Handler         - Address of the handler
250*29492bb7SDavid van Moolenbroek  *
251*29492bb7SDavid van Moolenbroek  * RETURN:      Status
252*29492bb7SDavid van Moolenbroek  *
253*29492bb7SDavid van Moolenbroek  * DESCRIPTION: Remove a handler for notifies on an ACPI device
254*29492bb7SDavid van Moolenbroek  *
255*29492bb7SDavid van Moolenbroek  ******************************************************************************/
256*29492bb7SDavid van Moolenbroek 
257*29492bb7SDavid van Moolenbroek ACPI_STATUS
258*29492bb7SDavid van Moolenbroek AcpiRemoveNotifyHandler (
259*29492bb7SDavid van Moolenbroek     ACPI_HANDLE             Device,
260*29492bb7SDavid van Moolenbroek     UINT32                  HandlerType,
261*29492bb7SDavid van Moolenbroek     ACPI_NOTIFY_HANDLER     Handler)
262*29492bb7SDavid van Moolenbroek {
263*29492bb7SDavid van Moolenbroek     ACPI_NAMESPACE_NODE     *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device);
264*29492bb7SDavid van Moolenbroek     ACPI_OPERAND_OBJECT     *ObjDesc;
265*29492bb7SDavid van Moolenbroek     ACPI_OPERAND_OBJECT     *HandlerObj;
266*29492bb7SDavid van Moolenbroek     ACPI_OPERAND_OBJECT     *PreviousHandlerObj;
267*29492bb7SDavid van Moolenbroek     ACPI_STATUS             Status = AE_OK;
268*29492bb7SDavid van Moolenbroek     UINT32                  i;
269*29492bb7SDavid van Moolenbroek 
270*29492bb7SDavid van Moolenbroek 
271*29492bb7SDavid van Moolenbroek     ACPI_FUNCTION_TRACE (AcpiRemoveNotifyHandler);
272*29492bb7SDavid van Moolenbroek 
273*29492bb7SDavid van Moolenbroek 
274*29492bb7SDavid van Moolenbroek     /* Parameter validation */
275*29492bb7SDavid van Moolenbroek 
276*29492bb7SDavid van Moolenbroek     if ((!Device) || (!Handler) || (!HandlerType) ||
277*29492bb7SDavid van Moolenbroek         (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
278*29492bb7SDavid van Moolenbroek     {
279*29492bb7SDavid van Moolenbroek         return_ACPI_STATUS (AE_BAD_PARAMETER);
280*29492bb7SDavid van Moolenbroek     }
281*29492bb7SDavid van Moolenbroek 
282*29492bb7SDavid van Moolenbroek     /* Root Object. Global handlers are removed here */
283*29492bb7SDavid van Moolenbroek 
284*29492bb7SDavid van Moolenbroek     if (Device == ACPI_ROOT_OBJECT)
285*29492bb7SDavid van Moolenbroek     {
286*29492bb7SDavid van Moolenbroek         for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
287*29492bb7SDavid van Moolenbroek         {
288*29492bb7SDavid van Moolenbroek             if (HandlerType & (i+1))
289*29492bb7SDavid van Moolenbroek             {
290*29492bb7SDavid van Moolenbroek                 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
291*29492bb7SDavid van Moolenbroek                 if (ACPI_FAILURE (Status))
292*29492bb7SDavid van Moolenbroek                 {
293*29492bb7SDavid van Moolenbroek                     return_ACPI_STATUS (Status);
294*29492bb7SDavid van Moolenbroek                 }
295*29492bb7SDavid van Moolenbroek 
296*29492bb7SDavid van Moolenbroek                 if (!AcpiGbl_GlobalNotify[i].Handler ||
297*29492bb7SDavid van Moolenbroek                     (AcpiGbl_GlobalNotify[i].Handler != Handler))
298*29492bb7SDavid van Moolenbroek                 {
299*29492bb7SDavid van Moolenbroek                     Status = AE_NOT_EXIST;
300*29492bb7SDavid van Moolenbroek                     goto UnlockAndExit;
301*29492bb7SDavid van Moolenbroek                 }
302*29492bb7SDavid van Moolenbroek 
303*29492bb7SDavid van Moolenbroek                 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
304*29492bb7SDavid van Moolenbroek                     "Removing global notify handler\n"));
305*29492bb7SDavid van Moolenbroek 
306*29492bb7SDavid van Moolenbroek                 AcpiGbl_GlobalNotify[i].Handler = NULL;
307*29492bb7SDavid van Moolenbroek                 AcpiGbl_GlobalNotify[i].Context = NULL;
308*29492bb7SDavid van Moolenbroek 
309*29492bb7SDavid van Moolenbroek                 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
310*29492bb7SDavid van Moolenbroek 
311*29492bb7SDavid van Moolenbroek                 /* Make sure all deferred notify tasks are completed */
312*29492bb7SDavid van Moolenbroek 
313*29492bb7SDavid van Moolenbroek                 AcpiOsWaitEventsComplete ();
314*29492bb7SDavid van Moolenbroek             }
315*29492bb7SDavid van Moolenbroek         }
316*29492bb7SDavid van Moolenbroek 
317*29492bb7SDavid van Moolenbroek         return_ACPI_STATUS (AE_OK);
318*29492bb7SDavid van Moolenbroek     }
319*29492bb7SDavid van Moolenbroek 
320*29492bb7SDavid van Moolenbroek     /* All other objects: Are Notifies allowed on this object? */
321*29492bb7SDavid van Moolenbroek 
322*29492bb7SDavid van Moolenbroek     if (!AcpiEvIsNotifyObject (Node))
323*29492bb7SDavid van Moolenbroek     {
324*29492bb7SDavid van Moolenbroek         return_ACPI_STATUS (AE_TYPE);
325*29492bb7SDavid van Moolenbroek     }
326*29492bb7SDavid van Moolenbroek 
327*29492bb7SDavid van Moolenbroek     /* Must have an existing internal object */
328*29492bb7SDavid van Moolenbroek 
329*29492bb7SDavid van Moolenbroek     ObjDesc = AcpiNsGetAttachedObject (Node);
330*29492bb7SDavid van Moolenbroek     if (!ObjDesc)
331*29492bb7SDavid van Moolenbroek     {
332*29492bb7SDavid van Moolenbroek         return_ACPI_STATUS (AE_NOT_EXIST);
333*29492bb7SDavid van Moolenbroek     }
334*29492bb7SDavid van Moolenbroek 
335*29492bb7SDavid van Moolenbroek     /* Internal object exists. Find the handler and remove it */
336*29492bb7SDavid van Moolenbroek 
337*29492bb7SDavid van Moolenbroek     for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
338*29492bb7SDavid van Moolenbroek     {
339*29492bb7SDavid van Moolenbroek         if (HandlerType & (i+1))
340*29492bb7SDavid van Moolenbroek         {
341*29492bb7SDavid van Moolenbroek             Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
342*29492bb7SDavid van Moolenbroek             if (ACPI_FAILURE (Status))
343*29492bb7SDavid van Moolenbroek             {
344*29492bb7SDavid van Moolenbroek                 return_ACPI_STATUS (Status);
345*29492bb7SDavid van Moolenbroek             }
346*29492bb7SDavid van Moolenbroek 
347*29492bb7SDavid van Moolenbroek             HandlerObj = ObjDesc->CommonNotify.NotifyList[i];
348*29492bb7SDavid van Moolenbroek             PreviousHandlerObj = NULL;
349*29492bb7SDavid van Moolenbroek 
350*29492bb7SDavid van Moolenbroek             /* Attempt to find the handler in the handler list */
351*29492bb7SDavid van Moolenbroek 
352*29492bb7SDavid van Moolenbroek             while (HandlerObj &&
353*29492bb7SDavid van Moolenbroek                   (HandlerObj->Notify.Handler != Handler))
354*29492bb7SDavid van Moolenbroek             {
355*29492bb7SDavid van Moolenbroek                 PreviousHandlerObj = HandlerObj;
356*29492bb7SDavid van Moolenbroek                 HandlerObj = HandlerObj->Notify.Next[i];
357*29492bb7SDavid van Moolenbroek             }
358*29492bb7SDavid van Moolenbroek 
359*29492bb7SDavid van Moolenbroek             if (!HandlerObj)
360*29492bb7SDavid van Moolenbroek             {
361*29492bb7SDavid van Moolenbroek                 Status = AE_NOT_EXIST;
362*29492bb7SDavid van Moolenbroek                 goto UnlockAndExit;
363*29492bb7SDavid van Moolenbroek             }
364*29492bb7SDavid van Moolenbroek 
365*29492bb7SDavid van Moolenbroek             /* Remove the handler object from the list */
366*29492bb7SDavid van Moolenbroek 
367*29492bb7SDavid van Moolenbroek             if (PreviousHandlerObj) /* Handler is not at the list head */
368*29492bb7SDavid van Moolenbroek             {
369*29492bb7SDavid van Moolenbroek                 PreviousHandlerObj->Notify.Next[i] =
370*29492bb7SDavid van Moolenbroek                     HandlerObj->Notify.Next[i];
371*29492bb7SDavid van Moolenbroek             }
372*29492bb7SDavid van Moolenbroek             else /* Handler is at the list head */
373*29492bb7SDavid van Moolenbroek             {
374*29492bb7SDavid van Moolenbroek                 ObjDesc->CommonNotify.NotifyList[i] =
375*29492bb7SDavid van Moolenbroek                     HandlerObj->Notify.Next[i];
376*29492bb7SDavid van Moolenbroek             }
377*29492bb7SDavid van Moolenbroek 
378*29492bb7SDavid van Moolenbroek             (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
379*29492bb7SDavid van Moolenbroek 
380*29492bb7SDavid van Moolenbroek             /* Make sure all deferred notify tasks are completed */
381*29492bb7SDavid van Moolenbroek 
382*29492bb7SDavid van Moolenbroek             AcpiOsWaitEventsComplete ();
383*29492bb7SDavid van Moolenbroek             AcpiUtRemoveReference (HandlerObj);
384*29492bb7SDavid van Moolenbroek         }
385*29492bb7SDavid van Moolenbroek     }
386*29492bb7SDavid van Moolenbroek 
387*29492bb7SDavid van Moolenbroek     return_ACPI_STATUS (Status);
388*29492bb7SDavid van Moolenbroek 
389*29492bb7SDavid van Moolenbroek 
390*29492bb7SDavid van Moolenbroek UnlockAndExit:
391*29492bb7SDavid van Moolenbroek     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
392*29492bb7SDavid van Moolenbroek     return_ACPI_STATUS (Status);
393*29492bb7SDavid van Moolenbroek }
394*29492bb7SDavid van Moolenbroek 
ACPI_EXPORT_SYMBOL(AcpiRemoveNotifyHandler)395*29492bb7SDavid van Moolenbroek ACPI_EXPORT_SYMBOL (AcpiRemoveNotifyHandler)
396*29492bb7SDavid van Moolenbroek 
397*29492bb7SDavid van Moolenbroek 
398*29492bb7SDavid van Moolenbroek /*******************************************************************************
399*29492bb7SDavid van Moolenbroek  *
400433d6423SLionel Sambuc  * FUNCTION:    AcpiInstallExceptionHandler
401433d6423SLionel Sambuc  *
402433d6423SLionel Sambuc  * PARAMETERS:  Handler         - Pointer to the handler function for the
403433d6423SLionel Sambuc  *                                event
404433d6423SLionel Sambuc  *
405433d6423SLionel Sambuc  * RETURN:      Status
406433d6423SLionel Sambuc  *
407433d6423SLionel Sambuc  * DESCRIPTION: Saves the pointer to the handler function
408433d6423SLionel Sambuc  *
409433d6423SLionel Sambuc  ******************************************************************************/
410433d6423SLionel Sambuc 
411433d6423SLionel Sambuc ACPI_STATUS
412433d6423SLionel Sambuc AcpiInstallExceptionHandler (
413433d6423SLionel Sambuc     ACPI_EXCEPTION_HANDLER  Handler)
414433d6423SLionel Sambuc {
415433d6423SLionel Sambuc     ACPI_STATUS             Status;
416433d6423SLionel Sambuc 
417433d6423SLionel Sambuc 
418433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE (AcpiInstallExceptionHandler);
419433d6423SLionel Sambuc 
420433d6423SLionel Sambuc 
421433d6423SLionel Sambuc     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
422433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
423433d6423SLionel Sambuc     {
424433d6423SLionel Sambuc         return_ACPI_STATUS (Status);
425433d6423SLionel Sambuc     }
426433d6423SLionel Sambuc 
427433d6423SLionel Sambuc     /* Don't allow two handlers. */
428433d6423SLionel Sambuc 
429433d6423SLionel Sambuc     if (AcpiGbl_ExceptionHandler)
430433d6423SLionel Sambuc     {
431433d6423SLionel Sambuc         Status = AE_ALREADY_EXISTS;
432433d6423SLionel Sambuc         goto Cleanup;
433433d6423SLionel Sambuc     }
434433d6423SLionel Sambuc 
435433d6423SLionel Sambuc     /* Install the handler */
436433d6423SLionel Sambuc 
437433d6423SLionel Sambuc     AcpiGbl_ExceptionHandler = Handler;
438433d6423SLionel Sambuc 
439433d6423SLionel Sambuc Cleanup:
440433d6423SLionel Sambuc     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
441433d6423SLionel Sambuc     return_ACPI_STATUS (Status);
442433d6423SLionel Sambuc }
443433d6423SLionel Sambuc 
ACPI_EXPORT_SYMBOL(AcpiInstallExceptionHandler)444433d6423SLionel Sambuc ACPI_EXPORT_SYMBOL (AcpiInstallExceptionHandler)
445433d6423SLionel Sambuc 
446433d6423SLionel Sambuc 
447*29492bb7SDavid van Moolenbroek #if (!ACPI_REDUCED_HARDWARE)
448*29492bb7SDavid van Moolenbroek /*******************************************************************************
449*29492bb7SDavid van Moolenbroek  *
450*29492bb7SDavid van Moolenbroek  * FUNCTION:    AcpiInstallSciHandler
451*29492bb7SDavid van Moolenbroek  *
452*29492bb7SDavid van Moolenbroek  * PARAMETERS:  Address             - Address of the handler
453*29492bb7SDavid van Moolenbroek  *              Context             - Value passed to the handler on each SCI
454*29492bb7SDavid van Moolenbroek  *
455*29492bb7SDavid van Moolenbroek  * RETURN:      Status
456*29492bb7SDavid van Moolenbroek  *
457*29492bb7SDavid van Moolenbroek  * DESCRIPTION: Install a handler for a System Control Interrupt.
458*29492bb7SDavid van Moolenbroek  *
459*29492bb7SDavid van Moolenbroek  ******************************************************************************/
460*29492bb7SDavid van Moolenbroek 
461*29492bb7SDavid van Moolenbroek ACPI_STATUS
462*29492bb7SDavid van Moolenbroek AcpiInstallSciHandler (
463*29492bb7SDavid van Moolenbroek     ACPI_SCI_HANDLER        Address,
464*29492bb7SDavid van Moolenbroek     void                    *Context)
465*29492bb7SDavid van Moolenbroek {
466*29492bb7SDavid van Moolenbroek     ACPI_SCI_HANDLER_INFO   *NewSciHandler;
467*29492bb7SDavid van Moolenbroek     ACPI_SCI_HANDLER_INFO   *SciHandler;
468*29492bb7SDavid van Moolenbroek     ACPI_CPU_FLAGS          Flags;
469*29492bb7SDavid van Moolenbroek     ACPI_STATUS             Status;
470*29492bb7SDavid van Moolenbroek 
471*29492bb7SDavid van Moolenbroek 
472*29492bb7SDavid van Moolenbroek     ACPI_FUNCTION_TRACE (AcpiInstallSciHandler);
473*29492bb7SDavid van Moolenbroek 
474*29492bb7SDavid van Moolenbroek 
475*29492bb7SDavid van Moolenbroek     if (!Address)
476*29492bb7SDavid van Moolenbroek     {
477*29492bb7SDavid van Moolenbroek         return_ACPI_STATUS (AE_BAD_PARAMETER);
478*29492bb7SDavid van Moolenbroek     }
479*29492bb7SDavid van Moolenbroek 
480*29492bb7SDavid van Moolenbroek     /* Allocate and init a handler object */
481*29492bb7SDavid van Moolenbroek 
482*29492bb7SDavid van Moolenbroek     NewSciHandler = ACPI_ALLOCATE (sizeof (ACPI_SCI_HANDLER_INFO));
483*29492bb7SDavid van Moolenbroek     if (!NewSciHandler)
484*29492bb7SDavid van Moolenbroek     {
485*29492bb7SDavid van Moolenbroek         return_ACPI_STATUS (AE_NO_MEMORY);
486*29492bb7SDavid van Moolenbroek     }
487*29492bb7SDavid van Moolenbroek 
488*29492bb7SDavid van Moolenbroek     NewSciHandler->Address = Address;
489*29492bb7SDavid van Moolenbroek     NewSciHandler->Context = Context;
490*29492bb7SDavid van Moolenbroek 
491*29492bb7SDavid van Moolenbroek     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
492*29492bb7SDavid van Moolenbroek     if (ACPI_FAILURE (Status))
493*29492bb7SDavid van Moolenbroek     {
494*29492bb7SDavid van Moolenbroek         goto Exit;
495*29492bb7SDavid van Moolenbroek     }
496*29492bb7SDavid van Moolenbroek 
497*29492bb7SDavid van Moolenbroek     /* Lock list during installation */
498*29492bb7SDavid van Moolenbroek 
499*29492bb7SDavid van Moolenbroek     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
500*29492bb7SDavid van Moolenbroek     SciHandler = AcpiGbl_SciHandlerList;
501*29492bb7SDavid van Moolenbroek 
502*29492bb7SDavid van Moolenbroek     /* Ensure handler does not already exist */
503*29492bb7SDavid van Moolenbroek 
504*29492bb7SDavid van Moolenbroek     while (SciHandler)
505*29492bb7SDavid van Moolenbroek     {
506*29492bb7SDavid van Moolenbroek         if (Address == SciHandler->Address)
507*29492bb7SDavid van Moolenbroek         {
508*29492bb7SDavid van Moolenbroek             Status = AE_ALREADY_EXISTS;
509*29492bb7SDavid van Moolenbroek             goto UnlockAndExit;
510*29492bb7SDavid van Moolenbroek         }
511*29492bb7SDavid van Moolenbroek 
512*29492bb7SDavid van Moolenbroek         SciHandler = SciHandler->Next;
513*29492bb7SDavid van Moolenbroek     }
514*29492bb7SDavid van Moolenbroek 
515*29492bb7SDavid van Moolenbroek     /* Install the new handler into the global list (at head) */
516*29492bb7SDavid van Moolenbroek 
517*29492bb7SDavid van Moolenbroek     NewSciHandler->Next = AcpiGbl_SciHandlerList;
518*29492bb7SDavid van Moolenbroek     AcpiGbl_SciHandlerList = NewSciHandler;
519*29492bb7SDavid van Moolenbroek 
520*29492bb7SDavid van Moolenbroek 
521*29492bb7SDavid van Moolenbroek UnlockAndExit:
522*29492bb7SDavid van Moolenbroek 
523*29492bb7SDavid van Moolenbroek     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
524*29492bb7SDavid van Moolenbroek     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
525*29492bb7SDavid van Moolenbroek 
526*29492bb7SDavid van Moolenbroek Exit:
527*29492bb7SDavid van Moolenbroek     if (ACPI_FAILURE (Status))
528*29492bb7SDavid van Moolenbroek     {
529*29492bb7SDavid van Moolenbroek         ACPI_FREE (NewSciHandler);
530*29492bb7SDavid van Moolenbroek     }
531*29492bb7SDavid van Moolenbroek     return_ACPI_STATUS (Status);
532*29492bb7SDavid van Moolenbroek }
533*29492bb7SDavid van Moolenbroek 
ACPI_EXPORT_SYMBOL(AcpiInstallSciHandler)534*29492bb7SDavid van Moolenbroek ACPI_EXPORT_SYMBOL (AcpiInstallSciHandler)
535*29492bb7SDavid van Moolenbroek 
536*29492bb7SDavid van Moolenbroek 
537*29492bb7SDavid van Moolenbroek /*******************************************************************************
538*29492bb7SDavid van Moolenbroek  *
539*29492bb7SDavid van Moolenbroek  * FUNCTION:    AcpiRemoveSciHandler
540*29492bb7SDavid van Moolenbroek  *
541*29492bb7SDavid van Moolenbroek  * PARAMETERS:  Address             - Address of the handler
542*29492bb7SDavid van Moolenbroek  *
543*29492bb7SDavid van Moolenbroek  * RETURN:      Status
544*29492bb7SDavid van Moolenbroek  *
545*29492bb7SDavid van Moolenbroek  * DESCRIPTION: Remove a handler for a System Control Interrupt.
546*29492bb7SDavid van Moolenbroek  *
547*29492bb7SDavid van Moolenbroek  ******************************************************************************/
548*29492bb7SDavid van Moolenbroek 
549*29492bb7SDavid van Moolenbroek ACPI_STATUS
550*29492bb7SDavid van Moolenbroek AcpiRemoveSciHandler (
551*29492bb7SDavid van Moolenbroek     ACPI_SCI_HANDLER        Address)
552*29492bb7SDavid van Moolenbroek {
553*29492bb7SDavid van Moolenbroek     ACPI_SCI_HANDLER_INFO   *PrevSciHandler;
554*29492bb7SDavid van Moolenbroek     ACPI_SCI_HANDLER_INFO   *NextSciHandler;
555*29492bb7SDavid van Moolenbroek     ACPI_CPU_FLAGS          Flags;
556*29492bb7SDavid van Moolenbroek     ACPI_STATUS             Status;
557*29492bb7SDavid van Moolenbroek 
558*29492bb7SDavid van Moolenbroek 
559*29492bb7SDavid van Moolenbroek     ACPI_FUNCTION_TRACE (AcpiRemoveSciHandler);
560*29492bb7SDavid van Moolenbroek 
561*29492bb7SDavid van Moolenbroek 
562*29492bb7SDavid van Moolenbroek     if (!Address)
563*29492bb7SDavid van Moolenbroek     {
564*29492bb7SDavid van Moolenbroek         return_ACPI_STATUS (AE_BAD_PARAMETER);
565*29492bb7SDavid van Moolenbroek     }
566*29492bb7SDavid van Moolenbroek 
567*29492bb7SDavid van Moolenbroek     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
568*29492bb7SDavid van Moolenbroek     if (ACPI_FAILURE (Status))
569*29492bb7SDavid van Moolenbroek     {
570*29492bb7SDavid van Moolenbroek         return_ACPI_STATUS (Status);
571*29492bb7SDavid van Moolenbroek     }
572*29492bb7SDavid van Moolenbroek 
573*29492bb7SDavid van Moolenbroek     /* Remove the SCI handler with lock */
574*29492bb7SDavid van Moolenbroek 
575*29492bb7SDavid van Moolenbroek     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
576*29492bb7SDavid van Moolenbroek 
577*29492bb7SDavid van Moolenbroek     PrevSciHandler = NULL;
578*29492bb7SDavid van Moolenbroek     NextSciHandler = AcpiGbl_SciHandlerList;
579*29492bb7SDavid van Moolenbroek     while (NextSciHandler)
580*29492bb7SDavid van Moolenbroek     {
581*29492bb7SDavid van Moolenbroek         if (NextSciHandler->Address == Address)
582*29492bb7SDavid van Moolenbroek         {
583*29492bb7SDavid van Moolenbroek             /* Unlink and free the SCI handler info block */
584*29492bb7SDavid van Moolenbroek 
585*29492bb7SDavid van Moolenbroek             if (PrevSciHandler)
586*29492bb7SDavid van Moolenbroek             {
587*29492bb7SDavid van Moolenbroek                 PrevSciHandler->Next = NextSciHandler->Next;
588*29492bb7SDavid van Moolenbroek             }
589*29492bb7SDavid van Moolenbroek             else
590*29492bb7SDavid van Moolenbroek             {
591*29492bb7SDavid van Moolenbroek                 AcpiGbl_SciHandlerList = NextSciHandler->Next;
592*29492bb7SDavid van Moolenbroek             }
593*29492bb7SDavid van Moolenbroek 
594*29492bb7SDavid van Moolenbroek             AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
595*29492bb7SDavid van Moolenbroek             ACPI_FREE (NextSciHandler);
596*29492bb7SDavid van Moolenbroek             goto UnlockAndExit;
597*29492bb7SDavid van Moolenbroek         }
598*29492bb7SDavid van Moolenbroek 
599*29492bb7SDavid van Moolenbroek         PrevSciHandler = NextSciHandler;
600*29492bb7SDavid van Moolenbroek         NextSciHandler = NextSciHandler->Next;
601*29492bb7SDavid van Moolenbroek     }
602*29492bb7SDavid van Moolenbroek 
603*29492bb7SDavid van Moolenbroek     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
604*29492bb7SDavid van Moolenbroek     Status = AE_NOT_EXIST;
605*29492bb7SDavid van Moolenbroek 
606*29492bb7SDavid van Moolenbroek 
607*29492bb7SDavid van Moolenbroek UnlockAndExit:
608*29492bb7SDavid van Moolenbroek     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
609*29492bb7SDavid van Moolenbroek     return_ACPI_STATUS (Status);
610*29492bb7SDavid van Moolenbroek }
611*29492bb7SDavid van Moolenbroek 
ACPI_EXPORT_SYMBOL(AcpiRemoveSciHandler)612*29492bb7SDavid van Moolenbroek ACPI_EXPORT_SYMBOL (AcpiRemoveSciHandler)
613*29492bb7SDavid van Moolenbroek 
614*29492bb7SDavid van Moolenbroek 
615*29492bb7SDavid van Moolenbroek /*******************************************************************************
616*29492bb7SDavid van Moolenbroek  *
617*29492bb7SDavid van Moolenbroek  * FUNCTION:    AcpiInstallGlobalEventHandler
618*29492bb7SDavid van Moolenbroek  *
619*29492bb7SDavid van Moolenbroek  * PARAMETERS:  Handler         - Pointer to the global event handler function
620*29492bb7SDavid van Moolenbroek  *              Context         - Value passed to the handler on each event
621*29492bb7SDavid van Moolenbroek  *
622*29492bb7SDavid van Moolenbroek  * RETURN:      Status
623*29492bb7SDavid van Moolenbroek  *
624*29492bb7SDavid van Moolenbroek  * DESCRIPTION: Saves the pointer to the handler function. The global handler
625*29492bb7SDavid van Moolenbroek  *              is invoked upon each incoming GPE and Fixed Event. It is
626*29492bb7SDavid van Moolenbroek  *              invoked at interrupt level at the time of the event dispatch.
627*29492bb7SDavid van Moolenbroek  *              Can be used to update event counters, etc.
628*29492bb7SDavid van Moolenbroek  *
629*29492bb7SDavid van Moolenbroek  ******************************************************************************/
630*29492bb7SDavid van Moolenbroek 
631*29492bb7SDavid van Moolenbroek ACPI_STATUS
632*29492bb7SDavid van Moolenbroek AcpiInstallGlobalEventHandler (
633*29492bb7SDavid van Moolenbroek     ACPI_GBL_EVENT_HANDLER  Handler,
634*29492bb7SDavid van Moolenbroek     void                    *Context)
635*29492bb7SDavid van Moolenbroek {
636*29492bb7SDavid van Moolenbroek     ACPI_STATUS             Status;
637*29492bb7SDavid van Moolenbroek 
638*29492bb7SDavid van Moolenbroek 
639*29492bb7SDavid van Moolenbroek     ACPI_FUNCTION_TRACE (AcpiInstallGlobalEventHandler);
640*29492bb7SDavid van Moolenbroek 
641*29492bb7SDavid van Moolenbroek 
642*29492bb7SDavid van Moolenbroek     /* Parameter validation */
643*29492bb7SDavid van Moolenbroek 
644*29492bb7SDavid van Moolenbroek     if (!Handler)
645*29492bb7SDavid van Moolenbroek     {
646*29492bb7SDavid van Moolenbroek         return_ACPI_STATUS (AE_BAD_PARAMETER);
647*29492bb7SDavid van Moolenbroek     }
648*29492bb7SDavid van Moolenbroek 
649*29492bb7SDavid van Moolenbroek     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
650*29492bb7SDavid van Moolenbroek     if (ACPI_FAILURE (Status))
651*29492bb7SDavid van Moolenbroek     {
652*29492bb7SDavid van Moolenbroek         return_ACPI_STATUS (Status);
653*29492bb7SDavid van Moolenbroek     }
654*29492bb7SDavid van Moolenbroek 
655*29492bb7SDavid van Moolenbroek     /* Don't allow two handlers. */
656*29492bb7SDavid van Moolenbroek 
657*29492bb7SDavid van Moolenbroek     if (AcpiGbl_GlobalEventHandler)
658*29492bb7SDavid van Moolenbroek     {
659*29492bb7SDavid van Moolenbroek         Status = AE_ALREADY_EXISTS;
660*29492bb7SDavid van Moolenbroek         goto Cleanup;
661*29492bb7SDavid van Moolenbroek     }
662*29492bb7SDavid van Moolenbroek 
663*29492bb7SDavid van Moolenbroek     AcpiGbl_GlobalEventHandler = Handler;
664*29492bb7SDavid van Moolenbroek     AcpiGbl_GlobalEventHandlerContext = Context;
665*29492bb7SDavid van Moolenbroek 
666*29492bb7SDavid van Moolenbroek 
667*29492bb7SDavid van Moolenbroek Cleanup:
668*29492bb7SDavid van Moolenbroek     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
669*29492bb7SDavid van Moolenbroek     return_ACPI_STATUS (Status);
670*29492bb7SDavid van Moolenbroek }
671*29492bb7SDavid van Moolenbroek 
ACPI_EXPORT_SYMBOL(AcpiInstallGlobalEventHandler)672*29492bb7SDavid van Moolenbroek ACPI_EXPORT_SYMBOL (AcpiInstallGlobalEventHandler)
673*29492bb7SDavid van Moolenbroek 
674*29492bb7SDavid van Moolenbroek 
675433d6423SLionel Sambuc /*******************************************************************************
676433d6423SLionel Sambuc  *
677433d6423SLionel Sambuc  * FUNCTION:    AcpiInstallFixedEventHandler
678433d6423SLionel Sambuc  *
679433d6423SLionel Sambuc  * PARAMETERS:  Event           - Event type to enable.
680433d6423SLionel Sambuc  *              Handler         - Pointer to the handler function for the
681433d6423SLionel Sambuc  *                                event
682433d6423SLionel Sambuc  *              Context         - Value passed to the handler on each GPE
683433d6423SLionel Sambuc  *
684433d6423SLionel Sambuc  * RETURN:      Status
685433d6423SLionel Sambuc  *
686433d6423SLionel Sambuc  * DESCRIPTION: Saves the pointer to the handler function and then enables the
687433d6423SLionel Sambuc  *              event.
688433d6423SLionel Sambuc  *
689433d6423SLionel Sambuc  ******************************************************************************/
690433d6423SLionel Sambuc 
691433d6423SLionel Sambuc ACPI_STATUS
692433d6423SLionel Sambuc AcpiInstallFixedEventHandler (
693433d6423SLionel Sambuc     UINT32                  Event,
694433d6423SLionel Sambuc     ACPI_EVENT_HANDLER      Handler,
695433d6423SLionel Sambuc     void                    *Context)
696433d6423SLionel Sambuc {
697433d6423SLionel Sambuc     ACPI_STATUS             Status;
698433d6423SLionel Sambuc 
699433d6423SLionel Sambuc 
700433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE (AcpiInstallFixedEventHandler);
701433d6423SLionel Sambuc 
702433d6423SLionel Sambuc 
703433d6423SLionel Sambuc     /* Parameter validation */
704433d6423SLionel Sambuc 
705433d6423SLionel Sambuc     if (Event > ACPI_EVENT_MAX)
706433d6423SLionel Sambuc     {
707433d6423SLionel Sambuc         return_ACPI_STATUS (AE_BAD_PARAMETER);
708433d6423SLionel Sambuc     }
709433d6423SLionel Sambuc 
710433d6423SLionel Sambuc     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
711433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
712433d6423SLionel Sambuc     {
713433d6423SLionel Sambuc         return_ACPI_STATUS (Status);
714433d6423SLionel Sambuc     }
715433d6423SLionel Sambuc 
716*29492bb7SDavid van Moolenbroek     /* Do not allow multiple handlers */
717433d6423SLionel Sambuc 
718*29492bb7SDavid van Moolenbroek     if (AcpiGbl_FixedEventHandlers[Event].Handler)
719433d6423SLionel Sambuc     {
720433d6423SLionel Sambuc         Status = AE_ALREADY_EXISTS;
721433d6423SLionel Sambuc         goto Cleanup;
722433d6423SLionel Sambuc     }
723433d6423SLionel Sambuc 
724433d6423SLionel Sambuc     /* Install the handler before enabling the event */
725433d6423SLionel Sambuc 
726433d6423SLionel Sambuc     AcpiGbl_FixedEventHandlers[Event].Handler = Handler;
727433d6423SLionel Sambuc     AcpiGbl_FixedEventHandlers[Event].Context = Context;
728433d6423SLionel Sambuc 
729433d6423SLionel Sambuc     Status = AcpiEnableEvent (Event, 0);
730433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
731433d6423SLionel Sambuc     {
732*29492bb7SDavid van Moolenbroek         ACPI_WARNING ((AE_INFO,
733*29492bb7SDavid van Moolenbroek             "Could not enable fixed event - %s (%u)",
734*29492bb7SDavid van Moolenbroek             AcpiUtGetEventName (Event), Event));
735433d6423SLionel Sambuc 
736433d6423SLionel Sambuc         /* Remove the handler */
737433d6423SLionel Sambuc 
738433d6423SLionel Sambuc         AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
739433d6423SLionel Sambuc         AcpiGbl_FixedEventHandlers[Event].Context = NULL;
740433d6423SLionel Sambuc     }
741433d6423SLionel Sambuc     else
742433d6423SLionel Sambuc     {
743433d6423SLionel Sambuc         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
744*29492bb7SDavid van Moolenbroek             "Enabled fixed event %s (%X), Handler=%p\n",
745*29492bb7SDavid van Moolenbroek             AcpiUtGetEventName (Event), Event, Handler));
746433d6423SLionel Sambuc     }
747433d6423SLionel Sambuc 
748433d6423SLionel Sambuc 
749433d6423SLionel Sambuc Cleanup:
750433d6423SLionel Sambuc     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
751433d6423SLionel Sambuc     return_ACPI_STATUS (Status);
752433d6423SLionel Sambuc }
753433d6423SLionel Sambuc 
ACPI_EXPORT_SYMBOL(AcpiInstallFixedEventHandler)754433d6423SLionel Sambuc ACPI_EXPORT_SYMBOL (AcpiInstallFixedEventHandler)
755433d6423SLionel Sambuc 
756433d6423SLionel Sambuc 
757433d6423SLionel Sambuc /*******************************************************************************
758433d6423SLionel Sambuc  *
759433d6423SLionel Sambuc  * FUNCTION:    AcpiRemoveFixedEventHandler
760433d6423SLionel Sambuc  *
761433d6423SLionel Sambuc  * PARAMETERS:  Event           - Event type to disable.
762433d6423SLionel Sambuc  *              Handler         - Address of the handler
763433d6423SLionel Sambuc  *
764433d6423SLionel Sambuc  * RETURN:      Status
765433d6423SLionel Sambuc  *
766433d6423SLionel Sambuc  * DESCRIPTION: Disables the event and unregisters the event handler.
767433d6423SLionel Sambuc  *
768433d6423SLionel Sambuc  ******************************************************************************/
769433d6423SLionel Sambuc 
770433d6423SLionel Sambuc ACPI_STATUS
771433d6423SLionel Sambuc AcpiRemoveFixedEventHandler (
772433d6423SLionel Sambuc     UINT32                  Event,
773433d6423SLionel Sambuc     ACPI_EVENT_HANDLER      Handler)
774433d6423SLionel Sambuc {
775433d6423SLionel Sambuc     ACPI_STATUS             Status = AE_OK;
776433d6423SLionel Sambuc 
777433d6423SLionel Sambuc 
778433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE (AcpiRemoveFixedEventHandler);
779433d6423SLionel Sambuc 
780433d6423SLionel Sambuc 
781433d6423SLionel Sambuc     /* Parameter validation */
782433d6423SLionel Sambuc 
783433d6423SLionel Sambuc     if (Event > ACPI_EVENT_MAX)
784433d6423SLionel Sambuc     {
785433d6423SLionel Sambuc         return_ACPI_STATUS (AE_BAD_PARAMETER);
786433d6423SLionel Sambuc     }
787433d6423SLionel Sambuc 
788433d6423SLionel Sambuc     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
789433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
790433d6423SLionel Sambuc     {
791433d6423SLionel Sambuc         return_ACPI_STATUS (Status);
792433d6423SLionel Sambuc     }
793433d6423SLionel Sambuc 
794433d6423SLionel Sambuc     /* Disable the event before removing the handler */
795433d6423SLionel Sambuc 
796433d6423SLionel Sambuc     Status = AcpiDisableEvent (Event, 0);
797433d6423SLionel Sambuc 
798433d6423SLionel Sambuc     /* Always Remove the handler */
799433d6423SLionel Sambuc 
800433d6423SLionel Sambuc     AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
801433d6423SLionel Sambuc     AcpiGbl_FixedEventHandlers[Event].Context = NULL;
802433d6423SLionel Sambuc 
803433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
804433d6423SLionel Sambuc     {
805433d6423SLionel Sambuc         ACPI_WARNING ((AE_INFO,
806*29492bb7SDavid van Moolenbroek             "Could not disable fixed event - %s (%u)",
807*29492bb7SDavid van Moolenbroek             AcpiUtGetEventName (Event), Event));
808433d6423SLionel Sambuc     }
809433d6423SLionel Sambuc     else
810433d6423SLionel Sambuc     {
811*29492bb7SDavid van Moolenbroek         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
812*29492bb7SDavid van Moolenbroek             "Disabled fixed event - %s (%X)\n",
813*29492bb7SDavid van Moolenbroek             AcpiUtGetEventName (Event), Event));
814433d6423SLionel Sambuc     }
815433d6423SLionel Sambuc 
816433d6423SLionel Sambuc     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
817433d6423SLionel Sambuc     return_ACPI_STATUS (Status);
818433d6423SLionel Sambuc }
819433d6423SLionel Sambuc 
ACPI_EXPORT_SYMBOL(AcpiRemoveFixedEventHandler)820433d6423SLionel Sambuc ACPI_EXPORT_SYMBOL (AcpiRemoveFixedEventHandler)
821433d6423SLionel Sambuc 
822433d6423SLionel Sambuc 
823433d6423SLionel Sambuc /*******************************************************************************
824433d6423SLionel Sambuc  *
825433d6423SLionel Sambuc  * FUNCTION:    AcpiInstallGpeHandler
826433d6423SLionel Sambuc  *
827433d6423SLionel Sambuc  * PARAMETERS:  GpeDevice       - Namespace node for the GPE (NULL for FADT
828433d6423SLionel Sambuc  *                                defined GPEs)
829433d6423SLionel Sambuc  *              GpeNumber       - The GPE number within the GPE block
830433d6423SLionel Sambuc  *              Type            - Whether this GPE should be treated as an
831433d6423SLionel Sambuc  *                                edge- or level-triggered interrupt.
832433d6423SLionel Sambuc  *              Address         - Address of the handler
833433d6423SLionel Sambuc  *              Context         - Value passed to the handler on each GPE
834433d6423SLionel Sambuc  *
835433d6423SLionel Sambuc  * RETURN:      Status
836433d6423SLionel Sambuc  *
837433d6423SLionel Sambuc  * DESCRIPTION: Install a handler for a General Purpose Event.
838433d6423SLionel Sambuc  *
839433d6423SLionel Sambuc  ******************************************************************************/
840433d6423SLionel Sambuc 
841433d6423SLionel Sambuc ACPI_STATUS
842433d6423SLionel Sambuc AcpiInstallGpeHandler (
843433d6423SLionel Sambuc     ACPI_HANDLE             GpeDevice,
844433d6423SLionel Sambuc     UINT32                  GpeNumber,
845433d6423SLionel Sambuc     UINT32                  Type,
846*29492bb7SDavid van Moolenbroek     ACPI_GPE_HANDLER        Address,
847433d6423SLionel Sambuc     void                    *Context)
848433d6423SLionel Sambuc {
849433d6423SLionel Sambuc     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
850*29492bb7SDavid van Moolenbroek     ACPI_GPE_HANDLER_INFO   *Handler;
851433d6423SLionel Sambuc     ACPI_STATUS             Status;
852433d6423SLionel Sambuc     ACPI_CPU_FLAGS          Flags;
853433d6423SLionel Sambuc 
854433d6423SLionel Sambuc 
855433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE (AcpiInstallGpeHandler);
856433d6423SLionel Sambuc 
857433d6423SLionel Sambuc 
858433d6423SLionel Sambuc     /* Parameter validation */
859433d6423SLionel Sambuc 
860433d6423SLionel Sambuc     if ((!Address) || (Type & ~ACPI_GPE_XRUPT_TYPE_MASK))
861433d6423SLionel Sambuc     {
862433d6423SLionel Sambuc         return_ACPI_STATUS (AE_BAD_PARAMETER);
863433d6423SLionel Sambuc     }
864433d6423SLionel Sambuc 
865433d6423SLionel Sambuc     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
866433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
867433d6423SLionel Sambuc     {
868433d6423SLionel Sambuc         return_ACPI_STATUS (Status);
869433d6423SLionel Sambuc     }
870433d6423SLionel Sambuc 
871*29492bb7SDavid van Moolenbroek     /* Allocate and init handler object (before lock) */
872*29492bb7SDavid van Moolenbroek 
873*29492bb7SDavid van Moolenbroek     Handler = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_HANDLER_INFO));
874*29492bb7SDavid van Moolenbroek     if (!Handler)
875*29492bb7SDavid van Moolenbroek     {
876*29492bb7SDavid van Moolenbroek         Status = AE_NO_MEMORY;
877*29492bb7SDavid van Moolenbroek         goto UnlockAndExit;
878*29492bb7SDavid van Moolenbroek     }
879*29492bb7SDavid van Moolenbroek 
880*29492bb7SDavid van Moolenbroek     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
881*29492bb7SDavid van Moolenbroek 
882433d6423SLionel Sambuc     /* Ensure that we have a valid GPE number */
883433d6423SLionel Sambuc 
884433d6423SLionel Sambuc     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
885433d6423SLionel Sambuc     if (!GpeEventInfo)
886433d6423SLionel Sambuc     {
887433d6423SLionel Sambuc         Status = AE_BAD_PARAMETER;
888*29492bb7SDavid van Moolenbroek         goto FreeAndExit;
889433d6423SLionel Sambuc     }
890433d6423SLionel Sambuc 
891433d6423SLionel Sambuc     /* Make sure that there isn't a handler there already */
892433d6423SLionel Sambuc 
893433d6423SLionel Sambuc     if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
894433d6423SLionel Sambuc             ACPI_GPE_DISPATCH_HANDLER)
895433d6423SLionel Sambuc     {
896433d6423SLionel Sambuc         Status = AE_ALREADY_EXISTS;
897*29492bb7SDavid van Moolenbroek         goto FreeAndExit;
898433d6423SLionel Sambuc     }
899433d6423SLionel Sambuc 
900433d6423SLionel Sambuc     Handler->Address = Address;
901433d6423SLionel Sambuc     Handler->Context = Context;
902433d6423SLionel Sambuc     Handler->MethodNode = GpeEventInfo->Dispatch.MethodNode;
903*29492bb7SDavid van Moolenbroek     Handler->OriginalFlags = (UINT8) (GpeEventInfo->Flags &
904*29492bb7SDavid van Moolenbroek         (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK));
905*29492bb7SDavid van Moolenbroek 
906*29492bb7SDavid van Moolenbroek     /*
907*29492bb7SDavid van Moolenbroek      * If the GPE is associated with a method, it may have been enabled
908*29492bb7SDavid van Moolenbroek      * automatically during initialization, in which case it has to be
909*29492bb7SDavid van Moolenbroek      * disabled now to avoid spurious execution of the handler.
910*29492bb7SDavid van Moolenbroek      */
911*29492bb7SDavid van Moolenbroek     if (((Handler->OriginalFlags & ACPI_GPE_DISPATCH_METHOD) ||
912*29492bb7SDavid van Moolenbroek          (Handler->OriginalFlags & ACPI_GPE_DISPATCH_NOTIFY)) &&
913*29492bb7SDavid van Moolenbroek         GpeEventInfo->RuntimeCount)
914*29492bb7SDavid van Moolenbroek     {
915*29492bb7SDavid van Moolenbroek         Handler->OriginallyEnabled = TRUE;
916*29492bb7SDavid van Moolenbroek         (void) AcpiEvRemoveGpeReference (GpeEventInfo);
917*29492bb7SDavid van Moolenbroek 
918*29492bb7SDavid van Moolenbroek         /* Sanity check of original type against new type */
919*29492bb7SDavid van Moolenbroek 
920*29492bb7SDavid van Moolenbroek         if (Type != (UINT32) (GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK))
921*29492bb7SDavid van Moolenbroek         {
922*29492bb7SDavid van Moolenbroek             ACPI_WARNING ((AE_INFO, "GPE type mismatch (level/edge)"));
923*29492bb7SDavid van Moolenbroek         }
924*29492bb7SDavid van Moolenbroek     }
925433d6423SLionel Sambuc 
926433d6423SLionel Sambuc     /* Install the handler */
927433d6423SLionel Sambuc 
928433d6423SLionel Sambuc     GpeEventInfo->Dispatch.Handler = Handler;
929433d6423SLionel Sambuc 
930*29492bb7SDavid van Moolenbroek     /* Setup up dispatch flags to indicate handler (vs. method/notify) */
931433d6423SLionel Sambuc 
932433d6423SLionel Sambuc     GpeEventInfo->Flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
933433d6423SLionel Sambuc     GpeEventInfo->Flags |= (UINT8) (Type | ACPI_GPE_DISPATCH_HANDLER);
934433d6423SLionel Sambuc 
935433d6423SLionel Sambuc     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
936433d6423SLionel Sambuc 
937433d6423SLionel Sambuc 
938433d6423SLionel Sambuc UnlockAndExit:
939433d6423SLionel Sambuc     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
940433d6423SLionel Sambuc     return_ACPI_STATUS (Status);
941*29492bb7SDavid van Moolenbroek 
942*29492bb7SDavid van Moolenbroek FreeAndExit:
943*29492bb7SDavid van Moolenbroek     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
944*29492bb7SDavid van Moolenbroek     ACPI_FREE (Handler);
945*29492bb7SDavid van Moolenbroek     goto UnlockAndExit;
946433d6423SLionel Sambuc }
947433d6423SLionel Sambuc 
ACPI_EXPORT_SYMBOL(AcpiInstallGpeHandler)948433d6423SLionel Sambuc ACPI_EXPORT_SYMBOL (AcpiInstallGpeHandler)
949433d6423SLionel Sambuc 
950433d6423SLionel Sambuc 
951433d6423SLionel Sambuc /*******************************************************************************
952433d6423SLionel Sambuc  *
953433d6423SLionel Sambuc  * FUNCTION:    AcpiRemoveGpeHandler
954433d6423SLionel Sambuc  *
955433d6423SLionel Sambuc  * PARAMETERS:  GpeDevice       - Namespace node for the GPE (NULL for FADT
956433d6423SLionel Sambuc  *                                defined GPEs)
957433d6423SLionel Sambuc  *              GpeNumber       - The event to remove a handler
958433d6423SLionel Sambuc  *              Address         - Address of the handler
959433d6423SLionel Sambuc  *
960433d6423SLionel Sambuc  * RETURN:      Status
961433d6423SLionel Sambuc  *
962433d6423SLionel Sambuc  * DESCRIPTION: Remove a handler for a General Purpose AcpiEvent.
963433d6423SLionel Sambuc  *
964433d6423SLionel Sambuc  ******************************************************************************/
965433d6423SLionel Sambuc 
966433d6423SLionel Sambuc ACPI_STATUS
967433d6423SLionel Sambuc AcpiRemoveGpeHandler (
968433d6423SLionel Sambuc     ACPI_HANDLE             GpeDevice,
969433d6423SLionel Sambuc     UINT32                  GpeNumber,
970*29492bb7SDavid van Moolenbroek     ACPI_GPE_HANDLER        Address)
971433d6423SLionel Sambuc {
972433d6423SLionel Sambuc     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
973*29492bb7SDavid van Moolenbroek     ACPI_GPE_HANDLER_INFO   *Handler;
974433d6423SLionel Sambuc     ACPI_STATUS             Status;
975433d6423SLionel Sambuc     ACPI_CPU_FLAGS          Flags;
976433d6423SLionel Sambuc 
977433d6423SLionel Sambuc 
978433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE (AcpiRemoveGpeHandler);
979433d6423SLionel Sambuc 
980433d6423SLionel Sambuc 
981433d6423SLionel Sambuc     /* Parameter validation */
982433d6423SLionel Sambuc 
983433d6423SLionel Sambuc     if (!Address)
984433d6423SLionel Sambuc     {
985433d6423SLionel Sambuc         return_ACPI_STATUS (AE_BAD_PARAMETER);
986433d6423SLionel Sambuc     }
987433d6423SLionel Sambuc 
988433d6423SLionel Sambuc     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
989433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
990433d6423SLionel Sambuc     {
991433d6423SLionel Sambuc         return_ACPI_STATUS (Status);
992433d6423SLionel Sambuc     }
993433d6423SLionel Sambuc 
994*29492bb7SDavid van Moolenbroek     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
995*29492bb7SDavid van Moolenbroek 
996433d6423SLionel Sambuc     /* Ensure that we have a valid GPE number */
997433d6423SLionel Sambuc 
998433d6423SLionel Sambuc     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
999433d6423SLionel Sambuc     if (!GpeEventInfo)
1000433d6423SLionel Sambuc     {
1001433d6423SLionel Sambuc         Status = AE_BAD_PARAMETER;
1002433d6423SLionel Sambuc         goto UnlockAndExit;
1003433d6423SLionel Sambuc     }
1004433d6423SLionel Sambuc 
1005433d6423SLionel Sambuc     /* Make sure that a handler is indeed installed */
1006433d6423SLionel Sambuc 
1007433d6423SLionel Sambuc     if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) !=
1008433d6423SLionel Sambuc             ACPI_GPE_DISPATCH_HANDLER)
1009433d6423SLionel Sambuc     {
1010433d6423SLionel Sambuc         Status = AE_NOT_EXIST;
1011433d6423SLionel Sambuc         goto UnlockAndExit;
1012433d6423SLionel Sambuc     }
1013433d6423SLionel Sambuc 
1014433d6423SLionel Sambuc     /* Make sure that the installed handler is the same */
1015433d6423SLionel Sambuc 
1016433d6423SLionel Sambuc     if (GpeEventInfo->Dispatch.Handler->Address != Address)
1017433d6423SLionel Sambuc     {
1018433d6423SLionel Sambuc         Status = AE_BAD_PARAMETER;
1019433d6423SLionel Sambuc         goto UnlockAndExit;
1020433d6423SLionel Sambuc     }
1021433d6423SLionel Sambuc 
1022433d6423SLionel Sambuc     /* Remove the handler */
1023433d6423SLionel Sambuc 
1024433d6423SLionel Sambuc     Handler = GpeEventInfo->Dispatch.Handler;
1025433d6423SLionel Sambuc 
1026433d6423SLionel Sambuc     /* Restore Method node (if any), set dispatch flags */
1027433d6423SLionel Sambuc 
1028433d6423SLionel Sambuc     GpeEventInfo->Dispatch.MethodNode = Handler->MethodNode;
1029*29492bb7SDavid van Moolenbroek     GpeEventInfo->Flags &=
1030*29492bb7SDavid van Moolenbroek         ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
1031*29492bb7SDavid van Moolenbroek     GpeEventInfo->Flags |= Handler->OriginalFlags;
1032*29492bb7SDavid van Moolenbroek 
1033*29492bb7SDavid van Moolenbroek     /*
1034*29492bb7SDavid van Moolenbroek      * If the GPE was previously associated with a method and it was
1035*29492bb7SDavid van Moolenbroek      * enabled, it should be enabled at this point to restore the
1036*29492bb7SDavid van Moolenbroek      * post-initialization configuration.
1037*29492bb7SDavid van Moolenbroek      */
1038*29492bb7SDavid van Moolenbroek     if (((Handler->OriginalFlags & ACPI_GPE_DISPATCH_METHOD) ||
1039*29492bb7SDavid van Moolenbroek          (Handler->OriginalFlags & ACPI_GPE_DISPATCH_NOTIFY)) &&
1040*29492bb7SDavid van Moolenbroek         Handler->OriginallyEnabled)
1041433d6423SLionel Sambuc     {
1042*29492bb7SDavid van Moolenbroek         (void) AcpiEvAddGpeReference (GpeEventInfo);
1043433d6423SLionel Sambuc     }
1044*29492bb7SDavid van Moolenbroek 
1045433d6423SLionel Sambuc     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
1046*29492bb7SDavid van Moolenbroek     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
1047*29492bb7SDavid van Moolenbroek 
1048*29492bb7SDavid van Moolenbroek     /* Make sure all deferred GPE tasks are completed */
1049*29492bb7SDavid van Moolenbroek 
1050*29492bb7SDavid van Moolenbroek     AcpiOsWaitEventsComplete ();
1051433d6423SLionel Sambuc 
1052433d6423SLionel Sambuc     /* Now we can free the handler object */
1053433d6423SLionel Sambuc 
1054433d6423SLionel Sambuc     ACPI_FREE (Handler);
1055*29492bb7SDavid van Moolenbroek     return_ACPI_STATUS (Status);
1056433d6423SLionel Sambuc 
1057433d6423SLionel Sambuc UnlockAndExit:
1058*29492bb7SDavid van Moolenbroek     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
1059433d6423SLionel Sambuc     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
1060433d6423SLionel Sambuc     return_ACPI_STATUS (Status);
1061433d6423SLionel Sambuc }
1062433d6423SLionel Sambuc 
ACPI_EXPORT_SYMBOL(AcpiRemoveGpeHandler)1063433d6423SLionel Sambuc ACPI_EXPORT_SYMBOL (AcpiRemoveGpeHandler)
1064433d6423SLionel Sambuc 
1065433d6423SLionel Sambuc 
1066433d6423SLionel Sambuc /*******************************************************************************
1067433d6423SLionel Sambuc  *
1068433d6423SLionel Sambuc  * FUNCTION:    AcpiAcquireGlobalLock
1069433d6423SLionel Sambuc  *
1070433d6423SLionel Sambuc  * PARAMETERS:  Timeout         - How long the caller is willing to wait
1071433d6423SLionel Sambuc  *              Handle          - Where the handle to the lock is returned
1072433d6423SLionel Sambuc  *                                (if acquired)
1073433d6423SLionel Sambuc  *
1074433d6423SLionel Sambuc  * RETURN:      Status
1075433d6423SLionel Sambuc  *
1076433d6423SLionel Sambuc  * DESCRIPTION: Acquire the ACPI Global Lock
1077433d6423SLionel Sambuc  *
1078433d6423SLionel Sambuc  * Note: Allows callers with the same thread ID to acquire the global lock
1079433d6423SLionel Sambuc  * multiple times. In other words, externally, the behavior of the global lock
1080433d6423SLionel Sambuc  * is identical to an AML mutex. On the first acquire, a new handle is
1081433d6423SLionel Sambuc  * returned. On any subsequent calls to acquire by the same thread, the same
1082433d6423SLionel Sambuc  * handle is returned.
1083433d6423SLionel Sambuc  *
1084433d6423SLionel Sambuc  ******************************************************************************/
1085433d6423SLionel Sambuc 
1086433d6423SLionel Sambuc ACPI_STATUS
1087433d6423SLionel Sambuc AcpiAcquireGlobalLock (
1088433d6423SLionel Sambuc     UINT16                  Timeout,
1089433d6423SLionel Sambuc     UINT32                  *Handle)
1090433d6423SLionel Sambuc {
1091433d6423SLionel Sambuc     ACPI_STATUS             Status;
1092433d6423SLionel Sambuc 
1093433d6423SLionel Sambuc 
1094433d6423SLionel Sambuc     if (!Handle)
1095433d6423SLionel Sambuc     {
1096433d6423SLionel Sambuc         return (AE_BAD_PARAMETER);
1097433d6423SLionel Sambuc     }
1098433d6423SLionel Sambuc 
1099433d6423SLionel Sambuc     /* Must lock interpreter to prevent race conditions */
1100433d6423SLionel Sambuc 
1101433d6423SLionel Sambuc     AcpiExEnterInterpreter ();
1102433d6423SLionel Sambuc 
1103433d6423SLionel Sambuc     Status = AcpiExAcquireMutexObject (Timeout,
1104433d6423SLionel Sambuc                 AcpiGbl_GlobalLockMutex, AcpiOsGetThreadId ());
1105433d6423SLionel Sambuc 
1106433d6423SLionel Sambuc     if (ACPI_SUCCESS (Status))
1107433d6423SLionel Sambuc     {
1108433d6423SLionel Sambuc         /* Return the global lock handle (updated in AcpiEvAcquireGlobalLock) */
1109433d6423SLionel Sambuc 
1110433d6423SLionel Sambuc         *Handle = AcpiGbl_GlobalLockHandle;
1111433d6423SLionel Sambuc     }
1112433d6423SLionel Sambuc 
1113433d6423SLionel Sambuc     AcpiExExitInterpreter ();
1114433d6423SLionel Sambuc     return (Status);
1115433d6423SLionel Sambuc }
1116433d6423SLionel Sambuc 
ACPI_EXPORT_SYMBOL(AcpiAcquireGlobalLock)1117433d6423SLionel Sambuc ACPI_EXPORT_SYMBOL (AcpiAcquireGlobalLock)
1118433d6423SLionel Sambuc 
1119433d6423SLionel Sambuc 
1120433d6423SLionel Sambuc /*******************************************************************************
1121433d6423SLionel Sambuc  *
1122433d6423SLionel Sambuc  * FUNCTION:    AcpiReleaseGlobalLock
1123433d6423SLionel Sambuc  *
1124433d6423SLionel Sambuc  * PARAMETERS:  Handle      - Returned from AcpiAcquireGlobalLock
1125433d6423SLionel Sambuc  *
1126433d6423SLionel Sambuc  * RETURN:      Status
1127433d6423SLionel Sambuc  *
1128433d6423SLionel Sambuc  * DESCRIPTION: Release the ACPI Global Lock. The handle must be valid.
1129433d6423SLionel Sambuc  *
1130433d6423SLionel Sambuc  ******************************************************************************/
1131433d6423SLionel Sambuc 
1132433d6423SLionel Sambuc ACPI_STATUS
1133433d6423SLionel Sambuc AcpiReleaseGlobalLock (
1134433d6423SLionel Sambuc     UINT32                  Handle)
1135433d6423SLionel Sambuc {
1136433d6423SLionel Sambuc     ACPI_STATUS             Status;
1137433d6423SLionel Sambuc 
1138433d6423SLionel Sambuc 
1139433d6423SLionel Sambuc     if (!Handle || (Handle != AcpiGbl_GlobalLockHandle))
1140433d6423SLionel Sambuc     {
1141433d6423SLionel Sambuc         return (AE_NOT_ACQUIRED);
1142433d6423SLionel Sambuc     }
1143433d6423SLionel Sambuc 
1144433d6423SLionel Sambuc     Status = AcpiExReleaseMutexObject (AcpiGbl_GlobalLockMutex);
1145433d6423SLionel Sambuc     return (Status);
1146433d6423SLionel Sambuc }
1147433d6423SLionel Sambuc 
1148433d6423SLionel Sambuc ACPI_EXPORT_SYMBOL (AcpiReleaseGlobalLock)
1149433d6423SLionel Sambuc 
1150*29492bb7SDavid van Moolenbroek #endif /* !ACPI_REDUCED_HARDWARE */
1151