]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - sys/contrib/dev/acpica/events/evxfevnt.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / sys / contrib / dev / acpica / events / evxfevnt.c
1 /******************************************************************************
2  *
3  * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable
4  *
5  *****************************************************************************/
6
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights.  You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code.  No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision.  In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change.  Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee.  Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution.  In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government.  In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************/
115
116
117 #define __EVXFEVNT_C__
118
119 #include <contrib/dev/acpica/include/acpi.h>
120 #include <contrib/dev/acpica/include/accommon.h>
121 #include <contrib/dev/acpica/include/acevents.h>
122 #include <contrib/dev/acpica/include/acnamesp.h>
123 #include <contrib/dev/acpica/include/actables.h>
124
125 #define _COMPONENT          ACPI_EVENTS
126         ACPI_MODULE_NAME    ("evxfevnt")
127
128 /* Local prototypes */
129
130 static ACPI_STATUS
131 AcpiEvGetGpeDevice (
132     ACPI_GPE_XRUPT_INFO     *GpeXruptInfo,
133     ACPI_GPE_BLOCK_INFO     *GpeBlock,
134     void                    *Context);
135
136
137 /*******************************************************************************
138  *
139  * FUNCTION:    AcpiEnable
140  *
141  * PARAMETERS:  None
142  *
143  * RETURN:      Status
144  *
145  * DESCRIPTION: Transfers the system into ACPI mode.
146  *
147  ******************************************************************************/
148
149 ACPI_STATUS
150 AcpiEnable (
151     void)
152 {
153     ACPI_STATUS             Status = AE_OK;
154
155
156     ACPI_FUNCTION_TRACE (AcpiEnable);
157
158
159     /* ACPI tables must be present */
160
161     if (!AcpiTbTablesLoaded ())
162     {
163         return_ACPI_STATUS (AE_NO_ACPI_TABLES);
164     }
165
166     /* Check current mode */
167
168     if (AcpiHwGetMode() == ACPI_SYS_MODE_ACPI)
169     {
170         ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "System is already in ACPI mode\n"));
171     }
172     else
173     {
174         /* Transition to ACPI mode */
175
176         Status = AcpiHwSetMode (ACPI_SYS_MODE_ACPI);
177         if (ACPI_FAILURE (Status))
178         {
179             ACPI_ERROR ((AE_INFO, "Could not transition to ACPI mode"));
180             return_ACPI_STATUS (Status);
181         }
182
183         ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
184             "Transition to ACPI mode successful\n"));
185     }
186
187     return_ACPI_STATUS (Status);
188 }
189
190 ACPI_EXPORT_SYMBOL (AcpiEnable)
191
192
193 /*******************************************************************************
194  *
195  * FUNCTION:    AcpiDisable
196  *
197  * PARAMETERS:  None
198  *
199  * RETURN:      Status
200  *
201  * DESCRIPTION: Transfers the system into LEGACY (non-ACPI) mode.
202  *
203  ******************************************************************************/
204
205 ACPI_STATUS
206 AcpiDisable (
207     void)
208 {
209     ACPI_STATUS             Status = AE_OK;
210
211
212     ACPI_FUNCTION_TRACE (AcpiDisable);
213
214
215     if (AcpiHwGetMode() == ACPI_SYS_MODE_LEGACY)
216     {
217         ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
218             "System is already in legacy (non-ACPI) mode\n"));
219     }
220     else
221     {
222         /* Transition to LEGACY mode */
223
224         Status = AcpiHwSetMode (ACPI_SYS_MODE_LEGACY);
225
226         if (ACPI_FAILURE (Status))
227         {
228             ACPI_ERROR ((AE_INFO,
229                 "Could not exit ACPI mode to legacy mode"));
230             return_ACPI_STATUS (Status);
231         }
232
233         ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "ACPI mode disabled\n"));
234     }
235
236     return_ACPI_STATUS (Status);
237 }
238
239 ACPI_EXPORT_SYMBOL (AcpiDisable)
240
241
242 /*******************************************************************************
243  *
244  * FUNCTION:    AcpiEnableEvent
245  *
246  * PARAMETERS:  Event           - The fixed eventto be enabled
247  *              Flags           - Reserved
248  *
249  * RETURN:      Status
250  *
251  * DESCRIPTION: Enable an ACPI event (fixed)
252  *
253  ******************************************************************************/
254
255 ACPI_STATUS
256 AcpiEnableEvent (
257     UINT32                  Event,
258     UINT32                  Flags)
259 {
260     ACPI_STATUS             Status = AE_OK;
261     UINT32                  Value;
262
263
264     ACPI_FUNCTION_TRACE (AcpiEnableEvent);
265
266
267     /* Decode the Fixed Event */
268
269     if (Event > ACPI_EVENT_MAX)
270     {
271         return_ACPI_STATUS (AE_BAD_PARAMETER);
272     }
273
274     /*
275      * Enable the requested fixed event (by writing a one to the enable
276      * register bit)
277      */
278     Status = AcpiWriteBitRegister (
279                 AcpiGbl_FixedEventInfo[Event].EnableRegisterId,
280                 ACPI_ENABLE_EVENT);
281     if (ACPI_FAILURE (Status))
282     {
283         return_ACPI_STATUS (Status);
284     }
285
286     /* Make sure that the hardware responded */
287
288     Status = AcpiReadBitRegister (
289                 AcpiGbl_FixedEventInfo[Event].EnableRegisterId, &Value);
290     if (ACPI_FAILURE (Status))
291     {
292         return_ACPI_STATUS (Status);
293     }
294
295     if (Value != 1)
296     {
297         ACPI_ERROR ((AE_INFO,
298             "Could not enable %s event", AcpiUtGetEventName (Event)));
299         return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
300     }
301
302     return_ACPI_STATUS (Status);
303 }
304
305 ACPI_EXPORT_SYMBOL (AcpiEnableEvent)
306
307
308 /*******************************************************************************
309  *
310  * FUNCTION:    AcpiEnableGpe
311  *
312  * PARAMETERS:  GpeDevice       - Parent GPE Device. NULL for GPE0/GPE1
313  *              GpeNumber       - GPE level within the GPE block
314  *              GpeType         - ACPI_GPE_TYPE_RUNTIME or ACPI_GPE_TYPE_WAKE
315  *                                or both
316  *
317  * RETURN:      Status
318  *
319  * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
320  *              hardware-enabled (for runtime GPEs), or the GPE register mask
321  *              is updated (for wake GPEs).
322  *
323  ******************************************************************************/
324
325 ACPI_STATUS
326 AcpiEnableGpe (
327     ACPI_HANDLE             GpeDevice,
328     UINT32                  GpeNumber,
329     UINT8                   GpeType)
330 {
331     ACPI_STATUS             Status = AE_OK;
332     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
333     ACPI_CPU_FLAGS          Flags;
334
335
336     ACPI_FUNCTION_TRACE (AcpiEnableGpe);
337
338
339     /* Parameter validation */
340
341     if (!GpeType || (GpeType & ~ACPI_GPE_TYPE_WAKE_RUN))
342     {
343         return_ACPI_STATUS (AE_BAD_PARAMETER);
344     }
345
346     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
347
348     /* Ensure that we have a valid GPE number */
349
350     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
351     if (!GpeEventInfo)
352     {
353         Status = AE_BAD_PARAMETER;
354         goto UnlockAndExit;
355     }
356
357     if (GpeType & ACPI_GPE_TYPE_RUNTIME)
358     {
359         if (GpeEventInfo->RuntimeCount == ACPI_UINT8_MAX)
360         {
361             Status = AE_LIMIT; /* Too many references */
362             goto UnlockAndExit;
363         }
364
365         GpeEventInfo->RuntimeCount++;
366         if (GpeEventInfo->RuntimeCount == 1)
367         {
368             Status = AcpiEvEnableGpe (GpeEventInfo);
369             if (ACPI_FAILURE (Status))
370             {
371                 GpeEventInfo->RuntimeCount--;
372                 goto UnlockAndExit;
373             }
374         }
375     }
376
377     if (GpeType & ACPI_GPE_TYPE_WAKE)
378     {
379         /* The GPE must have the ability to wake the system */
380
381         if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE))
382         {
383             Status = AE_TYPE;
384             goto UnlockAndExit;
385         }
386
387         if (GpeEventInfo->WakeupCount == ACPI_UINT8_MAX)
388         {
389             Status = AE_LIMIT; /* Too many references */
390             goto UnlockAndExit;
391         }
392
393         /*
394          * Update the enable mask on the first wakeup reference. Wake GPEs
395          * are only hardware-enabled just before sleeping.
396          */
397         GpeEventInfo->WakeupCount++;
398         if (GpeEventInfo->WakeupCount == 1)
399         {
400             (void) AcpiEvUpdateGpeEnableMasks (GpeEventInfo);
401         }
402     }
403
404 UnlockAndExit:
405     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
406     return_ACPI_STATUS (Status);
407 }
408
409 ACPI_EXPORT_SYMBOL (AcpiEnableGpe)
410
411
412 /*******************************************************************************
413  *
414  * FUNCTION:    AcpiDisableGpe
415  *
416  * PARAMETERS:  GpeDevice       - Parent GPE Device. NULL for GPE0/GPE1
417  *              GpeNumber       - GPE level within the GPE block
418  *              GpeType         - ACPI_GPE_TYPE_RUNTIME or ACPI_GPE_TYPE_WAKE
419  *                                or both
420  *
421  * RETURN:      Status
422  *
423  * DESCRIPTION: Remove a reference to a GPE. When the last reference is
424  *              removed, only then is the GPE disabled (for runtime GPEs), or
425  *              the GPE mask bit disabled (for wake GPEs)
426  *
427  ******************************************************************************/
428
429 ACPI_STATUS
430 AcpiDisableGpe (
431     ACPI_HANDLE             GpeDevice,
432     UINT32                  GpeNumber,
433     UINT8                   GpeType)
434 {
435     ACPI_STATUS             Status = AE_OK;
436     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
437     ACPI_CPU_FLAGS          Flags;
438
439
440     ACPI_FUNCTION_TRACE (AcpiDisableGpe);
441
442
443     /* Parameter validation */
444
445     if (!GpeType || (GpeType & ~ACPI_GPE_TYPE_WAKE_RUN))
446     {
447         return_ACPI_STATUS (AE_BAD_PARAMETER);
448     }
449
450     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
451
452     /* Ensure that we have a valid GPE number */
453
454     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
455     if (!GpeEventInfo)
456     {
457         Status = AE_BAD_PARAMETER;
458         goto UnlockAndExit;
459     }
460
461     /* Hardware-disable a runtime GPE on removal of the last reference */
462
463     if (GpeType & ACPI_GPE_TYPE_RUNTIME)
464     {
465         if (!GpeEventInfo->RuntimeCount)
466         {
467             Status = AE_LIMIT; /* There are no references to remove */
468             goto UnlockAndExit;
469         }
470
471         GpeEventInfo->RuntimeCount--;
472         if (!GpeEventInfo->RuntimeCount)
473         {
474             Status = AcpiEvDisableGpe (GpeEventInfo);
475             if (ACPI_FAILURE (Status))
476             {
477                 GpeEventInfo->RuntimeCount++;
478                 goto UnlockAndExit;
479             }
480         }
481     }
482
483     /*
484      * Update masks for wake GPE on removal of the last reference.
485      * No need to hardware-disable wake GPEs here, they are not currently
486      * enabled.
487      */
488     if (GpeType & ACPI_GPE_TYPE_WAKE)
489     {
490         if (!GpeEventInfo->WakeupCount)
491         {
492             Status = AE_LIMIT; /* There are no references to remove */
493             goto UnlockAndExit;
494         }
495
496         GpeEventInfo->WakeupCount--;
497         if (!GpeEventInfo->WakeupCount)
498         {
499             (void) AcpiEvUpdateGpeEnableMasks (GpeEventInfo);
500         }
501     }
502
503
504 UnlockAndExit:
505     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
506     return_ACPI_STATUS (Status);
507 }
508
509 ACPI_EXPORT_SYMBOL (AcpiDisableGpe)
510
511
512 /*******************************************************************************
513  *
514  * FUNCTION:    AcpiSetGpe
515  *
516  * PARAMETERS:  GpeDevice       - Parent GPE Device. NULL for GPE0/GPE1
517  *              GpeNumber       - GPE level within the GPE block
518  *              Action          - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
519  *
520  * RETURN:      Status
521  *
522  * DESCRIPTION: Enable or disable an individual GPE. This function bypasses
523  *              the reference count mechanism used in the AcpiEnableGpe and
524  *              AcpiDisableGpe interfaces -- and should be used with care.
525  *
526  * Note: Typically used to disable a runtime GPE for short period of time,
527  * then re-enable it, without disturbing the existing reference counts. This
528  * is useful, for example, in the Embedded Controller (EC) driver.
529  *
530  ******************************************************************************/
531
532 ACPI_STATUS
533 AcpiSetGpe (
534     ACPI_HANDLE             GpeDevice,
535     UINT32                  GpeNumber,
536     UINT8                   Action)
537 {
538     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
539     ACPI_STATUS             Status;
540     ACPI_CPU_FLAGS          Flags;
541
542
543     ACPI_FUNCTION_TRACE (AcpiSetGpe);
544
545
546     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
547
548     /* Ensure that we have a valid GPE number */
549
550     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
551     if (!GpeEventInfo)
552     {
553         Status = AE_BAD_PARAMETER;
554         goto UnlockAndExit;
555     }
556
557     /* Perform the action */
558
559     switch (Action)
560     {
561     case ACPI_GPE_ENABLE:
562         Status = AcpiEvEnableGpe (GpeEventInfo);
563         break;
564
565     case ACPI_GPE_DISABLE:
566         Status = AcpiEvDisableGpe (GpeEventInfo);
567         break;
568
569     default:
570         Status = AE_BAD_PARAMETER;
571         break;
572     }
573
574 UnlockAndExit:
575     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
576     return_ACPI_STATUS (Status);
577 }
578
579 ACPI_EXPORT_SYMBOL (AcpiSetGpe)
580
581
582 /*******************************************************************************
583  *
584  * FUNCTION:    AcpiDisableEvent
585  *
586  * PARAMETERS:  Event           - The fixed eventto be enabled
587  *              Flags           - Reserved
588  *
589  * RETURN:      Status
590  *
591  * DESCRIPTION: Disable an ACPI event (fixed)
592  *
593  ******************************************************************************/
594
595 ACPI_STATUS
596 AcpiDisableEvent (
597     UINT32                  Event,
598     UINT32                  Flags)
599 {
600     ACPI_STATUS             Status = AE_OK;
601     UINT32                  Value;
602
603
604     ACPI_FUNCTION_TRACE (AcpiDisableEvent);
605
606
607     /* Decode the Fixed Event */
608
609     if (Event > ACPI_EVENT_MAX)
610     {
611         return_ACPI_STATUS (AE_BAD_PARAMETER);
612     }
613
614     /*
615      * Disable the requested fixed event (by writing a zero to the enable
616      * register bit)
617      */
618     Status = AcpiWriteBitRegister (
619                 AcpiGbl_FixedEventInfo[Event].EnableRegisterId,
620                 ACPI_DISABLE_EVENT);
621     if (ACPI_FAILURE (Status))
622     {
623         return_ACPI_STATUS (Status);
624     }
625
626     Status = AcpiReadBitRegister (
627                 AcpiGbl_FixedEventInfo[Event].EnableRegisterId, &Value);
628     if (ACPI_FAILURE (Status))
629     {
630         return_ACPI_STATUS (Status);
631     }
632
633     if (Value != 0)
634     {
635         ACPI_ERROR ((AE_INFO,
636             "Could not disable %s events", AcpiUtGetEventName (Event)));
637         return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
638     }
639
640     return_ACPI_STATUS (Status);
641 }
642
643 ACPI_EXPORT_SYMBOL (AcpiDisableEvent)
644
645
646 /*******************************************************************************
647  *
648  * FUNCTION:    AcpiClearEvent
649  *
650  * PARAMETERS:  Event           - The fixed event to be cleared
651  *
652  * RETURN:      Status
653  *
654  * DESCRIPTION: Clear an ACPI event (fixed)
655  *
656  ******************************************************************************/
657
658 ACPI_STATUS
659 AcpiClearEvent (
660     UINT32                  Event)
661 {
662     ACPI_STATUS             Status = AE_OK;
663
664
665     ACPI_FUNCTION_TRACE (AcpiClearEvent);
666
667
668     /* Decode the Fixed Event */
669
670     if (Event > ACPI_EVENT_MAX)
671     {
672         return_ACPI_STATUS (AE_BAD_PARAMETER);
673     }
674
675     /*
676      * Clear the requested fixed event (By writing a one to the status
677      * register bit)
678      */
679     Status = AcpiWriteBitRegister (
680                 AcpiGbl_FixedEventInfo[Event].StatusRegisterId,
681                 ACPI_CLEAR_STATUS);
682
683     return_ACPI_STATUS (Status);
684 }
685
686 ACPI_EXPORT_SYMBOL (AcpiClearEvent)
687
688
689 /*******************************************************************************
690  *
691  * FUNCTION:    AcpiClearGpe
692  *
693  * PARAMETERS:  GpeDevice       - Parent GPE Device. NULL for GPE0/GPE1
694  *              GpeNumber       - GPE level within the GPE block
695  *
696  * RETURN:      Status
697  *
698  * DESCRIPTION: Clear an ACPI event (general purpose)
699  *
700  ******************************************************************************/
701
702 ACPI_STATUS
703 AcpiClearGpe (
704     ACPI_HANDLE             GpeDevice,
705     UINT32                  GpeNumber)
706 {
707     ACPI_STATUS             Status = AE_OK;
708     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
709     ACPI_CPU_FLAGS          Flags;
710
711
712     ACPI_FUNCTION_TRACE (AcpiClearGpe);
713
714
715     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
716
717     /* Ensure that we have a valid GPE number */
718
719     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
720     if (!GpeEventInfo)
721     {
722         Status = AE_BAD_PARAMETER;
723         goto UnlockAndExit;
724     }
725
726     Status = AcpiHwClearGpe (GpeEventInfo);
727
728 UnlockAndExit:
729     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
730     return_ACPI_STATUS (Status);
731 }
732
733 ACPI_EXPORT_SYMBOL (AcpiClearGpe)
734
735
736 /*******************************************************************************
737  *
738  * FUNCTION:    AcpiGetEventStatus
739  *
740  * PARAMETERS:  Event           - The fixed event
741  *              EventStatus     - Where the current status of the event will
742  *                                be returned
743  *
744  * RETURN:      Status
745  *
746  * DESCRIPTION: Obtains and returns the current status of the event
747  *
748  ******************************************************************************/
749
750 ACPI_STATUS
751 AcpiGetEventStatus (
752     UINT32                  Event,
753     ACPI_EVENT_STATUS       *EventStatus)
754 {
755     ACPI_STATUS             Status = AE_OK;
756
757
758     ACPI_FUNCTION_TRACE (AcpiGetEventStatus);
759
760
761     if (!EventStatus)
762     {
763         return_ACPI_STATUS (AE_BAD_PARAMETER);
764     }
765
766     /* Decode the Fixed Event */
767
768     if (Event > ACPI_EVENT_MAX)
769     {
770         return_ACPI_STATUS (AE_BAD_PARAMETER);
771     }
772
773     /* Get the status of the requested fixed event */
774
775     Status = AcpiReadBitRegister (
776                 AcpiGbl_FixedEventInfo[Event].StatusRegisterId, EventStatus);
777
778     return_ACPI_STATUS (Status);
779 }
780
781 ACPI_EXPORT_SYMBOL (AcpiGetEventStatus)
782
783
784 /*******************************************************************************
785  *
786  * FUNCTION:    AcpiGetGpeStatus
787  *
788  * PARAMETERS:  GpeDevice       - Parent GPE Device. NULL for GPE0/GPE1
789  *              GpeNumber       - GPE level within the GPE block
790  *              EventStatus     - Where the current status of the event will
791  *                                be returned
792  *
793  * RETURN:      Status
794  *
795  * DESCRIPTION: Get status of an event (general purpose)
796  *
797  ******************************************************************************/
798
799 ACPI_STATUS
800 AcpiGetGpeStatus (
801     ACPI_HANDLE             GpeDevice,
802     UINT32                  GpeNumber,
803     ACPI_EVENT_STATUS       *EventStatus)
804 {
805     ACPI_STATUS             Status = AE_OK;
806     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
807     ACPI_CPU_FLAGS          Flags;
808
809
810     ACPI_FUNCTION_TRACE (AcpiGetGpeStatus);
811
812
813     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
814
815     /* Ensure that we have a valid GPE number */
816
817     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
818     if (!GpeEventInfo)
819     {
820         Status = AE_BAD_PARAMETER;
821         goto UnlockAndExit;
822     }
823
824     /* Obtain status on the requested GPE number */
825
826     Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus);
827
828 UnlockAndExit:
829     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
830     return_ACPI_STATUS (Status);
831 }
832
833 ACPI_EXPORT_SYMBOL (AcpiGetGpeStatus)
834
835
836 /*******************************************************************************
837  *
838  * FUNCTION:    AcpiInstallGpeBlock
839  *
840  * PARAMETERS:  GpeDevice           - Handle to the parent GPE Block Device
841  *              GpeBlockAddress     - Address and SpaceID
842  *              RegisterCount       - Number of GPE register pairs in the block
843  *              InterruptNumber     - H/W interrupt for the block
844  *
845  * RETURN:      Status
846  *
847  * DESCRIPTION: Create and Install a block of GPE registers
848  *
849  ******************************************************************************/
850
851 ACPI_STATUS
852 AcpiInstallGpeBlock (
853     ACPI_HANDLE             GpeDevice,
854     ACPI_GENERIC_ADDRESS    *GpeBlockAddress,
855     UINT32                  RegisterCount,
856     UINT32                  InterruptNumber)
857 {
858     ACPI_STATUS             Status;
859     ACPI_OPERAND_OBJECT     *ObjDesc;
860     ACPI_NAMESPACE_NODE     *Node;
861     ACPI_GPE_BLOCK_INFO     *GpeBlock;
862
863
864     ACPI_FUNCTION_TRACE (AcpiInstallGpeBlock);
865
866
867     if ((!GpeDevice)       ||
868         (!GpeBlockAddress) ||
869         (!RegisterCount))
870     {
871         return_ACPI_STATUS (AE_BAD_PARAMETER);
872     }
873
874     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
875     if (ACPI_FAILURE (Status))
876     {
877         return (Status);
878     }
879
880     Node = AcpiNsValidateHandle (GpeDevice);
881     if (!Node)
882     {
883         Status = AE_BAD_PARAMETER;
884         goto UnlockAndExit;
885     }
886
887     /*
888      * For user-installed GPE Block Devices, the GpeBlockBaseNumber
889      * is always zero
890      */
891     Status = AcpiEvCreateGpeBlock (Node, GpeBlockAddress, RegisterCount,
892                 0, InterruptNumber, &GpeBlock);
893     if (ACPI_FAILURE (Status))
894     {
895         goto UnlockAndExit;
896     }
897
898     /* Install block in the DeviceObject attached to the node */
899
900     ObjDesc = AcpiNsGetAttachedObject (Node);
901     if (!ObjDesc)
902     {
903         /*
904          * No object, create a new one (Device nodes do not always have
905          * an attached object)
906          */
907         ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_DEVICE);
908         if (!ObjDesc)
909         {
910             Status = AE_NO_MEMORY;
911             goto UnlockAndExit;
912         }
913
914         Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_DEVICE);
915
916         /* Remove local reference to the object */
917
918         AcpiUtRemoveReference (ObjDesc);
919         if (ACPI_FAILURE (Status))
920         {
921             goto UnlockAndExit;
922         }
923     }
924
925     /* Now install the GPE block in the DeviceObject */
926
927     ObjDesc->Device.GpeBlock = GpeBlock;
928
929     /* Run the _PRW methods and enable the runtime GPEs in the new block */
930
931     Status = AcpiEvInitializeGpeBlock (Node, GpeBlock);
932
933
934 UnlockAndExit:
935     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
936     return_ACPI_STATUS (Status);
937 }
938
939 ACPI_EXPORT_SYMBOL (AcpiInstallGpeBlock)
940
941
942 /*******************************************************************************
943  *
944  * FUNCTION:    AcpiRemoveGpeBlock
945  *
946  * PARAMETERS:  GpeDevice           - Handle to the parent GPE Block Device
947  *
948  * RETURN:      Status
949  *
950  * DESCRIPTION: Remove a previously installed block of GPE registers
951  *
952  ******************************************************************************/
953
954 ACPI_STATUS
955 AcpiRemoveGpeBlock (
956     ACPI_HANDLE             GpeDevice)
957 {
958     ACPI_OPERAND_OBJECT     *ObjDesc;
959     ACPI_STATUS             Status;
960     ACPI_NAMESPACE_NODE     *Node;
961
962
963     ACPI_FUNCTION_TRACE (AcpiRemoveGpeBlock);
964
965
966     if (!GpeDevice)
967     {
968         return_ACPI_STATUS (AE_BAD_PARAMETER);
969     }
970
971     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
972     if (ACPI_FAILURE (Status))
973     {
974         return (Status);
975     }
976
977     Node = AcpiNsValidateHandle (GpeDevice);
978     if (!Node)
979     {
980         Status = AE_BAD_PARAMETER;
981         goto UnlockAndExit;
982     }
983
984     /* Get the DeviceObject attached to the node */
985
986     ObjDesc = AcpiNsGetAttachedObject (Node);
987     if (!ObjDesc ||
988         !ObjDesc->Device.GpeBlock)
989     {
990         return_ACPI_STATUS (AE_NULL_OBJECT);
991     }
992
993     /* Delete the GPE block (but not the DeviceObject) */
994
995     Status = AcpiEvDeleteGpeBlock (ObjDesc->Device.GpeBlock);
996     if (ACPI_SUCCESS (Status))
997     {
998         ObjDesc->Device.GpeBlock = NULL;
999     }
1000
1001 UnlockAndExit:
1002     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
1003     return_ACPI_STATUS (Status);
1004 }
1005
1006 ACPI_EXPORT_SYMBOL (AcpiRemoveGpeBlock)
1007
1008
1009 /*******************************************************************************
1010  *
1011  * FUNCTION:    AcpiGetGpeDevice
1012  *
1013  * PARAMETERS:  Index               - System GPE index (0-CurrentGpeCount)
1014  *              GpeDevice           - Where the parent GPE Device is returned
1015  *
1016  * RETURN:      Status
1017  *
1018  * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
1019  *              gpe device indicates that the gpe number is contained in one of
1020  *              the FADT-defined gpe blocks. Otherwise, the GPE block device.
1021  *
1022  ******************************************************************************/
1023
1024 ACPI_STATUS
1025 AcpiGetGpeDevice (
1026     UINT32                  Index,
1027     ACPI_HANDLE             *GpeDevice)
1028 {
1029     ACPI_GPE_DEVICE_INFO    Info;
1030     ACPI_STATUS             Status;
1031
1032
1033     ACPI_FUNCTION_TRACE (AcpiGetGpeDevice);
1034
1035
1036     if (!GpeDevice)
1037     {
1038         return_ACPI_STATUS (AE_BAD_PARAMETER);
1039     }
1040
1041     if (Index >= AcpiCurrentGpeCount)
1042     {
1043         return_ACPI_STATUS (AE_NOT_EXIST);
1044     }
1045
1046     /* Setup and walk the GPE list */
1047
1048     Info.Index = Index;
1049     Info.Status = AE_NOT_EXIST;
1050     Info.GpeDevice = NULL;
1051     Info.NextBlockBaseIndex = 0;
1052
1053     Status = AcpiEvWalkGpeList (AcpiEvGetGpeDevice, &Info);
1054     if (ACPI_FAILURE (Status))
1055     {
1056         return_ACPI_STATUS (Status);
1057     }
1058
1059     *GpeDevice = ACPI_CAST_PTR (ACPI_HANDLE, Info.GpeDevice);
1060     return_ACPI_STATUS (Info.Status);
1061 }
1062
1063 ACPI_EXPORT_SYMBOL (AcpiGetGpeDevice)
1064
1065
1066 /*******************************************************************************
1067  *
1068  * FUNCTION:    AcpiEvGetGpeDevice
1069  *
1070  * PARAMETERS:  GPE_WALK_CALLBACK
1071  *
1072  * RETURN:      Status
1073  *
1074  * DESCRIPTION: Matches the input GPE index (0-CurrentGpeCount) with a GPE
1075  *              block device. NULL if the GPE is one of the FADT-defined GPEs.
1076  *
1077  ******************************************************************************/
1078
1079 static ACPI_STATUS
1080 AcpiEvGetGpeDevice (
1081     ACPI_GPE_XRUPT_INFO     *GpeXruptInfo,
1082     ACPI_GPE_BLOCK_INFO     *GpeBlock,
1083     void                    *Context)
1084 {
1085     ACPI_GPE_DEVICE_INFO    *Info = Context;
1086
1087
1088     /* Increment Index by the number of GPEs in this block */
1089
1090     Info->NextBlockBaseIndex += GpeBlock->GpeCount;
1091
1092     if (Info->Index < Info->NextBlockBaseIndex)
1093     {
1094         /*
1095          * The GPE index is within this block, get the node. Leave the node
1096          * NULL for the FADT-defined GPEs
1097          */
1098         if ((GpeBlock->Node)->Type == ACPI_TYPE_DEVICE)
1099         {
1100             Info->GpeDevice = GpeBlock->Node;
1101         }
1102
1103         Info->Status = AE_OK;
1104         return (AE_CTRL_END);
1105     }
1106
1107     return (AE_OK);
1108 }
1109
1110
1111 /******************************************************************************
1112  *
1113  * FUNCTION:    AcpiDisableAllGpes
1114  *
1115  * PARAMETERS:  None
1116  *
1117  * RETURN:      Status
1118  *
1119  * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
1120  *
1121  ******************************************************************************/
1122
1123 ACPI_STATUS
1124 AcpiDisableAllGpes (
1125     void)
1126 {
1127     ACPI_STATUS             Status;
1128
1129
1130     ACPI_FUNCTION_TRACE (AcpiDisableAllGpes);
1131
1132
1133     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
1134     if (ACPI_FAILURE (Status))
1135     {
1136         return_ACPI_STATUS (Status);
1137     }
1138
1139     Status = AcpiHwDisableAllGpes ();
1140     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
1141
1142     return_ACPI_STATUS (Status);
1143 }
1144
1145
1146 /******************************************************************************
1147  *
1148  * FUNCTION:    AcpiEnableAllRuntimeGpes
1149  *
1150  * PARAMETERS:  None
1151  *
1152  * RETURN:      Status
1153  *
1154  * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
1155  *
1156  ******************************************************************************/
1157
1158 ACPI_STATUS
1159 AcpiEnableAllRuntimeGpes (
1160     void)
1161 {
1162     ACPI_STATUS             Status;
1163
1164
1165     ACPI_FUNCTION_TRACE (AcpiEnableAllRuntimeGpes);
1166
1167
1168     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
1169     if (ACPI_FAILURE (Status))
1170     {
1171         return_ACPI_STATUS (Status);
1172     }
1173
1174     Status = AcpiHwEnableAllRuntimeGpes ();
1175     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
1176
1177     return_ACPI_STATUS (Status);
1178 }
1179
1180