1 /******************************************************************************
3 * Module Name: evxface - External interfaces for ACPI events
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2013, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
47 #include <contrib/dev/acpica/include/acpi.h>
48 #include <contrib/dev/acpica/include/accommon.h>
49 #include <contrib/dev/acpica/include/acnamesp.h>
50 #include <contrib/dev/acpica/include/acevents.h>
51 #include <contrib/dev/acpica/include/acinterp.h>
53 #define _COMPONENT ACPI_EVENTS
54 ACPI_MODULE_NAME ("evxface")
57 /*******************************************************************************
59 * FUNCTION: AcpiInstallNotifyHandler
61 * PARAMETERS: Device - The device for which notifies will be handled
62 * HandlerType - The type of handler:
63 * ACPI_SYSTEM_NOTIFY: System Handler (00-7F)
64 * ACPI_DEVICE_NOTIFY: Device Handler (80-FF)
65 * ACPI_ALL_NOTIFY: Both System and Device
66 * Handler - Address of the handler
67 * Context - Value passed to the handler on each GPE
71 * DESCRIPTION: Install a handler for notifications on an ACPI Device,
72 * ThermalZone, or Processor object.
74 * NOTES: The Root namespace object may have only one handler for each
75 * type of notify (System/Device). Device/Thermal/Processor objects
76 * may have one device notify handler, and multiple system notify
79 ******************************************************************************/
82 AcpiInstallNotifyHandler (
85 ACPI_NOTIFY_HANDLER Handler,
88 ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device);
89 ACPI_OPERAND_OBJECT *ObjDesc;
90 ACPI_OPERAND_OBJECT *HandlerObj;
95 ACPI_FUNCTION_TRACE (AcpiInstallNotifyHandler);
98 /* Parameter validation */
100 if ((!Device) || (!Handler) || (!HandlerType) ||
101 (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
103 return_ACPI_STATUS (AE_BAD_PARAMETER);
106 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
107 if (ACPI_FAILURE (Status))
109 return_ACPI_STATUS (Status);
114 * Registering a notify handler on the root object indicates that the
115 * caller wishes to receive notifications for all objects. Note that
116 * only one global handler can be registered per notify type.
117 * Ensure that a handler is not already installed.
119 if (Device == ACPI_ROOT_OBJECT)
121 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
123 if (HandlerType & (i+1))
125 if (AcpiGbl_GlobalNotify[i].Handler)
127 Status = AE_ALREADY_EXISTS;
131 AcpiGbl_GlobalNotify[i].Handler = Handler;
132 AcpiGbl_GlobalNotify[i].Context = Context;
136 goto UnlockAndExit; /* Global notify handler installed, all done */
141 * Caller will only receive notifications specific to the target
142 * object. Note that only certain object types are allowed to
143 * receive notifications.
146 /* Are Notifies allowed on this object? */
148 if (!AcpiEvIsNotifyObject (Node))
154 /* Check for an existing internal object, might not exist */
156 ObjDesc = AcpiNsGetAttachedObject (Node);
159 /* Create a new object */
161 ObjDesc = AcpiUtCreateInternalObject (Node->Type);
164 Status = AE_NO_MEMORY;
168 /* Attach new object to the Node, remove local reference */
170 Status = AcpiNsAttachObject (Device, ObjDesc, Node->Type);
171 AcpiUtRemoveReference (ObjDesc);
172 if (ACPI_FAILURE (Status))
178 /* Ensure that the handler is not already installed in the lists */
180 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
182 if (HandlerType & (i+1))
184 HandlerObj = ObjDesc->CommonNotify.NotifyList[i];
187 if (HandlerObj->Notify.Handler == Handler)
189 Status = AE_ALREADY_EXISTS;
193 HandlerObj = HandlerObj->Notify.Next[i];
198 /* Create and populate a new notify handler object */
200 HandlerObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_NOTIFY);
203 Status = AE_NO_MEMORY;
207 HandlerObj->Notify.Node = Node;
208 HandlerObj->Notify.HandlerType = HandlerType;
209 HandlerObj->Notify.Handler = Handler;
210 HandlerObj->Notify.Context = Context;
212 /* Install the handler at the list head(s) */
214 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
216 if (HandlerType & (i+1))
218 HandlerObj->Notify.Next[i] =
219 ObjDesc->CommonNotify.NotifyList[i];
221 ObjDesc->CommonNotify.NotifyList[i] = HandlerObj;
225 /* Add an extra reference if handler was installed in both lists */
227 if (HandlerType == ACPI_ALL_NOTIFY)
229 AcpiUtAddReference (HandlerObj);
234 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
235 return_ACPI_STATUS (Status);
238 ACPI_EXPORT_SYMBOL (AcpiInstallNotifyHandler)
241 /*******************************************************************************
243 * FUNCTION: AcpiRemoveNotifyHandler
245 * PARAMETERS: Device - The device for which the handler is installed
246 * HandlerType - The type of handler:
247 * ACPI_SYSTEM_NOTIFY: System Handler (00-7F)
248 * ACPI_DEVICE_NOTIFY: Device Handler (80-FF)
249 * ACPI_ALL_NOTIFY: Both System and Device
250 * Handler - Address of the handler
254 * DESCRIPTION: Remove a handler for notifies on an ACPI device
256 ******************************************************************************/
259 AcpiRemoveNotifyHandler (
262 ACPI_NOTIFY_HANDLER Handler)
264 ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device);
265 ACPI_OPERAND_OBJECT *ObjDesc;
266 ACPI_OPERAND_OBJECT *HandlerObj;
267 ACPI_OPERAND_OBJECT *PreviousHandlerObj;
272 ACPI_FUNCTION_TRACE (AcpiRemoveNotifyHandler);
275 /* Parameter validation */
277 if ((!Device) || (!Handler) || (!HandlerType) ||
278 (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
280 return_ACPI_STATUS (AE_BAD_PARAMETER);
283 /* Make sure all deferred notify tasks are completed */
285 AcpiOsWaitEventsComplete ();
287 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
288 if (ACPI_FAILURE (Status))
290 return_ACPI_STATUS (Status);
293 /* Root Object. Global handlers are removed here */
295 if (Device == ACPI_ROOT_OBJECT)
297 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
299 if (HandlerType & (i+1))
301 if (!AcpiGbl_GlobalNotify[i].Handler ||
302 (AcpiGbl_GlobalNotify[i].Handler != Handler))
304 Status = AE_NOT_EXIST;
308 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
309 "Removing global notify handler\n"));
311 AcpiGbl_GlobalNotify[i].Handler = NULL;
312 AcpiGbl_GlobalNotify[i].Context = NULL;
319 /* All other objects: Are Notifies allowed on this object? */
321 if (!AcpiEvIsNotifyObject (Node))
327 /* Must have an existing internal object */
329 ObjDesc = AcpiNsGetAttachedObject (Node);
332 Status = AE_NOT_EXIST;
336 /* Internal object exists. Find the handler and remove it */
338 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
340 if (HandlerType & (i+1))
342 HandlerObj = ObjDesc->CommonNotify.NotifyList[i];
343 PreviousHandlerObj = NULL;
345 /* Attempt to find the handler in the handler list */
348 (HandlerObj->Notify.Handler != Handler))
350 PreviousHandlerObj = HandlerObj;
351 HandlerObj = HandlerObj->Notify.Next[i];
356 Status = AE_NOT_EXIST;
360 /* Remove the handler object from the list */
362 if (PreviousHandlerObj) /* Handler is not at the list head */
364 PreviousHandlerObj->Notify.Next[i] =
365 HandlerObj->Notify.Next[i];
367 else /* Handler is at the list head */
369 ObjDesc->CommonNotify.NotifyList[i] =
370 HandlerObj->Notify.Next[i];
373 AcpiUtRemoveReference (HandlerObj);
379 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
380 return_ACPI_STATUS (Status);
383 ACPI_EXPORT_SYMBOL (AcpiRemoveNotifyHandler)
386 /*******************************************************************************
388 * FUNCTION: AcpiInstallExceptionHandler
390 * PARAMETERS: Handler - Pointer to the handler function for the
395 * DESCRIPTION: Saves the pointer to the handler function
397 ******************************************************************************/
400 AcpiInstallExceptionHandler (
401 ACPI_EXCEPTION_HANDLER Handler)
406 ACPI_FUNCTION_TRACE (AcpiInstallExceptionHandler);
409 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
410 if (ACPI_FAILURE (Status))
412 return_ACPI_STATUS (Status);
415 /* Don't allow two handlers. */
417 if (AcpiGbl_ExceptionHandler)
419 Status = AE_ALREADY_EXISTS;
423 /* Install the handler */
425 AcpiGbl_ExceptionHandler = Handler;
428 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
429 return_ACPI_STATUS (Status);
432 ACPI_EXPORT_SYMBOL (AcpiInstallExceptionHandler)
435 #if (!ACPI_REDUCED_HARDWARE)
436 /*******************************************************************************
438 * FUNCTION: AcpiInstallSciHandler
440 * PARAMETERS: Address - Address of the handler
441 * Context - Value passed to the handler on each SCI
445 * DESCRIPTION: Install a handler for a System Control Interrupt.
447 ******************************************************************************/
450 AcpiInstallSciHandler (
451 ACPI_SCI_HANDLER Address,
454 ACPI_SCI_HANDLER_INFO *NewSciHandler;
455 ACPI_SCI_HANDLER_INFO *SciHandler;
456 ACPI_CPU_FLAGS Flags;
460 ACPI_FUNCTION_TRACE (AcpiInstallSciHandler);
465 return_ACPI_STATUS (AE_BAD_PARAMETER);
468 /* Allocate and init a handler object */
470 NewSciHandler = ACPI_ALLOCATE (sizeof (ACPI_SCI_HANDLER_INFO));
473 return_ACPI_STATUS (AE_NO_MEMORY);
476 NewSciHandler->Address = Address;
477 NewSciHandler->Context = Context;
479 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
480 if (ACPI_FAILURE (Status))
485 /* Lock list during installation */
487 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
488 SciHandler = AcpiGbl_SciHandlerList;
490 /* Ensure handler does not already exist */
494 if (Address == SciHandler->Address)
496 Status = AE_ALREADY_EXISTS;
500 SciHandler = SciHandler->Next;
503 /* Install the new handler into the global list (at head) */
505 NewSciHandler->Next = AcpiGbl_SciHandlerList;
506 AcpiGbl_SciHandlerList = NewSciHandler;
511 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
512 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
515 if (ACPI_FAILURE (Status))
517 ACPI_FREE (NewSciHandler);
519 return_ACPI_STATUS (Status);
523 /*******************************************************************************
525 * FUNCTION: AcpiRemoveSciHandler
527 * PARAMETERS: Address - Address of the handler
531 * DESCRIPTION: Remove a handler for a System Control Interrupt.
533 ******************************************************************************/
536 AcpiRemoveSciHandler (
537 ACPI_SCI_HANDLER Address)
539 ACPI_SCI_HANDLER_INFO *PrevSciHandler;
540 ACPI_SCI_HANDLER_INFO *NextSciHandler;
541 ACPI_CPU_FLAGS Flags;
545 ACPI_FUNCTION_TRACE (AcpiRemoveSciHandler);
550 return_ACPI_STATUS (AE_BAD_PARAMETER);
553 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
554 if (ACPI_FAILURE (Status))
556 return_ACPI_STATUS (Status);
559 /* Remove the SCI handler with lock */
561 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
563 PrevSciHandler = NULL;
564 NextSciHandler = AcpiGbl_SciHandlerList;
565 while (NextSciHandler)
567 if (NextSciHandler->Address == Address)
569 /* Unlink and free the SCI handler info block */
573 PrevSciHandler->Next = NextSciHandler->Next;
577 AcpiGbl_SciHandlerList = NextSciHandler->Next;
580 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
581 ACPI_FREE (NextSciHandler);
585 PrevSciHandler = NextSciHandler;
586 NextSciHandler = NextSciHandler->Next;
589 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
590 Status = AE_NOT_EXIST;
594 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
595 return_ACPI_STATUS (Status);
599 /*******************************************************************************
601 * FUNCTION: AcpiInstallGlobalEventHandler
603 * PARAMETERS: Handler - Pointer to the global event handler function
604 * Context - Value passed to the handler on each event
608 * DESCRIPTION: Saves the pointer to the handler function. The global handler
609 * is invoked upon each incoming GPE and Fixed Event. It is
610 * invoked at interrupt level at the time of the event dispatch.
611 * Can be used to update event counters, etc.
613 ******************************************************************************/
616 AcpiInstallGlobalEventHandler (
617 ACPI_GBL_EVENT_HANDLER Handler,
623 ACPI_FUNCTION_TRACE (AcpiInstallGlobalEventHandler);
626 /* Parameter validation */
630 return_ACPI_STATUS (AE_BAD_PARAMETER);
633 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
634 if (ACPI_FAILURE (Status))
636 return_ACPI_STATUS (Status);
639 /* Don't allow two handlers. */
641 if (AcpiGbl_GlobalEventHandler)
643 Status = AE_ALREADY_EXISTS;
647 AcpiGbl_GlobalEventHandler = Handler;
648 AcpiGbl_GlobalEventHandlerContext = Context;
652 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
653 return_ACPI_STATUS (Status);
656 ACPI_EXPORT_SYMBOL (AcpiInstallGlobalEventHandler)
659 /*******************************************************************************
661 * FUNCTION: AcpiInstallFixedEventHandler
663 * PARAMETERS: Event - Event type to enable.
664 * Handler - Pointer to the handler function for the
666 * Context - Value passed to the handler on each GPE
670 * DESCRIPTION: Saves the pointer to the handler function and then enables the
673 ******************************************************************************/
676 AcpiInstallFixedEventHandler (
678 ACPI_EVENT_HANDLER Handler,
684 ACPI_FUNCTION_TRACE (AcpiInstallFixedEventHandler);
687 /* Parameter validation */
689 if (Event > ACPI_EVENT_MAX)
691 return_ACPI_STATUS (AE_BAD_PARAMETER);
694 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
695 if (ACPI_FAILURE (Status))
697 return_ACPI_STATUS (Status);
700 /* Do not allow multiple handlers */
702 if (AcpiGbl_FixedEventHandlers[Event].Handler)
704 Status = AE_ALREADY_EXISTS;
708 /* Install the handler before enabling the event */
710 AcpiGbl_FixedEventHandlers[Event].Handler = Handler;
711 AcpiGbl_FixedEventHandlers[Event].Context = Context;
713 Status = AcpiEnableEvent (Event, 0);
714 if (ACPI_FAILURE (Status))
716 ACPI_WARNING ((AE_INFO,
717 "Could not enable fixed event - %s (%u)",
718 AcpiUtGetEventName (Event), Event));
720 /* Remove the handler */
722 AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
723 AcpiGbl_FixedEventHandlers[Event].Context = NULL;
727 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
728 "Enabled fixed event %s (%X), Handler=%p\n",
729 AcpiUtGetEventName (Event), Event, Handler));
734 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
735 return_ACPI_STATUS (Status);
738 ACPI_EXPORT_SYMBOL (AcpiInstallFixedEventHandler)
741 /*******************************************************************************
743 * FUNCTION: AcpiRemoveFixedEventHandler
745 * PARAMETERS: Event - Event type to disable.
746 * Handler - Address of the handler
750 * DESCRIPTION: Disables the event and unregisters the event handler.
752 ******************************************************************************/
755 AcpiRemoveFixedEventHandler (
757 ACPI_EVENT_HANDLER Handler)
759 ACPI_STATUS Status = AE_OK;
762 ACPI_FUNCTION_TRACE (AcpiRemoveFixedEventHandler);
765 /* Parameter validation */
767 if (Event > ACPI_EVENT_MAX)
769 return_ACPI_STATUS (AE_BAD_PARAMETER);
772 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
773 if (ACPI_FAILURE (Status))
775 return_ACPI_STATUS (Status);
778 /* Disable the event before removing the handler */
780 Status = AcpiDisableEvent (Event, 0);
782 /* Always Remove the handler */
784 AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
785 AcpiGbl_FixedEventHandlers[Event].Context = NULL;
787 if (ACPI_FAILURE (Status))
789 ACPI_WARNING ((AE_INFO,
790 "Could not disable fixed event - %s (%u)",
791 AcpiUtGetEventName (Event), Event));
795 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
796 "Disabled fixed event - %s (%X)\n",
797 AcpiUtGetEventName (Event), Event));
800 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
801 return_ACPI_STATUS (Status);
804 ACPI_EXPORT_SYMBOL (AcpiRemoveFixedEventHandler)
807 /*******************************************************************************
809 * FUNCTION: AcpiInstallGpeHandler
811 * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT
813 * GpeNumber - The GPE number within the GPE block
814 * Type - Whether this GPE should be treated as an
815 * edge- or level-triggered interrupt.
816 * Address - Address of the handler
817 * Context - Value passed to the handler on each GPE
821 * DESCRIPTION: Install a handler for a General Purpose Event.
823 ******************************************************************************/
826 AcpiInstallGpeHandler (
827 ACPI_HANDLE GpeDevice,
830 ACPI_GPE_HANDLER Address,
833 ACPI_GPE_EVENT_INFO *GpeEventInfo;
834 ACPI_GPE_HANDLER_INFO *Handler;
836 ACPI_CPU_FLAGS Flags;
839 ACPI_FUNCTION_TRACE (AcpiInstallGpeHandler);
842 /* Parameter validation */
844 if ((!Address) || (Type & ~ACPI_GPE_XRUPT_TYPE_MASK))
846 return_ACPI_STATUS (AE_BAD_PARAMETER);
849 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
850 if (ACPI_FAILURE (Status))
852 return_ACPI_STATUS (Status);
855 /* Allocate and init handler object (before lock) */
857 Handler = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_HANDLER_INFO));
860 Status = AE_NO_MEMORY;
864 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
866 /* Ensure that we have a valid GPE number */
868 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
871 Status = AE_BAD_PARAMETER;
875 /* Make sure that there isn't a handler there already */
877 if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
878 ACPI_GPE_DISPATCH_HANDLER)
880 Status = AE_ALREADY_EXISTS;
884 Handler->Address = Address;
885 Handler->Context = Context;
886 Handler->MethodNode = GpeEventInfo->Dispatch.MethodNode;
887 Handler->OriginalFlags = (UINT8) (GpeEventInfo->Flags &
888 (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK));
891 * If the GPE is associated with a method, it may have been enabled
892 * automatically during initialization, in which case it has to be
893 * disabled now to avoid spurious execution of the handler.
895 if (((Handler->OriginalFlags & ACPI_GPE_DISPATCH_METHOD) ||
896 (Handler->OriginalFlags & ACPI_GPE_DISPATCH_NOTIFY)) &&
897 GpeEventInfo->RuntimeCount)
899 Handler->OriginallyEnabled = TRUE;
900 (void) AcpiEvRemoveGpeReference (GpeEventInfo);
902 /* Sanity check of original type against new type */
904 if (Type != (UINT32) (GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK))
906 ACPI_WARNING ((AE_INFO, "GPE type mismatch (level/edge)"));
910 /* Install the handler */
912 GpeEventInfo->Dispatch.Handler = Handler;
914 /* Setup up dispatch flags to indicate handler (vs. method/notify) */
916 GpeEventInfo->Flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
917 GpeEventInfo->Flags |= (UINT8) (Type | ACPI_GPE_DISPATCH_HANDLER);
919 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
923 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
924 return_ACPI_STATUS (Status);
927 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
932 ACPI_EXPORT_SYMBOL (AcpiInstallGpeHandler)
935 /*******************************************************************************
937 * FUNCTION: AcpiRemoveGpeHandler
939 * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT
941 * GpeNumber - The event to remove a handler
942 * Address - Address of the handler
946 * DESCRIPTION: Remove a handler for a General Purpose AcpiEvent.
948 ******************************************************************************/
951 AcpiRemoveGpeHandler (
952 ACPI_HANDLE GpeDevice,
954 ACPI_GPE_HANDLER Address)
956 ACPI_GPE_EVENT_INFO *GpeEventInfo;
957 ACPI_GPE_HANDLER_INFO *Handler;
959 ACPI_CPU_FLAGS Flags;
962 ACPI_FUNCTION_TRACE (AcpiRemoveGpeHandler);
965 /* Parameter validation */
969 return_ACPI_STATUS (AE_BAD_PARAMETER);
972 /* Make sure all deferred GPE tasks are completed */
974 AcpiOsWaitEventsComplete ();
976 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
977 if (ACPI_FAILURE (Status))
979 return_ACPI_STATUS (Status);
982 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
984 /* Ensure that we have a valid GPE number */
986 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
989 Status = AE_BAD_PARAMETER;
993 /* Make sure that a handler is indeed installed */
995 if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) !=
996 ACPI_GPE_DISPATCH_HANDLER)
998 Status = AE_NOT_EXIST;
1002 /* Make sure that the installed handler is the same */
1004 if (GpeEventInfo->Dispatch.Handler->Address != Address)
1006 Status = AE_BAD_PARAMETER;
1010 /* Remove the handler */
1012 Handler = GpeEventInfo->Dispatch.Handler;
1014 /* Restore Method node (if any), set dispatch flags */
1016 GpeEventInfo->Dispatch.MethodNode = Handler->MethodNode;
1017 GpeEventInfo->Flags &=
1018 ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
1019 GpeEventInfo->Flags |= Handler->OriginalFlags;
1022 * If the GPE was previously associated with a method and it was
1023 * enabled, it should be enabled at this point to restore the
1024 * post-initialization configuration.
1026 if ((Handler->OriginalFlags & ACPI_GPE_DISPATCH_METHOD) &&
1027 Handler->OriginallyEnabled)
1029 (void) AcpiEvAddGpeReference (GpeEventInfo);
1032 /* Now we can free the handler object */
1034 ACPI_FREE (Handler);
1038 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
1039 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
1040 return_ACPI_STATUS (Status);
1043 ACPI_EXPORT_SYMBOL (AcpiRemoveGpeHandler)
1046 /*******************************************************************************
1048 * FUNCTION: AcpiAcquireGlobalLock
1050 * PARAMETERS: Timeout - How long the caller is willing to wait
1051 * Handle - Where the handle to the lock is returned
1056 * DESCRIPTION: Acquire the ACPI Global Lock
1058 * Note: Allows callers with the same thread ID to acquire the global lock
1059 * multiple times. In other words, externally, the behavior of the global lock
1060 * is identical to an AML mutex. On the first acquire, a new handle is
1061 * returned. On any subsequent calls to acquire by the same thread, the same
1062 * handle is returned.
1064 ******************************************************************************/
1067 AcpiAcquireGlobalLock (
1076 return (AE_BAD_PARAMETER);
1079 /* Must lock interpreter to prevent race conditions */
1081 AcpiExEnterInterpreter ();
1083 Status = AcpiExAcquireMutexObject (Timeout,
1084 AcpiGbl_GlobalLockMutex, AcpiOsGetThreadId ());
1086 if (ACPI_SUCCESS (Status))
1088 /* Return the global lock handle (updated in AcpiEvAcquireGlobalLock) */
1090 *Handle = AcpiGbl_GlobalLockHandle;
1093 AcpiExExitInterpreter ();
1097 ACPI_EXPORT_SYMBOL (AcpiAcquireGlobalLock)
1100 /*******************************************************************************
1102 * FUNCTION: AcpiReleaseGlobalLock
1104 * PARAMETERS: Handle - Returned from AcpiAcquireGlobalLock
1108 * DESCRIPTION: Release the ACPI Global Lock. The handle must be valid.
1110 ******************************************************************************/
1113 AcpiReleaseGlobalLock (
1119 if (!Handle || (Handle != AcpiGbl_GlobalLockHandle))
1121 return (AE_NOT_ACQUIRED);
1124 Status = AcpiExReleaseMutexObject (AcpiGbl_GlobalLockMutex);
1128 ACPI_EXPORT_SYMBOL (AcpiReleaseGlobalLock)
1130 #endif /* !ACPI_REDUCED_HARDWARE */