evxfevnt.c revision 1.1 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 "acpi.h"
120 #include "accommon.h"
121 #include "acevents.h"
122 #include "acnamesp.h"
123 #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
1181