]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/contrib/dev/acpica/components/events/evxfgpe.c
Merge ACPICA 20120620.
[FreeBSD/FreeBSD.git] / sys / contrib / dev / acpica / components / events / evxfgpe.c
1 /******************************************************************************
2  *
3  * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs)
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2012, 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 (AcpiUpdateGpes);
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         Status = AcpiEvEnableGpe (GpeEventInfo);
254         break;
255
256     case ACPI_GPE_DISABLE:
257         Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
258         break;
259
260     default:
261         Status = AE_BAD_PARAMETER;
262         break;
263     }
264
265 UnlockAndExit:
266     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
267     return_ACPI_STATUS (Status);
268 }
269
270 ACPI_EXPORT_SYMBOL (AcpiSetGpe)
271
272
273 /*******************************************************************************
274  *
275  * FUNCTION:    AcpiSetupGpeForWake
276  *
277  * PARAMETERS:  WakeDevice          - Device associated with the GPE (via _PRW)
278  *              GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
279  *              GpeNumber           - GPE level within the GPE block
280  *
281  * RETURN:      Status
282  *
283  * DESCRIPTION: Mark a GPE as having the ability to wake the system. This
284  *              interface is intended to be used as the host executes the
285  *              _PRW methods (Power Resources for Wake) in the system tables.
286  *              Each _PRW appears under a Device Object (The WakeDevice), and
287  *              contains the info for the wake GPE associated with the
288  *              WakeDevice.
289  *
290  ******************************************************************************/
291
292 ACPI_STATUS
293 AcpiSetupGpeForWake (
294     ACPI_HANDLE             WakeDevice,
295     ACPI_HANDLE             GpeDevice,
296     UINT32                  GpeNumber)
297 {
298     ACPI_STATUS             Status;
299     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
300     ACPI_NAMESPACE_NODE     *DeviceNode;
301     ACPI_GPE_NOTIFY_INFO    *Notify;
302     ACPI_CPU_FLAGS          Flags;
303
304
305     ACPI_FUNCTION_TRACE (AcpiSetupGpeForWake);
306
307
308     /* Parameter Validation */
309
310     if (!WakeDevice)
311     {
312         /*
313          * By forcing WakeDevice to be valid, we automatically enable the
314          * implicit notify feature on all hosts.
315          */
316         return_ACPI_STATUS (AE_BAD_PARAMETER);
317     }
318
319     /* Handle root object case */
320
321     if (WakeDevice == ACPI_ROOT_OBJECT)
322     {
323         DeviceNode = AcpiGbl_RootNode;
324     }
325     else
326     {
327         DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, WakeDevice);
328     }
329
330     /* Validate WakeDevice is of type Device */
331
332     if (DeviceNode->Type != ACPI_TYPE_DEVICE)
333     {
334         return_ACPI_STATUS (AE_BAD_PARAMETER);
335     }
336
337     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
338
339     /* Ensure that we have a valid GPE number */
340
341     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
342     if (!GpeEventInfo)
343     {
344         Status = AE_BAD_PARAMETER;
345         goto UnlockAndExit;
346     }
347
348     /*
349      * If there is no method or handler for this GPE, then the
350      * WakeDevice will be notified whenever this GPE fires. This is
351      * known as an "implicit notify". Note: The GPE is assumed to be
352      * level-triggered (for windows compatibility).
353      */
354     if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
355             ACPI_GPE_DISPATCH_NONE)
356     {
357         /*
358          * This is the first device for implicit notify on this GPE.
359          * Just set the flags here, and enter the NOTIFY block below.
360          */
361         GpeEventInfo->Flags =
362             (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED);
363     }
364
365     /*
366      * If we already have an implicit notify on this GPE, add
367      * this device to the notify list.
368      */
369     if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
370             ACPI_GPE_DISPATCH_NOTIFY)
371     {
372         /* Ensure that the device is not already in the list */
373
374         Notify = GpeEventInfo->Dispatch.NotifyList;
375         while (Notify)
376         {
377             if (Notify->DeviceNode == DeviceNode)
378             {
379                 Status = AE_ALREADY_EXISTS;
380                 goto UnlockAndExit;
381             }
382             Notify = Notify->Next;
383         }
384
385         /* Add this device to the notify list for this GPE */
386
387         Notify = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_NOTIFY_INFO));
388         if (!Notify)
389         {
390             Status = AE_NO_MEMORY;
391             goto UnlockAndExit;
392         }
393
394         Notify->DeviceNode = DeviceNode;
395         Notify->Next = GpeEventInfo->Dispatch.NotifyList;
396         GpeEventInfo->Dispatch.NotifyList = Notify;
397     }
398
399     /* Mark the GPE as a possible wake event */
400
401     GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
402     Status = AE_OK;
403
404 UnlockAndExit:
405     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
406     return_ACPI_STATUS (Status);
407 }
408
409 ACPI_EXPORT_SYMBOL (AcpiSetupGpeForWake)
410
411
412 /*******************************************************************************
413  *
414  * FUNCTION:    AcpiSetGpeWakeMask
415  *
416  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
417  *              GpeNumber           - GPE level within the GPE block
418  *              Action              - Enable or Disable
419  *
420  * RETURN:      Status
421  *
422  * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must
423  *              already be marked as a WAKE GPE.
424  *
425  ******************************************************************************/
426
427 ACPI_STATUS
428 AcpiSetGpeWakeMask (
429     ACPI_HANDLE             GpeDevice,
430     UINT32                  GpeNumber,
431     UINT8                   Action)
432 {
433     ACPI_STATUS             Status = AE_OK;
434     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
435     ACPI_GPE_REGISTER_INFO  *GpeRegisterInfo;
436     ACPI_CPU_FLAGS          Flags;
437     UINT32                  RegisterBit;
438
439
440     ACPI_FUNCTION_TRACE (AcpiSetGpeWakeMask);
441
442
443     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
444
445     /*
446      * Ensure that we have a valid GPE number and that this GPE is in
447      * fact a wake GPE
448      */
449     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
450     if (!GpeEventInfo)
451     {
452         Status = AE_BAD_PARAMETER;
453         goto UnlockAndExit;
454     }
455
456     if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE))
457     {
458         Status = AE_TYPE;
459         goto UnlockAndExit;
460     }
461
462     GpeRegisterInfo = GpeEventInfo->RegisterInfo;
463     if (!GpeRegisterInfo)
464     {
465         Status = AE_NOT_EXIST;
466         goto UnlockAndExit;
467     }
468
469     RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo, GpeRegisterInfo);
470
471     /* Perform the action */
472
473     switch (Action)
474     {
475     case ACPI_GPE_ENABLE:
476         ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
477         break;
478
479     case ACPI_GPE_DISABLE:
480         ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
481         break;
482
483     default:
484         ACPI_ERROR ((AE_INFO, "%u, Invalid action", Action));
485         Status = AE_BAD_PARAMETER;
486         break;
487     }
488
489 UnlockAndExit:
490     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
491     return_ACPI_STATUS (Status);
492 }
493
494 ACPI_EXPORT_SYMBOL (AcpiSetGpeWakeMask)
495
496
497 /*******************************************************************************
498  *
499  * FUNCTION:    AcpiClearGpe
500  *
501  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
502  *              GpeNumber           - GPE level within the GPE block
503  *
504  * RETURN:      Status
505  *
506  * DESCRIPTION: Clear an ACPI event (general purpose)
507  *
508  ******************************************************************************/
509
510 ACPI_STATUS
511 AcpiClearGpe (
512     ACPI_HANDLE             GpeDevice,
513     UINT32                  GpeNumber)
514 {
515     ACPI_STATUS             Status = AE_OK;
516     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
517     ACPI_CPU_FLAGS          Flags;
518
519
520     ACPI_FUNCTION_TRACE (AcpiClearGpe);
521
522
523     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
524
525     /* Ensure that we have a valid GPE number */
526
527     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
528     if (!GpeEventInfo)
529     {
530         Status = AE_BAD_PARAMETER;
531         goto UnlockAndExit;
532     }
533
534     Status = AcpiHwClearGpe (GpeEventInfo);
535
536 UnlockAndExit:
537     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
538     return_ACPI_STATUS (Status);
539 }
540
541 ACPI_EXPORT_SYMBOL (AcpiClearGpe)
542
543
544 /*******************************************************************************
545  *
546  * FUNCTION:    AcpiGetGpeStatus
547  *
548  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
549  *              GpeNumber           - GPE level within the GPE block
550  *              EventStatus         - Where the current status of the event
551  *                                    will be returned
552  *
553  * RETURN:      Status
554  *
555  * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled)
556  *
557  ******************************************************************************/
558
559 ACPI_STATUS
560 AcpiGetGpeStatus (
561     ACPI_HANDLE             GpeDevice,
562     UINT32                  GpeNumber,
563     ACPI_EVENT_STATUS       *EventStatus)
564 {
565     ACPI_STATUS             Status = AE_OK;
566     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
567     ACPI_CPU_FLAGS          Flags;
568
569
570     ACPI_FUNCTION_TRACE (AcpiGetGpeStatus);
571
572
573     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
574
575     /* Ensure that we have a valid GPE number */
576
577     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
578     if (!GpeEventInfo)
579     {
580         Status = AE_BAD_PARAMETER;
581         goto UnlockAndExit;
582     }
583
584     /* Obtain status on the requested GPE number */
585
586     Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus);
587
588 UnlockAndExit:
589     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
590     return_ACPI_STATUS (Status);
591 }
592
593 ACPI_EXPORT_SYMBOL (AcpiGetGpeStatus)
594
595
596 /*******************************************************************************
597  *
598  * FUNCTION:    AcpiFinishGpe
599  *
600  * PARAMETERS:  GpeDevice           - Namespace node for the GPE Block
601  *                                    (NULL for FADT defined GPEs)
602  *              GpeNumber           - GPE level within the GPE block
603  *
604  * RETURN:      Status
605  *
606  * DESCRIPTION: Clear and conditionally reenable a GPE. This completes the GPE
607  *              processing. Intended for use by asynchronous host-installed
608  *              GPE handlers. The GPE is only reenabled if the EnableForRun bit
609  *              is set in the GPE info.
610  *
611  ******************************************************************************/
612
613 ACPI_STATUS
614 AcpiFinishGpe (
615     ACPI_HANDLE             GpeDevice,
616     UINT32                  GpeNumber)
617 {
618     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
619     ACPI_STATUS             Status;
620     ACPI_CPU_FLAGS          Flags;
621
622
623     ACPI_FUNCTION_TRACE (AcpiFinishGpe);
624
625
626     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
627
628     /* Ensure that we have a valid GPE number */
629
630     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
631     if (!GpeEventInfo)
632     {
633         Status = AE_BAD_PARAMETER;
634         goto UnlockAndExit;
635     }
636
637     Status = AcpiEvFinishGpe (GpeEventInfo);
638
639 UnlockAndExit:
640     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
641     return_ACPI_STATUS (Status);
642 }
643
644 ACPI_EXPORT_SYMBOL (AcpiFinishGpe)
645
646
647 /******************************************************************************
648  *
649  * FUNCTION:    AcpiDisableAllGpes
650  *
651  * PARAMETERS:  None
652  *
653  * RETURN:      Status
654  *
655  * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
656  *
657  ******************************************************************************/
658
659 ACPI_STATUS
660 AcpiDisableAllGpes (
661     void)
662 {
663     ACPI_STATUS             Status;
664
665
666     ACPI_FUNCTION_TRACE (AcpiDisableAllGpes);
667
668
669     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
670     if (ACPI_FAILURE (Status))
671     {
672         return_ACPI_STATUS (Status);
673     }
674
675     Status = AcpiHwDisableAllGpes ();
676     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
677
678     return_ACPI_STATUS (Status);
679 }
680
681 ACPI_EXPORT_SYMBOL (AcpiDisableAllGpes)
682
683
684 /******************************************************************************
685  *
686  * FUNCTION:    AcpiEnableAllRuntimeGpes
687  *
688  * PARAMETERS:  None
689  *
690  * RETURN:      Status
691  *
692  * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
693  *
694  ******************************************************************************/
695
696 ACPI_STATUS
697 AcpiEnableAllRuntimeGpes (
698     void)
699 {
700     ACPI_STATUS             Status;
701
702
703     ACPI_FUNCTION_TRACE (AcpiEnableAllRuntimeGpes);
704
705
706     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
707     if (ACPI_FAILURE (Status))
708     {
709         return_ACPI_STATUS (Status);
710     }
711
712     Status = AcpiHwEnableAllRuntimeGpes ();
713     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
714
715     return_ACPI_STATUS (Status);
716 }
717
718 ACPI_EXPORT_SYMBOL (AcpiEnableAllRuntimeGpes)
719
720
721 /*******************************************************************************
722  *
723  * FUNCTION:    AcpiInstallGpeBlock
724  *
725  * PARAMETERS:  GpeDevice           - Handle to the parent GPE Block Device
726  *              GpeBlockAddress     - Address and SpaceID
727  *              RegisterCount       - Number of GPE register pairs in the block
728  *              InterruptNumber     - H/W interrupt for the block
729  *
730  * RETURN:      Status
731  *
732  * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not
733  *              enabled here.
734  *
735  ******************************************************************************/
736
737 ACPI_STATUS
738 AcpiInstallGpeBlock (
739     ACPI_HANDLE             GpeDevice,
740     ACPI_GENERIC_ADDRESS    *GpeBlockAddress,
741     UINT32                  RegisterCount,
742     UINT32                  InterruptNumber)
743 {
744     ACPI_STATUS             Status;
745     ACPI_OPERAND_OBJECT     *ObjDesc;
746     ACPI_NAMESPACE_NODE     *Node;
747     ACPI_GPE_BLOCK_INFO     *GpeBlock;
748
749
750     ACPI_FUNCTION_TRACE (AcpiInstallGpeBlock);
751
752
753     if ((!GpeDevice)       ||
754         (!GpeBlockAddress) ||
755         (!RegisterCount))
756     {
757         return_ACPI_STATUS (AE_BAD_PARAMETER);
758     }
759
760     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
761     if (ACPI_FAILURE (Status))
762     {
763         return (Status);
764     }
765
766     Node = AcpiNsValidateHandle (GpeDevice);
767     if (!Node)
768     {
769         Status = AE_BAD_PARAMETER;
770         goto UnlockAndExit;
771     }
772
773     /*
774      * For user-installed GPE Block Devices, the GpeBlockBaseNumber
775      * is always zero
776      */
777     Status = AcpiEvCreateGpeBlock (Node, GpeBlockAddress, RegisterCount,
778                 0, InterruptNumber, &GpeBlock);
779     if (ACPI_FAILURE (Status))
780     {
781         goto UnlockAndExit;
782     }
783
784     /* Install block in the DeviceObject attached to the node */
785
786     ObjDesc = AcpiNsGetAttachedObject (Node);
787     if (!ObjDesc)
788     {
789         /*
790          * No object, create a new one (Device nodes do not always have
791          * an attached object)
792          */
793         ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_DEVICE);
794         if (!ObjDesc)
795         {
796             Status = AE_NO_MEMORY;
797             goto UnlockAndExit;
798         }
799
800         Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_DEVICE);
801
802         /* Remove local reference to the object */
803
804         AcpiUtRemoveReference (ObjDesc);
805         if (ACPI_FAILURE (Status))
806         {
807             goto UnlockAndExit;
808         }
809     }
810
811     /* Now install the GPE block in the DeviceObject */
812
813     ObjDesc->Device.GpeBlock = GpeBlock;
814
815
816 UnlockAndExit:
817     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
818     return_ACPI_STATUS (Status);
819 }
820
821 ACPI_EXPORT_SYMBOL (AcpiInstallGpeBlock)
822
823
824 /*******************************************************************************
825  *
826  * FUNCTION:    AcpiRemoveGpeBlock
827  *
828  * PARAMETERS:  GpeDevice           - Handle to the parent GPE Block Device
829  *
830  * RETURN:      Status
831  *
832  * DESCRIPTION: Remove a previously installed block of GPE registers
833  *
834  ******************************************************************************/
835
836 ACPI_STATUS
837 AcpiRemoveGpeBlock (
838     ACPI_HANDLE             GpeDevice)
839 {
840     ACPI_OPERAND_OBJECT     *ObjDesc;
841     ACPI_STATUS             Status;
842     ACPI_NAMESPACE_NODE     *Node;
843
844
845     ACPI_FUNCTION_TRACE (AcpiRemoveGpeBlock);
846
847
848     if (!GpeDevice)
849     {
850         return_ACPI_STATUS (AE_BAD_PARAMETER);
851     }
852
853     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
854     if (ACPI_FAILURE (Status))
855     {
856         return (Status);
857     }
858
859     Node = AcpiNsValidateHandle (GpeDevice);
860     if (!Node)
861     {
862         Status = AE_BAD_PARAMETER;
863         goto UnlockAndExit;
864     }
865
866     /* Get the DeviceObject attached to the node */
867
868     ObjDesc = AcpiNsGetAttachedObject (Node);
869     if (!ObjDesc ||
870         !ObjDesc->Device.GpeBlock)
871     {
872         return_ACPI_STATUS (AE_NULL_OBJECT);
873     }
874
875     /* Delete the GPE block (but not the DeviceObject) */
876
877     Status = AcpiEvDeleteGpeBlock (ObjDesc->Device.GpeBlock);
878     if (ACPI_SUCCESS (Status))
879     {
880         ObjDesc->Device.GpeBlock = NULL;
881     }
882
883 UnlockAndExit:
884     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
885     return_ACPI_STATUS (Status);
886 }
887
888 ACPI_EXPORT_SYMBOL (AcpiRemoveGpeBlock)
889
890
891 /*******************************************************************************
892  *
893  * FUNCTION:    AcpiGetGpeDevice
894  *
895  * PARAMETERS:  Index               - System GPE index (0-CurrentGpeCount)
896  *              GpeDevice           - Where the parent GPE Device is returned
897  *
898  * RETURN:      Status
899  *
900  * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
901  *              gpe device indicates that the gpe number is contained in one of
902  *              the FADT-defined gpe blocks. Otherwise, the GPE block device.
903  *
904  ******************************************************************************/
905
906 ACPI_STATUS
907 AcpiGetGpeDevice (
908     UINT32                  Index,
909     ACPI_HANDLE             *GpeDevice)
910 {
911     ACPI_GPE_DEVICE_INFO    Info;
912     ACPI_STATUS             Status;
913
914
915     ACPI_FUNCTION_TRACE (AcpiGetGpeDevice);
916
917
918     if (!GpeDevice)
919     {
920         return_ACPI_STATUS (AE_BAD_PARAMETER);
921     }
922
923     if (Index >= AcpiCurrentGpeCount)
924     {
925         return_ACPI_STATUS (AE_NOT_EXIST);
926     }
927
928     /* Setup and walk the GPE list */
929
930     Info.Index = Index;
931     Info.Status = AE_NOT_EXIST;
932     Info.GpeDevice = NULL;
933     Info.NextBlockBaseIndex = 0;
934
935     Status = AcpiEvWalkGpeList (AcpiEvGetGpeDevice, &Info);
936     if (ACPI_FAILURE (Status))
937     {
938         return_ACPI_STATUS (Status);
939     }
940
941     *GpeDevice = ACPI_CAST_PTR (ACPI_HANDLE, Info.GpeDevice);
942     return_ACPI_STATUS (Info.Status);
943 }
944
945 ACPI_EXPORT_SYMBOL (AcpiGetGpeDevice)
946
947 #endif /* !ACPI_REDUCED_HARDWARE */