ReactOS 0.4.15-dev-7934-g1dc8d80
evxfgpe.c
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs)
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2022, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
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.
25 *
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.
29 *
30 * NO WARRANTY
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 MERCHANTABILITY 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.
42 */
43
44#define EXPORT_ACPI_INTERFACES
45
46#include "acpi.h"
47#include "accommon.h"
48#include "acevents.h"
49#include "acnamesp.h"
50
51#define _COMPONENT ACPI_EVENTS
52 ACPI_MODULE_NAME ("evxfgpe")
53
54
55#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
56/*******************************************************************************
57 *
58 * FUNCTION: AcpiUpdateAllGpes
59 *
60 * PARAMETERS: None
61 *
62 * RETURN: Status
63 *
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.)
70 *
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
74 * dynamic table load.
75 *
76 ******************************************************************************/
77
80 void)
81{
83 BOOLEAN IsPollingNeeded = FALSE;
84
85
87
88
90 if (ACPI_FAILURE (Status))
91 {
93 }
94
95 if (AcpiGbl_AllGpesInitialized)
96 {
97 goto UnlockAndExit;
98 }
99
101 &IsPollingNeeded);
102 if (ACPI_SUCCESS (Status))
103 {
104 AcpiGbl_AllGpesInitialized = TRUE;
105 }
106
107UnlockAndExit:
109
110 if (IsPollingNeeded && AcpiGbl_AllGpesInitialized)
111 {
112 /* Poll GPEs to handle already triggered events */
113
114 AcpiEvGpeDetect (AcpiGbl_GpeXruptListHead);
115 }
117}
118
120
121
122/*******************************************************************************
123 *
124 * FUNCTION: AcpiEnableGpe
125 *
126 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
127 * GpeNumber - GPE level within the GPE block
128 *
129 * RETURN: Status
130 *
131 * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
132 * hardware-enabled.
133 *
134 ******************************************************************************/
135
138 ACPI_HANDLE GpeDevice,
140{
144
145
147
148
149 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
150
151 /*
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.
155 */
157 if (GpeEventInfo)
158 {
161 {
163 if (ACPI_SUCCESS (Status) &&
165 {
166 /* Poll edge-triggered GPEs to handle existing events */
167
168 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
170 GpeDevice, GpeEventInfo, GpeNumber);
171 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
172 }
173 }
174 else
175 {
177 }
178 }
179
180 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
182}
183
185
186
187/*******************************************************************************
188 *
189 * FUNCTION: AcpiDisableGpe
190 *
191 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
192 * GpeNumber - GPE level within the GPE block
193 *
194 * RETURN: Status
195 *
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)
199 *
200 ******************************************************************************/
201
204 ACPI_HANDLE GpeDevice,
206{
210
211
213
214
215 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
216
217 /* Ensure that we have a valid GPE number */
218
220 if (GpeEventInfo)
221 {
223 }
224
225 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
227}
228
230
231
232/*******************************************************************************
233 *
234 * FUNCTION: AcpiSetGpe
235 *
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
239 *
240 * RETURN: Status
241 *
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
253 *
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.
258 *
259 ******************************************************************************/
260
263 ACPI_HANDLE GpeDevice,
266{
270
271
273
274
275 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
276
277 /* Ensure that we have a valid GPE number */
278
280 if (!GpeEventInfo)
281 {
283 goto UnlockAndExit;
284 }
285
286 /* Perform the action */
287
288 switch (Action)
289 {
290 case ACPI_GPE_ENABLE:
291
294 break;
295
296 case ACPI_GPE_DISABLE:
297
300 break;
301
302 default:
303
305 break;
306 }
307
308UnlockAndExit:
309 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
311}
312
314
315
316/*******************************************************************************
317 *
318 * FUNCTION: AcpiMaskGpe
319 *
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
323 *
324 * RETURN: Status
325 *
326 * DESCRIPTION: Unconditionally mask/unmask the an individual GPE, ex., to
327 * prevent a GPE flooding.
328 *
329 ******************************************************************************/
330
333 ACPI_HANDLE GpeDevice,
335 BOOLEAN IsMasked)
336{
340
341
343
344
345 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
346
347 /* Ensure that we have a valid GPE number */
348
350 if (!GpeEventInfo)
351 {
353 goto UnlockAndExit;
354 }
355
356 Status = AcpiEvMaskGpe (GpeEventInfo, IsMasked);
357
358UnlockAndExit:
359 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
361}
362
364
365
366/*******************************************************************************
367 *
368 * FUNCTION: AcpiMarkGpeForWake
369 *
370 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
371 * GpeNumber - GPE level within the GPE block
372 *
373 * RETURN: Status
374 *
375 * DESCRIPTION: Mark a GPE as having the ability to wake the system. Simply
376 * sets the ACPI_GPE_CAN_WAKE flag.
377 *
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).
384 *
385 ******************************************************************************/
386
389 ACPI_HANDLE GpeDevice,
391{
395
396
398
399
400 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
401
402 /* Ensure that we have a valid GPE number */
403
405 if (GpeEventInfo)
406 {
407 /* Mark the GPE as a possible wake event */
408
410 Status = AE_OK;
411 }
412
413 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
415}
416
418
419
420/*******************************************************************************
421 *
422 * FUNCTION: AcpiSetupGpeForWake
423 *
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
427 *
428 * RETURN: Status
429 *
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
435 * WakeDevice.
436 *
437 ******************************************************************************/
438
441 ACPI_HANDLE WakeDevice,
442 ACPI_HANDLE GpeDevice,
444{
449 ACPI_GPE_NOTIFY_INFO *NewNotify;
451
452
454
455
456 /* Parameter Validation */
457
458 if (!WakeDevice)
459 {
460 /*
461 * By forcing WakeDevice to be valid, we automatically enable the
462 * implicit notify feature on all hosts.
463 */
465 }
466
467 /* Handle root object case */
468
469 if (WakeDevice == ACPI_ROOT_OBJECT)
470 {
471 DeviceNode = AcpiGbl_RootNode;
472 }
473 else
474 {
476 }
477
478 /* Validate WakeDevice is of type Device */
479
480 if (DeviceNode->Type != ACPI_TYPE_DEVICE)
481 {
483 }
484
485 /*
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
488 * on some hosts.
489 */
490 NewNotify = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_NOTIFY_INFO));
491 if (!NewNotify)
492 {
494 }
495
496 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
497
498 /* Ensure that we have a valid GPE number */
499
501 if (!GpeEventInfo)
502 {
504 goto UnlockAndExit;
505 }
506
507 /*
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).
512 */
515 {
516 /*
517 * This is the first device for implicit notify on this GPE.
518 * Just set the flags here, and enter the NOTIFY block below.
519 */
522 }
524 {
525 /*
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.
529 */
531 GpeEventInfo->Flags &= ~~ACPI_GPE_AUTO_ENABLED;
532 }
533
534 /*
535 * If we already have an implicit notify on this GPE, add
536 * this device to the notify list.
537 */
540 {
541 /* Ensure that the device is not already in the list */
542
544 while (Notify)
545 {
546 if (Notify->DeviceNode == DeviceNode)
547 {
549 goto UnlockAndExit;
550 }
551 Notify = Notify->Next;
552 }
553
554 /* Add this device to the notify list for this GPE */
555
556 NewNotify->DeviceNode = DeviceNode;
557 NewNotify->Next = GpeEventInfo->Dispatch.NotifyList;
558 GpeEventInfo->Dispatch.NotifyList = NewNotify;
559 NewNotify = NULL;
560 }
561
562 /* Mark the GPE as a possible wake event */
563
565 Status = AE_OK;
566
567
568UnlockAndExit:
569 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
570
571 /* Delete the notify object if it was not used above */
572
573 if (NewNotify)
574 {
575 ACPI_FREE (NewNotify);
576 }
578}
579
581
582
583/*******************************************************************************
584 *
585 * FUNCTION: AcpiSetGpeWakeMask
586 *
587 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
588 * GpeNumber - GPE level within the GPE block
589 * Action - Enable or Disable
590 *
591 * RETURN: Status
592 *
593 * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must
594 * already be marked as a WAKE GPE.
595 *
596 ******************************************************************************/
597
600 ACPI_HANDLE GpeDevice,
603{
606 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
608 UINT32 RegisterBit;
609
610
612
613
614 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
615
616 /*
617 * Ensure that we have a valid GPE number and that this GPE is in
618 * fact a wake GPE
619 */
621 if (!GpeEventInfo)
622 {
624 goto UnlockAndExit;
625 }
626
628 {
629 Status = AE_TYPE;
630 goto UnlockAndExit;
631 }
632
633 GpeRegisterInfo = GpeEventInfo->RegisterInfo;
634 if (!GpeRegisterInfo)
635 {
637 goto UnlockAndExit;
638 }
639
641
642 /* Perform the action */
643
644 switch (Action)
645 {
646 case ACPI_GPE_ENABLE:
647
648 ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
649 break;
650
651 case ACPI_GPE_DISABLE:
652
653 ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
654 break;
655
656 default:
657
658 ACPI_ERROR ((AE_INFO, "%u, Invalid action", Action));
660 break;
661 }
662
663UnlockAndExit:
664 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
666}
667
669
670
671/*******************************************************************************
672 *
673 * FUNCTION: AcpiClearGpe
674 *
675 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
676 * GpeNumber - GPE level within the GPE block
677 *
678 * RETURN: Status
679 *
680 * DESCRIPTION: Clear an ACPI event (general purpose)
681 *
682 ******************************************************************************/
683
686 ACPI_HANDLE GpeDevice,
688{
692
693
695
696
697 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
698
699 /* Ensure that we have a valid GPE number */
700
702 if (!GpeEventInfo)
703 {
705 goto UnlockAndExit;
706 }
707
709
710UnlockAndExit:
711 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
713}
714
716
717
718/*******************************************************************************
719 *
720 * FUNCTION: AcpiGetGpeStatus
721 *
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
725 * will be returned
726 *
727 * RETURN: Status
728 *
729 * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled)
730 *
731 ******************************************************************************/
732
735 ACPI_HANDLE GpeDevice,
737 ACPI_EVENT_STATUS *EventStatus)
738{
742
743
745
746
747 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
748
749 /* Ensure that we have a valid GPE number */
750
752 if (!GpeEventInfo)
753 {
755 goto UnlockAndExit;
756 }
757
758 /* Obtain status on the requested GPE number */
759
760 Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus);
761
762UnlockAndExit:
763 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
765}
766
768
769
770/*******************************************************************************
771 *
772 * FUNCTION: AcpiDispatchGpe
773 *
774 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
775 * GpeNumber - GPE level within the GPE block
776 *
777 * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
778 *
779 * DESCRIPTION: Detect and dispatch a General Purpose Event to either a function
780 * (e.g. EC) or method (e.g. _Lxx/_Exx) handler.
781 *
782 ******************************************************************************/
783
784UINT32
786 ACPI_HANDLE GpeDevice,
788{
789 ACPI_FUNCTION_TRACE(acpi_dispatch_gpe);
790
791 return (AcpiEvDetectGpe (GpeDevice, NULL, GpeNumber));
792}
793
795
796
797/*******************************************************************************
798 *
799 * FUNCTION: AcpiFinishGpe
800 *
801 * PARAMETERS: GpeDevice - Namespace node for the GPE Block
802 * (NULL for FADT defined GPEs)
803 * GpeNumber - GPE level within the GPE block
804 *
805 * RETURN: Status
806 *
807 * DESCRIPTION: Clear and conditionally re-enable a GPE. This completes the GPE
808 * processing. Intended for use by asynchronous host-installed
809 * GPE handlers. The GPE is only re-enabled if the EnableForRun bit
810 * is set in the GPE info.
811 *
812 ******************************************************************************/
813
816 ACPI_HANDLE GpeDevice,
818{
822
823
825
826
827 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
828
829 /* Ensure that we have a valid GPE number */
830
832 if (!GpeEventInfo)
833 {
835 goto UnlockAndExit;
836 }
837
839
840UnlockAndExit:
841 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
843}
844
846
847
848/******************************************************************************
849 *
850 * FUNCTION: AcpiDisableAllGpes
851 *
852 * PARAMETERS: None
853 *
854 * RETURN: Status
855 *
856 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
857 *
858 ******************************************************************************/
859
862 void)
863{
865
866
868
869
871 if (ACPI_FAILURE (Status))
872 {
874 }
875
878
880}
881
883
884
885/******************************************************************************
886 *
887 * FUNCTION: AcpiEnableAllRuntimeGpes
888 *
889 * PARAMETERS: None
890 *
891 * RETURN: Status
892 *
893 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
894 *
895 ******************************************************************************/
896
899 void)
900{
902
903
905
906
908 if (ACPI_FAILURE (Status))
909 {
911 }
912
915
917}
918
920
921
922/******************************************************************************
923 *
924 * FUNCTION: AcpiEnableAllWakeupGpes
925 *
926 * PARAMETERS: None
927 *
928 * RETURN: Status
929 *
930 * DESCRIPTION: Enable all "wakeup" GPEs and disable all of the other GPEs, in
931 * all GPE blocks.
932 *
933 ******************************************************************************/
934
937 void)
938{
940
941
943
944
946 if (ACPI_FAILURE (Status))
947 {
949 }
950
953
955}
956
958
959
960/******************************************************************************
961 *
962 * FUNCTION: AcpiAnyGpeStatusSet
963 *
964 * PARAMETERS: None
965 *
966 * RETURN: Whether or not the status bit is set for any GPE
967 *
968 * DESCRIPTION: Check the status bits of all enabled GPEs and return TRUE if any
969 * of them is set or FALSE otherwise.
970 *
971 ******************************************************************************/
972
973UINT32
975 void)
976{
978 UINT8 Ret;
979
980
982
984 if (ACPI_FAILURE (Status))
985 {
986 return (FALSE);
987 }
988
989 Ret = AcpiHwCheckAllGpes ();
991
992 return (Ret);
993}
994
996
997
998/*******************************************************************************
999 *
1000 * FUNCTION: AcpiInstallGpeBlock
1001 *
1002 * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device
1003 * GpeBlockAddress - Address and SpaceID
1004 * RegisterCount - Number of GPE register pairs in the block
1005 * InterruptNumber - H/W interrupt for the block
1006 *
1007 * RETURN: Status
1008 *
1009 * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not
1010 * enabled here.
1011 *
1012 ******************************************************************************/
1013
1016 ACPI_HANDLE GpeDevice,
1017 ACPI_GENERIC_ADDRESS *GpeBlockAddress,
1018 UINT32 RegisterCount,
1019 UINT32 InterruptNumber)
1020{
1022 ACPI_OPERAND_OBJECT *ObjDesc;
1024 ACPI_GPE_BLOCK_INFO *GpeBlock;
1025
1026
1028
1029
1030 if ((!GpeDevice) ||
1031 (!GpeBlockAddress) ||
1032 (!RegisterCount))
1033 {
1035 }
1036
1038 if (ACPI_FAILURE (Status))
1039 {
1041 }
1042
1043 Node = AcpiNsValidateHandle (GpeDevice);
1044 if (!Node)
1045 {
1047 goto UnlockAndExit;
1048 }
1049
1050 /* Validate the parent device */
1051
1052 if (Node->Type != ACPI_TYPE_DEVICE)
1053 {
1054 Status = AE_TYPE;
1055 goto UnlockAndExit;
1056 }
1057
1058 if (Node->Object)
1059 {
1061 goto UnlockAndExit;
1062 }
1063
1064 /*
1065 * For user-installed GPE Block Devices, the GpeBlockBaseNumber
1066 * is always zero
1067 */
1068 Status = AcpiEvCreateGpeBlock (Node, GpeBlockAddress->Address,
1069 GpeBlockAddress->SpaceId, RegisterCount,
1070 0, InterruptNumber, &GpeBlock);
1071 if (ACPI_FAILURE (Status))
1072 {
1073 goto UnlockAndExit;
1074 }
1075
1076 /* Install block in the DeviceObject attached to the node */
1077
1078 ObjDesc = AcpiNsGetAttachedObject (Node);
1079 if (!ObjDesc)
1080 {
1081 /*
1082 * No object, create a new one (Device nodes do not always have
1083 * an attached object)
1084 */
1086 if (!ObjDesc)
1087 {
1089 goto UnlockAndExit;
1090 }
1091
1093
1094 /* Remove local reference to the object */
1095
1096 AcpiUtRemoveReference (ObjDesc);
1097 if (ACPI_FAILURE (Status))
1098 {
1099 goto UnlockAndExit;
1100 }
1101 }
1102
1103 /* Now install the GPE block in the DeviceObject */
1104
1105 ObjDesc->Device.GpeBlock = GpeBlock;
1106
1107
1108UnlockAndExit:
1111}
1112
1114
1115
1116/*******************************************************************************
1117 *
1118 * FUNCTION: AcpiRemoveGpeBlock
1119 *
1120 * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device
1121 *
1122 * RETURN: Status
1123 *
1124 * DESCRIPTION: Remove a previously installed block of GPE registers
1125 *
1126 ******************************************************************************/
1127
1130 ACPI_HANDLE GpeDevice)
1131{
1132 ACPI_OPERAND_OBJECT *ObjDesc;
1135
1136
1138
1139
1140 if (!GpeDevice)
1141 {
1143 }
1144
1146 if (ACPI_FAILURE (Status))
1147 {
1149 }
1150
1151 Node = AcpiNsValidateHandle (GpeDevice);
1152 if (!Node)
1153 {
1155 goto UnlockAndExit;
1156 }
1157
1158 /* Validate the parent device */
1159
1160 if (Node->Type != ACPI_TYPE_DEVICE)
1161 {
1162 Status = AE_TYPE;
1163 goto UnlockAndExit;
1164 }
1165
1166 /* Get the DeviceObject attached to the node */
1167
1168 ObjDesc = AcpiNsGetAttachedObject (Node);
1169 if (!ObjDesc ||
1170 !ObjDesc->Device.GpeBlock)
1171 {
1173 }
1174
1175 /* Delete the GPE block (but not the DeviceObject) */
1176
1178 if (ACPI_SUCCESS (Status))
1179 {
1180 ObjDesc->Device.GpeBlock = NULL;
1181 }
1182
1183UnlockAndExit:
1186}
1187
1189
1190
1191/*******************************************************************************
1192 *
1193 * FUNCTION: AcpiGetGpeDevice
1194 *
1195 * PARAMETERS: Index - System GPE index (0-CurrentGpeCount)
1196 * GpeDevice - Where the parent GPE Device is returned
1197 *
1198 * RETURN: Status
1199 *
1200 * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
1201 * gpe device indicates that the gpe number is contained in one of
1202 * the FADT-defined gpe blocks. Otherwise, the GPE block device.
1203 *
1204 ******************************************************************************/
1205
1208 UINT32 Index,
1209 ACPI_HANDLE *GpeDevice)
1210{
1213
1214
1216
1217
1218 if (!GpeDevice)
1219 {
1221 }
1222
1223 if (Index >= AcpiCurrentGpeCount)
1224 {
1226 }
1227
1228 /* Setup and walk the GPE list */
1229
1230 Info.Index = Index;
1231 Info.Status = AE_NOT_EXIST;
1232 Info.GpeDevice = NULL;
1233 Info.NextBlockBaseIndex = 0;
1234
1236 if (ACPI_FAILURE (Status))
1237 {
1239 }
1240
1241 *GpeDevice = ACPI_CAST_PTR (ACPI_HANDLE, Info.GpeDevice);
1242 return_ACPI_STATUS (Info.Status);
1243}
1244
1246
1247#endif /* !ACPI_REDUCED_HARDWARE */
@ DeviceNode
Definition: Node.h:9
unsigned char BOOLEAN
unsigned char UINT8
unsigned int UINT32
#define ACPI_GPE_IS_POLLING_NEEDED(__gpe__)
Definition: acevents.h:59
ACPI_GPE_EVENT_INFO * GpeEventInfo
Definition: acevents.h:195
ACPI_GPE_EVENT_INFO UINT32 GpeNumber
Definition: acevents.h:196
#define AE_NO_HANDLER
Definition: acexcep.h:134
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
#define AE_BAD_PARAMETER
Definition: acexcep.h:151
#define AE_ALREADY_EXISTS
Definition: acexcep.h:115
#define AE_NULL_OBJECT
Definition: acexcep.h:117
#define AE_NO_MEMORY
Definition: acexcep.h:112
#define AE_NOT_EXIST
Definition: acexcep.h:114
#define AE_TYPE
Definition: acexcep.h:116
#define ACPI_SUCCESS(a)
Definition: acexcep.h:94
#define AE_OK
Definition: acexcep.h:97
#define ACPI_MTX_NAMESPACE
Definition: aclocal.h:85
#define ACPI_MTX_EVENTS
Definition: aclocal.h:87
ACPI_OPERAND_OBJECT * AcpiNsGetAttachedObject(ACPI_NAMESPACE_NODE *Node)
Definition: nsobject.c:308
ACPI_NAMESPACE_NODE * AcpiNsValidateHandle(ACPI_HANDLE Handle)
Definition: nsutils.c:655
ACPI_STATUS AcpiNsAttachObject(ACPI_NAMESPACE_NODE *Node, ACPI_OPERAND_OBJECT *Object, ACPI_OBJECT_TYPE Type)
Definition: nsobject.c:76
#define ACPI_MODULE_NAME(Name)
Definition: acoutput.h:216
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_FUNCTION_TRACE(a)
Definition: acoutput.h:480
#define ACPI_ERROR(plist)
Definition: acoutput.h:240
#define AE_INFO
Definition: acoutput.h:230
void AcpiOsReleaseLock(ACPI_SPINLOCK Handle, ACPI_CPU_FLAGS Flags)
Definition: osl.c:516
ACPI_CPU_FLAGS AcpiOsAcquireLock(ACPI_SPINLOCK Handle)
Definition: osl.c:498
#define ACPI_GPE_LEVEL_TRIGGERED
Definition: actypes.h:827
#define ACPI_GPE_ENABLE
Definition: actypes.h:803
#define ACPI_SET_BIT(target, bit)
Definition: actypes.h:533
#define ACPI_CPU_FLAGS
Definition: actypes.h:252
#define ACPI_FREE(a)
Definition: actypes.h:386
#define ACPI_GPE_DISPATCH_NONE
Definition: actypes.h:819
UINT32 ACPI_STATUS
Definition: actypes.h:460
#define ACPI_GPE_AUTO_ENABLED
Definition: actypes.h:832
#define ACPI_GPE_DISPATCH_TYPE(flags)
Definition: actypes.h:825
#define ACPI_GPE_CAN_WAKE
Definition: actypes.h:831
#define ACPI_GPE_DISABLE
Definition: actypes.h:804
#define ACPI_GPE_DISPATCH_NOTIFY
Definition: actypes.h:822
#define ACPI_TYPE_DEVICE
Definition: actypes.h:693
#define ACPI_CAST_PTR(t, p)
Definition: actypes.h:544
#define ACPI_EXPORT_SYMBOL(Symbol)
Definition: actypes.h:343
UINT32 ACPI_EVENT_STATUS
Definition: actypes.h:790
#define ACPI_ALLOCATE_ZEROED(a)
Definition: actypes.h:385
#define ACPI_CLEAR_BIT(target, bit)
Definition: actypes.h:534
#define ACPI_ROOT_OBJECT
Definition: actypes.h:500
#define AcpiUtCreateInternalObject(t)
Definition: acutils.h:681
ACPI_STATUS AcpiUtAcquireMutex(ACPI_MUTEX_HANDLE MutexId)
Definition: utmutex.c:256
ACPI_STATUS AcpiUtReleaseMutex(ACPI_MUTEX_HANDLE MutexId)
Definition: utmutex.c:348
void AcpiUtRemoveReference(ACPI_OPERAND_OBJECT *Object)
Definition: utdelete.c:790
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
BOOL WINAPI SHIM_OBJ_NAME() Notify(DWORD fdwReason, PVOID ptr)
union node Node
Definition: types.h:1255
ACPI_STATUS AcpiEvFinishGpe(ACPI_GPE_EVENT_INFO *GpeEventInfo)
Definition: evgpe.c:670
ACPI_GPE_EVENT_INFO * AcpiEvGetGpeEventInfo(ACPI_HANDLE GpeDevice, UINT32 GpeNumber)
Definition: evgpe.c:372
UINT32 AcpiEvGpeDetect(ACPI_GPE_XRUPT_INFO *GpeXruptList)
Definition: evgpe.c:433
ACPI_STATUS AcpiEvMaskGpe(ACPI_GPE_EVENT_INFO *GpeEventInfo, BOOLEAN IsMasked)
Definition: evgpe.c:156
UINT32 AcpiEvDetectGpe(ACPI_NAMESPACE_NODE *GpeDevice, ACPI_GPE_EVENT_INFO *GpeEventInfo, UINT32 GpeNumber)
Definition: evgpe.c:722
ACPI_STATUS AcpiEvRemoveGpeReference(ACPI_GPE_EVENT_INFO *GpeEventInfo)
Definition: evgpe.c:276
ACPI_STATUS AcpiEvAddGpeReference(ACPI_GPE_EVENT_INFO *GpeEventInfo, BOOLEAN ClearOnEnable)
Definition: evgpe.c:221
ACPI_STATUS AcpiEvInitializeGpeBlock(ACPI_GPE_XRUPT_INFO *GpeXruptInfo, ACPI_GPE_BLOCK_INFO *GpeBlock, void *Context)
Definition: evgpeblk.c:481
ACPI_STATUS AcpiEvDeleteGpeBlock(ACPI_GPE_BLOCK_INFO *GpeBlock)
Definition: evgpeblk.c:148
ACPI_STATUS AcpiEvCreateGpeBlock(ACPI_NAMESPACE_NODE *GpeDevice, UINT64 Address, UINT8 SpaceId, UINT32 RegisterCount, UINT16 GpeBlockBaseNumber, UINT32 InterruptNumber, ACPI_GPE_BLOCK_INFO **ReturnGpeBlock)
Definition: evgpeblk.c:371
ACPI_STATUS AcpiEvWalkGpeList(ACPI_GPE_CALLBACK GpeWalkCallback, void *Context)
Definition: evgpeutil.c:67
ACPI_STATUS AcpiEvGetGpeDevice(ACPI_GPE_XRUPT_INFO *GpeXruptInfo, ACPI_GPE_BLOCK_INFO *GpeBlock, void *Context)
Definition: evgpeutil.c:130
ACPI_STATUS AcpiClearGpe(ACPI_HANDLE GpeDevice, UINT32 GpeNumber)
Definition: evxfgpe.c:685
ACPI_STATUS AcpiUpdateAllGpes(void)
Definition: evxfgpe.c:79
UINT32 AcpiAnyGpeStatusSet(void)
Definition: evxfgpe.c:974
UINT32 AcpiDispatchGpe(ACPI_HANDLE GpeDevice, UINT32 GpeNumber)
Definition: evxfgpe.c:785
ACPI_STATUS AcpiMarkGpeForWake(ACPI_HANDLE GpeDevice, UINT32 GpeNumber)
Definition: evxfgpe.c:388
ACPI_STATUS AcpiEnableGpe(ACPI_HANDLE GpeDevice, UINT32 GpeNumber)
Definition: evxfgpe.c:137
ACPI_STATUS AcpiEnableAllRuntimeGpes(void)
Definition: evxfgpe.c:898
ACPI_STATUS AcpiDisableGpe(ACPI_HANDLE GpeDevice, UINT32 GpeNumber)
Definition: evxfgpe.c:203
ACPI_STATUS AcpiDisableAllGpes(void)
Definition: evxfgpe.c:861
ACPI_STATUS AcpiMaskGpe(ACPI_HANDLE GpeDevice, UINT32 GpeNumber, BOOLEAN IsMasked)
Definition: evxfgpe.c:332
ACPI_STATUS AcpiGetGpeDevice(UINT32 Index, ACPI_HANDLE *GpeDevice)
Definition: evxfgpe.c:1207
ACPI_STATUS AcpiSetGpe(ACPI_HANDLE GpeDevice, UINT32 GpeNumber, UINT8 Action)
Definition: evxfgpe.c:262
ACPI_STATUS AcpiInstallGpeBlock(ACPI_HANDLE GpeDevice, ACPI_GENERIC_ADDRESS *GpeBlockAddress, UINT32 RegisterCount, UINT32 InterruptNumber)
Definition: evxfgpe.c:1015
ACPI_STATUS AcpiSetGpeWakeMask(ACPI_HANDLE GpeDevice, UINT32 GpeNumber, UINT8 Action)
Definition: evxfgpe.c:599
ACPI_STATUS AcpiGetGpeStatus(ACPI_HANDLE GpeDevice, UINT32 GpeNumber, ACPI_EVENT_STATUS *EventStatus)
Definition: evxfgpe.c:734
ACPI_STATUS AcpiSetupGpeForWake(ACPI_HANDLE WakeDevice, ACPI_HANDLE GpeDevice, UINT32 GpeNumber)
Definition: evxfgpe.c:440
ACPI_STATUS AcpiEnableAllWakeupGpes(void)
Definition: evxfgpe.c:936
ACPI_STATUS AcpiRemoveGpeBlock(ACPI_HANDLE GpeDevice)
Definition: evxfgpe.c:1129
ACPI_STATUS AcpiFinishGpe(ACPI_HANDLE GpeDevice, UINT32 GpeNumber)
Definition: evxfgpe.c:815
Status
Definition: gdiplustypes.h:25
UINT32 AcpiHwGetGpeRegisterBit(ACPI_GPE_EVENT_INFO *GpeEventInfo)
Definition: hwgpe.c:81
ACPI_STATUS AcpiHwClearGpe(ACPI_GPE_EVENT_INFO *GpeEventInfo)
Definition: hwgpe.c:190
ACPI_STATUS AcpiHwEnableAllWakeupGpes(void)
Definition: hwgpe.c:649
ACPI_STATUS AcpiHwLowSetGpe(ACPI_GPE_EVENT_INFO *GpeEventInfo, UINT32 Action)
Definition: hwgpe.c:106
ACPI_STATUS AcpiHwDisableAllGpes(void)
Definition: hwgpe.c:595
UINT8 AcpiHwCheckAllGpes(void)
Definition: hwgpe.c:677
ACPI_STATUS AcpiHwEnableAllRuntimeGpes(void)
Definition: hwgpe.c:622
ACPI_STATUS AcpiHwGetGpeStatus(ACPI_GPE_EVENT_INFO *GpeEventInfo, ACPI_EVENT_STATUS *EventStatus)
Definition: hwgpe.c:233
struct acpi_gpe_register_info * RegisterInfo
Definition: aclocal.h:555
union acpi_gpe_dispatch_info Dispatch
Definition: aclocal.h:554
BOOLEAN DisableForDispatch
Definition: aclocal.h:559
struct acpi_gpe_notify_info * Next
Definition: aclocal.h:532
ACPI_NAMESPACE_NODE * DeviceNode
Definition: aclocal.h:531
ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_NOTIFY_INFO ACPI_GPE_BLOCK_INFO * GpeBlock
Definition: acobject.h:271
ACPI_GPE_NOTIFY_INFO * NotifyList
Definition: aclocal.h:544
ACPI_OBJECT_DEVICE Device
Definition: acobject.h:529
Definition: dlist.c:348
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:510
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170