xref: /titanic_52/usr/src/uts/intel/io/acpica/events/evxface.c (revision 385cc6b4ad1792caef3f84eb61eed3f27085801f)
1ae115bc7Smrj /******************************************************************************
2ae115bc7Smrj  *
3ae115bc7Smrj  * Module Name: evxface - External interfaces for ACPI events
4ae115bc7Smrj  *
5ae115bc7Smrj  *****************************************************************************/
6ae115bc7Smrj 
726f3cdf0SGordon Ross /*
8*385cc6b4SJerry Jelinek  * Copyright (C) 2000 - 2016, Intel Corp.
9ae115bc7Smrj  * All rights reserved.
10ae115bc7Smrj  *
1126f3cdf0SGordon Ross  * Redistribution and use in source and binary forms, with or without
1226f3cdf0SGordon Ross  * modification, are permitted provided that the following conditions
1326f3cdf0SGordon Ross  * are met:
1426f3cdf0SGordon Ross  * 1. Redistributions of source code must retain the above copyright
1526f3cdf0SGordon Ross  *    notice, this list of conditions, and the following disclaimer,
1626f3cdf0SGordon Ross  *    without modification.
1726f3cdf0SGordon Ross  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1826f3cdf0SGordon Ross  *    substantially similar to the "NO WARRANTY" disclaimer below
1926f3cdf0SGordon Ross  *    ("Disclaimer") and any redistribution must be conditioned upon
2026f3cdf0SGordon Ross  *    including a substantially similar Disclaimer requirement for further
2126f3cdf0SGordon Ross  *    binary redistribution.
2226f3cdf0SGordon Ross  * 3. Neither the names of the above-listed copyright holders nor the names
2326f3cdf0SGordon Ross  *    of any contributors may be used to endorse or promote products derived
2426f3cdf0SGordon Ross  *    from this software without specific prior written permission.
25ae115bc7Smrj  *
2626f3cdf0SGordon Ross  * Alternatively, this software may be distributed under the terms of the
2726f3cdf0SGordon Ross  * GNU General Public License ("GPL") version 2 as published by the Free
2826f3cdf0SGordon Ross  * Software Foundation.
29ae115bc7Smrj  *
3026f3cdf0SGordon Ross  * NO WARRANTY
3126f3cdf0SGordon Ross  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3226f3cdf0SGordon Ross  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3326f3cdf0SGordon Ross  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
3426f3cdf0SGordon Ross  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3526f3cdf0SGordon Ross  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3626f3cdf0SGordon Ross  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3726f3cdf0SGordon Ross  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3826f3cdf0SGordon Ross  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
3926f3cdf0SGordon Ross  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
4026f3cdf0SGordon Ross  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
4126f3cdf0SGordon Ross  * POSSIBILITY OF SUCH DAMAGES.
4226f3cdf0SGordon Ross  */
43ae115bc7Smrj 
44*385cc6b4SJerry Jelinek #define EXPORT_ACPI_INTERFACES
45ae115bc7Smrj 
46ae115bc7Smrj #include "acpi.h"
47aa2aa9a6SDana Myers #include "accommon.h"
48ae115bc7Smrj #include "acnamesp.h"
49ae115bc7Smrj #include "acevents.h"
50ae115bc7Smrj #include "acinterp.h"
51ae115bc7Smrj 
52ae115bc7Smrj #define _COMPONENT          ACPI_EVENTS
53ae115bc7Smrj         ACPI_MODULE_NAME    ("evxface")
54ae115bc7Smrj 
55*385cc6b4SJerry Jelinek #if (!ACPI_REDUCED_HARDWARE)
56*385cc6b4SJerry Jelinek 
57*385cc6b4SJerry Jelinek /* Local prototypes */
58*385cc6b4SJerry Jelinek 
59*385cc6b4SJerry Jelinek static ACPI_STATUS
60*385cc6b4SJerry Jelinek AcpiEvInstallGpeHandler (
61*385cc6b4SJerry Jelinek     ACPI_HANDLE             GpeDevice,
62*385cc6b4SJerry Jelinek     UINT32                  GpeNumber,
63*385cc6b4SJerry Jelinek     UINT32                  Type,
64*385cc6b4SJerry Jelinek     BOOLEAN                 IsRawHandler,
65*385cc6b4SJerry Jelinek     ACPI_GPE_HANDLER        Address,
66*385cc6b4SJerry Jelinek     void                    *Context);
67*385cc6b4SJerry Jelinek 
68*385cc6b4SJerry Jelinek #endif
69*385cc6b4SJerry Jelinek 
70*385cc6b4SJerry Jelinek 
71*385cc6b4SJerry Jelinek /*******************************************************************************
72*385cc6b4SJerry Jelinek  *
73*385cc6b4SJerry Jelinek  * FUNCTION:    AcpiInstallNotifyHandler
74*385cc6b4SJerry Jelinek  *
75*385cc6b4SJerry Jelinek  * PARAMETERS:  Device          - The device for which notifies will be handled
76*385cc6b4SJerry Jelinek  *              HandlerType     - The type of handler:
77*385cc6b4SJerry Jelinek  *                                  ACPI_SYSTEM_NOTIFY: System Handler (00-7F)
78*385cc6b4SJerry Jelinek  *                                  ACPI_DEVICE_NOTIFY: Device Handler (80-FF)
79*385cc6b4SJerry Jelinek  *                                  ACPI_ALL_NOTIFY:    Both System and Device
80*385cc6b4SJerry Jelinek  *              Handler         - Address of the handler
81*385cc6b4SJerry Jelinek  *              Context         - Value passed to the handler on each GPE
82*385cc6b4SJerry Jelinek  *
83*385cc6b4SJerry Jelinek  * RETURN:      Status
84*385cc6b4SJerry Jelinek  *
85*385cc6b4SJerry Jelinek  * DESCRIPTION: Install a handler for notifications on an ACPI Device,
86*385cc6b4SJerry Jelinek  *              ThermalZone, or Processor object.
87*385cc6b4SJerry Jelinek  *
88*385cc6b4SJerry Jelinek  * NOTES:       The Root namespace object may have only one handler for each
89*385cc6b4SJerry Jelinek  *              type of notify (System/Device). Device/Thermal/Processor objects
90*385cc6b4SJerry Jelinek  *              may have one device notify handler, and multiple system notify
91*385cc6b4SJerry Jelinek  *              handlers.
92*385cc6b4SJerry Jelinek  *
93*385cc6b4SJerry Jelinek  ******************************************************************************/
94*385cc6b4SJerry Jelinek 
95*385cc6b4SJerry Jelinek ACPI_STATUS
96*385cc6b4SJerry Jelinek AcpiInstallNotifyHandler (
97*385cc6b4SJerry Jelinek     ACPI_HANDLE             Device,
98*385cc6b4SJerry Jelinek     UINT32                  HandlerType,
99*385cc6b4SJerry Jelinek     ACPI_NOTIFY_HANDLER     Handler,
100*385cc6b4SJerry Jelinek     void                    *Context)
101*385cc6b4SJerry Jelinek {
102*385cc6b4SJerry Jelinek     ACPI_NAMESPACE_NODE     *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device);
103*385cc6b4SJerry Jelinek     ACPI_OPERAND_OBJECT     *ObjDesc;
104*385cc6b4SJerry Jelinek     ACPI_OPERAND_OBJECT     *HandlerObj;
105*385cc6b4SJerry Jelinek     ACPI_STATUS             Status;
106*385cc6b4SJerry Jelinek     UINT32                  i;
107*385cc6b4SJerry Jelinek 
108*385cc6b4SJerry Jelinek 
109*385cc6b4SJerry Jelinek     ACPI_FUNCTION_TRACE (AcpiInstallNotifyHandler);
110*385cc6b4SJerry Jelinek 
111*385cc6b4SJerry Jelinek 
112*385cc6b4SJerry Jelinek     /* Parameter validation */
113*385cc6b4SJerry Jelinek 
114*385cc6b4SJerry Jelinek     if ((!Device) || (!Handler) || (!HandlerType) ||
115*385cc6b4SJerry Jelinek         (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
116*385cc6b4SJerry Jelinek     {
117*385cc6b4SJerry Jelinek         return_ACPI_STATUS (AE_BAD_PARAMETER);
118*385cc6b4SJerry Jelinek     }
119*385cc6b4SJerry Jelinek 
120*385cc6b4SJerry Jelinek     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
121*385cc6b4SJerry Jelinek     if (ACPI_FAILURE (Status))
122*385cc6b4SJerry Jelinek     {
123*385cc6b4SJerry Jelinek         return_ACPI_STATUS (Status);
124*385cc6b4SJerry Jelinek     }
125*385cc6b4SJerry Jelinek 
126*385cc6b4SJerry Jelinek     /*
127*385cc6b4SJerry Jelinek      * Root Object:
128*385cc6b4SJerry Jelinek      * Registering a notify handler on the root object indicates that the
129*385cc6b4SJerry Jelinek      * caller wishes to receive notifications for all objects. Note that
130*385cc6b4SJerry Jelinek      * only one global handler can be registered per notify type.
131*385cc6b4SJerry Jelinek      * Ensure that a handler is not already installed.
132*385cc6b4SJerry Jelinek      */
133*385cc6b4SJerry Jelinek     if (Device == ACPI_ROOT_OBJECT)
134*385cc6b4SJerry Jelinek     {
135*385cc6b4SJerry Jelinek         for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
136*385cc6b4SJerry Jelinek         {
137*385cc6b4SJerry Jelinek             if (HandlerType & (i+1))
138*385cc6b4SJerry Jelinek             {
139*385cc6b4SJerry Jelinek                 if (AcpiGbl_GlobalNotify[i].Handler)
140*385cc6b4SJerry Jelinek                 {
141*385cc6b4SJerry Jelinek                     Status = AE_ALREADY_EXISTS;
142*385cc6b4SJerry Jelinek                     goto UnlockAndExit;
143*385cc6b4SJerry Jelinek                 }
144*385cc6b4SJerry Jelinek 
145*385cc6b4SJerry Jelinek                 AcpiGbl_GlobalNotify[i].Handler = Handler;
146*385cc6b4SJerry Jelinek                 AcpiGbl_GlobalNotify[i].Context = Context;
147*385cc6b4SJerry Jelinek             }
148*385cc6b4SJerry Jelinek         }
149*385cc6b4SJerry Jelinek 
150*385cc6b4SJerry Jelinek         goto UnlockAndExit; /* Global notify handler installed, all done */
151*385cc6b4SJerry Jelinek     }
152*385cc6b4SJerry Jelinek 
153*385cc6b4SJerry Jelinek     /*
154*385cc6b4SJerry Jelinek      * All Other Objects:
155*385cc6b4SJerry Jelinek      * Caller will only receive notifications specific to the target
156*385cc6b4SJerry Jelinek      * object. Note that only certain object types are allowed to
157*385cc6b4SJerry Jelinek      * receive notifications.
158*385cc6b4SJerry Jelinek      */
159*385cc6b4SJerry Jelinek 
160*385cc6b4SJerry Jelinek     /* Are Notifies allowed on this object? */
161*385cc6b4SJerry Jelinek 
162*385cc6b4SJerry Jelinek     if (!AcpiEvIsNotifyObject (Node))
163*385cc6b4SJerry Jelinek     {
164*385cc6b4SJerry Jelinek         Status = AE_TYPE;
165*385cc6b4SJerry Jelinek         goto UnlockAndExit;
166*385cc6b4SJerry Jelinek     }
167*385cc6b4SJerry Jelinek 
168*385cc6b4SJerry Jelinek     /* Check for an existing internal object, might not exist */
169*385cc6b4SJerry Jelinek 
170*385cc6b4SJerry Jelinek     ObjDesc = AcpiNsGetAttachedObject (Node);
171*385cc6b4SJerry Jelinek     if (!ObjDesc)
172*385cc6b4SJerry Jelinek     {
173*385cc6b4SJerry Jelinek         /* Create a new object */
174*385cc6b4SJerry Jelinek 
175*385cc6b4SJerry Jelinek         ObjDesc = AcpiUtCreateInternalObject (Node->Type);
176*385cc6b4SJerry Jelinek         if (!ObjDesc)
177*385cc6b4SJerry Jelinek         {
178*385cc6b4SJerry Jelinek             Status = AE_NO_MEMORY;
179*385cc6b4SJerry Jelinek             goto UnlockAndExit;
180*385cc6b4SJerry Jelinek         }
181*385cc6b4SJerry Jelinek 
182*385cc6b4SJerry Jelinek         /* Attach new object to the Node, remove local reference */
183*385cc6b4SJerry Jelinek 
184*385cc6b4SJerry Jelinek         Status = AcpiNsAttachObject (Device, ObjDesc, Node->Type);
185*385cc6b4SJerry Jelinek         AcpiUtRemoveReference (ObjDesc);
186*385cc6b4SJerry Jelinek         if (ACPI_FAILURE (Status))
187*385cc6b4SJerry Jelinek         {
188*385cc6b4SJerry Jelinek             goto UnlockAndExit;
189*385cc6b4SJerry Jelinek         }
190*385cc6b4SJerry Jelinek     }
191*385cc6b4SJerry Jelinek 
192*385cc6b4SJerry Jelinek     /* Ensure that the handler is not already installed in the lists */
193*385cc6b4SJerry Jelinek 
194*385cc6b4SJerry Jelinek     for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
195*385cc6b4SJerry Jelinek     {
196*385cc6b4SJerry Jelinek         if (HandlerType & (i+1))
197*385cc6b4SJerry Jelinek         {
198*385cc6b4SJerry Jelinek             HandlerObj = ObjDesc->CommonNotify.NotifyList[i];
199*385cc6b4SJerry Jelinek             while (HandlerObj)
200*385cc6b4SJerry Jelinek             {
201*385cc6b4SJerry Jelinek                 if (HandlerObj->Notify.Handler == Handler)
202*385cc6b4SJerry Jelinek                 {
203*385cc6b4SJerry Jelinek                     Status = AE_ALREADY_EXISTS;
204*385cc6b4SJerry Jelinek                     goto UnlockAndExit;
205*385cc6b4SJerry Jelinek                 }
206*385cc6b4SJerry Jelinek 
207*385cc6b4SJerry Jelinek                 HandlerObj = HandlerObj->Notify.Next[i];
208*385cc6b4SJerry Jelinek             }
209*385cc6b4SJerry Jelinek         }
210*385cc6b4SJerry Jelinek     }
211*385cc6b4SJerry Jelinek 
212*385cc6b4SJerry Jelinek     /* Create and populate a new notify handler object */
213*385cc6b4SJerry Jelinek 
214*385cc6b4SJerry Jelinek     HandlerObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_NOTIFY);
215*385cc6b4SJerry Jelinek     if (!HandlerObj)
216*385cc6b4SJerry Jelinek     {
217*385cc6b4SJerry Jelinek         Status = AE_NO_MEMORY;
218*385cc6b4SJerry Jelinek         goto UnlockAndExit;
219*385cc6b4SJerry Jelinek     }
220*385cc6b4SJerry Jelinek 
221*385cc6b4SJerry Jelinek     HandlerObj->Notify.Node = Node;
222*385cc6b4SJerry Jelinek     HandlerObj->Notify.HandlerType = HandlerType;
223*385cc6b4SJerry Jelinek     HandlerObj->Notify.Handler = Handler;
224*385cc6b4SJerry Jelinek     HandlerObj->Notify.Context = Context;
225*385cc6b4SJerry Jelinek 
226*385cc6b4SJerry Jelinek     /* Install the handler at the list head(s) */
227*385cc6b4SJerry Jelinek 
228*385cc6b4SJerry Jelinek     for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
229*385cc6b4SJerry Jelinek     {
230*385cc6b4SJerry Jelinek         if (HandlerType & (i+1))
231*385cc6b4SJerry Jelinek         {
232*385cc6b4SJerry Jelinek             HandlerObj->Notify.Next[i] =
233*385cc6b4SJerry Jelinek                 ObjDesc->CommonNotify.NotifyList[i];
234*385cc6b4SJerry Jelinek 
235*385cc6b4SJerry Jelinek             ObjDesc->CommonNotify.NotifyList[i] = HandlerObj;
236*385cc6b4SJerry Jelinek         }
237*385cc6b4SJerry Jelinek     }
238*385cc6b4SJerry Jelinek 
239*385cc6b4SJerry Jelinek     /* Add an extra reference if handler was installed in both lists */
240*385cc6b4SJerry Jelinek 
241*385cc6b4SJerry Jelinek     if (HandlerType == ACPI_ALL_NOTIFY)
242*385cc6b4SJerry Jelinek     {
243*385cc6b4SJerry Jelinek         AcpiUtAddReference (HandlerObj);
244*385cc6b4SJerry Jelinek     }
245*385cc6b4SJerry Jelinek 
246*385cc6b4SJerry Jelinek 
247*385cc6b4SJerry Jelinek UnlockAndExit:
248*385cc6b4SJerry Jelinek     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
249*385cc6b4SJerry Jelinek     return_ACPI_STATUS (Status);
250*385cc6b4SJerry Jelinek }
251*385cc6b4SJerry Jelinek 
252*385cc6b4SJerry Jelinek ACPI_EXPORT_SYMBOL (AcpiInstallNotifyHandler)
253*385cc6b4SJerry Jelinek 
254*385cc6b4SJerry Jelinek 
255*385cc6b4SJerry Jelinek /*******************************************************************************
256*385cc6b4SJerry Jelinek  *
257*385cc6b4SJerry Jelinek  * FUNCTION:    AcpiRemoveNotifyHandler
258*385cc6b4SJerry Jelinek  *
259*385cc6b4SJerry Jelinek  * PARAMETERS:  Device          - The device for which the handler is installed
260*385cc6b4SJerry Jelinek  *              HandlerType     - The type of handler:
261*385cc6b4SJerry Jelinek  *                                  ACPI_SYSTEM_NOTIFY: System Handler (00-7F)
262*385cc6b4SJerry Jelinek  *                                  ACPI_DEVICE_NOTIFY: Device Handler (80-FF)
263*385cc6b4SJerry Jelinek  *                                  ACPI_ALL_NOTIFY:    Both System and Device
264*385cc6b4SJerry Jelinek  *              Handler         - Address of the handler
265*385cc6b4SJerry Jelinek  *
266*385cc6b4SJerry Jelinek  * RETURN:      Status
267*385cc6b4SJerry Jelinek  *
268*385cc6b4SJerry Jelinek  * DESCRIPTION: Remove a handler for notifies on an ACPI device
269*385cc6b4SJerry Jelinek  *
270*385cc6b4SJerry Jelinek  ******************************************************************************/
271*385cc6b4SJerry Jelinek 
272*385cc6b4SJerry Jelinek ACPI_STATUS
273*385cc6b4SJerry Jelinek AcpiRemoveNotifyHandler (
274*385cc6b4SJerry Jelinek     ACPI_HANDLE             Device,
275*385cc6b4SJerry Jelinek     UINT32                  HandlerType,
276*385cc6b4SJerry Jelinek     ACPI_NOTIFY_HANDLER     Handler)
277*385cc6b4SJerry Jelinek {
278*385cc6b4SJerry Jelinek     ACPI_NAMESPACE_NODE     *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device);
279*385cc6b4SJerry Jelinek     ACPI_OPERAND_OBJECT     *ObjDesc;
280*385cc6b4SJerry Jelinek     ACPI_OPERAND_OBJECT     *HandlerObj;
281*385cc6b4SJerry Jelinek     ACPI_OPERAND_OBJECT     *PreviousHandlerObj;
282*385cc6b4SJerry Jelinek     ACPI_STATUS             Status = AE_OK;
283*385cc6b4SJerry Jelinek     UINT32                  i;
284*385cc6b4SJerry Jelinek 
285*385cc6b4SJerry Jelinek 
286*385cc6b4SJerry Jelinek     ACPI_FUNCTION_TRACE (AcpiRemoveNotifyHandler);
287*385cc6b4SJerry Jelinek 
288*385cc6b4SJerry Jelinek 
289*385cc6b4SJerry Jelinek     /* Parameter validation */
290*385cc6b4SJerry Jelinek 
291*385cc6b4SJerry Jelinek     if ((!Device) || (!Handler) || (!HandlerType) ||
292*385cc6b4SJerry Jelinek         (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
293*385cc6b4SJerry Jelinek     {
294*385cc6b4SJerry Jelinek         return_ACPI_STATUS (AE_BAD_PARAMETER);
295*385cc6b4SJerry Jelinek     }
296*385cc6b4SJerry Jelinek 
297*385cc6b4SJerry Jelinek     /* Root Object. Global handlers are removed here */
298*385cc6b4SJerry Jelinek 
299*385cc6b4SJerry Jelinek     if (Device == ACPI_ROOT_OBJECT)
300*385cc6b4SJerry Jelinek     {
301*385cc6b4SJerry Jelinek         for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
302*385cc6b4SJerry Jelinek         {
303*385cc6b4SJerry Jelinek             if (HandlerType & (i+1))
304*385cc6b4SJerry Jelinek             {
305*385cc6b4SJerry Jelinek                 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
306*385cc6b4SJerry Jelinek                 if (ACPI_FAILURE (Status))
307*385cc6b4SJerry Jelinek                 {
308*385cc6b4SJerry Jelinek                     return_ACPI_STATUS (Status);
309*385cc6b4SJerry Jelinek                 }
310*385cc6b4SJerry Jelinek 
311*385cc6b4SJerry Jelinek                 if (!AcpiGbl_GlobalNotify[i].Handler ||
312*385cc6b4SJerry Jelinek                     (AcpiGbl_GlobalNotify[i].Handler != Handler))
313*385cc6b4SJerry Jelinek                 {
314*385cc6b4SJerry Jelinek                     Status = AE_NOT_EXIST;
315*385cc6b4SJerry Jelinek                     goto UnlockAndExit;
316*385cc6b4SJerry Jelinek                 }
317*385cc6b4SJerry Jelinek 
318*385cc6b4SJerry Jelinek                 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
319*385cc6b4SJerry Jelinek                     "Removing global notify handler\n"));
320*385cc6b4SJerry Jelinek 
321*385cc6b4SJerry Jelinek                 AcpiGbl_GlobalNotify[i].Handler = NULL;
322*385cc6b4SJerry Jelinek                 AcpiGbl_GlobalNotify[i].Context = NULL;
323*385cc6b4SJerry Jelinek 
324*385cc6b4SJerry Jelinek                 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
325*385cc6b4SJerry Jelinek 
326*385cc6b4SJerry Jelinek                 /* Make sure all deferred notify tasks are completed */
327*385cc6b4SJerry Jelinek 
328*385cc6b4SJerry Jelinek                 AcpiOsWaitEventsComplete ();
329*385cc6b4SJerry Jelinek             }
330*385cc6b4SJerry Jelinek         }
331*385cc6b4SJerry Jelinek 
332*385cc6b4SJerry Jelinek         return_ACPI_STATUS (AE_OK);
333*385cc6b4SJerry Jelinek     }
334*385cc6b4SJerry Jelinek 
335*385cc6b4SJerry Jelinek     /* All other objects: Are Notifies allowed on this object? */
336*385cc6b4SJerry Jelinek 
337*385cc6b4SJerry Jelinek     if (!AcpiEvIsNotifyObject (Node))
338*385cc6b4SJerry Jelinek     {
339*385cc6b4SJerry Jelinek         return_ACPI_STATUS (AE_TYPE);
340*385cc6b4SJerry Jelinek     }
341*385cc6b4SJerry Jelinek 
342*385cc6b4SJerry Jelinek     /* Must have an existing internal object */
343*385cc6b4SJerry Jelinek 
344*385cc6b4SJerry Jelinek     ObjDesc = AcpiNsGetAttachedObject (Node);
345*385cc6b4SJerry Jelinek     if (!ObjDesc)
346*385cc6b4SJerry Jelinek     {
347*385cc6b4SJerry Jelinek         return_ACPI_STATUS (AE_NOT_EXIST);
348*385cc6b4SJerry Jelinek     }
349*385cc6b4SJerry Jelinek 
350*385cc6b4SJerry Jelinek     /* Internal object exists. Find the handler and remove it */
351*385cc6b4SJerry Jelinek 
352*385cc6b4SJerry Jelinek     for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
353*385cc6b4SJerry Jelinek     {
354*385cc6b4SJerry Jelinek         if (HandlerType & (i+1))
355*385cc6b4SJerry Jelinek         {
356*385cc6b4SJerry Jelinek             Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
357*385cc6b4SJerry Jelinek             if (ACPI_FAILURE (Status))
358*385cc6b4SJerry Jelinek             {
359*385cc6b4SJerry Jelinek                 return_ACPI_STATUS (Status);
360*385cc6b4SJerry Jelinek             }
361*385cc6b4SJerry Jelinek 
362*385cc6b4SJerry Jelinek             HandlerObj = ObjDesc->CommonNotify.NotifyList[i];
363*385cc6b4SJerry Jelinek             PreviousHandlerObj = NULL;
364*385cc6b4SJerry Jelinek 
365*385cc6b4SJerry Jelinek             /* Attempt to find the handler in the handler list */
366*385cc6b4SJerry Jelinek 
367*385cc6b4SJerry Jelinek             while (HandlerObj &&
368*385cc6b4SJerry Jelinek                   (HandlerObj->Notify.Handler != Handler))
369*385cc6b4SJerry Jelinek             {
370*385cc6b4SJerry Jelinek                 PreviousHandlerObj = HandlerObj;
371*385cc6b4SJerry Jelinek                 HandlerObj = HandlerObj->Notify.Next[i];
372*385cc6b4SJerry Jelinek             }
373*385cc6b4SJerry Jelinek 
374*385cc6b4SJerry Jelinek             if (!HandlerObj)
375*385cc6b4SJerry Jelinek             {
376*385cc6b4SJerry Jelinek                 Status = AE_NOT_EXIST;
377*385cc6b4SJerry Jelinek                 goto UnlockAndExit;
378*385cc6b4SJerry Jelinek             }
379*385cc6b4SJerry Jelinek 
380*385cc6b4SJerry Jelinek             /* Remove the handler object from the list */
381*385cc6b4SJerry Jelinek 
382*385cc6b4SJerry Jelinek             if (PreviousHandlerObj) /* Handler is not at the list head */
383*385cc6b4SJerry Jelinek             {
384*385cc6b4SJerry Jelinek                 PreviousHandlerObj->Notify.Next[i] =
385*385cc6b4SJerry Jelinek                     HandlerObj->Notify.Next[i];
386*385cc6b4SJerry Jelinek             }
387*385cc6b4SJerry Jelinek             else /* Handler is at the list head */
388*385cc6b4SJerry Jelinek             {
389*385cc6b4SJerry Jelinek                 ObjDesc->CommonNotify.NotifyList[i] =
390*385cc6b4SJerry Jelinek                     HandlerObj->Notify.Next[i];
391*385cc6b4SJerry Jelinek             }
392*385cc6b4SJerry Jelinek 
393*385cc6b4SJerry Jelinek             (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
394*385cc6b4SJerry Jelinek 
395*385cc6b4SJerry Jelinek             /* Make sure all deferred notify tasks are completed */
396*385cc6b4SJerry Jelinek 
397*385cc6b4SJerry Jelinek             AcpiOsWaitEventsComplete ();
398*385cc6b4SJerry Jelinek             AcpiUtRemoveReference (HandlerObj);
399*385cc6b4SJerry Jelinek         }
400*385cc6b4SJerry Jelinek     }
401*385cc6b4SJerry Jelinek 
402*385cc6b4SJerry Jelinek     return_ACPI_STATUS (Status);
403*385cc6b4SJerry Jelinek 
404*385cc6b4SJerry Jelinek 
405*385cc6b4SJerry Jelinek UnlockAndExit:
406*385cc6b4SJerry Jelinek     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
407*385cc6b4SJerry Jelinek     return_ACPI_STATUS (Status);
408*385cc6b4SJerry Jelinek }
409*385cc6b4SJerry Jelinek 
410*385cc6b4SJerry Jelinek ACPI_EXPORT_SYMBOL (AcpiRemoveNotifyHandler)
411*385cc6b4SJerry Jelinek 
412ae115bc7Smrj 
413ae115bc7Smrj /*******************************************************************************
414ae115bc7Smrj  *
415ae115bc7Smrj  * FUNCTION:    AcpiInstallExceptionHandler
416ae115bc7Smrj  *
417ae115bc7Smrj  * PARAMETERS:  Handler         - Pointer to the handler function for the
418ae115bc7Smrj  *                                event
419ae115bc7Smrj  *
420ae115bc7Smrj  * RETURN:      Status
421ae115bc7Smrj  *
422ae115bc7Smrj  * DESCRIPTION: Saves the pointer to the handler function
423ae115bc7Smrj  *
424ae115bc7Smrj  ******************************************************************************/
425ae115bc7Smrj 
426ae115bc7Smrj ACPI_STATUS
427ae115bc7Smrj AcpiInstallExceptionHandler (
428ae115bc7Smrj     ACPI_EXCEPTION_HANDLER  Handler)
429ae115bc7Smrj {
430ae115bc7Smrj     ACPI_STATUS             Status;
431ae115bc7Smrj 
432ae115bc7Smrj 
433ae115bc7Smrj     ACPI_FUNCTION_TRACE (AcpiInstallExceptionHandler);
434ae115bc7Smrj 
435ae115bc7Smrj 
436ae115bc7Smrj     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
437ae115bc7Smrj     if (ACPI_FAILURE (Status))
438ae115bc7Smrj     {
439ae115bc7Smrj         return_ACPI_STATUS (Status);
440ae115bc7Smrj     }
441ae115bc7Smrj 
442ae115bc7Smrj     /* Don't allow two handlers. */
443ae115bc7Smrj 
444ae115bc7Smrj     if (AcpiGbl_ExceptionHandler)
445ae115bc7Smrj     {
446ae115bc7Smrj         Status = AE_ALREADY_EXISTS;
447ae115bc7Smrj         goto Cleanup;
448ae115bc7Smrj     }
449ae115bc7Smrj 
450ae115bc7Smrj     /* Install the handler */
451ae115bc7Smrj 
452ae115bc7Smrj     AcpiGbl_ExceptionHandler = Handler;
453ae115bc7Smrj 
454ae115bc7Smrj Cleanup:
455ae115bc7Smrj     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
456ae115bc7Smrj     return_ACPI_STATUS (Status);
457ae115bc7Smrj }
458ae115bc7Smrj 
459ae115bc7Smrj ACPI_EXPORT_SYMBOL (AcpiInstallExceptionHandler)
460ae115bc7Smrj 
461ae115bc7Smrj 
462*385cc6b4SJerry Jelinek #if (!ACPI_REDUCED_HARDWARE)
463*385cc6b4SJerry Jelinek /*******************************************************************************
464*385cc6b4SJerry Jelinek  *
465*385cc6b4SJerry Jelinek  * FUNCTION:    AcpiInstallSciHandler
466*385cc6b4SJerry Jelinek  *
467*385cc6b4SJerry Jelinek  * PARAMETERS:  Address             - Address of the handler
468*385cc6b4SJerry Jelinek  *              Context             - Value passed to the handler on each SCI
469*385cc6b4SJerry Jelinek  *
470*385cc6b4SJerry Jelinek  * RETURN:      Status
471*385cc6b4SJerry Jelinek  *
472*385cc6b4SJerry Jelinek  * DESCRIPTION: Install a handler for a System Control Interrupt.
473*385cc6b4SJerry Jelinek  *
474*385cc6b4SJerry Jelinek  ******************************************************************************/
475*385cc6b4SJerry Jelinek 
476*385cc6b4SJerry Jelinek ACPI_STATUS
477*385cc6b4SJerry Jelinek AcpiInstallSciHandler (
478*385cc6b4SJerry Jelinek     ACPI_SCI_HANDLER        Address,
479*385cc6b4SJerry Jelinek     void                    *Context)
480*385cc6b4SJerry Jelinek {
481*385cc6b4SJerry Jelinek     ACPI_SCI_HANDLER_INFO   *NewSciHandler;
482*385cc6b4SJerry Jelinek     ACPI_SCI_HANDLER_INFO   *SciHandler;
483*385cc6b4SJerry Jelinek     ACPI_CPU_FLAGS          Flags;
484*385cc6b4SJerry Jelinek     ACPI_STATUS             Status;
485*385cc6b4SJerry Jelinek 
486*385cc6b4SJerry Jelinek 
487*385cc6b4SJerry Jelinek     ACPI_FUNCTION_TRACE (AcpiInstallSciHandler);
488*385cc6b4SJerry Jelinek 
489*385cc6b4SJerry Jelinek 
490*385cc6b4SJerry Jelinek     if (!Address)
491*385cc6b4SJerry Jelinek     {
492*385cc6b4SJerry Jelinek         return_ACPI_STATUS (AE_BAD_PARAMETER);
493*385cc6b4SJerry Jelinek     }
494*385cc6b4SJerry Jelinek 
495*385cc6b4SJerry Jelinek     /* Allocate and init a handler object */
496*385cc6b4SJerry Jelinek 
497*385cc6b4SJerry Jelinek     NewSciHandler = ACPI_ALLOCATE (sizeof (ACPI_SCI_HANDLER_INFO));
498*385cc6b4SJerry Jelinek     if (!NewSciHandler)
499*385cc6b4SJerry Jelinek     {
500*385cc6b4SJerry Jelinek         return_ACPI_STATUS (AE_NO_MEMORY);
501*385cc6b4SJerry Jelinek     }
502*385cc6b4SJerry Jelinek 
503*385cc6b4SJerry Jelinek     NewSciHandler->Address = Address;
504*385cc6b4SJerry Jelinek     NewSciHandler->Context = Context;
505*385cc6b4SJerry Jelinek 
506*385cc6b4SJerry Jelinek     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
507*385cc6b4SJerry Jelinek     if (ACPI_FAILURE (Status))
508*385cc6b4SJerry Jelinek     {
509*385cc6b4SJerry Jelinek         goto Exit;
510*385cc6b4SJerry Jelinek     }
511*385cc6b4SJerry Jelinek 
512*385cc6b4SJerry Jelinek     /* Lock list during installation */
513*385cc6b4SJerry Jelinek 
514*385cc6b4SJerry Jelinek     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
515*385cc6b4SJerry Jelinek     SciHandler = AcpiGbl_SciHandlerList;
516*385cc6b4SJerry Jelinek 
517*385cc6b4SJerry Jelinek     /* Ensure handler does not already exist */
518*385cc6b4SJerry Jelinek 
519*385cc6b4SJerry Jelinek     while (SciHandler)
520*385cc6b4SJerry Jelinek     {
521*385cc6b4SJerry Jelinek         if (Address == SciHandler->Address)
522*385cc6b4SJerry Jelinek         {
523*385cc6b4SJerry Jelinek             Status = AE_ALREADY_EXISTS;
524*385cc6b4SJerry Jelinek             goto UnlockAndExit;
525*385cc6b4SJerry Jelinek         }
526*385cc6b4SJerry Jelinek 
527*385cc6b4SJerry Jelinek         SciHandler = SciHandler->Next;
528*385cc6b4SJerry Jelinek     }
529*385cc6b4SJerry Jelinek 
530*385cc6b4SJerry Jelinek     /* Install the new handler into the global list (at head) */
531*385cc6b4SJerry Jelinek 
532*385cc6b4SJerry Jelinek     NewSciHandler->Next = AcpiGbl_SciHandlerList;
533*385cc6b4SJerry Jelinek     AcpiGbl_SciHandlerList = NewSciHandler;
534*385cc6b4SJerry Jelinek 
535*385cc6b4SJerry Jelinek 
536*385cc6b4SJerry Jelinek UnlockAndExit:
537*385cc6b4SJerry Jelinek 
538*385cc6b4SJerry Jelinek     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
539*385cc6b4SJerry Jelinek     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
540*385cc6b4SJerry Jelinek 
541*385cc6b4SJerry Jelinek Exit:
542*385cc6b4SJerry Jelinek     if (ACPI_FAILURE (Status))
543*385cc6b4SJerry Jelinek     {
544*385cc6b4SJerry Jelinek         ACPI_FREE (NewSciHandler);
545*385cc6b4SJerry Jelinek     }
546*385cc6b4SJerry Jelinek     return_ACPI_STATUS (Status);
547*385cc6b4SJerry Jelinek }
548*385cc6b4SJerry Jelinek 
549*385cc6b4SJerry Jelinek ACPI_EXPORT_SYMBOL (AcpiInstallSciHandler)
550*385cc6b4SJerry Jelinek 
551*385cc6b4SJerry Jelinek 
552*385cc6b4SJerry Jelinek /*******************************************************************************
553*385cc6b4SJerry Jelinek  *
554*385cc6b4SJerry Jelinek  * FUNCTION:    AcpiRemoveSciHandler
555*385cc6b4SJerry Jelinek  *
556*385cc6b4SJerry Jelinek  * PARAMETERS:  Address             - Address of the handler
557*385cc6b4SJerry Jelinek  *
558*385cc6b4SJerry Jelinek  * RETURN:      Status
559*385cc6b4SJerry Jelinek  *
560*385cc6b4SJerry Jelinek  * DESCRIPTION: Remove a handler for a System Control Interrupt.
561*385cc6b4SJerry Jelinek  *
562*385cc6b4SJerry Jelinek  ******************************************************************************/
563*385cc6b4SJerry Jelinek 
564*385cc6b4SJerry Jelinek ACPI_STATUS
565*385cc6b4SJerry Jelinek AcpiRemoveSciHandler (
566*385cc6b4SJerry Jelinek     ACPI_SCI_HANDLER        Address)
567*385cc6b4SJerry Jelinek {
568*385cc6b4SJerry Jelinek     ACPI_SCI_HANDLER_INFO   *PrevSciHandler;
569*385cc6b4SJerry Jelinek     ACPI_SCI_HANDLER_INFO   *NextSciHandler;
570*385cc6b4SJerry Jelinek     ACPI_CPU_FLAGS          Flags;
571*385cc6b4SJerry Jelinek     ACPI_STATUS             Status;
572*385cc6b4SJerry Jelinek 
573*385cc6b4SJerry Jelinek 
574*385cc6b4SJerry Jelinek     ACPI_FUNCTION_TRACE (AcpiRemoveSciHandler);
575*385cc6b4SJerry Jelinek 
576*385cc6b4SJerry Jelinek 
577*385cc6b4SJerry Jelinek     if (!Address)
578*385cc6b4SJerry Jelinek     {
579*385cc6b4SJerry Jelinek         return_ACPI_STATUS (AE_BAD_PARAMETER);
580*385cc6b4SJerry Jelinek     }
581*385cc6b4SJerry Jelinek 
582*385cc6b4SJerry Jelinek     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
583*385cc6b4SJerry Jelinek     if (ACPI_FAILURE (Status))
584*385cc6b4SJerry Jelinek     {
585*385cc6b4SJerry Jelinek         return_ACPI_STATUS (Status);
586*385cc6b4SJerry Jelinek     }
587*385cc6b4SJerry Jelinek 
588*385cc6b4SJerry Jelinek     /* Remove the SCI handler with lock */
589*385cc6b4SJerry Jelinek 
590*385cc6b4SJerry Jelinek     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
591*385cc6b4SJerry Jelinek 
592*385cc6b4SJerry Jelinek     PrevSciHandler = NULL;
593*385cc6b4SJerry Jelinek     NextSciHandler = AcpiGbl_SciHandlerList;
594*385cc6b4SJerry Jelinek     while (NextSciHandler)
595*385cc6b4SJerry Jelinek     {
596*385cc6b4SJerry Jelinek         if (NextSciHandler->Address == Address)
597*385cc6b4SJerry Jelinek         {
598*385cc6b4SJerry Jelinek             /* Unlink and free the SCI handler info block */
599*385cc6b4SJerry Jelinek 
600*385cc6b4SJerry Jelinek             if (PrevSciHandler)
601*385cc6b4SJerry Jelinek             {
602*385cc6b4SJerry Jelinek                 PrevSciHandler->Next = NextSciHandler->Next;
603*385cc6b4SJerry Jelinek             }
604*385cc6b4SJerry Jelinek             else
605*385cc6b4SJerry Jelinek             {
606*385cc6b4SJerry Jelinek                 AcpiGbl_SciHandlerList = NextSciHandler->Next;
607*385cc6b4SJerry Jelinek             }
608*385cc6b4SJerry Jelinek 
609*385cc6b4SJerry Jelinek             AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
610*385cc6b4SJerry Jelinek             ACPI_FREE (NextSciHandler);
611*385cc6b4SJerry Jelinek             goto UnlockAndExit;
612*385cc6b4SJerry Jelinek         }
613*385cc6b4SJerry Jelinek 
614*385cc6b4SJerry Jelinek         PrevSciHandler = NextSciHandler;
615*385cc6b4SJerry Jelinek         NextSciHandler = NextSciHandler->Next;
616*385cc6b4SJerry Jelinek     }
617*385cc6b4SJerry Jelinek 
618*385cc6b4SJerry Jelinek     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
619*385cc6b4SJerry Jelinek     Status = AE_NOT_EXIST;
620*385cc6b4SJerry Jelinek 
621*385cc6b4SJerry Jelinek 
622*385cc6b4SJerry Jelinek UnlockAndExit:
623*385cc6b4SJerry Jelinek     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
624*385cc6b4SJerry Jelinek     return_ACPI_STATUS (Status);
625*385cc6b4SJerry Jelinek }
626*385cc6b4SJerry Jelinek 
627*385cc6b4SJerry Jelinek ACPI_EXPORT_SYMBOL (AcpiRemoveSciHandler)
628*385cc6b4SJerry Jelinek 
629*385cc6b4SJerry Jelinek 
630ae115bc7Smrj /*******************************************************************************
631ae115bc7Smrj  *
63226f3cdf0SGordon Ross  * FUNCTION:    AcpiInstallGlobalEventHandler
63326f3cdf0SGordon Ross  *
63426f3cdf0SGordon Ross  * PARAMETERS:  Handler         - Pointer to the global event handler function
63526f3cdf0SGordon Ross  *              Context         - Value passed to the handler on each event
63626f3cdf0SGordon Ross  *
63726f3cdf0SGordon Ross  * RETURN:      Status
63826f3cdf0SGordon Ross  *
63926f3cdf0SGordon Ross  * DESCRIPTION: Saves the pointer to the handler function. The global handler
64026f3cdf0SGordon Ross  *              is invoked upon each incoming GPE and Fixed Event. It is
64126f3cdf0SGordon Ross  *              invoked at interrupt level at the time of the event dispatch.
64226f3cdf0SGordon Ross  *              Can be used to update event counters, etc.
64326f3cdf0SGordon Ross  *
64426f3cdf0SGordon Ross  ******************************************************************************/
64526f3cdf0SGordon Ross 
64626f3cdf0SGordon Ross ACPI_STATUS
64726f3cdf0SGordon Ross AcpiInstallGlobalEventHandler (
64826f3cdf0SGordon Ross     ACPI_GBL_EVENT_HANDLER  Handler,
64926f3cdf0SGordon Ross     void                    *Context)
65026f3cdf0SGordon Ross {
65126f3cdf0SGordon Ross     ACPI_STATUS             Status;
65226f3cdf0SGordon Ross 
65326f3cdf0SGordon Ross 
65426f3cdf0SGordon Ross     ACPI_FUNCTION_TRACE (AcpiInstallGlobalEventHandler);
65526f3cdf0SGordon Ross 
65626f3cdf0SGordon Ross 
65726f3cdf0SGordon Ross     /* Parameter validation */
65826f3cdf0SGordon Ross 
65926f3cdf0SGordon Ross     if (!Handler)
66026f3cdf0SGordon Ross     {
66126f3cdf0SGordon Ross         return_ACPI_STATUS (AE_BAD_PARAMETER);
66226f3cdf0SGordon Ross     }
66326f3cdf0SGordon Ross 
66426f3cdf0SGordon Ross     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
66526f3cdf0SGordon Ross     if (ACPI_FAILURE (Status))
66626f3cdf0SGordon Ross     {
66726f3cdf0SGordon Ross         return_ACPI_STATUS (Status);
66826f3cdf0SGordon Ross     }
66926f3cdf0SGordon Ross 
67026f3cdf0SGordon Ross     /* Don't allow two handlers. */
67126f3cdf0SGordon Ross 
67226f3cdf0SGordon Ross     if (AcpiGbl_GlobalEventHandler)
67326f3cdf0SGordon Ross     {
67426f3cdf0SGordon Ross         Status = AE_ALREADY_EXISTS;
67526f3cdf0SGordon Ross         goto Cleanup;
67626f3cdf0SGordon Ross     }
67726f3cdf0SGordon Ross 
67826f3cdf0SGordon Ross     AcpiGbl_GlobalEventHandler = Handler;
67926f3cdf0SGordon Ross     AcpiGbl_GlobalEventHandlerContext = Context;
68026f3cdf0SGordon Ross 
68126f3cdf0SGordon Ross 
68226f3cdf0SGordon Ross Cleanup:
68326f3cdf0SGordon Ross     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
68426f3cdf0SGordon Ross     return_ACPI_STATUS (Status);
68526f3cdf0SGordon Ross }
68626f3cdf0SGordon Ross 
68726f3cdf0SGordon Ross ACPI_EXPORT_SYMBOL (AcpiInstallGlobalEventHandler)
68826f3cdf0SGordon Ross 
68926f3cdf0SGordon Ross 
69026f3cdf0SGordon Ross /*******************************************************************************
69126f3cdf0SGordon Ross  *
692ae115bc7Smrj  * FUNCTION:    AcpiInstallFixedEventHandler
693ae115bc7Smrj  *
694ae115bc7Smrj  * PARAMETERS:  Event           - Event type to enable.
695ae115bc7Smrj  *              Handler         - Pointer to the handler function for the
696ae115bc7Smrj  *                                event
697ae115bc7Smrj  *              Context         - Value passed to the handler on each GPE
698ae115bc7Smrj  *
699ae115bc7Smrj  * RETURN:      Status
700ae115bc7Smrj  *
701ae115bc7Smrj  * DESCRIPTION: Saves the pointer to the handler function and then enables the
702ae115bc7Smrj  *              event.
703ae115bc7Smrj  *
704ae115bc7Smrj  ******************************************************************************/
705ae115bc7Smrj 
706ae115bc7Smrj ACPI_STATUS
707ae115bc7Smrj AcpiInstallFixedEventHandler (
708ae115bc7Smrj     UINT32                  Event,
709ae115bc7Smrj     ACPI_EVENT_HANDLER      Handler,
710ae115bc7Smrj     void                    *Context)
711ae115bc7Smrj {
712ae115bc7Smrj     ACPI_STATUS             Status;
713ae115bc7Smrj 
714ae115bc7Smrj 
715ae115bc7Smrj     ACPI_FUNCTION_TRACE (AcpiInstallFixedEventHandler);
716ae115bc7Smrj 
717ae115bc7Smrj 
718ae115bc7Smrj     /* Parameter validation */
719ae115bc7Smrj 
720ae115bc7Smrj     if (Event > ACPI_EVENT_MAX)
721ae115bc7Smrj     {
722ae115bc7Smrj         return_ACPI_STATUS (AE_BAD_PARAMETER);
723ae115bc7Smrj     }
724ae115bc7Smrj 
725ae115bc7Smrj     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
726ae115bc7Smrj     if (ACPI_FAILURE (Status))
727ae115bc7Smrj     {
728ae115bc7Smrj         return_ACPI_STATUS (Status);
729ae115bc7Smrj     }
730ae115bc7Smrj 
731*385cc6b4SJerry Jelinek     /* Do not allow multiple handlers */
732ae115bc7Smrj 
733*385cc6b4SJerry Jelinek     if (AcpiGbl_FixedEventHandlers[Event].Handler)
734ae115bc7Smrj     {
735ae115bc7Smrj         Status = AE_ALREADY_EXISTS;
736ae115bc7Smrj         goto Cleanup;
737ae115bc7Smrj     }
738ae115bc7Smrj 
739ae115bc7Smrj     /* Install the handler before enabling the event */
740ae115bc7Smrj 
741ae115bc7Smrj     AcpiGbl_FixedEventHandlers[Event].Handler = Handler;
742ae115bc7Smrj     AcpiGbl_FixedEventHandlers[Event].Context = Context;
743ae115bc7Smrj 
744ae115bc7Smrj     Status = AcpiEnableEvent (Event, 0);
745ae115bc7Smrj     if (ACPI_FAILURE (Status))
746ae115bc7Smrj     {
747*385cc6b4SJerry Jelinek         ACPI_WARNING ((AE_INFO,
748*385cc6b4SJerry Jelinek             "Could not enable fixed event - %s (%u)",
749*385cc6b4SJerry Jelinek             AcpiUtGetEventName (Event), Event));
750ae115bc7Smrj 
751ae115bc7Smrj         /* Remove the handler */
752ae115bc7Smrj 
753ae115bc7Smrj         AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
754ae115bc7Smrj         AcpiGbl_FixedEventHandlers[Event].Context = NULL;
755ae115bc7Smrj     }
756ae115bc7Smrj     else
757ae115bc7Smrj     {
758ae115bc7Smrj         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
759*385cc6b4SJerry Jelinek             "Enabled fixed event %s (%X), Handler=%p\n",
760*385cc6b4SJerry Jelinek             AcpiUtGetEventName (Event), Event, Handler));
761ae115bc7Smrj     }
762ae115bc7Smrj 
763ae115bc7Smrj 
764ae115bc7Smrj Cleanup:
765ae115bc7Smrj     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
766ae115bc7Smrj     return_ACPI_STATUS (Status);
767ae115bc7Smrj }
768ae115bc7Smrj 
769ae115bc7Smrj ACPI_EXPORT_SYMBOL (AcpiInstallFixedEventHandler)
770ae115bc7Smrj 
771ae115bc7Smrj 
772ae115bc7Smrj /*******************************************************************************
773ae115bc7Smrj  *
774ae115bc7Smrj  * FUNCTION:    AcpiRemoveFixedEventHandler
775ae115bc7Smrj  *
776ae115bc7Smrj  * PARAMETERS:  Event           - Event type to disable.
777ae115bc7Smrj  *              Handler         - Address of the handler
778ae115bc7Smrj  *
779ae115bc7Smrj  * RETURN:      Status
780ae115bc7Smrj  *
781ae115bc7Smrj  * DESCRIPTION: Disables the event and unregisters the event handler.
782ae115bc7Smrj  *
783ae115bc7Smrj  ******************************************************************************/
784ae115bc7Smrj 
785ae115bc7Smrj ACPI_STATUS
786ae115bc7Smrj AcpiRemoveFixedEventHandler (
787ae115bc7Smrj     UINT32                  Event,
788ae115bc7Smrj     ACPI_EVENT_HANDLER      Handler)
789ae115bc7Smrj {
790ae115bc7Smrj     ACPI_STATUS             Status = AE_OK;
791ae115bc7Smrj 
792ae115bc7Smrj 
793ae115bc7Smrj     ACPI_FUNCTION_TRACE (AcpiRemoveFixedEventHandler);
794ae115bc7Smrj 
795ae115bc7Smrj 
796ae115bc7Smrj     /* Parameter validation */
797ae115bc7Smrj 
798ae115bc7Smrj     if (Event > ACPI_EVENT_MAX)
799ae115bc7Smrj     {
800ae115bc7Smrj         return_ACPI_STATUS (AE_BAD_PARAMETER);
801ae115bc7Smrj     }
802ae115bc7Smrj 
803ae115bc7Smrj     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
804ae115bc7Smrj     if (ACPI_FAILURE (Status))
805ae115bc7Smrj     {
806ae115bc7Smrj         return_ACPI_STATUS (Status);
807ae115bc7Smrj     }
808ae115bc7Smrj 
809ae115bc7Smrj     /* Disable the event before removing the handler */
810ae115bc7Smrj 
811ae115bc7Smrj     Status = AcpiDisableEvent (Event, 0);
812ae115bc7Smrj 
813ae115bc7Smrj     /* Always Remove the handler */
814ae115bc7Smrj 
815ae115bc7Smrj     AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
816ae115bc7Smrj     AcpiGbl_FixedEventHandlers[Event].Context = NULL;
817ae115bc7Smrj 
818ae115bc7Smrj     if (ACPI_FAILURE (Status))
819ae115bc7Smrj     {
820ae115bc7Smrj         ACPI_WARNING ((AE_INFO,
821*385cc6b4SJerry Jelinek             "Could not disable fixed event - %s (%u)",
822*385cc6b4SJerry Jelinek             AcpiUtGetEventName (Event), Event));
823ae115bc7Smrj     }
824ae115bc7Smrj     else
825ae115bc7Smrj     {
826*385cc6b4SJerry Jelinek         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
827*385cc6b4SJerry Jelinek             "Disabled fixed event - %s (%X)\n",
828*385cc6b4SJerry Jelinek             AcpiUtGetEventName (Event), Event));
829ae115bc7Smrj     }
830ae115bc7Smrj 
831ae115bc7Smrj     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
832ae115bc7Smrj     return_ACPI_STATUS (Status);
833ae115bc7Smrj }
834ae115bc7Smrj 
835ae115bc7Smrj ACPI_EXPORT_SYMBOL (AcpiRemoveFixedEventHandler)
836ae115bc7Smrj 
837ae115bc7Smrj 
838ae115bc7Smrj /*******************************************************************************
839ae115bc7Smrj  *
840*385cc6b4SJerry Jelinek  * FUNCTION:    AcpiEvInstallGpeHandler
841ae115bc7Smrj  *
842ae115bc7Smrj  * PARAMETERS:  GpeDevice       - Namespace node for the GPE (NULL for FADT
843ae115bc7Smrj  *                                defined GPEs)
844ae115bc7Smrj  *              GpeNumber       - The GPE number within the GPE block
845ae115bc7Smrj  *              Type            - Whether this GPE should be treated as an
846ae115bc7Smrj  *                                edge- or level-triggered interrupt.
847*385cc6b4SJerry Jelinek  *              IsRawHandler    - Whether this GPE should be handled using
848*385cc6b4SJerry Jelinek  *                                the special GPE handler mode.
849ae115bc7Smrj  *              Address         - Address of the handler
850ae115bc7Smrj  *              Context         - Value passed to the handler on each GPE
851ae115bc7Smrj  *
852ae115bc7Smrj  * RETURN:      Status
853ae115bc7Smrj  *
854*385cc6b4SJerry Jelinek  * DESCRIPTION: Internal function to install a handler for a General Purpose
855*385cc6b4SJerry Jelinek  *              Event.
856ae115bc7Smrj  *
857ae115bc7Smrj  ******************************************************************************/
858ae115bc7Smrj 
859*385cc6b4SJerry Jelinek static ACPI_STATUS
860*385cc6b4SJerry Jelinek AcpiEvInstallGpeHandler (
861ae115bc7Smrj     ACPI_HANDLE             GpeDevice,
862ae115bc7Smrj     UINT32                  GpeNumber,
863ae115bc7Smrj     UINT32                  Type,
864*385cc6b4SJerry Jelinek     BOOLEAN                 IsRawHandler,
86526f3cdf0SGordon Ross     ACPI_GPE_HANDLER        Address,
866ae115bc7Smrj     void                    *Context)
867ae115bc7Smrj {
868ae115bc7Smrj     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
86926f3cdf0SGordon Ross     ACPI_GPE_HANDLER_INFO   *Handler;
870ae115bc7Smrj     ACPI_STATUS             Status;
871ae115bc7Smrj     ACPI_CPU_FLAGS          Flags;
872ae115bc7Smrj 
873ae115bc7Smrj 
874*385cc6b4SJerry Jelinek     ACPI_FUNCTION_TRACE (EvInstallGpeHandler);
875ae115bc7Smrj 
876ae115bc7Smrj 
877ae115bc7Smrj     /* Parameter validation */
878ae115bc7Smrj 
87926f3cdf0SGordon Ross     if ((!Address) || (Type & ~ACPI_GPE_XRUPT_TYPE_MASK))
880ae115bc7Smrj     {
881ae115bc7Smrj         return_ACPI_STATUS (AE_BAD_PARAMETER);
882ae115bc7Smrj     }
883ae115bc7Smrj 
884ae115bc7Smrj     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
885ae115bc7Smrj     if (ACPI_FAILURE (Status))
886ae115bc7Smrj     {
887ae115bc7Smrj         return_ACPI_STATUS (Status);
888ae115bc7Smrj     }
889ae115bc7Smrj 
89026f3cdf0SGordon Ross     /* Allocate and init handler object (before lock) */
89126f3cdf0SGordon Ross 
89226f3cdf0SGordon Ross     Handler = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_HANDLER_INFO));
89326f3cdf0SGordon Ross     if (!Handler)
89426f3cdf0SGordon Ross     {
89526f3cdf0SGordon Ross         Status = AE_NO_MEMORY;
89626f3cdf0SGordon Ross         goto UnlockAndExit;
89726f3cdf0SGordon Ross     }
89826f3cdf0SGordon Ross 
89926f3cdf0SGordon Ross     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
90026f3cdf0SGordon Ross 
901ae115bc7Smrj     /* Ensure that we have a valid GPE number */
902ae115bc7Smrj 
903ae115bc7Smrj     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
904ae115bc7Smrj     if (!GpeEventInfo)
905ae115bc7Smrj     {
906ae115bc7Smrj         Status = AE_BAD_PARAMETER;
90726f3cdf0SGordon Ross         goto FreeAndExit;
908ae115bc7Smrj     }
909ae115bc7Smrj 
910ae115bc7Smrj     /* Make sure that there isn't a handler there already */
911ae115bc7Smrj 
912*385cc6b4SJerry Jelinek     if ((ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
913*385cc6b4SJerry Jelinek             ACPI_GPE_DISPATCH_HANDLER) ||
914*385cc6b4SJerry Jelinek         (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
915*385cc6b4SJerry Jelinek             ACPI_GPE_DISPATCH_RAW_HANDLER))
916ae115bc7Smrj     {
917ae115bc7Smrj         Status = AE_ALREADY_EXISTS;
91826f3cdf0SGordon Ross         goto FreeAndExit;
919ae115bc7Smrj     }
920ae115bc7Smrj 
921ae115bc7Smrj     Handler->Address = Address;
922ae115bc7Smrj     Handler->Context = Context;
923ae115bc7Smrj     Handler->MethodNode = GpeEventInfo->Dispatch.MethodNode;
92426f3cdf0SGordon Ross     Handler->OriginalFlags = (UINT8) (GpeEventInfo->Flags &
92526f3cdf0SGordon Ross         (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK));
926ae115bc7Smrj 
92726f3cdf0SGordon Ross     /*
92826f3cdf0SGordon Ross      * If the GPE is associated with a method, it may have been enabled
92926f3cdf0SGordon Ross      * automatically during initialization, in which case it has to be
93026f3cdf0SGordon Ross      * disabled now to avoid spurious execution of the handler.
93126f3cdf0SGordon Ross      */
932*385cc6b4SJerry Jelinek     if (((ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) ==
933*385cc6b4SJerry Jelinek             ACPI_GPE_DISPATCH_METHOD) ||
934*385cc6b4SJerry Jelinek          (ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) ==
935*385cc6b4SJerry Jelinek             ACPI_GPE_DISPATCH_NOTIFY)) &&
93626f3cdf0SGordon Ross         GpeEventInfo->RuntimeCount)
937ae115bc7Smrj     {
93826f3cdf0SGordon Ross         Handler->OriginallyEnabled = TRUE;
93926f3cdf0SGordon Ross         (void) AcpiEvRemoveGpeReference (GpeEventInfo);
94026f3cdf0SGordon Ross 
94126f3cdf0SGordon Ross         /* Sanity check of original type against new type */
94226f3cdf0SGordon Ross 
94326f3cdf0SGordon Ross         if (Type != (UINT32) (GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK))
94426f3cdf0SGordon Ross         {
94526f3cdf0SGordon Ross             ACPI_WARNING ((AE_INFO, "GPE type mismatch (level/edge)"));
94626f3cdf0SGordon Ross         }
947ae115bc7Smrj     }
948ae115bc7Smrj 
949ae115bc7Smrj     /* Install the handler */
950ae115bc7Smrj 
951ae115bc7Smrj     GpeEventInfo->Dispatch.Handler = Handler;
952ae115bc7Smrj 
95326f3cdf0SGordon Ross     /* Setup up dispatch flags to indicate handler (vs. method/notify) */
954ae115bc7Smrj 
955aa2aa9a6SDana Myers     GpeEventInfo->Flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
956*385cc6b4SJerry Jelinek     GpeEventInfo->Flags |= (UINT8) (Type | (IsRawHandler ?
957*385cc6b4SJerry Jelinek         ACPI_GPE_DISPATCH_RAW_HANDLER : ACPI_GPE_DISPATCH_HANDLER));
958ae115bc7Smrj 
959ae115bc7Smrj     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
960ae115bc7Smrj 
961ae115bc7Smrj 
962ae115bc7Smrj UnlockAndExit:
963ae115bc7Smrj     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
964ae115bc7Smrj     return_ACPI_STATUS (Status);
96526f3cdf0SGordon Ross 
96626f3cdf0SGordon Ross FreeAndExit:
96726f3cdf0SGordon Ross     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
96826f3cdf0SGordon Ross     ACPI_FREE (Handler);
96926f3cdf0SGordon Ross     goto UnlockAndExit;
970ae115bc7Smrj }
971ae115bc7Smrj 
972*385cc6b4SJerry Jelinek 
973*385cc6b4SJerry Jelinek /*******************************************************************************
974*385cc6b4SJerry Jelinek  *
975*385cc6b4SJerry Jelinek  * FUNCTION:    AcpiInstallGpeHandler
976*385cc6b4SJerry Jelinek  *
977*385cc6b4SJerry Jelinek  * PARAMETERS:  GpeDevice       - Namespace node for the GPE (NULL for FADT
978*385cc6b4SJerry Jelinek  *                                defined GPEs)
979*385cc6b4SJerry Jelinek  *              GpeNumber       - The GPE number within the GPE block
980*385cc6b4SJerry Jelinek  *              Type            - Whether this GPE should be treated as an
981*385cc6b4SJerry Jelinek  *                                edge- or level-triggered interrupt.
982*385cc6b4SJerry Jelinek  *              Address         - Address of the handler
983*385cc6b4SJerry Jelinek  *              Context         - Value passed to the handler on each GPE
984*385cc6b4SJerry Jelinek  *
985*385cc6b4SJerry Jelinek  * RETURN:      Status
986*385cc6b4SJerry Jelinek  *
987*385cc6b4SJerry Jelinek  * DESCRIPTION: Install a handler for a General Purpose Event.
988*385cc6b4SJerry Jelinek  *
989*385cc6b4SJerry Jelinek  ******************************************************************************/
990*385cc6b4SJerry Jelinek 
991*385cc6b4SJerry Jelinek ACPI_STATUS
992*385cc6b4SJerry Jelinek AcpiInstallGpeHandler (
993*385cc6b4SJerry Jelinek     ACPI_HANDLE             GpeDevice,
994*385cc6b4SJerry Jelinek     UINT32                  GpeNumber,
995*385cc6b4SJerry Jelinek     UINT32                  Type,
996*385cc6b4SJerry Jelinek     ACPI_GPE_HANDLER        Address,
997*385cc6b4SJerry Jelinek     void                    *Context)
998*385cc6b4SJerry Jelinek {
999*385cc6b4SJerry Jelinek     ACPI_STATUS             Status;
1000*385cc6b4SJerry Jelinek 
1001*385cc6b4SJerry Jelinek 
1002*385cc6b4SJerry Jelinek     ACPI_FUNCTION_TRACE (AcpiInstallGpeHandler);
1003*385cc6b4SJerry Jelinek 
1004*385cc6b4SJerry Jelinek 
1005*385cc6b4SJerry Jelinek     Status = AcpiEvInstallGpeHandler (GpeDevice, GpeNumber, Type,
1006*385cc6b4SJerry Jelinek         FALSE, Address, Context);
1007*385cc6b4SJerry Jelinek 
1008*385cc6b4SJerry Jelinek     return_ACPI_STATUS (Status);
1009*385cc6b4SJerry Jelinek }
1010*385cc6b4SJerry Jelinek 
1011ae115bc7Smrj ACPI_EXPORT_SYMBOL (AcpiInstallGpeHandler)
1012ae115bc7Smrj 
1013ae115bc7Smrj 
1014ae115bc7Smrj /*******************************************************************************
1015ae115bc7Smrj  *
1016*385cc6b4SJerry Jelinek  * FUNCTION:    AcpiInstallGpeRawHandler
1017*385cc6b4SJerry Jelinek  *
1018*385cc6b4SJerry Jelinek  * PARAMETERS:  GpeDevice       - Namespace node for the GPE (NULL for FADT
1019*385cc6b4SJerry Jelinek  *                                defined GPEs)
1020*385cc6b4SJerry Jelinek  *              GpeNumber       - The GPE number within the GPE block
1021*385cc6b4SJerry Jelinek  *              Type            - Whether this GPE should be treated as an
1022*385cc6b4SJerry Jelinek  *                                edge- or level-triggered interrupt.
1023*385cc6b4SJerry Jelinek  *              Address         - Address of the handler
1024*385cc6b4SJerry Jelinek  *              Context         - Value passed to the handler on each GPE
1025*385cc6b4SJerry Jelinek  *
1026*385cc6b4SJerry Jelinek  * RETURN:      Status
1027*385cc6b4SJerry Jelinek  *
1028*385cc6b4SJerry Jelinek  * DESCRIPTION: Install a handler for a General Purpose Event.
1029*385cc6b4SJerry Jelinek  *
1030*385cc6b4SJerry Jelinek  ******************************************************************************/
1031*385cc6b4SJerry Jelinek 
1032*385cc6b4SJerry Jelinek ACPI_STATUS
1033*385cc6b4SJerry Jelinek AcpiInstallGpeRawHandler (
1034*385cc6b4SJerry Jelinek     ACPI_HANDLE             GpeDevice,
1035*385cc6b4SJerry Jelinek     UINT32                  GpeNumber,
1036*385cc6b4SJerry Jelinek     UINT32                  Type,
1037*385cc6b4SJerry Jelinek     ACPI_GPE_HANDLER        Address,
1038*385cc6b4SJerry Jelinek     void                    *Context)
1039*385cc6b4SJerry Jelinek {
1040*385cc6b4SJerry Jelinek     ACPI_STATUS             Status;
1041*385cc6b4SJerry Jelinek 
1042*385cc6b4SJerry Jelinek 
1043*385cc6b4SJerry Jelinek     ACPI_FUNCTION_TRACE (AcpiInstallGpeRawHandler);
1044*385cc6b4SJerry Jelinek 
1045*385cc6b4SJerry Jelinek 
1046*385cc6b4SJerry Jelinek     Status = AcpiEvInstallGpeHandler (GpeDevice, GpeNumber, Type,
1047*385cc6b4SJerry Jelinek         TRUE, Address, Context);
1048*385cc6b4SJerry Jelinek 
1049*385cc6b4SJerry Jelinek     return_ACPI_STATUS (Status);
1050*385cc6b4SJerry Jelinek }
1051*385cc6b4SJerry Jelinek 
1052*385cc6b4SJerry Jelinek ACPI_EXPORT_SYMBOL (AcpiInstallGpeRawHandler)
1053*385cc6b4SJerry Jelinek 
1054*385cc6b4SJerry Jelinek 
1055*385cc6b4SJerry Jelinek /*******************************************************************************
1056*385cc6b4SJerry Jelinek  *
1057ae115bc7Smrj  * FUNCTION:    AcpiRemoveGpeHandler
1058ae115bc7Smrj  *
1059ae115bc7Smrj  * PARAMETERS:  GpeDevice       - Namespace node for the GPE (NULL for FADT
1060ae115bc7Smrj  *                                defined GPEs)
1061ae115bc7Smrj  *              GpeNumber       - The event to remove a handler
1062ae115bc7Smrj  *              Address         - Address of the handler
1063ae115bc7Smrj  *
1064ae115bc7Smrj  * RETURN:      Status
1065ae115bc7Smrj  *
1066ae115bc7Smrj  * DESCRIPTION: Remove a handler for a General Purpose AcpiEvent.
1067ae115bc7Smrj  *
1068ae115bc7Smrj  ******************************************************************************/
1069ae115bc7Smrj 
1070ae115bc7Smrj ACPI_STATUS
1071ae115bc7Smrj AcpiRemoveGpeHandler (
1072ae115bc7Smrj     ACPI_HANDLE             GpeDevice,
1073ae115bc7Smrj     UINT32                  GpeNumber,
107426f3cdf0SGordon Ross     ACPI_GPE_HANDLER        Address)
1075ae115bc7Smrj {
1076ae115bc7Smrj     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
107726f3cdf0SGordon Ross     ACPI_GPE_HANDLER_INFO   *Handler;
1078ae115bc7Smrj     ACPI_STATUS             Status;
1079ae115bc7Smrj     ACPI_CPU_FLAGS          Flags;
1080ae115bc7Smrj 
1081ae115bc7Smrj 
1082ae115bc7Smrj     ACPI_FUNCTION_TRACE (AcpiRemoveGpeHandler);
1083ae115bc7Smrj 
1084ae115bc7Smrj 
1085ae115bc7Smrj     /* Parameter validation */
1086ae115bc7Smrj 
1087ae115bc7Smrj     if (!Address)
1088ae115bc7Smrj     {
1089ae115bc7Smrj         return_ACPI_STATUS (AE_BAD_PARAMETER);
1090ae115bc7Smrj     }
1091ae115bc7Smrj 
1092ae115bc7Smrj     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
1093ae115bc7Smrj     if (ACPI_FAILURE (Status))
1094ae115bc7Smrj     {
1095ae115bc7Smrj         return_ACPI_STATUS (Status);
1096ae115bc7Smrj     }
1097ae115bc7Smrj 
109826f3cdf0SGordon Ross     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
109926f3cdf0SGordon Ross 
1100ae115bc7Smrj     /* Ensure that we have a valid GPE number */
1101ae115bc7Smrj 
1102ae115bc7Smrj     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
1103ae115bc7Smrj     if (!GpeEventInfo)
1104ae115bc7Smrj     {
1105ae115bc7Smrj         Status = AE_BAD_PARAMETER;
1106ae115bc7Smrj         goto UnlockAndExit;
1107ae115bc7Smrj     }
1108ae115bc7Smrj 
1109ae115bc7Smrj     /* Make sure that a handler is indeed installed */
1110ae115bc7Smrj 
1111*385cc6b4SJerry Jelinek     if ((ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) !=
1112*385cc6b4SJerry Jelinek             ACPI_GPE_DISPATCH_HANDLER) &&
1113*385cc6b4SJerry Jelinek         (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) !=
1114*385cc6b4SJerry Jelinek             ACPI_GPE_DISPATCH_RAW_HANDLER))
1115ae115bc7Smrj     {
1116ae115bc7Smrj         Status = AE_NOT_EXIST;
1117ae115bc7Smrj         goto UnlockAndExit;
1118ae115bc7Smrj     }
1119ae115bc7Smrj 
1120ae115bc7Smrj     /* Make sure that the installed handler is the same */
1121ae115bc7Smrj 
1122ae115bc7Smrj     if (GpeEventInfo->Dispatch.Handler->Address != Address)
1123ae115bc7Smrj     {
1124ae115bc7Smrj         Status = AE_BAD_PARAMETER;
1125ae115bc7Smrj         goto UnlockAndExit;
1126ae115bc7Smrj     }
1127ae115bc7Smrj 
1128ae115bc7Smrj     /* Remove the handler */
1129ae115bc7Smrj 
1130ae115bc7Smrj     Handler = GpeEventInfo->Dispatch.Handler;
1131*385cc6b4SJerry Jelinek     GpeEventInfo->Dispatch.Handler = NULL;
1132ae115bc7Smrj 
1133ae115bc7Smrj     /* Restore Method node (if any), set dispatch flags */
1134ae115bc7Smrj 
1135ae115bc7Smrj     GpeEventInfo->Dispatch.MethodNode = Handler->MethodNode;
113626f3cdf0SGordon Ross     GpeEventInfo->Flags &=
113726f3cdf0SGordon Ross         ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
113826f3cdf0SGordon Ross     GpeEventInfo->Flags |= Handler->OriginalFlags;
113926f3cdf0SGordon Ross 
114026f3cdf0SGordon Ross     /*
114126f3cdf0SGordon Ross      * If the GPE was previously associated with a method and it was
114226f3cdf0SGordon Ross      * enabled, it should be enabled at this point to restore the
114326f3cdf0SGordon Ross      * post-initialization configuration.
114426f3cdf0SGordon Ross      */
1145*385cc6b4SJerry Jelinek     if (((ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) ==
1146*385cc6b4SJerry Jelinek             ACPI_GPE_DISPATCH_METHOD) ||
1147*385cc6b4SJerry Jelinek          (ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) ==
1148*385cc6b4SJerry Jelinek             ACPI_GPE_DISPATCH_NOTIFY)) &&
114926f3cdf0SGordon Ross         Handler->OriginallyEnabled)
1150ae115bc7Smrj     {
115126f3cdf0SGordon Ross         (void) AcpiEvAddGpeReference (GpeEventInfo);
1152ae115bc7Smrj     }
1153ae115bc7Smrj 
1154*385cc6b4SJerry Jelinek     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
1155*385cc6b4SJerry Jelinek     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
1156*385cc6b4SJerry Jelinek 
1157*385cc6b4SJerry Jelinek     /* Make sure all deferred GPE tasks are completed */
1158*385cc6b4SJerry Jelinek 
1159*385cc6b4SJerry Jelinek     AcpiOsWaitEventsComplete ();
1160*385cc6b4SJerry Jelinek 
1161ae115bc7Smrj     /* Now we can free the handler object */
1162ae115bc7Smrj 
1163ae115bc7Smrj     ACPI_FREE (Handler);
1164*385cc6b4SJerry Jelinek     return_ACPI_STATUS (Status);
1165ae115bc7Smrj 
1166ae115bc7Smrj UnlockAndExit:
116726f3cdf0SGordon Ross     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
1168ae115bc7Smrj     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
1169ae115bc7Smrj     return_ACPI_STATUS (Status);
1170ae115bc7Smrj }
1171ae115bc7Smrj 
1172ae115bc7Smrj ACPI_EXPORT_SYMBOL (AcpiRemoveGpeHandler)
1173ae115bc7Smrj 
1174ae115bc7Smrj 
1175ae115bc7Smrj /*******************************************************************************
1176ae115bc7Smrj  *
1177ae115bc7Smrj  * FUNCTION:    AcpiAcquireGlobalLock
1178ae115bc7Smrj  *
1179ae115bc7Smrj  * PARAMETERS:  Timeout         - How long the caller is willing to wait
1180ae115bc7Smrj  *              Handle          - Where the handle to the lock is returned
1181ae115bc7Smrj  *                                (if acquired)
1182ae115bc7Smrj  *
1183ae115bc7Smrj  * RETURN:      Status
1184ae115bc7Smrj  *
1185ae115bc7Smrj  * DESCRIPTION: Acquire the ACPI Global Lock
1186ae115bc7Smrj  *
1187db2bae30SDana Myers  * Note: Allows callers with the same thread ID to acquire the global lock
1188db2bae30SDana Myers  * multiple times. In other words, externally, the behavior of the global lock
1189db2bae30SDana Myers  * is identical to an AML mutex. On the first acquire, a new handle is
1190db2bae30SDana Myers  * returned. On any subsequent calls to acquire by the same thread, the same
1191db2bae30SDana Myers  * handle is returned.
1192db2bae30SDana Myers  *
1193ae115bc7Smrj  ******************************************************************************/
1194ae115bc7Smrj 
1195ae115bc7Smrj ACPI_STATUS
1196ae115bc7Smrj AcpiAcquireGlobalLock (
1197ae115bc7Smrj     UINT16                  Timeout,
1198ae115bc7Smrj     UINT32                  *Handle)
1199ae115bc7Smrj {
1200ae115bc7Smrj     ACPI_STATUS             Status;
1201ae115bc7Smrj 
1202ae115bc7Smrj 
1203ae115bc7Smrj     if (!Handle)
1204ae115bc7Smrj     {
1205ae115bc7Smrj         return (AE_BAD_PARAMETER);
1206ae115bc7Smrj     }
1207ae115bc7Smrj 
1208db2bae30SDana Myers     /* Must lock interpreter to prevent race conditions */
1209ae115bc7Smrj 
1210db2bae30SDana Myers     AcpiExEnterInterpreter ();
1211db2bae30SDana Myers 
1212db2bae30SDana Myers     Status = AcpiExAcquireMutexObject (Timeout,
1213db2bae30SDana Myers         AcpiGbl_GlobalLockMutex, AcpiOsGetThreadId ());
1214ae115bc7Smrj 
1215ae115bc7Smrj     if (ACPI_SUCCESS (Status))
1216ae115bc7Smrj     {
1217db2bae30SDana Myers         /* Return the global lock handle (updated in AcpiEvAcquireGlobalLock) */
1218db2bae30SDana Myers 
1219ae115bc7Smrj         *Handle = AcpiGbl_GlobalLockHandle;
1220ae115bc7Smrj     }
1221ae115bc7Smrj 
1222db2bae30SDana Myers     AcpiExExitInterpreter ();
1223ae115bc7Smrj     return (Status);
1224ae115bc7Smrj }
1225ae115bc7Smrj 
1226ae115bc7Smrj ACPI_EXPORT_SYMBOL (AcpiAcquireGlobalLock)
1227ae115bc7Smrj 
1228ae115bc7Smrj 
1229ae115bc7Smrj /*******************************************************************************
1230ae115bc7Smrj  *
1231ae115bc7Smrj  * FUNCTION:    AcpiReleaseGlobalLock
1232ae115bc7Smrj  *
1233ae115bc7Smrj  * PARAMETERS:  Handle      - Returned from AcpiAcquireGlobalLock
1234ae115bc7Smrj  *
1235ae115bc7Smrj  * RETURN:      Status
1236ae115bc7Smrj  *
1237ae115bc7Smrj  * DESCRIPTION: Release the ACPI Global Lock. The handle must be valid.
1238ae115bc7Smrj  *
1239ae115bc7Smrj  ******************************************************************************/
1240ae115bc7Smrj 
1241ae115bc7Smrj ACPI_STATUS
1242ae115bc7Smrj AcpiReleaseGlobalLock (
1243ae115bc7Smrj     UINT32                  Handle)
1244ae115bc7Smrj {
1245ae115bc7Smrj     ACPI_STATUS             Status;
1246ae115bc7Smrj 
1247ae115bc7Smrj 
1248db2bae30SDana Myers     if (!Handle || (Handle != AcpiGbl_GlobalLockHandle))
1249ae115bc7Smrj     {
1250ae115bc7Smrj         return (AE_NOT_ACQUIRED);
1251ae115bc7Smrj     }
1252ae115bc7Smrj 
1253db2bae30SDana Myers     Status = AcpiExReleaseMutexObject (AcpiGbl_GlobalLockMutex);
1254ae115bc7Smrj     return (Status);
1255ae115bc7Smrj }
1256ae115bc7Smrj 
1257ae115bc7Smrj ACPI_EXPORT_SYMBOL (AcpiReleaseGlobalLock)
1258ae115bc7Smrj 
1259*385cc6b4SJerry Jelinek #endif /* !ACPI_REDUCED_HARDWARE */
1260