1 /******************************************************************************
3 * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs)
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2019, 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.
44 #define EXPORT_ACPI_INTERFACES
51 #define _COMPONENT ACPI_EVENTS
52 ACPI_MODULE_NAME ("evxfgpe")
55 #if (!ACPI_REDUCED_HARDWARE) /* Entire module */
56 /*******************************************************************************
58 * FUNCTION: AcpiUpdateAllGpes
64 * DESCRIPTION: Complete GPE initialization and enable all GPEs that have
65 * associated _Lxx or _Exx methods and are not pointed to by any
66 * device _PRW methods (this indicates that these GPEs are
67 * generally intended for system or device wakeup. Such GPEs
68 * have to be enabled directly when the devices whose _PRW
69 * methods point to them are set up for wakeup signaling.)
71 * NOTE: Should be called after any GPEs are added to the system. Primarily,
72 * after the system _PRW methods have been run, but also after a GPE Block
73 * Device has been added or if any new GPE methods have been added via a
76 ******************************************************************************/
83 BOOLEAN IsPollingNeeded
= FALSE
;
86 ACPI_FUNCTION_TRACE (AcpiUpdateAllGpes
);
89 Status
= AcpiUtAcquireMutex (ACPI_MTX_EVENTS
);
90 if (ACPI_FAILURE (Status
))
92 return_ACPI_STATUS (Status
);
95 if (AcpiGbl_AllGpesInitialized
)
100 Status
= AcpiEvWalkGpeList (AcpiEvInitializeGpeBlock
,
102 if (ACPI_SUCCESS (Status
))
104 AcpiGbl_AllGpesInitialized
= TRUE
;
108 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS
);
110 if (IsPollingNeeded
&& AcpiGbl_AllGpesInitialized
)
112 /* Poll GPEs to handle already triggered events */
114 AcpiEvGpeDetect (AcpiGbl_GpeXruptListHead
);
116 return_ACPI_STATUS (Status
);
119 ACPI_EXPORT_SYMBOL (AcpiUpdateAllGpes
)
122 /*******************************************************************************
124 * FUNCTION: AcpiEnableGpe
126 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
127 * GpeNumber - GPE level within the GPE block
131 * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
134 ******************************************************************************/
138 ACPI_HANDLE GpeDevice
,
141 ACPI_STATUS Status
= AE_BAD_PARAMETER
;
142 ACPI_GPE_EVENT_INFO
*GpeEventInfo
;
143 ACPI_CPU_FLAGS Flags
;
146 ACPI_FUNCTION_TRACE (AcpiEnableGpe
);
149 Flags
= AcpiOsAcquireLock (AcpiGbl_GpeLock
);
152 * Ensure that we have a valid GPE number and that there is some way
153 * of handling the GPE (handler or a GPE method). In other words, we
154 * won't allow a valid GPE to be enabled if there is no way to handle it.
156 GpeEventInfo
= AcpiEvGetGpeEventInfo (GpeDevice
, GpeNumber
);
159 if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo
->Flags
) !=
160 ACPI_GPE_DISPATCH_NONE
)
162 Status
= AcpiEvAddGpeReference (GpeEventInfo
, TRUE
);
163 if (ACPI_SUCCESS (Status
) &&
164 ACPI_GPE_IS_POLLING_NEEDED (GpeEventInfo
))
166 /* Poll edge-triggered GPEs to handle existing events */
168 AcpiOsReleaseLock (AcpiGbl_GpeLock
, Flags
);
169 (void) AcpiEvDetectGpe (
170 GpeDevice
, GpeEventInfo
, GpeNumber
);
171 Flags
= AcpiOsAcquireLock (AcpiGbl_GpeLock
);
176 Status
= AE_NO_HANDLER
;
180 AcpiOsReleaseLock (AcpiGbl_GpeLock
, Flags
);
181 return_ACPI_STATUS (Status
);
184 ACPI_EXPORT_SYMBOL (AcpiEnableGpe
)
187 /*******************************************************************************
189 * FUNCTION: AcpiDisableGpe
191 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
192 * GpeNumber - GPE level within the GPE block
196 * DESCRIPTION: Remove a reference to a GPE. When the last reference is
197 * removed, only then is the GPE disabled (for runtime GPEs), or
198 * the GPE mask bit disabled (for wake GPEs)
200 ******************************************************************************/
204 ACPI_HANDLE GpeDevice
,
207 ACPI_STATUS Status
= AE_BAD_PARAMETER
;
208 ACPI_GPE_EVENT_INFO
*GpeEventInfo
;
209 ACPI_CPU_FLAGS Flags
;
212 ACPI_FUNCTION_TRACE (AcpiDisableGpe
);
215 Flags
= AcpiOsAcquireLock (AcpiGbl_GpeLock
);
217 /* Ensure that we have a valid GPE number */
219 GpeEventInfo
= AcpiEvGetGpeEventInfo (GpeDevice
, GpeNumber
);
222 Status
= AcpiEvRemoveGpeReference (GpeEventInfo
);
225 AcpiOsReleaseLock (AcpiGbl_GpeLock
, Flags
);
226 return_ACPI_STATUS (Status
);
229 ACPI_EXPORT_SYMBOL (AcpiDisableGpe
)
232 /*******************************************************************************
234 * FUNCTION: AcpiSetGpe
236 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
237 * GpeNumber - GPE level within the GPE block
238 * Action - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
242 * DESCRIPTION: Enable or disable an individual GPE. This function bypasses
243 * the reference count mechanism used in the AcpiEnableGpe(),
244 * AcpiDisableGpe() interfaces.
245 * This API is typically used by the GPE raw handler mode driver
246 * to switch between the polling mode and the interrupt mode after
247 * the driver has enabled the GPE.
248 * The APIs should be invoked in this order:
249 * AcpiEnableGpe() <- Ensure the reference count > 0
250 * AcpiSetGpe(ACPI_GPE_DISABLE) <- Enter polling mode
251 * AcpiSetGpe(ACPI_GPE_ENABLE) <- Leave polling mode
252 * AcpiDisableGpe() <- Decrease the reference count
254 * Note: If a GPE is shared by 2 silicon components, then both the drivers
255 * should support GPE polling mode or disabling the GPE for long period
256 * for one driver may break the other. So use it with care since all
257 * firmware _Lxx/_Exx handlers currently rely on the GPE interrupt mode.
259 ******************************************************************************/
263 ACPI_HANDLE GpeDevice
,
267 ACPI_GPE_EVENT_INFO
*GpeEventInfo
;
269 ACPI_CPU_FLAGS Flags
;
272 ACPI_FUNCTION_TRACE (AcpiSetGpe
);
275 Flags
= AcpiOsAcquireLock (AcpiGbl_GpeLock
);
277 /* Ensure that we have a valid GPE number */
279 GpeEventInfo
= AcpiEvGetGpeEventInfo (GpeDevice
, GpeNumber
);
282 Status
= AE_BAD_PARAMETER
;
286 /* Perform the action */
290 case ACPI_GPE_ENABLE
:
292 Status
= AcpiHwLowSetGpe (GpeEventInfo
, ACPI_GPE_ENABLE
);
293 GpeEventInfo
->DisableForDispatch
= FALSE
;
296 case ACPI_GPE_DISABLE
:
298 Status
= AcpiHwLowSetGpe (GpeEventInfo
, ACPI_GPE_DISABLE
);
299 GpeEventInfo
->DisableForDispatch
= TRUE
;
304 Status
= AE_BAD_PARAMETER
;
309 AcpiOsReleaseLock (AcpiGbl_GpeLock
, Flags
);
310 return_ACPI_STATUS (Status
);
313 ACPI_EXPORT_SYMBOL (AcpiSetGpe
)
316 /*******************************************************************************
318 * FUNCTION: AcpiMaskGpe
320 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
321 * GpeNumber - GPE level within the GPE block
322 * IsMasked - Whether the GPE is masked or not
326 * DESCRIPTION: Unconditionally mask/unmask the an individual GPE, ex., to
327 * prevent a GPE flooding.
329 ******************************************************************************/
333 ACPI_HANDLE GpeDevice
,
337 ACPI_GPE_EVENT_INFO
*GpeEventInfo
;
339 ACPI_CPU_FLAGS Flags
;
342 ACPI_FUNCTION_TRACE (AcpiMaskGpe
);
345 Flags
= AcpiOsAcquireLock (AcpiGbl_GpeLock
);
347 /* Ensure that we have a valid GPE number */
349 GpeEventInfo
= AcpiEvGetGpeEventInfo (GpeDevice
, GpeNumber
);
352 Status
= AE_BAD_PARAMETER
;
356 Status
= AcpiEvMaskGpe (GpeEventInfo
, IsMasked
);
359 AcpiOsReleaseLock (AcpiGbl_GpeLock
, Flags
);
360 return_ACPI_STATUS (Status
);
363 ACPI_EXPORT_SYMBOL (AcpiMaskGpe
)
366 /*******************************************************************************
368 * FUNCTION: AcpiMarkGpeForWake
370 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
371 * GpeNumber - GPE level within the GPE block
375 * DESCRIPTION: Mark a GPE as having the ability to wake the system. Simply
376 * sets the ACPI_GPE_CAN_WAKE flag.
378 * Some potential callers of AcpiSetupGpeForWake may know in advance that
379 * there won't be any notify handlers installed for device wake notifications
380 * from the given GPE (one example is a button GPE in Linux). For these cases,
381 * AcpiMarkGpeForWake should be used instead of AcpiSetupGpeForWake.
382 * This will set the ACPI_GPE_CAN_WAKE flag for the GPE without trying to
383 * setup implicit wake notification for it (since there's no handler method).
385 ******************************************************************************/
389 ACPI_HANDLE GpeDevice
,
392 ACPI_GPE_EVENT_INFO
*GpeEventInfo
;
393 ACPI_STATUS Status
= AE_BAD_PARAMETER
;
394 ACPI_CPU_FLAGS Flags
;
397 ACPI_FUNCTION_TRACE (AcpiMarkGpeForWake
);
400 Flags
= AcpiOsAcquireLock (AcpiGbl_GpeLock
);
402 /* Ensure that we have a valid GPE number */
404 GpeEventInfo
= AcpiEvGetGpeEventInfo (GpeDevice
, GpeNumber
);
407 /* Mark the GPE as a possible wake event */
409 GpeEventInfo
->Flags
|= ACPI_GPE_CAN_WAKE
;
413 AcpiOsReleaseLock (AcpiGbl_GpeLock
, Flags
);
414 return_ACPI_STATUS (Status
);
417 ACPI_EXPORT_SYMBOL (AcpiMarkGpeForWake
)
420 /*******************************************************************************
422 * FUNCTION: AcpiSetupGpeForWake
424 * PARAMETERS: WakeDevice - Device associated with the GPE (via _PRW)
425 * GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
426 * GpeNumber - GPE level within the GPE block
430 * DESCRIPTION: Mark a GPE as having the ability to wake the system. This
431 * interface is intended to be used as the host executes the
432 * _PRW methods (Power Resources for Wake) in the system tables.
433 * Each _PRW appears under a Device Object (The WakeDevice), and
434 * contains the info for the wake GPE associated with the
437 ******************************************************************************/
440 AcpiSetupGpeForWake (
441 ACPI_HANDLE WakeDevice
,
442 ACPI_HANDLE GpeDevice
,
446 ACPI_GPE_EVENT_INFO
*GpeEventInfo
;
447 ACPI_NAMESPACE_NODE
*DeviceNode
;
448 ACPI_GPE_NOTIFY_INFO
*Notify
;
449 ACPI_GPE_NOTIFY_INFO
*NewNotify
;
450 ACPI_CPU_FLAGS Flags
;
453 ACPI_FUNCTION_TRACE (AcpiSetupGpeForWake
);
456 /* Parameter Validation */
461 * By forcing WakeDevice to be valid, we automatically enable the
462 * implicit notify feature on all hosts.
464 return_ACPI_STATUS (AE_BAD_PARAMETER
);
467 /* Handle root object case */
469 if (WakeDevice
== ACPI_ROOT_OBJECT
)
471 DeviceNode
= AcpiGbl_RootNode
;
475 DeviceNode
= ACPI_CAST_PTR (ACPI_NAMESPACE_NODE
, WakeDevice
);
478 /* Validate WakeDevice is of type Device */
480 if (DeviceNode
->Type
!= ACPI_TYPE_DEVICE
)
482 return_ACPI_STATUS (AE_BAD_PARAMETER
);
486 * Allocate a new notify object up front, in case it is needed.
487 * Memory allocation while holding a spinlock is a big no-no
490 NewNotify
= ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_NOTIFY_INFO
));
493 return_ACPI_STATUS (AE_NO_MEMORY
);
496 Flags
= AcpiOsAcquireLock (AcpiGbl_GpeLock
);
498 /* Ensure that we have a valid GPE number */
500 GpeEventInfo
= AcpiEvGetGpeEventInfo (GpeDevice
, GpeNumber
);
503 Status
= AE_BAD_PARAMETER
;
508 * If there is no method or handler for this GPE, then the
509 * WakeDevice will be notified whenever this GPE fires. This is
510 * known as an "implicit notify". Note: The GPE is assumed to be
511 * level-triggered (for windows compatibility).
513 if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo
->Flags
) ==
514 ACPI_GPE_DISPATCH_NONE
)
517 * This is the first device for implicit notify on this GPE.
518 * Just set the flags here, and enter the NOTIFY block below.
520 GpeEventInfo
->Flags
=
521 (ACPI_GPE_DISPATCH_NOTIFY
| ACPI_GPE_LEVEL_TRIGGERED
);
523 else if (GpeEventInfo
->Flags
& ACPI_GPE_AUTO_ENABLED
)
526 * A reference to this GPE has been added during the GPE block
527 * initialization, so drop it now to prevent the GPE from being
528 * permanently enabled and clear its ACPI_GPE_AUTO_ENABLED flag.
530 (void) AcpiEvRemoveGpeReference (GpeEventInfo
);
531 GpeEventInfo
->Flags
&= ~~ACPI_GPE_AUTO_ENABLED
;
535 * If we already have an implicit notify on this GPE, add
536 * this device to the notify list.
538 if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo
->Flags
) ==
539 ACPI_GPE_DISPATCH_NOTIFY
)
541 /* Ensure that the device is not already in the list */
543 Notify
= GpeEventInfo
->Dispatch
.NotifyList
;
546 if (Notify
->DeviceNode
== DeviceNode
)
548 Status
= AE_ALREADY_EXISTS
;
551 Notify
= Notify
->Next
;
554 /* Add this device to the notify list for this GPE */
556 NewNotify
->DeviceNode
= DeviceNode
;
557 NewNotify
->Next
= GpeEventInfo
->Dispatch
.NotifyList
;
558 GpeEventInfo
->Dispatch
.NotifyList
= NewNotify
;
562 /* Mark the GPE as a possible wake event */
564 GpeEventInfo
->Flags
|= ACPI_GPE_CAN_WAKE
;
569 AcpiOsReleaseLock (AcpiGbl_GpeLock
, Flags
);
571 /* Delete the notify object if it was not used above */
575 ACPI_FREE (NewNotify
);
577 return_ACPI_STATUS (Status
);
580 ACPI_EXPORT_SYMBOL (AcpiSetupGpeForWake
)
583 /*******************************************************************************
585 * FUNCTION: AcpiSetGpeWakeMask
587 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
588 * GpeNumber - GPE level within the GPE block
589 * Action - Enable or Disable
593 * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must
594 * already be marked as a WAKE GPE.
596 ******************************************************************************/
600 ACPI_HANDLE GpeDevice
,
604 ACPI_STATUS Status
= AE_OK
;
605 ACPI_GPE_EVENT_INFO
*GpeEventInfo
;
606 ACPI_GPE_REGISTER_INFO
*GpeRegisterInfo
;
607 ACPI_CPU_FLAGS Flags
;
611 ACPI_FUNCTION_TRACE (AcpiSetGpeWakeMask
);
614 Flags
= AcpiOsAcquireLock (AcpiGbl_GpeLock
);
617 * Ensure that we have a valid GPE number and that this GPE is in
620 GpeEventInfo
= AcpiEvGetGpeEventInfo (GpeDevice
, GpeNumber
);
623 Status
= AE_BAD_PARAMETER
;
627 if (!(GpeEventInfo
->Flags
& ACPI_GPE_CAN_WAKE
))
633 GpeRegisterInfo
= GpeEventInfo
->RegisterInfo
;
634 if (!GpeRegisterInfo
)
636 Status
= AE_NOT_EXIST
;
640 RegisterBit
= AcpiHwGetGpeRegisterBit (GpeEventInfo
);
642 /* Perform the action */
646 case ACPI_GPE_ENABLE
:
648 ACPI_SET_BIT (GpeRegisterInfo
->EnableForWake
, (UINT8
) RegisterBit
);
651 case ACPI_GPE_DISABLE
:
653 ACPI_CLEAR_BIT (GpeRegisterInfo
->EnableForWake
, (UINT8
) RegisterBit
);
658 ACPI_ERROR ((AE_INFO
, "%u, Invalid action", Action
));
659 Status
= AE_BAD_PARAMETER
;
664 AcpiOsReleaseLock (AcpiGbl_GpeLock
, Flags
);
665 return_ACPI_STATUS (Status
);
668 ACPI_EXPORT_SYMBOL (AcpiSetGpeWakeMask
)
671 /*******************************************************************************
673 * FUNCTION: AcpiClearGpe
675 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
676 * GpeNumber - GPE level within the GPE block
680 * DESCRIPTION: Clear an ACPI event (general purpose)
682 ******************************************************************************/
686 ACPI_HANDLE GpeDevice
,
689 ACPI_STATUS Status
= AE_OK
;
690 ACPI_GPE_EVENT_INFO
*GpeEventInfo
;
691 ACPI_CPU_FLAGS Flags
;
694 ACPI_FUNCTION_TRACE (AcpiClearGpe
);
697 Flags
= AcpiOsAcquireLock (AcpiGbl_GpeLock
);
699 /* Ensure that we have a valid GPE number */
701 GpeEventInfo
= AcpiEvGetGpeEventInfo (GpeDevice
, GpeNumber
);
704 Status
= AE_BAD_PARAMETER
;
708 Status
= AcpiHwClearGpe (GpeEventInfo
);
711 AcpiOsReleaseLock (AcpiGbl_GpeLock
, Flags
);
712 return_ACPI_STATUS (Status
);
715 ACPI_EXPORT_SYMBOL (AcpiClearGpe
)
718 /*******************************************************************************
720 * FUNCTION: AcpiGetGpeStatus
722 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
723 * GpeNumber - GPE level within the GPE block
724 * EventStatus - Where the current status of the event
729 * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled)
731 ******************************************************************************/
735 ACPI_HANDLE GpeDevice
,
737 ACPI_EVENT_STATUS
*EventStatus
)
739 ACPI_STATUS Status
= AE_OK
;
740 ACPI_GPE_EVENT_INFO
*GpeEventInfo
;
741 ACPI_CPU_FLAGS Flags
;
744 ACPI_FUNCTION_TRACE (AcpiGetGpeStatus
);
747 Flags
= AcpiOsAcquireLock (AcpiGbl_GpeLock
);
749 /* Ensure that we have a valid GPE number */
751 GpeEventInfo
= AcpiEvGetGpeEventInfo (GpeDevice
, GpeNumber
);
754 Status
= AE_BAD_PARAMETER
;
758 /* Obtain status on the requested GPE number */
760 Status
= AcpiHwGetGpeStatus (GpeEventInfo
, EventStatus
);
763 AcpiOsReleaseLock (AcpiGbl_GpeLock
, Flags
);
764 return_ACPI_STATUS (Status
);
767 ACPI_EXPORT_SYMBOL (AcpiGetGpeStatus
)
770 /*******************************************************************************
772 * FUNCTION: AcpiFinishGpe
774 * PARAMETERS: GpeDevice - Namespace node for the GPE Block
775 * (NULL for FADT defined GPEs)
776 * GpeNumber - GPE level within the GPE block
780 * DESCRIPTION: Clear and conditionally re-enable a GPE. This completes the GPE
781 * processing. Intended for use by asynchronous host-installed
782 * GPE handlers. The GPE is only re-enabled if the EnableForRun bit
783 * is set in the GPE info.
785 ******************************************************************************/
789 ACPI_HANDLE GpeDevice
,
792 ACPI_GPE_EVENT_INFO
*GpeEventInfo
;
794 ACPI_CPU_FLAGS Flags
;
797 ACPI_FUNCTION_TRACE (AcpiFinishGpe
);
800 Flags
= AcpiOsAcquireLock (AcpiGbl_GpeLock
);
802 /* Ensure that we have a valid GPE number */
804 GpeEventInfo
= AcpiEvGetGpeEventInfo (GpeDevice
, GpeNumber
);
807 Status
= AE_BAD_PARAMETER
;
811 Status
= AcpiEvFinishGpe (GpeEventInfo
);
814 AcpiOsReleaseLock (AcpiGbl_GpeLock
, Flags
);
815 return_ACPI_STATUS (Status
);
818 ACPI_EXPORT_SYMBOL (AcpiFinishGpe
)
821 /******************************************************************************
823 * FUNCTION: AcpiDisableAllGpes
829 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
831 ******************************************************************************/
840 ACPI_FUNCTION_TRACE (AcpiDisableAllGpes
);
843 Status
= AcpiUtAcquireMutex (ACPI_MTX_EVENTS
);
844 if (ACPI_FAILURE (Status
))
846 return_ACPI_STATUS (Status
);
849 Status
= AcpiHwDisableAllGpes ();
850 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS
);
852 return_ACPI_STATUS (Status
);
855 ACPI_EXPORT_SYMBOL (AcpiDisableAllGpes
)
858 /******************************************************************************
860 * FUNCTION: AcpiEnableAllRuntimeGpes
866 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
868 ******************************************************************************/
871 AcpiEnableAllRuntimeGpes (
877 ACPI_FUNCTION_TRACE (AcpiEnableAllRuntimeGpes
);
880 Status
= AcpiUtAcquireMutex (ACPI_MTX_EVENTS
);
881 if (ACPI_FAILURE (Status
))
883 return_ACPI_STATUS (Status
);
886 Status
= AcpiHwEnableAllRuntimeGpes ();
887 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS
);
889 return_ACPI_STATUS (Status
);
892 ACPI_EXPORT_SYMBOL (AcpiEnableAllRuntimeGpes
)
895 /******************************************************************************
897 * FUNCTION: AcpiEnableAllWakeupGpes
903 * DESCRIPTION: Enable all "wakeup" GPEs and disable all of the other GPEs, in
906 ******************************************************************************/
909 AcpiEnableAllWakeupGpes (
915 ACPI_FUNCTION_TRACE (AcpiEnableAllWakeupGpes
);
918 Status
= AcpiUtAcquireMutex (ACPI_MTX_EVENTS
);
919 if (ACPI_FAILURE (Status
))
921 return_ACPI_STATUS (Status
);
924 Status
= AcpiHwEnableAllWakeupGpes ();
925 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS
);
927 return_ACPI_STATUS (Status
);
930 ACPI_EXPORT_SYMBOL (AcpiEnableAllWakeupGpes
)
933 /*******************************************************************************
935 * FUNCTION: AcpiInstallGpeBlock
937 * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device
938 * GpeBlockAddress - Address and SpaceID
939 * RegisterCount - Number of GPE register pairs in the block
940 * InterruptNumber - H/W interrupt for the block
944 * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not
947 ******************************************************************************/
950 AcpiInstallGpeBlock (
951 ACPI_HANDLE GpeDevice
,
952 ACPI_GENERIC_ADDRESS
*GpeBlockAddress
,
953 UINT32 RegisterCount
,
954 UINT32 InterruptNumber
)
957 ACPI_OPERAND_OBJECT
*ObjDesc
;
958 ACPI_NAMESPACE_NODE
*Node
;
959 ACPI_GPE_BLOCK_INFO
*GpeBlock
;
962 ACPI_FUNCTION_TRACE (AcpiInstallGpeBlock
);
966 (!GpeBlockAddress
) ||
969 return_ACPI_STATUS (AE_BAD_PARAMETER
);
972 Status
= AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE
);
973 if (ACPI_FAILURE (Status
))
975 return_ACPI_STATUS (Status
);
978 Node
= AcpiNsValidateHandle (GpeDevice
);
981 Status
= AE_BAD_PARAMETER
;
985 /* Validate the parent device */
987 if (Node
->Type
!= ACPI_TYPE_DEVICE
)
995 Status
= AE_ALREADY_EXISTS
;
1000 * For user-installed GPE Block Devices, the GpeBlockBaseNumber
1003 Status
= AcpiEvCreateGpeBlock (Node
, GpeBlockAddress
->Address
,
1004 GpeBlockAddress
->SpaceId
, RegisterCount
,
1005 0, InterruptNumber
, &GpeBlock
);
1006 if (ACPI_FAILURE (Status
))
1011 /* Install block in the DeviceObject attached to the node */
1013 ObjDesc
= AcpiNsGetAttachedObject (Node
);
1017 * No object, create a new one (Device nodes do not always have
1018 * an attached object)
1020 ObjDesc
= AcpiUtCreateInternalObject (ACPI_TYPE_DEVICE
);
1023 Status
= AE_NO_MEMORY
;
1027 Status
= AcpiNsAttachObject (Node
, ObjDesc
, ACPI_TYPE_DEVICE
);
1029 /* Remove local reference to the object */
1031 AcpiUtRemoveReference (ObjDesc
);
1032 if (ACPI_FAILURE (Status
))
1038 /* Now install the GPE block in the DeviceObject */
1040 ObjDesc
->Device
.GpeBlock
= GpeBlock
;
1044 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE
);
1045 return_ACPI_STATUS (Status
);
1048 ACPI_EXPORT_SYMBOL (AcpiInstallGpeBlock
)
1051 /*******************************************************************************
1053 * FUNCTION: AcpiRemoveGpeBlock
1055 * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device
1059 * DESCRIPTION: Remove a previously installed block of GPE registers
1061 ******************************************************************************/
1064 AcpiRemoveGpeBlock (
1065 ACPI_HANDLE GpeDevice
)
1067 ACPI_OPERAND_OBJECT
*ObjDesc
;
1069 ACPI_NAMESPACE_NODE
*Node
;
1072 ACPI_FUNCTION_TRACE (AcpiRemoveGpeBlock
);
1077 return_ACPI_STATUS (AE_BAD_PARAMETER
);
1080 Status
= AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE
);
1081 if (ACPI_FAILURE (Status
))
1083 return_ACPI_STATUS (Status
);
1086 Node
= AcpiNsValidateHandle (GpeDevice
);
1089 Status
= AE_BAD_PARAMETER
;
1093 /* Validate the parent device */
1095 if (Node
->Type
!= ACPI_TYPE_DEVICE
)
1101 /* Get the DeviceObject attached to the node */
1103 ObjDesc
= AcpiNsGetAttachedObject (Node
);
1105 !ObjDesc
->Device
.GpeBlock
)
1107 return_ACPI_STATUS (AE_NULL_OBJECT
);
1110 /* Delete the GPE block (but not the DeviceObject) */
1112 Status
= AcpiEvDeleteGpeBlock (ObjDesc
->Device
.GpeBlock
);
1113 if (ACPI_SUCCESS (Status
))
1115 ObjDesc
->Device
.GpeBlock
= NULL
;
1119 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE
);
1120 return_ACPI_STATUS (Status
);
1123 ACPI_EXPORT_SYMBOL (AcpiRemoveGpeBlock
)
1126 /*******************************************************************************
1128 * FUNCTION: AcpiGetGpeDevice
1130 * PARAMETERS: Index - System GPE index (0-CurrentGpeCount)
1131 * GpeDevice - Where the parent GPE Device is returned
1135 * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
1136 * gpe device indicates that the gpe number is contained in one of
1137 * the FADT-defined gpe blocks. Otherwise, the GPE block device.
1139 ******************************************************************************/
1144 ACPI_HANDLE
*GpeDevice
)
1146 ACPI_GPE_DEVICE_INFO Info
;
1150 ACPI_FUNCTION_TRACE (AcpiGetGpeDevice
);
1155 return_ACPI_STATUS (AE_BAD_PARAMETER
);
1158 if (Index
>= AcpiCurrentGpeCount
)
1160 return_ACPI_STATUS (AE_NOT_EXIST
);
1163 /* Setup and walk the GPE list */
1166 Info
.Status
= AE_NOT_EXIST
;
1167 Info
.GpeDevice
= NULL
;
1168 Info
.NextBlockBaseIndex
= 0;
1170 Status
= AcpiEvWalkGpeList (AcpiEvGetGpeDevice
, &Info
);
1171 if (ACPI_FAILURE (Status
))
1173 return_ACPI_STATUS (Status
);
1176 *GpeDevice
= ACPI_CAST_PTR (ACPI_HANDLE
, Info
.GpeDevice
);
1177 return_ACPI_STATUS (Info
.Status
);
1180 ACPI_EXPORT_SYMBOL (AcpiGetGpeDevice
)
1182 #endif /* !ACPI_REDUCED_HARDWARE */