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
AcpiInstallNotifyHandler(ACPI_HANDLE Device,UINT32 HandlerType,ACPI_NOTIFY_HANDLER Handler,void * Context)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
ACPI_EXPORT_SYMBOL(AcpiInstallNotifyHandler)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
ACPI_EXPORT_SYMBOL(AcpiRemoveNotifyHandler)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
ACPI_EXPORT_SYMBOL(AcpiInstallExceptionHandler)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
ACPI_EXPORT_SYMBOL(AcpiInstallSciHandler)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
ACPI_EXPORT_SYMBOL(AcpiRemoveSciHandler)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
ACPI_EXPORT_SYMBOL(AcpiInstallGlobalEventHandler)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
ACPI_EXPORT_SYMBOL(AcpiInstallFixedEventHandler)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
ACPI_EXPORT_SYMBOL(AcpiRemoveFixedEventHandler)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
AcpiInstallGpeHandler(ACPI_HANDLE GpeDevice,UINT32 GpeNumber,UINT32 Type,ACPI_GPE_HANDLER Address,void * Context)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
ACPI_EXPORT_SYMBOL(AcpiInstallGpeHandler)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
ACPI_EXPORT_SYMBOL(AcpiInstallGpeRawHandler)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
ACPI_EXPORT_SYMBOL(AcpiRemoveGpeHandler)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
ACPI_EXPORT_SYMBOL(AcpiAcquireGlobalLock)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