xref: /minix3/minix/drivers/power/acpi/events/evmisc.c (revision 29492bb71c7148a089a5afafa0c99409161218df)
1433d6423SLionel Sambuc /******************************************************************************
2433d6423SLionel Sambuc  *
3433d6423SLionel Sambuc  * Module Name: evmisc - Miscellaneous event manager support functions
4433d6423SLionel Sambuc  *
5433d6423SLionel Sambuc  *****************************************************************************/
6433d6423SLionel Sambuc 
7*29492bb7SDavid van Moolenbroek /*
8*29492bb7SDavid van Moolenbroek  * Copyright (C) 2000 - 2014, Intel Corp.
9433d6423SLionel Sambuc  * All rights reserved.
10433d6423SLionel Sambuc  *
11*29492bb7SDavid van Moolenbroek  * Redistribution and use in source and binary forms, with or without
12*29492bb7SDavid van Moolenbroek  * modification, are permitted provided that the following conditions
13*29492bb7SDavid van Moolenbroek  * are met:
14*29492bb7SDavid van Moolenbroek  * 1. Redistributions of source code must retain the above copyright
15*29492bb7SDavid van Moolenbroek  *    notice, this list of conditions, and the following disclaimer,
16*29492bb7SDavid van Moolenbroek  *    without modification.
17*29492bb7SDavid van Moolenbroek  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18*29492bb7SDavid van Moolenbroek  *    substantially similar to the "NO WARRANTY" disclaimer below
19*29492bb7SDavid van Moolenbroek  *    ("Disclaimer") and any redistribution must be conditioned upon
20*29492bb7SDavid van Moolenbroek  *    including a substantially similar Disclaimer requirement for further
21*29492bb7SDavid van Moolenbroek  *    binary redistribution.
22*29492bb7SDavid van Moolenbroek  * 3. Neither the names of the above-listed copyright holders nor the names
23*29492bb7SDavid van Moolenbroek  *    of any contributors may be used to endorse or promote products derived
24*29492bb7SDavid van Moolenbroek  *    from this software without specific prior written permission.
25433d6423SLionel Sambuc  *
26*29492bb7SDavid van Moolenbroek  * Alternatively, this software may be distributed under the terms of the
27*29492bb7SDavid van Moolenbroek  * GNU General Public License ("GPL") version 2 as published by the Free
28*29492bb7SDavid van Moolenbroek  * Software Foundation.
29433d6423SLionel Sambuc  *
30*29492bb7SDavid van Moolenbroek  * NO WARRANTY
31*29492bb7SDavid van Moolenbroek  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32*29492bb7SDavid van Moolenbroek  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33*29492bb7SDavid van Moolenbroek  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34*29492bb7SDavid van Moolenbroek  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35*29492bb7SDavid van Moolenbroek  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36*29492bb7SDavid van Moolenbroek  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37*29492bb7SDavid van Moolenbroek  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38*29492bb7SDavid van Moolenbroek  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39*29492bb7SDavid van Moolenbroek  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40*29492bb7SDavid van Moolenbroek  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41*29492bb7SDavid van Moolenbroek  * POSSIBILITY OF SUCH DAMAGES.
42*29492bb7SDavid van Moolenbroek  */
43433d6423SLionel Sambuc 
44433d6423SLionel Sambuc #include "acpi.h"
45433d6423SLionel Sambuc #include "accommon.h"
46433d6423SLionel Sambuc #include "acevents.h"
47433d6423SLionel Sambuc #include "acnamesp.h"
48433d6423SLionel Sambuc 
49433d6423SLionel Sambuc #define _COMPONENT          ACPI_EVENTS
50433d6423SLionel Sambuc         ACPI_MODULE_NAME    ("evmisc")
51433d6423SLionel Sambuc 
52433d6423SLionel Sambuc 
53433d6423SLionel Sambuc /* Local prototypes */
54433d6423SLionel Sambuc 
55433d6423SLionel Sambuc static void ACPI_SYSTEM_XFACE
56433d6423SLionel Sambuc AcpiEvNotifyDispatch (
57433d6423SLionel Sambuc     void                    *Context);
58433d6423SLionel Sambuc 
59433d6423SLionel Sambuc 
60433d6423SLionel Sambuc /*******************************************************************************
61433d6423SLionel Sambuc  *
62433d6423SLionel Sambuc  * FUNCTION:    AcpiEvIsNotifyObject
63433d6423SLionel Sambuc  *
64433d6423SLionel Sambuc  * PARAMETERS:  Node            - Node to check
65433d6423SLionel Sambuc  *
66433d6423SLionel Sambuc  * RETURN:      TRUE if notifies allowed on this object
67433d6423SLionel Sambuc  *
68433d6423SLionel Sambuc  * DESCRIPTION: Check type of node for a object that supports notifies.
69433d6423SLionel Sambuc  *
70433d6423SLionel Sambuc  *              TBD: This could be replaced by a flag bit in the node.
71433d6423SLionel Sambuc  *
72433d6423SLionel Sambuc  ******************************************************************************/
73433d6423SLionel Sambuc 
74433d6423SLionel Sambuc BOOLEAN
AcpiEvIsNotifyObject(ACPI_NAMESPACE_NODE * Node)75433d6423SLionel Sambuc AcpiEvIsNotifyObject (
76433d6423SLionel Sambuc     ACPI_NAMESPACE_NODE     *Node)
77433d6423SLionel Sambuc {
78433d6423SLionel Sambuc     switch (Node->Type)
79433d6423SLionel Sambuc     {
80433d6423SLionel Sambuc     case ACPI_TYPE_DEVICE:
81433d6423SLionel Sambuc     case ACPI_TYPE_PROCESSOR:
82433d6423SLionel Sambuc     case ACPI_TYPE_THERMAL:
83433d6423SLionel Sambuc         /*
84433d6423SLionel Sambuc          * These are the ONLY objects that can receive ACPI notifications
85433d6423SLionel Sambuc          */
86433d6423SLionel Sambuc         return (TRUE);
87433d6423SLionel Sambuc 
88433d6423SLionel Sambuc     default:
89*29492bb7SDavid van Moolenbroek 
90433d6423SLionel Sambuc         return (FALSE);
91433d6423SLionel Sambuc     }
92433d6423SLionel Sambuc }
93433d6423SLionel Sambuc 
94433d6423SLionel Sambuc 
95433d6423SLionel Sambuc /*******************************************************************************
96433d6423SLionel Sambuc  *
97433d6423SLionel Sambuc  * FUNCTION:    AcpiEvQueueNotifyRequest
98433d6423SLionel Sambuc  *
99433d6423SLionel Sambuc  * PARAMETERS:  Node            - NS node for the notified object
100433d6423SLionel Sambuc  *              NotifyValue     - Value from the Notify() request
101433d6423SLionel Sambuc  *
102433d6423SLionel Sambuc  * RETURN:      Status
103433d6423SLionel Sambuc  *
104433d6423SLionel Sambuc  * DESCRIPTION: Dispatch a device notification event to a previously
105433d6423SLionel Sambuc  *              installed handler.
106433d6423SLionel Sambuc  *
107433d6423SLionel Sambuc  ******************************************************************************/
108433d6423SLionel Sambuc 
109433d6423SLionel Sambuc ACPI_STATUS
AcpiEvQueueNotifyRequest(ACPI_NAMESPACE_NODE * Node,UINT32 NotifyValue)110433d6423SLionel Sambuc AcpiEvQueueNotifyRequest (
111433d6423SLionel Sambuc     ACPI_NAMESPACE_NODE     *Node,
112433d6423SLionel Sambuc     UINT32                  NotifyValue)
113433d6423SLionel Sambuc {
114433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *ObjDesc;
115*29492bb7SDavid van Moolenbroek     ACPI_OPERAND_OBJECT     *HandlerListHead = NULL;
116*29492bb7SDavid van Moolenbroek     ACPI_GENERIC_STATE      *Info;
117*29492bb7SDavid van Moolenbroek     UINT8                   HandlerListId = 0;
118433d6423SLionel Sambuc     ACPI_STATUS             Status = AE_OK;
119433d6423SLionel Sambuc 
120433d6423SLionel Sambuc 
121433d6423SLionel Sambuc     ACPI_FUNCTION_NAME (EvQueueNotifyRequest);
122433d6423SLionel Sambuc 
123433d6423SLionel Sambuc 
124*29492bb7SDavid van Moolenbroek     /* Are Notifies allowed on this object? */
125433d6423SLionel Sambuc 
126*29492bb7SDavid van Moolenbroek     if (!AcpiEvIsNotifyObject (Node))
127*29492bb7SDavid van Moolenbroek     {
128*29492bb7SDavid van Moolenbroek         return (AE_TYPE);
129*29492bb7SDavid van Moolenbroek     }
130*29492bb7SDavid van Moolenbroek 
131*29492bb7SDavid van Moolenbroek     /* Get the correct notify list type (System or Device) */
132*29492bb7SDavid van Moolenbroek 
133*29492bb7SDavid van Moolenbroek     if (NotifyValue <= ACPI_MAX_SYS_NOTIFY)
134*29492bb7SDavid van Moolenbroek     {
135*29492bb7SDavid van Moolenbroek         HandlerListId = ACPI_SYSTEM_HANDLER_LIST;
136*29492bb7SDavid van Moolenbroek     }
137*29492bb7SDavid van Moolenbroek     else
138*29492bb7SDavid van Moolenbroek     {
139*29492bb7SDavid van Moolenbroek         HandlerListId = ACPI_DEVICE_HANDLER_LIST;
140*29492bb7SDavid van Moolenbroek     }
141*29492bb7SDavid van Moolenbroek 
142*29492bb7SDavid van Moolenbroek     /* Get the notify object attached to the namespace Node */
143433d6423SLionel Sambuc 
144433d6423SLionel Sambuc     ObjDesc = AcpiNsGetAttachedObject (Node);
145433d6423SLionel Sambuc     if (ObjDesc)
146433d6423SLionel Sambuc     {
147*29492bb7SDavid van Moolenbroek         /* We have an attached object, Get the correct handler list */
148433d6423SLionel Sambuc 
149*29492bb7SDavid van Moolenbroek         HandlerListHead = ObjDesc->CommonNotify.NotifyList[HandlerListId];
150433d6423SLionel Sambuc     }
151433d6423SLionel Sambuc 
152433d6423SLionel Sambuc     /*
153*29492bb7SDavid van Moolenbroek      * If there is no notify handler (Global or Local)
154*29492bb7SDavid van Moolenbroek      * for this object, just ignore the notify
155433d6423SLionel Sambuc      */
156*29492bb7SDavid van Moolenbroek     if (!AcpiGbl_GlobalNotify[HandlerListId].Handler && !HandlerListHead)
157433d6423SLionel Sambuc     {
158*29492bb7SDavid van Moolenbroek         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
159*29492bb7SDavid van Moolenbroek             "No notify handler for Notify, ignoring (%4.4s, %X) node %p\n",
160*29492bb7SDavid van Moolenbroek             AcpiUtGetNodeName (Node), NotifyValue, Node));
161*29492bb7SDavid van Moolenbroek 
162*29492bb7SDavid van Moolenbroek         return (AE_OK);
163*29492bb7SDavid van Moolenbroek     }
164*29492bb7SDavid van Moolenbroek 
165*29492bb7SDavid van Moolenbroek     /* Setup notify info and schedule the notify dispatcher */
166*29492bb7SDavid van Moolenbroek 
167*29492bb7SDavid van Moolenbroek     Info = AcpiUtCreateGenericState ();
168*29492bb7SDavid van Moolenbroek     if (!Info)
169433d6423SLionel Sambuc     {
170433d6423SLionel Sambuc         return (AE_NO_MEMORY);
171433d6423SLionel Sambuc     }
172433d6423SLionel Sambuc 
173*29492bb7SDavid van Moolenbroek     Info->Common.DescriptorType = ACPI_DESC_TYPE_STATE_NOTIFY;
174*29492bb7SDavid van Moolenbroek 
175*29492bb7SDavid van Moolenbroek     Info->Notify.Node = Node;
176*29492bb7SDavid van Moolenbroek     Info->Notify.Value = (UINT16) NotifyValue;
177*29492bb7SDavid van Moolenbroek     Info->Notify.HandlerListId = HandlerListId;
178*29492bb7SDavid van Moolenbroek     Info->Notify.HandlerListHead = HandlerListHead;
179*29492bb7SDavid van Moolenbroek     Info->Notify.Global = &AcpiGbl_GlobalNotify[HandlerListId];
180*29492bb7SDavid van Moolenbroek 
181433d6423SLionel Sambuc     ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
182*29492bb7SDavid van Moolenbroek         "Dispatching Notify on [%4.4s] (%s) Value 0x%2.2X (%s) Node %p\n",
183*29492bb7SDavid van Moolenbroek         AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type),
184*29492bb7SDavid van Moolenbroek         NotifyValue, AcpiUtGetNotifyName (NotifyValue, ACPI_TYPE_ANY), Node));
185433d6423SLionel Sambuc 
186*29492bb7SDavid van Moolenbroek     Status = AcpiOsExecute (OSL_NOTIFY_HANDLER, AcpiEvNotifyDispatch,
187*29492bb7SDavid van Moolenbroek         Info);
188433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
189433d6423SLionel Sambuc     {
190*29492bb7SDavid van Moolenbroek         AcpiUtDeleteGenericState (Info);
191433d6423SLionel Sambuc     }
192433d6423SLionel Sambuc 
193433d6423SLionel Sambuc     return (Status);
194433d6423SLionel Sambuc }
195433d6423SLionel Sambuc 
196433d6423SLionel Sambuc 
197433d6423SLionel Sambuc /*******************************************************************************
198433d6423SLionel Sambuc  *
199433d6423SLionel Sambuc  * FUNCTION:    AcpiEvNotifyDispatch
200433d6423SLionel Sambuc  *
201433d6423SLionel Sambuc  * PARAMETERS:  Context         - To be passed to the notify handler
202433d6423SLionel Sambuc  *
203433d6423SLionel Sambuc  * RETURN:      None.
204433d6423SLionel Sambuc  *
205433d6423SLionel Sambuc  * DESCRIPTION: Dispatch a device notification event to a previously
206433d6423SLionel Sambuc  *              installed handler.
207433d6423SLionel Sambuc  *
208433d6423SLionel Sambuc  ******************************************************************************/
209433d6423SLionel Sambuc 
210433d6423SLionel Sambuc static void ACPI_SYSTEM_XFACE
AcpiEvNotifyDispatch(void * Context)211433d6423SLionel Sambuc AcpiEvNotifyDispatch (
212433d6423SLionel Sambuc     void                    *Context)
213433d6423SLionel Sambuc {
214*29492bb7SDavid van Moolenbroek     ACPI_GENERIC_STATE      *Info = (ACPI_GENERIC_STATE *) Context;
215433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *HandlerObj;
216433d6423SLionel Sambuc 
217433d6423SLionel Sambuc 
218433d6423SLionel Sambuc     ACPI_FUNCTION_ENTRY ();
219433d6423SLionel Sambuc 
220433d6423SLionel Sambuc 
221*29492bb7SDavid van Moolenbroek     /* Invoke a global notify handler if installed */
222433d6423SLionel Sambuc 
223*29492bb7SDavid van Moolenbroek     if (Info->Notify.Global->Handler)
224433d6423SLionel Sambuc     {
225*29492bb7SDavid van Moolenbroek         Info->Notify.Global->Handler (Info->Notify.Node,
226*29492bb7SDavid van Moolenbroek             Info->Notify.Value,
227*29492bb7SDavid van Moolenbroek             Info->Notify.Global->Context);
228433d6423SLionel Sambuc     }
229433d6423SLionel Sambuc 
230*29492bb7SDavid van Moolenbroek     /* Now invoke the local notify handler(s) if any are installed */
231433d6423SLionel Sambuc 
232*29492bb7SDavid van Moolenbroek     HandlerObj = Info->Notify.HandlerListHead;
233*29492bb7SDavid van Moolenbroek     while (HandlerObj)
234433d6423SLionel Sambuc     {
235*29492bb7SDavid van Moolenbroek         HandlerObj->Notify.Handler (Info->Notify.Node,
236*29492bb7SDavid van Moolenbroek             Info->Notify.Value,
237433d6423SLionel Sambuc             HandlerObj->Notify.Context);
238*29492bb7SDavid van Moolenbroek 
239*29492bb7SDavid van Moolenbroek         HandlerObj = HandlerObj->Notify.Next[Info->Notify.HandlerListId];
240433d6423SLionel Sambuc     }
241433d6423SLionel Sambuc 
242433d6423SLionel Sambuc     /* All done with the info object */
243433d6423SLionel Sambuc 
244*29492bb7SDavid van Moolenbroek     AcpiUtDeleteGenericState (Info);
245433d6423SLionel Sambuc }
246433d6423SLionel Sambuc 
247433d6423SLionel Sambuc 
248*29492bb7SDavid van Moolenbroek #if (!ACPI_REDUCED_HARDWARE)
249433d6423SLionel Sambuc /******************************************************************************
250433d6423SLionel Sambuc  *
251433d6423SLionel Sambuc  * FUNCTION:    AcpiEvTerminate
252433d6423SLionel Sambuc  *
253433d6423SLionel Sambuc  * PARAMETERS:  none
254433d6423SLionel Sambuc  *
255433d6423SLionel Sambuc  * RETURN:      none
256433d6423SLionel Sambuc  *
257433d6423SLionel Sambuc  * DESCRIPTION: Disable events and free memory allocated for table storage.
258433d6423SLionel Sambuc  *
259433d6423SLionel Sambuc  ******************************************************************************/
260433d6423SLionel Sambuc 
261433d6423SLionel Sambuc void
AcpiEvTerminate(void)262433d6423SLionel Sambuc AcpiEvTerminate (
263433d6423SLionel Sambuc     void)
264433d6423SLionel Sambuc {
265433d6423SLionel Sambuc     UINT32                  i;
266433d6423SLionel Sambuc     ACPI_STATUS             Status;
267433d6423SLionel Sambuc 
268433d6423SLionel Sambuc 
269433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE (EvTerminate);
270433d6423SLionel Sambuc 
271433d6423SLionel Sambuc 
272433d6423SLionel Sambuc     if (AcpiGbl_EventsInitialized)
273433d6423SLionel Sambuc     {
274433d6423SLionel Sambuc         /*
275433d6423SLionel Sambuc          * Disable all event-related functionality. In all cases, on error,
276433d6423SLionel Sambuc          * print a message but obviously we don't abort.
277433d6423SLionel Sambuc          */
278433d6423SLionel Sambuc 
279433d6423SLionel Sambuc         /* Disable all fixed events */
280433d6423SLionel Sambuc 
281433d6423SLionel Sambuc         for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++)
282433d6423SLionel Sambuc         {
283433d6423SLionel Sambuc             Status = AcpiDisableEvent (i, 0);
284433d6423SLionel Sambuc             if (ACPI_FAILURE (Status))
285433d6423SLionel Sambuc             {
286433d6423SLionel Sambuc                 ACPI_ERROR ((AE_INFO,
287433d6423SLionel Sambuc                     "Could not disable fixed event %u", (UINT32) i));
288433d6423SLionel Sambuc             }
289433d6423SLionel Sambuc         }
290433d6423SLionel Sambuc 
291433d6423SLionel Sambuc         /* Disable all GPEs in all GPE blocks */
292433d6423SLionel Sambuc 
293433d6423SLionel Sambuc         Status = AcpiEvWalkGpeList (AcpiHwDisableGpeBlock, NULL);
294433d6423SLionel Sambuc 
295433d6423SLionel Sambuc         Status = AcpiEvRemoveGlobalLockHandler ();
296433d6423SLionel Sambuc         if (ACPI_FAILURE(Status))
297433d6423SLionel Sambuc         {
298433d6423SLionel Sambuc             ACPI_ERROR ((AE_INFO,
299433d6423SLionel Sambuc                 "Could not remove Global Lock handler"));
300433d6423SLionel Sambuc         }
301*29492bb7SDavid van Moolenbroek 
302*29492bb7SDavid van Moolenbroek         AcpiGbl_EventsInitialized = FALSE;
303*29492bb7SDavid van Moolenbroek     }
304*29492bb7SDavid van Moolenbroek 
305*29492bb7SDavid van Moolenbroek     /* Remove SCI handlers */
306*29492bb7SDavid van Moolenbroek 
307*29492bb7SDavid van Moolenbroek     Status = AcpiEvRemoveAllSciHandlers ();
308*29492bb7SDavid van Moolenbroek     if (ACPI_FAILURE(Status))
309*29492bb7SDavid van Moolenbroek     {
310*29492bb7SDavid van Moolenbroek         ACPI_ERROR ((AE_INFO,
311*29492bb7SDavid van Moolenbroek             "Could not remove SCI handler"));
312433d6423SLionel Sambuc     }
313433d6423SLionel Sambuc 
314433d6423SLionel Sambuc     /* Deallocate all handler objects installed within GPE info structs */
315433d6423SLionel Sambuc 
316433d6423SLionel Sambuc     Status = AcpiEvWalkGpeList (AcpiEvDeleteGpeHandlers, NULL);
317433d6423SLionel Sambuc 
318433d6423SLionel Sambuc     /* Return to original mode if necessary */
319433d6423SLionel Sambuc 
320433d6423SLionel Sambuc     if (AcpiGbl_OriginalMode == ACPI_SYS_MODE_LEGACY)
321433d6423SLionel Sambuc     {
322433d6423SLionel Sambuc         Status = AcpiDisable ();
323433d6423SLionel Sambuc         if (ACPI_FAILURE (Status))
324433d6423SLionel Sambuc         {
325433d6423SLionel Sambuc             ACPI_WARNING ((AE_INFO, "AcpiDisable failed"));
326433d6423SLionel Sambuc         }
327433d6423SLionel Sambuc     }
328433d6423SLionel Sambuc     return_VOID;
329433d6423SLionel Sambuc }
330433d6423SLionel Sambuc 
331*29492bb7SDavid van Moolenbroek #endif /* !ACPI_REDUCED_HARDWARE */
332