xref: /freebsd/sys/contrib/dev/acpica/components/events/evxfgpe.c (revision ce3adf4362fcca6a43e500b2531f0038adbfbd21)
1 /******************************************************************************
2  *
3  * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs)
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2013, 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 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.
42  */
43 
44 
45 #define __EVXFGPE_C__
46 
47 #include <contrib/dev/acpica/include/acpi.h>
48 #include <contrib/dev/acpica/include/accommon.h>
49 #include <contrib/dev/acpica/include/acevents.h>
50 #include <contrib/dev/acpica/include/acnamesp.h>
51 
52 #define _COMPONENT          ACPI_EVENTS
53         ACPI_MODULE_NAME    ("evxfgpe")
54 
55 
56 #if (!ACPI_REDUCED_HARDWARE) /* Entire module */
57 /*******************************************************************************
58  *
59  * FUNCTION:    AcpiUpdateAllGpes
60  *
61  * PARAMETERS:  None
62  *
63  * RETURN:      Status
64  *
65  * DESCRIPTION: Complete GPE initialization and enable all GPEs that have
66  *              associated _Lxx or _Exx methods and are not pointed to by any
67  *              device _PRW methods (this indicates that these GPEs are
68  *              generally intended for system or device wakeup. Such GPEs
69  *              have to be enabled directly when the devices whose _PRW
70  *              methods point to them are set up for wakeup signaling.)
71  *
72  * NOTE: Should be called after any GPEs are added to the system. Primarily,
73  * after the system _PRW methods have been run, but also after a GPE Block
74  * Device has been added or if any new GPE methods have been added via a
75  * dynamic table load.
76  *
77  ******************************************************************************/
78 
79 ACPI_STATUS
80 AcpiUpdateAllGpes (
81     void)
82 {
83     ACPI_STATUS             Status;
84 
85 
86     ACPI_FUNCTION_TRACE (AcpiUpdateAllGpes);
87 
88 
89     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
90     if (ACPI_FAILURE (Status))
91     {
92         return_ACPI_STATUS (Status);
93     }
94 
95     if (AcpiGbl_AllGpesInitialized)
96     {
97         goto UnlockAndExit;
98     }
99 
100     Status = AcpiEvWalkGpeList (AcpiEvInitializeGpeBlock, NULL);
101     if (ACPI_SUCCESS (Status))
102     {
103         AcpiGbl_AllGpesInitialized = TRUE;
104     }
105 
106 UnlockAndExit:
107     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
108     return_ACPI_STATUS (Status);
109 }
110 
111 ACPI_EXPORT_SYMBOL (AcpiUpdateAllGpes)
112 
113 
114 /*******************************************************************************
115  *
116  * FUNCTION:    AcpiEnableGpe
117  *
118  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
119  *              GpeNumber           - GPE level within the GPE block
120  *
121  * RETURN:      Status
122  *
123  * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
124  *              hardware-enabled.
125  *
126  ******************************************************************************/
127 
128 ACPI_STATUS
129 AcpiEnableGpe (
130     ACPI_HANDLE             GpeDevice,
131     UINT32                  GpeNumber)
132 {
133     ACPI_STATUS             Status = AE_BAD_PARAMETER;
134     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
135     ACPI_CPU_FLAGS          Flags;
136 
137 
138     ACPI_FUNCTION_TRACE (AcpiEnableGpe);
139 
140 
141     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
142 
143     /* Ensure that we have a valid GPE number */
144 
145     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
146     if (GpeEventInfo)
147     {
148         Status = AcpiEvAddGpeReference (GpeEventInfo);
149     }
150 
151     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
152     return_ACPI_STATUS (Status);
153 }
154 
155 ACPI_EXPORT_SYMBOL (AcpiEnableGpe)
156 
157 
158 /*******************************************************************************
159  *
160  * FUNCTION:    AcpiDisableGpe
161  *
162  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
163  *              GpeNumber           - GPE level within the GPE block
164  *
165  * RETURN:      Status
166  *
167  * DESCRIPTION: Remove a reference to a GPE. When the last reference is
168  *              removed, only then is the GPE disabled (for runtime GPEs), or
169  *              the GPE mask bit disabled (for wake GPEs)
170  *
171  ******************************************************************************/
172 
173 ACPI_STATUS
174 AcpiDisableGpe (
175     ACPI_HANDLE             GpeDevice,
176     UINT32                  GpeNumber)
177 {
178     ACPI_STATUS             Status = AE_BAD_PARAMETER;
179     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
180     ACPI_CPU_FLAGS          Flags;
181 
182 
183     ACPI_FUNCTION_TRACE (AcpiDisableGpe);
184 
185 
186     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
187 
188     /* Ensure that we have a valid GPE number */
189 
190     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
191     if (GpeEventInfo)
192     {
193         Status = AcpiEvRemoveGpeReference (GpeEventInfo);
194     }
195 
196     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
197     return_ACPI_STATUS (Status);
198 }
199 
200 ACPI_EXPORT_SYMBOL (AcpiDisableGpe)
201 
202 
203 /*******************************************************************************
204  *
205  * FUNCTION:    AcpiSetGpe
206  *
207  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
208  *              GpeNumber           - GPE level within the GPE block
209  *              Action              - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
210  *
211  * RETURN:      Status
212  *
213  * DESCRIPTION: Enable or disable an individual GPE. This function bypasses
214  *              the reference count mechanism used in the AcpiEnableGpe and
215  *              AcpiDisableGpe interfaces -- and should be used with care.
216  *
217  * Note: Typically used to disable a runtime GPE for short period of time,
218  * then re-enable it, without disturbing the existing reference counts. This
219  * is useful, for example, in the Embedded Controller (EC) driver.
220  *
221  ******************************************************************************/
222 
223 ACPI_STATUS
224 AcpiSetGpe (
225     ACPI_HANDLE             GpeDevice,
226     UINT32                  GpeNumber,
227     UINT8                   Action)
228 {
229     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
230     ACPI_STATUS             Status;
231     ACPI_CPU_FLAGS          Flags;
232 
233 
234     ACPI_FUNCTION_TRACE (AcpiSetGpe);
235 
236 
237     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
238 
239     /* Ensure that we have a valid GPE number */
240 
241     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
242     if (!GpeEventInfo)
243     {
244         Status = AE_BAD_PARAMETER;
245         goto UnlockAndExit;
246     }
247 
248     /* Perform the action */
249 
250     switch (Action)
251     {
252     case ACPI_GPE_ENABLE:
253 
254         Status = AcpiEvEnableGpe (GpeEventInfo);
255         break;
256 
257     case ACPI_GPE_DISABLE:
258 
259         Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
260         break;
261 
262     default:
263 
264         Status = AE_BAD_PARAMETER;
265         break;
266     }
267 
268 UnlockAndExit:
269     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
270     return_ACPI_STATUS (Status);
271 }
272 
273 ACPI_EXPORT_SYMBOL (AcpiSetGpe)
274 
275 
276 /*******************************************************************************
277  *
278  * FUNCTION:    AcpiSetupGpeForWake
279  *
280  * PARAMETERS:  WakeDevice          - Device associated with the GPE (via _PRW)
281  *              GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
282  *              GpeNumber           - GPE level within the GPE block
283  *
284  * RETURN:      Status
285  *
286  * DESCRIPTION: Mark a GPE as having the ability to wake the system. This
287  *              interface is intended to be used as the host executes the
288  *              _PRW methods (Power Resources for Wake) in the system tables.
289  *              Each _PRW appears under a Device Object (The WakeDevice), and
290  *              contains the info for the wake GPE associated with the
291  *              WakeDevice.
292  *
293  ******************************************************************************/
294 
295 ACPI_STATUS
296 AcpiSetupGpeForWake (
297     ACPI_HANDLE             WakeDevice,
298     ACPI_HANDLE             GpeDevice,
299     UINT32                  GpeNumber)
300 {
301     ACPI_STATUS             Status;
302     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
303     ACPI_NAMESPACE_NODE     *DeviceNode;
304     ACPI_GPE_NOTIFY_INFO    *Notify;
305     ACPI_GPE_NOTIFY_INFO    *NewNotify;
306     ACPI_CPU_FLAGS          Flags;
307 
308 
309     ACPI_FUNCTION_TRACE (AcpiSetupGpeForWake);
310 
311 
312     /* Parameter Validation */
313 
314     if (!WakeDevice)
315     {
316         /*
317          * By forcing WakeDevice to be valid, we automatically enable the
318          * implicit notify feature on all hosts.
319          */
320         return_ACPI_STATUS (AE_BAD_PARAMETER);
321     }
322 
323     /* Handle root object case */
324 
325     if (WakeDevice == ACPI_ROOT_OBJECT)
326     {
327         DeviceNode = AcpiGbl_RootNode;
328     }
329     else
330     {
331         DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, WakeDevice);
332     }
333 
334     /* Validate WakeDevice is of type Device */
335 
336     if (DeviceNode->Type != ACPI_TYPE_DEVICE)
337     {
338         return_ACPI_STATUS (AE_BAD_PARAMETER);
339     }
340 
341     /*
342      * Allocate a new notify object up front, in case it is needed.
343      * Memory allocation while holding a spinlock is a big no-no
344      * on some hosts.
345      */
346     NewNotify = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_NOTIFY_INFO));
347     if (!NewNotify)
348     {
349         return_ACPI_STATUS (AE_NO_MEMORY);
350     }
351 
352     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
353 
354     /* Ensure that we have a valid GPE number */
355 
356     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
357     if (!GpeEventInfo)
358     {
359         Status = AE_BAD_PARAMETER;
360         goto UnlockAndExit;
361     }
362 
363     /*
364      * If there is no method or handler for this GPE, then the
365      * WakeDevice will be notified whenever this GPE fires. This is
366      * known as an "implicit notify". Note: The GPE is assumed to be
367      * level-triggered (for windows compatibility).
368      */
369     if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
370             ACPI_GPE_DISPATCH_NONE)
371     {
372         /*
373          * This is the first device for implicit notify on this GPE.
374          * Just set the flags here, and enter the NOTIFY block below.
375          */
376         GpeEventInfo->Flags =
377             (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED);
378     }
379 
380     /*
381      * If we already have an implicit notify on this GPE, add
382      * this device to the notify list.
383      */
384     if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
385             ACPI_GPE_DISPATCH_NOTIFY)
386     {
387         /* Ensure that the device is not already in the list */
388 
389         Notify = GpeEventInfo->Dispatch.NotifyList;
390         while (Notify)
391         {
392             if (Notify->DeviceNode == DeviceNode)
393             {
394                 Status = AE_ALREADY_EXISTS;
395                 goto UnlockAndExit;
396             }
397             Notify = Notify->Next;
398         }
399 
400         /* Add this device to the notify list for this GPE */
401 
402         NewNotify->DeviceNode = DeviceNode;
403         NewNotify->Next = GpeEventInfo->Dispatch.NotifyList;
404         GpeEventInfo->Dispatch.NotifyList = NewNotify;
405         NewNotify = NULL;
406     }
407 
408     /* Mark the GPE as a possible wake event */
409 
410     GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
411     Status = AE_OK;
412 
413 
414 UnlockAndExit:
415     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
416 
417     /* Delete the notify object if it was not used above */
418 
419     if (NewNotify)
420     {
421         ACPI_FREE (NewNotify);
422     }
423     return_ACPI_STATUS (Status);
424 }
425 
426 ACPI_EXPORT_SYMBOL (AcpiSetupGpeForWake)
427 
428 
429 /*******************************************************************************
430  *
431  * FUNCTION:    AcpiSetGpeWakeMask
432  *
433  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
434  *              GpeNumber           - GPE level within the GPE block
435  *              Action              - Enable or Disable
436  *
437  * RETURN:      Status
438  *
439  * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must
440  *              already be marked as a WAKE GPE.
441  *
442  ******************************************************************************/
443 
444 ACPI_STATUS
445 AcpiSetGpeWakeMask (
446     ACPI_HANDLE             GpeDevice,
447     UINT32                  GpeNumber,
448     UINT8                   Action)
449 {
450     ACPI_STATUS             Status = AE_OK;
451     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
452     ACPI_GPE_REGISTER_INFO  *GpeRegisterInfo;
453     ACPI_CPU_FLAGS          Flags;
454     UINT32                  RegisterBit;
455 
456 
457     ACPI_FUNCTION_TRACE (AcpiSetGpeWakeMask);
458 
459 
460     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
461 
462     /*
463      * Ensure that we have a valid GPE number and that this GPE is in
464      * fact a wake GPE
465      */
466     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
467     if (!GpeEventInfo)
468     {
469         Status = AE_BAD_PARAMETER;
470         goto UnlockAndExit;
471     }
472 
473     if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE))
474     {
475         Status = AE_TYPE;
476         goto UnlockAndExit;
477     }
478 
479     GpeRegisterInfo = GpeEventInfo->RegisterInfo;
480     if (!GpeRegisterInfo)
481     {
482         Status = AE_NOT_EXIST;
483         goto UnlockAndExit;
484     }
485 
486     RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo);
487 
488     /* Perform the action */
489 
490     switch (Action)
491     {
492     case ACPI_GPE_ENABLE:
493 
494         ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
495         break;
496 
497     case ACPI_GPE_DISABLE:
498 
499         ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
500         break;
501 
502     default:
503 
504         ACPI_ERROR ((AE_INFO, "%u, Invalid action", Action));
505         Status = AE_BAD_PARAMETER;
506         break;
507     }
508 
509 UnlockAndExit:
510     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
511     return_ACPI_STATUS (Status);
512 }
513 
514 ACPI_EXPORT_SYMBOL (AcpiSetGpeWakeMask)
515 
516 
517 /*******************************************************************************
518  *
519  * FUNCTION:    AcpiClearGpe
520  *
521  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
522  *              GpeNumber           - GPE level within the GPE block
523  *
524  * RETURN:      Status
525  *
526  * DESCRIPTION: Clear an ACPI event (general purpose)
527  *
528  ******************************************************************************/
529 
530 ACPI_STATUS
531 AcpiClearGpe (
532     ACPI_HANDLE             GpeDevice,
533     UINT32                  GpeNumber)
534 {
535     ACPI_STATUS             Status = AE_OK;
536     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
537     ACPI_CPU_FLAGS          Flags;
538 
539 
540     ACPI_FUNCTION_TRACE (AcpiClearGpe);
541 
542 
543     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
544 
545     /* Ensure that we have a valid GPE number */
546 
547     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
548     if (!GpeEventInfo)
549     {
550         Status = AE_BAD_PARAMETER;
551         goto UnlockAndExit;
552     }
553 
554     Status = AcpiHwClearGpe (GpeEventInfo);
555 
556 UnlockAndExit:
557     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
558     return_ACPI_STATUS (Status);
559 }
560 
561 ACPI_EXPORT_SYMBOL (AcpiClearGpe)
562 
563 
564 /*******************************************************************************
565  *
566  * FUNCTION:    AcpiGetGpeStatus
567  *
568  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
569  *              GpeNumber           - GPE level within the GPE block
570  *              EventStatus         - Where the current status of the event
571  *                                    will be returned
572  *
573  * RETURN:      Status
574  *
575  * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled)
576  *
577  ******************************************************************************/
578 
579 ACPI_STATUS
580 AcpiGetGpeStatus (
581     ACPI_HANDLE             GpeDevice,
582     UINT32                  GpeNumber,
583     ACPI_EVENT_STATUS       *EventStatus)
584 {
585     ACPI_STATUS             Status = AE_OK;
586     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
587     ACPI_CPU_FLAGS          Flags;
588 
589 
590     ACPI_FUNCTION_TRACE (AcpiGetGpeStatus);
591 
592 
593     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
594 
595     /* Ensure that we have a valid GPE number */
596 
597     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
598     if (!GpeEventInfo)
599     {
600         Status = AE_BAD_PARAMETER;
601         goto UnlockAndExit;
602     }
603 
604     /* Obtain status on the requested GPE number */
605 
606     Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus);
607 
608 UnlockAndExit:
609     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
610     return_ACPI_STATUS (Status);
611 }
612 
613 ACPI_EXPORT_SYMBOL (AcpiGetGpeStatus)
614 
615 
616 /*******************************************************************************
617  *
618  * FUNCTION:    AcpiFinishGpe
619  *
620  * PARAMETERS:  GpeDevice           - Namespace node for the GPE Block
621  *                                    (NULL for FADT defined GPEs)
622  *              GpeNumber           - GPE level within the GPE block
623  *
624  * RETURN:      Status
625  *
626  * DESCRIPTION: Clear and conditionally reenable a GPE. This completes the GPE
627  *              processing. Intended for use by asynchronous host-installed
628  *              GPE handlers. The GPE is only reenabled if the EnableForRun bit
629  *              is set in the GPE info.
630  *
631  ******************************************************************************/
632 
633 ACPI_STATUS
634 AcpiFinishGpe (
635     ACPI_HANDLE             GpeDevice,
636     UINT32                  GpeNumber)
637 {
638     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
639     ACPI_STATUS             Status;
640     ACPI_CPU_FLAGS          Flags;
641 
642 
643     ACPI_FUNCTION_TRACE (AcpiFinishGpe);
644 
645 
646     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
647 
648     /* Ensure that we have a valid GPE number */
649 
650     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
651     if (!GpeEventInfo)
652     {
653         Status = AE_BAD_PARAMETER;
654         goto UnlockAndExit;
655     }
656 
657     Status = AcpiEvFinishGpe (GpeEventInfo);
658 
659 UnlockAndExit:
660     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
661     return_ACPI_STATUS (Status);
662 }
663 
664 ACPI_EXPORT_SYMBOL (AcpiFinishGpe)
665 
666 
667 /******************************************************************************
668  *
669  * FUNCTION:    AcpiDisableAllGpes
670  *
671  * PARAMETERS:  None
672  *
673  * RETURN:      Status
674  *
675  * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
676  *
677  ******************************************************************************/
678 
679 ACPI_STATUS
680 AcpiDisableAllGpes (
681     void)
682 {
683     ACPI_STATUS             Status;
684 
685 
686     ACPI_FUNCTION_TRACE (AcpiDisableAllGpes);
687 
688 
689     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
690     if (ACPI_FAILURE (Status))
691     {
692         return_ACPI_STATUS (Status);
693     }
694 
695     Status = AcpiHwDisableAllGpes ();
696     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
697 
698     return_ACPI_STATUS (Status);
699 }
700 
701 ACPI_EXPORT_SYMBOL (AcpiDisableAllGpes)
702 
703 
704 /******************************************************************************
705  *
706  * FUNCTION:    AcpiEnableAllRuntimeGpes
707  *
708  * PARAMETERS:  None
709  *
710  * RETURN:      Status
711  *
712  * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
713  *
714  ******************************************************************************/
715 
716 ACPI_STATUS
717 AcpiEnableAllRuntimeGpes (
718     void)
719 {
720     ACPI_STATUS             Status;
721 
722 
723     ACPI_FUNCTION_TRACE (AcpiEnableAllRuntimeGpes);
724 
725 
726     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
727     if (ACPI_FAILURE (Status))
728     {
729         return_ACPI_STATUS (Status);
730     }
731 
732     Status = AcpiHwEnableAllRuntimeGpes ();
733     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
734 
735     return_ACPI_STATUS (Status);
736 }
737 
738 ACPI_EXPORT_SYMBOL (AcpiEnableAllRuntimeGpes)
739 
740 
741 /*******************************************************************************
742  *
743  * FUNCTION:    AcpiInstallGpeBlock
744  *
745  * PARAMETERS:  GpeDevice           - Handle to the parent GPE Block Device
746  *              GpeBlockAddress     - Address and SpaceID
747  *              RegisterCount       - Number of GPE register pairs in the block
748  *              InterruptNumber     - H/W interrupt for the block
749  *
750  * RETURN:      Status
751  *
752  * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not
753  *              enabled here.
754  *
755  ******************************************************************************/
756 
757 ACPI_STATUS
758 AcpiInstallGpeBlock (
759     ACPI_HANDLE             GpeDevice,
760     ACPI_GENERIC_ADDRESS    *GpeBlockAddress,
761     UINT32                  RegisterCount,
762     UINT32                  InterruptNumber)
763 {
764     ACPI_STATUS             Status;
765     ACPI_OPERAND_OBJECT     *ObjDesc;
766     ACPI_NAMESPACE_NODE     *Node;
767     ACPI_GPE_BLOCK_INFO     *GpeBlock;
768 
769 
770     ACPI_FUNCTION_TRACE (AcpiInstallGpeBlock);
771 
772 
773     if ((!GpeDevice)       ||
774         (!GpeBlockAddress) ||
775         (!RegisterCount))
776     {
777         return_ACPI_STATUS (AE_BAD_PARAMETER);
778     }
779 
780     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
781     if (ACPI_FAILURE (Status))
782     {
783         return_ACPI_STATUS (Status);
784     }
785 
786     Node = AcpiNsValidateHandle (GpeDevice);
787     if (!Node)
788     {
789         Status = AE_BAD_PARAMETER;
790         goto UnlockAndExit;
791     }
792 
793     /*
794      * For user-installed GPE Block Devices, the GpeBlockBaseNumber
795      * is always zero
796      */
797     Status = AcpiEvCreateGpeBlock (Node, GpeBlockAddress, RegisterCount,
798                 0, InterruptNumber, &GpeBlock);
799     if (ACPI_FAILURE (Status))
800     {
801         goto UnlockAndExit;
802     }
803 
804     /* Install block in the DeviceObject attached to the node */
805 
806     ObjDesc = AcpiNsGetAttachedObject (Node);
807     if (!ObjDesc)
808     {
809         /*
810          * No object, create a new one (Device nodes do not always have
811          * an attached object)
812          */
813         ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_DEVICE);
814         if (!ObjDesc)
815         {
816             Status = AE_NO_MEMORY;
817             goto UnlockAndExit;
818         }
819 
820         Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_DEVICE);
821 
822         /* Remove local reference to the object */
823 
824         AcpiUtRemoveReference (ObjDesc);
825         if (ACPI_FAILURE (Status))
826         {
827             goto UnlockAndExit;
828         }
829     }
830 
831     /* Now install the GPE block in the DeviceObject */
832 
833     ObjDesc->Device.GpeBlock = GpeBlock;
834 
835 
836 UnlockAndExit:
837     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
838     return_ACPI_STATUS (Status);
839 }
840 
841 ACPI_EXPORT_SYMBOL (AcpiInstallGpeBlock)
842 
843 
844 /*******************************************************************************
845  *
846  * FUNCTION:    AcpiRemoveGpeBlock
847  *
848  * PARAMETERS:  GpeDevice           - Handle to the parent GPE Block Device
849  *
850  * RETURN:      Status
851  *
852  * DESCRIPTION: Remove a previously installed block of GPE registers
853  *
854  ******************************************************************************/
855 
856 ACPI_STATUS
857 AcpiRemoveGpeBlock (
858     ACPI_HANDLE             GpeDevice)
859 {
860     ACPI_OPERAND_OBJECT     *ObjDesc;
861     ACPI_STATUS             Status;
862     ACPI_NAMESPACE_NODE     *Node;
863 
864 
865     ACPI_FUNCTION_TRACE (AcpiRemoveGpeBlock);
866 
867 
868     if (!GpeDevice)
869     {
870         return_ACPI_STATUS (AE_BAD_PARAMETER);
871     }
872 
873     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
874     if (ACPI_FAILURE (Status))
875     {
876         return_ACPI_STATUS (Status);
877     }
878 
879     Node = AcpiNsValidateHandle (GpeDevice);
880     if (!Node)
881     {
882         Status = AE_BAD_PARAMETER;
883         goto UnlockAndExit;
884     }
885 
886     /* Get the DeviceObject attached to the node */
887 
888     ObjDesc = AcpiNsGetAttachedObject (Node);
889     if (!ObjDesc ||
890         !ObjDesc->Device.GpeBlock)
891     {
892         return_ACPI_STATUS (AE_NULL_OBJECT);
893     }
894 
895     /* Delete the GPE block (but not the DeviceObject) */
896 
897     Status = AcpiEvDeleteGpeBlock (ObjDesc->Device.GpeBlock);
898     if (ACPI_SUCCESS (Status))
899     {
900         ObjDesc->Device.GpeBlock = NULL;
901     }
902 
903 UnlockAndExit:
904     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
905     return_ACPI_STATUS (Status);
906 }
907 
908 ACPI_EXPORT_SYMBOL (AcpiRemoveGpeBlock)
909 
910 
911 /*******************************************************************************
912  *
913  * FUNCTION:    AcpiGetGpeDevice
914  *
915  * PARAMETERS:  Index               - System GPE index (0-CurrentGpeCount)
916  *              GpeDevice           - Where the parent GPE Device is returned
917  *
918  * RETURN:      Status
919  *
920  * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
921  *              gpe device indicates that the gpe number is contained in one of
922  *              the FADT-defined gpe blocks. Otherwise, the GPE block device.
923  *
924  ******************************************************************************/
925 
926 ACPI_STATUS
927 AcpiGetGpeDevice (
928     UINT32                  Index,
929     ACPI_HANDLE             *GpeDevice)
930 {
931     ACPI_GPE_DEVICE_INFO    Info;
932     ACPI_STATUS             Status;
933 
934 
935     ACPI_FUNCTION_TRACE (AcpiGetGpeDevice);
936 
937 
938     if (!GpeDevice)
939     {
940         return_ACPI_STATUS (AE_BAD_PARAMETER);
941     }
942 
943     if (Index >= AcpiCurrentGpeCount)
944     {
945         return_ACPI_STATUS (AE_NOT_EXIST);
946     }
947 
948     /* Setup and walk the GPE list */
949 
950     Info.Index = Index;
951     Info.Status = AE_NOT_EXIST;
952     Info.GpeDevice = NULL;
953     Info.NextBlockBaseIndex = 0;
954 
955     Status = AcpiEvWalkGpeList (AcpiEvGetGpeDevice, &Info);
956     if (ACPI_FAILURE (Status))
957     {
958         return_ACPI_STATUS (Status);
959     }
960 
961     *GpeDevice = ACPI_CAST_PTR (ACPI_HANDLE, Info.GpeDevice);
962     return_ACPI_STATUS (Info.Status);
963 }
964 
965 ACPI_EXPORT_SYMBOL (AcpiGetGpeDevice)
966 
967 #endif /* !ACPI_REDUCED_HARDWARE */
968