]> CyberLeo.Net >> Repos - FreeBSD/releng/8.2.git/blob - sys/contrib/dev/acpica/events/evxfevnt.c
Copy stable/8 to releng/8.2 in preparation for FreeBSD-8.2 release.
[FreeBSD/releng/8.2.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:    AcpiGpeWakeup
311  *
312  * PARAMETERS:  GpeDevice       - Parent GPE Device. NULL for GPE0/GPE1
313  *              GpeNumber       - GPE level within the GPE block
314  *              Action          - Enable or Disable
315  *
316  * RETURN:      Status
317  *
318  * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit.
319  *
320  ******************************************************************************/
321
322 ACPI_STATUS
323 AcpiGpeWakeup (
324     ACPI_HANDLE             GpeDevice,
325     UINT32                  GpeNumber,
326     UINT8                   Action)
327 {
328     ACPI_STATUS             Status = AE_OK;
329     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
330     ACPI_GPE_REGISTER_INFO  *GpeRegisterInfo;
331     ACPI_CPU_FLAGS          Flags;
332     UINT32                  RegisterBit;
333
334
335     ACPI_FUNCTION_TRACE (AcpiGpeWakeup);
336
337
338     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
339
340     /* Ensure that we have a valid GPE number */
341
342     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
343     if (!GpeEventInfo)
344     {
345         Status = AE_BAD_PARAMETER;
346         goto UnlockAndExit;
347     }
348
349     GpeRegisterInfo = GpeEventInfo->RegisterInfo;
350     if (!GpeRegisterInfo)
351     {
352         Status = AE_NOT_EXIST;
353         goto UnlockAndExit;
354     }
355
356     RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo, GpeRegisterInfo);
357
358     /* Perform the action */
359
360     switch (Action)
361     {
362     case ACPI_GPE_ENABLE:
363         ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
364         break;
365
366     case ACPI_GPE_DISABLE:
367         ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
368         break;
369
370     default:
371         ACPI_ERROR ((AE_INFO, "%u, Invalid action", Action));
372         Status = AE_BAD_PARAMETER;
373         break;
374     }
375
376 UnlockAndExit:
377     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
378     return_ACPI_STATUS (Status);
379 }
380
381 ACPI_EXPORT_SYMBOL (AcpiGpeWakeup)
382
383
384 /*******************************************************************************
385  *
386  * FUNCTION:    AcpiEnableGpe
387  *
388  * PARAMETERS:  GpeDevice       - Parent GPE Device. NULL for GPE0/GPE1
389  *              GpeNumber       - GPE level within the GPE block
390  *
391  * RETURN:      Status
392  *
393  * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
394  *              hardware-enabled.
395  *
396  ******************************************************************************/
397
398 ACPI_STATUS
399 AcpiEnableGpe (
400     ACPI_HANDLE             GpeDevice,
401     UINT32                  GpeNumber)
402 {
403     ACPI_STATUS             Status = AE_OK;
404     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
405     ACPI_CPU_FLAGS          Flags;
406
407
408     ACPI_FUNCTION_TRACE (AcpiEnableGpe);
409
410
411     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
412
413     /* Ensure that we have a valid GPE number */
414
415     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
416     if (!GpeEventInfo)
417     {
418         Status = AE_BAD_PARAMETER;
419         goto UnlockAndExit;
420     }
421
422     if (GpeEventInfo->RuntimeCount == ACPI_UINT8_MAX)
423     {
424         Status = AE_LIMIT; /* Too many references */
425         goto UnlockAndExit;
426     }
427
428     GpeEventInfo->RuntimeCount++;
429     if (GpeEventInfo->RuntimeCount == 1)
430     {
431         Status = AcpiEvUpdateGpeEnableMask (GpeEventInfo);
432         if (ACPI_SUCCESS (Status))
433         {
434             Status = AcpiEvEnableGpe (GpeEventInfo);
435         }
436         if (ACPI_FAILURE (Status))
437         {
438             GpeEventInfo->RuntimeCount--;
439         }
440     }
441
442 UnlockAndExit:
443     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
444     return_ACPI_STATUS (Status);
445 }
446
447 ACPI_EXPORT_SYMBOL (AcpiEnableGpe)
448
449
450 /*******************************************************************************
451  *
452  * FUNCTION:    AcpiDisableGpe
453  *
454  * PARAMETERS:  GpeDevice       - Parent GPE Device. NULL for GPE0/GPE1
455  *              GpeNumber       - GPE level within the GPE block
456  *
457  * RETURN:      Status
458  *
459  * DESCRIPTION: Remove a reference to a GPE. When the last reference is
460  *              removed, only then is the GPE disabled (for runtime GPEs), or
461  *              the GPE mask bit disabled (for wake GPEs)
462  *
463  ******************************************************************************/
464
465 ACPI_STATUS
466 AcpiDisableGpe (
467     ACPI_HANDLE             GpeDevice,
468     UINT32                  GpeNumber)
469 {
470     ACPI_STATUS             Status = AE_OK;
471     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
472     ACPI_CPU_FLAGS          Flags;
473
474
475     ACPI_FUNCTION_TRACE (AcpiDisableGpe);
476
477
478     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
479
480     /* Ensure that we have a valid GPE number */
481
482     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
483     if (!GpeEventInfo)
484     {
485         Status = AE_BAD_PARAMETER;
486         goto UnlockAndExit;
487     }
488
489     /* Hardware-disable a runtime GPE on removal of the last reference */
490
491     if (!GpeEventInfo->RuntimeCount)
492     {
493         Status = AE_LIMIT; /* There are no references to remove */
494         goto UnlockAndExit;
495     }
496
497     GpeEventInfo->RuntimeCount--;
498     if (!GpeEventInfo->RuntimeCount)
499     {
500         Status = AcpiEvUpdateGpeEnableMask (GpeEventInfo);
501         if (ACPI_SUCCESS (Status))
502         {
503             Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
504         }
505         if (ACPI_FAILURE (Status))
506         {
507             GpeEventInfo->RuntimeCount++;
508         }
509     }
510
511 UnlockAndExit:
512     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
513     return_ACPI_STATUS (Status);
514 }
515
516 ACPI_EXPORT_SYMBOL (AcpiDisableGpe)
517
518
519 /*******************************************************************************
520  *
521  * FUNCTION:    AcpiSetGpe
522  *
523  * PARAMETERS:  GpeDevice       - Parent GPE Device. NULL for GPE0/GPE1
524  *              GpeNumber       - GPE level within the GPE block
525  *              Action          - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
526  *
527  * RETURN:      Status
528  *
529  * DESCRIPTION: Enable or disable an individual GPE. This function bypasses
530  *              the reference count mechanism used in the AcpiEnableGpe and
531  *              AcpiDisableGpe interfaces -- and should be used with care.
532  *
533  * Note: Typically used to disable a runtime GPE for short period of time,
534  * then re-enable it, without disturbing the existing reference counts. This
535  * is useful, for example, in the Embedded Controller (EC) driver.
536  *
537  ******************************************************************************/
538
539 ACPI_STATUS
540 AcpiSetGpe (
541     ACPI_HANDLE             GpeDevice,
542     UINT32                  GpeNumber,
543     UINT8                   Action)
544 {
545     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
546     ACPI_STATUS             Status;
547     ACPI_CPU_FLAGS          Flags;
548
549
550     ACPI_FUNCTION_TRACE (AcpiSetGpe);
551
552
553     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
554
555     /* Ensure that we have a valid GPE number */
556
557     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
558     if (!GpeEventInfo)
559     {
560         Status = AE_BAD_PARAMETER;
561         goto UnlockAndExit;
562     }
563
564     /* Perform the action */
565
566     switch (Action)
567     {
568     case ACPI_GPE_ENABLE:
569         Status = AcpiEvEnableGpe (GpeEventInfo);
570         break;
571
572     case ACPI_GPE_DISABLE:
573         Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
574         break;
575
576     default:
577         Status = AE_BAD_PARAMETER;
578         break;
579     }
580
581 UnlockAndExit:
582     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
583     return_ACPI_STATUS (Status);
584 }
585
586 ACPI_EXPORT_SYMBOL (AcpiSetGpe)
587
588
589 /*******************************************************************************
590  *
591  * FUNCTION:    AcpiDisableEvent
592  *
593  * PARAMETERS:  Event           - The fixed eventto be enabled
594  *              Flags           - Reserved
595  *
596  * RETURN:      Status
597  *
598  * DESCRIPTION: Disable an ACPI event (fixed)
599  *
600  ******************************************************************************/
601
602 ACPI_STATUS
603 AcpiDisableEvent (
604     UINT32                  Event,
605     UINT32                  Flags)
606 {
607     ACPI_STATUS             Status = AE_OK;
608     UINT32                  Value;
609
610
611     ACPI_FUNCTION_TRACE (AcpiDisableEvent);
612
613
614     /* Decode the Fixed Event */
615
616     if (Event > ACPI_EVENT_MAX)
617     {
618         return_ACPI_STATUS (AE_BAD_PARAMETER);
619     }
620
621     /*
622      * Disable the requested fixed event (by writing a zero to the enable
623      * register bit)
624      */
625     Status = AcpiWriteBitRegister (
626                 AcpiGbl_FixedEventInfo[Event].EnableRegisterId,
627                 ACPI_DISABLE_EVENT);
628     if (ACPI_FAILURE (Status))
629     {
630         return_ACPI_STATUS (Status);
631     }
632
633     Status = AcpiReadBitRegister (
634                 AcpiGbl_FixedEventInfo[Event].EnableRegisterId, &Value);
635     if (ACPI_FAILURE (Status))
636     {
637         return_ACPI_STATUS (Status);
638     }
639
640     if (Value != 0)
641     {
642         ACPI_ERROR ((AE_INFO,
643             "Could not disable %s events", AcpiUtGetEventName (Event)));
644         return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
645     }
646
647     return_ACPI_STATUS (Status);
648 }
649
650 ACPI_EXPORT_SYMBOL (AcpiDisableEvent)
651
652
653 /*******************************************************************************
654  *
655  * FUNCTION:    AcpiClearEvent
656  *
657  * PARAMETERS:  Event           - The fixed event to be cleared
658  *
659  * RETURN:      Status
660  *
661  * DESCRIPTION: Clear an ACPI event (fixed)
662  *
663  ******************************************************************************/
664
665 ACPI_STATUS
666 AcpiClearEvent (
667     UINT32                  Event)
668 {
669     ACPI_STATUS             Status = AE_OK;
670
671
672     ACPI_FUNCTION_TRACE (AcpiClearEvent);
673
674
675     /* Decode the Fixed Event */
676
677     if (Event > ACPI_EVENT_MAX)
678     {
679         return_ACPI_STATUS (AE_BAD_PARAMETER);
680     }
681
682     /*
683      * Clear the requested fixed event (By writing a one to the status
684      * register bit)
685      */
686     Status = AcpiWriteBitRegister (
687                 AcpiGbl_FixedEventInfo[Event].StatusRegisterId,
688                 ACPI_CLEAR_STATUS);
689
690     return_ACPI_STATUS (Status);
691 }
692
693 ACPI_EXPORT_SYMBOL (AcpiClearEvent)
694
695
696 /*******************************************************************************
697  *
698  * FUNCTION:    AcpiClearGpe
699  *
700  * PARAMETERS:  GpeDevice       - Parent GPE Device. NULL for GPE0/GPE1
701  *              GpeNumber       - GPE level within the GPE block
702  *
703  * RETURN:      Status
704  *
705  * DESCRIPTION: Clear an ACPI event (general purpose)
706  *
707  ******************************************************************************/
708
709 ACPI_STATUS
710 AcpiClearGpe (
711     ACPI_HANDLE             GpeDevice,
712     UINT32                  GpeNumber)
713 {
714     ACPI_STATUS             Status = AE_OK;
715     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
716     ACPI_CPU_FLAGS          Flags;
717
718
719     ACPI_FUNCTION_TRACE (AcpiClearGpe);
720
721
722     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
723
724     /* Ensure that we have a valid GPE number */
725
726     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
727     if (!GpeEventInfo)
728     {
729         Status = AE_BAD_PARAMETER;
730         goto UnlockAndExit;
731     }
732
733     Status = AcpiHwClearGpe (GpeEventInfo);
734
735 UnlockAndExit:
736     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
737     return_ACPI_STATUS (Status);
738 }
739
740 ACPI_EXPORT_SYMBOL (AcpiClearGpe)
741
742
743 /*******************************************************************************
744  *
745  * FUNCTION:    AcpiGetEventStatus
746  *
747  * PARAMETERS:  Event           - The fixed event
748  *              EventStatus     - Where the current status of the event will
749  *                                be returned
750  *
751  * RETURN:      Status
752  *
753  * DESCRIPTION: Obtains and returns the current status of the event
754  *
755  ******************************************************************************/
756
757 ACPI_STATUS
758 AcpiGetEventStatus (
759     UINT32                  Event,
760     ACPI_EVENT_STATUS       *EventStatus)
761 {
762     ACPI_STATUS             Status = AE_OK;
763
764
765     ACPI_FUNCTION_TRACE (AcpiGetEventStatus);
766
767
768     if (!EventStatus)
769     {
770         return_ACPI_STATUS (AE_BAD_PARAMETER);
771     }
772
773     /* Decode the Fixed Event */
774
775     if (Event > ACPI_EVENT_MAX)
776     {
777         return_ACPI_STATUS (AE_BAD_PARAMETER);
778     }
779
780     /* Get the status of the requested fixed event */
781
782     Status = AcpiReadBitRegister (
783                 AcpiGbl_FixedEventInfo[Event].StatusRegisterId, EventStatus);
784
785     return_ACPI_STATUS (Status);
786 }
787
788 ACPI_EXPORT_SYMBOL (AcpiGetEventStatus)
789
790
791 /*******************************************************************************
792  *
793  * FUNCTION:    AcpiGetGpeStatus
794  *
795  * PARAMETERS:  GpeDevice       - Parent GPE Device. NULL for GPE0/GPE1
796  *              GpeNumber       - GPE level within the GPE block
797  *              EventStatus     - Where the current status of the event will
798  *                                be returned
799  *
800  * RETURN:      Status
801  *
802  * DESCRIPTION: Get status of an event (general purpose)
803  *
804  ******************************************************************************/
805
806 ACPI_STATUS
807 AcpiGetGpeStatus (
808     ACPI_HANDLE             GpeDevice,
809     UINT32                  GpeNumber,
810     ACPI_EVENT_STATUS       *EventStatus)
811 {
812     ACPI_STATUS             Status = AE_OK;
813     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
814     ACPI_CPU_FLAGS          Flags;
815
816
817     ACPI_FUNCTION_TRACE (AcpiGetGpeStatus);
818
819
820     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
821
822     /* Ensure that we have a valid GPE number */
823
824     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
825     if (!GpeEventInfo)
826     {
827         Status = AE_BAD_PARAMETER;
828         goto UnlockAndExit;
829     }
830
831     /* Obtain status on the requested GPE number */
832
833     Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus);
834
835 UnlockAndExit:
836     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
837     return_ACPI_STATUS (Status);
838 }
839
840 ACPI_EXPORT_SYMBOL (AcpiGetGpeStatus)
841
842
843 /*******************************************************************************
844  *
845  * FUNCTION:    AcpiInstallGpeBlock
846  *
847  * PARAMETERS:  GpeDevice           - Handle to the parent GPE Block Device
848  *              GpeBlockAddress     - Address and SpaceID
849  *              RegisterCount       - Number of GPE register pairs in the block
850  *              InterruptNumber     - H/W interrupt for the block
851  *
852  * RETURN:      Status
853  *
854  * DESCRIPTION: Create and Install a block of GPE registers
855  *
856  ******************************************************************************/
857
858 ACPI_STATUS
859 AcpiInstallGpeBlock (
860     ACPI_HANDLE             GpeDevice,
861     ACPI_GENERIC_ADDRESS    *GpeBlockAddress,
862     UINT32                  RegisterCount,
863     UINT32                  InterruptNumber)
864 {
865     ACPI_STATUS             Status;
866     ACPI_OPERAND_OBJECT     *ObjDesc;
867     ACPI_NAMESPACE_NODE     *Node;
868     ACPI_GPE_BLOCK_INFO     *GpeBlock;
869
870
871     ACPI_FUNCTION_TRACE (AcpiInstallGpeBlock);
872
873
874     if ((!GpeDevice)       ||
875         (!GpeBlockAddress) ||
876         (!RegisterCount))
877     {
878         return_ACPI_STATUS (AE_BAD_PARAMETER);
879     }
880
881     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
882     if (ACPI_FAILURE (Status))
883     {
884         return (Status);
885     }
886
887     Node = AcpiNsValidateHandle (GpeDevice);
888     if (!Node)
889     {
890         Status = AE_BAD_PARAMETER;
891         goto UnlockAndExit;
892     }
893
894     /*
895      * For user-installed GPE Block Devices, the GpeBlockBaseNumber
896      * is always zero
897      */
898     Status = AcpiEvCreateGpeBlock (Node, GpeBlockAddress, RegisterCount,
899                 0, InterruptNumber, &GpeBlock);
900     if (ACPI_FAILURE (Status))
901     {
902         goto UnlockAndExit;
903     }
904
905     /* Install block in the DeviceObject attached to the node */
906
907     ObjDesc = AcpiNsGetAttachedObject (Node);
908     if (!ObjDesc)
909     {
910         /*
911          * No object, create a new one (Device nodes do not always have
912          * an attached object)
913          */
914         ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_DEVICE);
915         if (!ObjDesc)
916         {
917             Status = AE_NO_MEMORY;
918             goto UnlockAndExit;
919         }
920
921         Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_DEVICE);
922
923         /* Remove local reference to the object */
924
925         AcpiUtRemoveReference (ObjDesc);
926         if (ACPI_FAILURE (Status))
927         {
928             goto UnlockAndExit;
929         }
930     }
931
932     /* Now install the GPE block in the DeviceObject */
933
934     ObjDesc->Device.GpeBlock = GpeBlock;
935
936     /* Run the _PRW methods and enable the runtime GPEs in the new block */
937
938     Status = AcpiEvInitializeGpeBlock (Node, GpeBlock);
939
940
941 UnlockAndExit:
942     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
943     return_ACPI_STATUS (Status);
944 }
945
946 ACPI_EXPORT_SYMBOL (AcpiInstallGpeBlock)
947
948
949 /*******************************************************************************
950  *
951  * FUNCTION:    AcpiRemoveGpeBlock
952  *
953  * PARAMETERS:  GpeDevice           - Handle to the parent GPE Block Device
954  *
955  * RETURN:      Status
956  *
957  * DESCRIPTION: Remove a previously installed block of GPE registers
958  *
959  ******************************************************************************/
960
961 ACPI_STATUS
962 AcpiRemoveGpeBlock (
963     ACPI_HANDLE             GpeDevice)
964 {
965     ACPI_OPERAND_OBJECT     *ObjDesc;
966     ACPI_STATUS             Status;
967     ACPI_NAMESPACE_NODE     *Node;
968
969
970     ACPI_FUNCTION_TRACE (AcpiRemoveGpeBlock);
971
972
973     if (!GpeDevice)
974     {
975         return_ACPI_STATUS (AE_BAD_PARAMETER);
976     }
977
978     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
979     if (ACPI_FAILURE (Status))
980     {
981         return (Status);
982     }
983
984     Node = AcpiNsValidateHandle (GpeDevice);
985     if (!Node)
986     {
987         Status = AE_BAD_PARAMETER;
988         goto UnlockAndExit;
989     }
990
991     /* Get the DeviceObject attached to the node */
992
993     ObjDesc = AcpiNsGetAttachedObject (Node);
994     if (!ObjDesc ||
995         !ObjDesc->Device.GpeBlock)
996     {
997         return_ACPI_STATUS (AE_NULL_OBJECT);
998     }
999
1000     /* Delete the GPE block (but not the DeviceObject) */
1001
1002     Status = AcpiEvDeleteGpeBlock (ObjDesc->Device.GpeBlock);
1003     if (ACPI_SUCCESS (Status))
1004     {
1005         ObjDesc->Device.GpeBlock = NULL;
1006     }
1007
1008 UnlockAndExit:
1009     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
1010     return_ACPI_STATUS (Status);
1011 }
1012
1013 ACPI_EXPORT_SYMBOL (AcpiRemoveGpeBlock)
1014
1015
1016 /*******************************************************************************
1017  *
1018  * FUNCTION:    AcpiGetGpeDevice
1019  *
1020  * PARAMETERS:  Index               - System GPE index (0-CurrentGpeCount)
1021  *              GpeDevice           - Where the parent GPE Device is returned
1022  *
1023  * RETURN:      Status
1024  *
1025  * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
1026  *              gpe device indicates that the gpe number is contained in one of
1027  *              the FADT-defined gpe blocks. Otherwise, the GPE block device.
1028  *
1029  ******************************************************************************/
1030
1031 ACPI_STATUS
1032 AcpiGetGpeDevice (
1033     UINT32                  Index,
1034     ACPI_HANDLE             *GpeDevice)
1035 {
1036     ACPI_GPE_DEVICE_INFO    Info;
1037     ACPI_STATUS             Status;
1038
1039
1040     ACPI_FUNCTION_TRACE (AcpiGetGpeDevice);
1041
1042
1043     if (!GpeDevice)
1044     {
1045         return_ACPI_STATUS (AE_BAD_PARAMETER);
1046     }
1047
1048     if (Index >= AcpiCurrentGpeCount)
1049     {
1050         return_ACPI_STATUS (AE_NOT_EXIST);
1051     }
1052
1053     /* Setup and walk the GPE list */
1054
1055     Info.Index = Index;
1056     Info.Status = AE_NOT_EXIST;
1057     Info.GpeDevice = NULL;
1058     Info.NextBlockBaseIndex = 0;
1059
1060     Status = AcpiEvWalkGpeList (AcpiEvGetGpeDevice, &Info);
1061     if (ACPI_FAILURE (Status))
1062     {
1063         return_ACPI_STATUS (Status);
1064     }
1065
1066     *GpeDevice = ACPI_CAST_PTR (ACPI_HANDLE, Info.GpeDevice);
1067     return_ACPI_STATUS (Info.Status);
1068 }
1069
1070 ACPI_EXPORT_SYMBOL (AcpiGetGpeDevice)
1071
1072
1073 /*******************************************************************************
1074  *
1075  * FUNCTION:    AcpiEvGetGpeDevice
1076  *
1077  * PARAMETERS:  GPE_WALK_CALLBACK
1078  *
1079  * RETURN:      Status
1080  *
1081  * DESCRIPTION: Matches the input GPE index (0-CurrentGpeCount) with a GPE
1082  *              block device. NULL if the GPE is one of the FADT-defined GPEs.
1083  *
1084  ******************************************************************************/
1085
1086 static ACPI_STATUS
1087 AcpiEvGetGpeDevice (
1088     ACPI_GPE_XRUPT_INFO     *GpeXruptInfo,
1089     ACPI_GPE_BLOCK_INFO     *GpeBlock,
1090     void                    *Context)
1091 {
1092     ACPI_GPE_DEVICE_INFO    *Info = Context;
1093
1094
1095     /* Increment Index by the number of GPEs in this block */
1096
1097     Info->NextBlockBaseIndex += GpeBlock->GpeCount;
1098
1099     if (Info->Index < Info->NextBlockBaseIndex)
1100     {
1101         /*
1102          * The GPE index is within this block, get the node. Leave the node
1103          * NULL for the FADT-defined GPEs
1104          */
1105         if ((GpeBlock->Node)->Type == ACPI_TYPE_DEVICE)
1106         {
1107             Info->GpeDevice = GpeBlock->Node;
1108         }
1109
1110         Info->Status = AE_OK;
1111         return (AE_CTRL_END);
1112     }
1113
1114     return (AE_OK);
1115 }
1116
1117
1118 /******************************************************************************
1119  *
1120  * FUNCTION:    AcpiDisableAllGpes
1121  *
1122  * PARAMETERS:  None
1123  *
1124  * RETURN:      Status
1125  *
1126  * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
1127  *
1128  ******************************************************************************/
1129
1130 ACPI_STATUS
1131 AcpiDisableAllGpes (
1132     void)
1133 {
1134     ACPI_STATUS             Status;
1135
1136
1137     ACPI_FUNCTION_TRACE (AcpiDisableAllGpes);
1138
1139
1140     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
1141     if (ACPI_FAILURE (Status))
1142     {
1143         return_ACPI_STATUS (Status);
1144     }
1145
1146     Status = AcpiHwDisableAllGpes ();
1147     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
1148
1149     return_ACPI_STATUS (Status);
1150 }
1151
1152
1153 /******************************************************************************
1154  *
1155  * FUNCTION:    AcpiEnableAllRuntimeGpes
1156  *
1157  * PARAMETERS:  None
1158  *
1159  * RETURN:      Status
1160  *
1161  * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
1162  *
1163  ******************************************************************************/
1164
1165 ACPI_STATUS
1166 AcpiEnableAllRuntimeGpes (
1167     void)
1168 {
1169     ACPI_STATUS             Status;
1170
1171
1172     ACPI_FUNCTION_TRACE (AcpiEnableAllRuntimeGpes);
1173
1174
1175     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
1176     if (ACPI_FAILURE (Status))
1177     {
1178         return_ACPI_STATUS (Status);
1179     }
1180
1181     Status = AcpiHwEnableAllRuntimeGpes ();
1182     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
1183
1184     return_ACPI_STATUS (Status);
1185 }
1186
1187