10174267aSFredrik Holmqvist /******************************************************************************
20174267aSFredrik Holmqvist *
30174267aSFredrik Holmqvist * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs)
40174267aSFredrik Holmqvist *
50174267aSFredrik Holmqvist *****************************************************************************/
60174267aSFredrik Holmqvist
70174267aSFredrik Holmqvist /******************************************************************************
80174267aSFredrik Holmqvist *
90174267aSFredrik Holmqvist * 1. Copyright Notice
100174267aSFredrik Holmqvist *
11*6dde014fSPulkoMandy * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp.
120174267aSFredrik Holmqvist * All rights reserved.
130174267aSFredrik Holmqvist *
140174267aSFredrik Holmqvist * 2. License
150174267aSFredrik Holmqvist *
160174267aSFredrik Holmqvist * 2.1. This is your license from Intel Corp. under its intellectual property
170174267aSFredrik Holmqvist * rights. You may have additional license terms from the party that provided
180174267aSFredrik Holmqvist * you this software, covering your right to use that party's intellectual
190174267aSFredrik Holmqvist * property rights.
200174267aSFredrik Holmqvist *
210174267aSFredrik Holmqvist * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
220174267aSFredrik Holmqvist * copy of the source code appearing in this file ("Covered Code") an
230174267aSFredrik Holmqvist * irrevocable, perpetual, worldwide license under Intel's copyrights in the
240174267aSFredrik Holmqvist * base code distributed originally by Intel ("Original Intel Code") to copy,
250174267aSFredrik Holmqvist * make derivatives, distribute, use and display any portion of the Covered
260174267aSFredrik Holmqvist * Code in any form, with the right to sublicense such rights; and
270174267aSFredrik Holmqvist *
280174267aSFredrik Holmqvist * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
290174267aSFredrik Holmqvist * license (with the right to sublicense), under only those claims of Intel
300174267aSFredrik Holmqvist * patents that are infringed by the Original Intel Code, to make, use, sell,
310174267aSFredrik Holmqvist * offer to sell, and import the Covered Code and derivative works thereof
320174267aSFredrik Holmqvist * solely to the minimum extent necessary to exercise the above copyright
330174267aSFredrik Holmqvist * license, and in no event shall the patent license extend to any additions
340174267aSFredrik Holmqvist * to or modifications of the Original Intel Code. No other license or right
350174267aSFredrik Holmqvist * is granted directly or by implication, estoppel or otherwise;
360174267aSFredrik Holmqvist *
370174267aSFredrik Holmqvist * The above copyright and patent license is granted only if the following
380174267aSFredrik Holmqvist * conditions are met:
390174267aSFredrik Holmqvist *
400174267aSFredrik Holmqvist * 3. Conditions
410174267aSFredrik Holmqvist *
420174267aSFredrik Holmqvist * 3.1. Redistribution of Source with Rights to Further Distribute Source.
430174267aSFredrik Holmqvist * Redistribution of source code of any substantial portion of the Covered
440174267aSFredrik Holmqvist * Code or modification with rights to further distribute source must include
450174267aSFredrik Holmqvist * the above Copyright Notice, the above License, this list of Conditions,
460174267aSFredrik Holmqvist * and the following Disclaimer and Export Compliance provision. In addition,
470174267aSFredrik Holmqvist * Licensee must cause all Covered Code to which Licensee contributes to
480174267aSFredrik Holmqvist * contain a file documenting the changes Licensee made to create that Covered
490174267aSFredrik Holmqvist * Code and the date of any change. Licensee must include in that file the
500174267aSFredrik Holmqvist * documentation of any changes made by any predecessor Licensee. Licensee
510174267aSFredrik Holmqvist * must include a prominent statement that the modification is derived,
520174267aSFredrik Holmqvist * directly or indirectly, from Original Intel Code.
530174267aSFredrik Holmqvist *
540174267aSFredrik Holmqvist * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
550174267aSFredrik Holmqvist * Redistribution of source code of any substantial portion of the Covered
560174267aSFredrik Holmqvist * Code or modification without rights to further distribute source must
570174267aSFredrik Holmqvist * include the following Disclaimer and Export Compliance provision in the
580174267aSFredrik Holmqvist * documentation and/or other materials provided with distribution. In
590174267aSFredrik Holmqvist * addition, Licensee may not authorize further sublicense of source of any
600174267aSFredrik Holmqvist * portion of the Covered Code, and must include terms to the effect that the
610174267aSFredrik Holmqvist * license from Licensee to its licensee is limited to the intellectual
620174267aSFredrik Holmqvist * property embodied in the software Licensee provides to its licensee, and
630174267aSFredrik Holmqvist * not to intellectual property embodied in modifications its licensee may
640174267aSFredrik Holmqvist * make.
650174267aSFredrik Holmqvist *
660174267aSFredrik Holmqvist * 3.3. Redistribution of Executable. Redistribution in executable form of any
670174267aSFredrik Holmqvist * substantial portion of the Covered Code or modification must reproduce the
680174267aSFredrik Holmqvist * above Copyright Notice, and the following Disclaimer and Export Compliance
690174267aSFredrik Holmqvist * provision in the documentation and/or other materials provided with the
700174267aSFredrik Holmqvist * distribution.
710174267aSFredrik Holmqvist *
720174267aSFredrik Holmqvist * 3.4. Intel retains all right, title, and interest in and to the Original
730174267aSFredrik Holmqvist * Intel Code.
740174267aSFredrik Holmqvist *
750174267aSFredrik Holmqvist * 3.5. Neither the name Intel nor any other trademark owned or controlled by
760174267aSFredrik Holmqvist * Intel shall be used in advertising or otherwise to promote the sale, use or
770174267aSFredrik Holmqvist * other dealings in products derived from or relating to the Covered Code
780174267aSFredrik Holmqvist * without prior written authorization from Intel.
790174267aSFredrik Holmqvist *
800174267aSFredrik Holmqvist * 4. Disclaimer and Export Compliance
810174267aSFredrik Holmqvist *
820174267aSFredrik Holmqvist * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
830174267aSFredrik Holmqvist * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
840174267aSFredrik Holmqvist * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
850174267aSFredrik Holmqvist * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
860174267aSFredrik Holmqvist * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
870174267aSFredrik Holmqvist * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
880174267aSFredrik Holmqvist * PARTICULAR PURPOSE.
890174267aSFredrik Holmqvist *
900174267aSFredrik Holmqvist * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
910174267aSFredrik Holmqvist * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
920174267aSFredrik Holmqvist * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
930174267aSFredrik Holmqvist * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
940174267aSFredrik Holmqvist * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
950174267aSFredrik Holmqvist * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
960174267aSFredrik Holmqvist * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
970174267aSFredrik Holmqvist * LIMITED REMEDY.
980174267aSFredrik Holmqvist *
990174267aSFredrik Holmqvist * 4.3. Licensee shall not export, either directly or indirectly, any of this
1000174267aSFredrik Holmqvist * software or system incorporating such software without first obtaining any
1010174267aSFredrik Holmqvist * required license or other approval from the U. S. Department of Commerce or
1020174267aSFredrik Holmqvist * any other agency or department of the United States Government. In the
1030174267aSFredrik Holmqvist * event Licensee exports any such software from the United States or
1040174267aSFredrik Holmqvist * re-exports any such software from a foreign destination, Licensee shall
1050174267aSFredrik Holmqvist * ensure that the distribution and export/re-export of the software is in
1060174267aSFredrik Holmqvist * compliance with all laws, regulations, orders, or other restrictions of the
1070174267aSFredrik Holmqvist * U.S. Export Administration Regulations. Licensee agrees that neither it nor
1080174267aSFredrik Holmqvist * any of its subsidiaries will export/re-export any technical data, process,
1090174267aSFredrik Holmqvist * software, or service, directly or indirectly, to any country for which the
1100174267aSFredrik Holmqvist * United States government or any agency thereof requires an export license,
1110174267aSFredrik Holmqvist * other governmental approval, or letter of assurance, without first obtaining
1120174267aSFredrik Holmqvist * such license, approval or letter.
1130174267aSFredrik Holmqvist *
114ff2e2f81SFredrik Holmqvist *****************************************************************************
115ff2e2f81SFredrik Holmqvist *
116ff2e2f81SFredrik Holmqvist * Alternatively, you may choose to be licensed under the terms of the
117ff2e2f81SFredrik Holmqvist * following license:
118ff2e2f81SFredrik Holmqvist *
119ff2e2f81SFredrik Holmqvist * Redistribution and use in source and binary forms, with or without
120ff2e2f81SFredrik Holmqvist * modification, are permitted provided that the following conditions
121ff2e2f81SFredrik Holmqvist * are met:
122ff2e2f81SFredrik Holmqvist * 1. Redistributions of source code must retain the above copyright
123ff2e2f81SFredrik Holmqvist * notice, this list of conditions, and the following disclaimer,
124ff2e2f81SFredrik Holmqvist * without modification.
125ff2e2f81SFredrik Holmqvist * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126ff2e2f81SFredrik Holmqvist * substantially similar to the "NO WARRANTY" disclaimer below
127ff2e2f81SFredrik Holmqvist * ("Disclaimer") and any redistribution must be conditioned upon
128ff2e2f81SFredrik Holmqvist * including a substantially similar Disclaimer requirement for further
129ff2e2f81SFredrik Holmqvist * binary redistribution.
130ff2e2f81SFredrik Holmqvist * 3. Neither the names of the above-listed copyright holders nor the names
131ff2e2f81SFredrik Holmqvist * of any contributors may be used to endorse or promote products derived
132ff2e2f81SFredrik Holmqvist * from this software without specific prior written permission.
133ff2e2f81SFredrik Holmqvist *
134ff2e2f81SFredrik Holmqvist * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135ff2e2f81SFredrik Holmqvist * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136ff2e2f81SFredrik Holmqvist * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137ff2e2f81SFredrik Holmqvist * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138ff2e2f81SFredrik Holmqvist * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139ff2e2f81SFredrik Holmqvist * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140ff2e2f81SFredrik Holmqvist * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141ff2e2f81SFredrik Holmqvist * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142ff2e2f81SFredrik Holmqvist * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143ff2e2f81SFredrik Holmqvist * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144ff2e2f81SFredrik Holmqvist * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145ff2e2f81SFredrik Holmqvist *
146ff2e2f81SFredrik Holmqvist * Alternatively, you may choose to be licensed under the terms of the
147ff2e2f81SFredrik Holmqvist * GNU General Public License ("GPL") version 2 as published by the Free
148ff2e2f81SFredrik Holmqvist * Software Foundation.
149ff2e2f81SFredrik Holmqvist *
1500174267aSFredrik Holmqvist *****************************************************************************/
1510174267aSFredrik Holmqvist
152ad5bbfb8SFredrik Holmqvist #define EXPORT_ACPI_INTERFACES
1530174267aSFredrik Holmqvist
1540174267aSFredrik Holmqvist #include "acpi.h"
1550174267aSFredrik Holmqvist #include "accommon.h"
1560174267aSFredrik Holmqvist #include "acevents.h"
1570174267aSFredrik Holmqvist #include "acnamesp.h"
1580174267aSFredrik Holmqvist
1590174267aSFredrik Holmqvist #define _COMPONENT ACPI_EVENTS
1600174267aSFredrik Holmqvist ACPI_MODULE_NAME ("evxfgpe")
1610174267aSFredrik Holmqvist
1620174267aSFredrik Holmqvist
1636822cda0SFredrik Holmqvist #if (!ACPI_REDUCED_HARDWARE) /* Entire module */
1640174267aSFredrik Holmqvist /*******************************************************************************
1650174267aSFredrik Holmqvist *
1660174267aSFredrik Holmqvist * FUNCTION: AcpiUpdateAllGpes
1670174267aSFredrik Holmqvist *
1680174267aSFredrik Holmqvist * PARAMETERS: None
1690174267aSFredrik Holmqvist *
1700174267aSFredrik Holmqvist * RETURN: Status
1710174267aSFredrik Holmqvist *
1720174267aSFredrik Holmqvist * DESCRIPTION: Complete GPE initialization and enable all GPEs that have
1730174267aSFredrik Holmqvist * associated _Lxx or _Exx methods and are not pointed to by any
1740174267aSFredrik Holmqvist * device _PRW methods (this indicates that these GPEs are
1750174267aSFredrik Holmqvist * generally intended for system or device wakeup. Such GPEs
1760174267aSFredrik Holmqvist * have to be enabled directly when the devices whose _PRW
1770174267aSFredrik Holmqvist * methods point to them are set up for wakeup signaling.)
1780174267aSFredrik Holmqvist *
1790174267aSFredrik Holmqvist * NOTE: Should be called after any GPEs are added to the system. Primarily,
1800174267aSFredrik Holmqvist * after the system _PRW methods have been run, but also after a GPE Block
1810174267aSFredrik Holmqvist * Device has been added or if any new GPE methods have been added via a
1820174267aSFredrik Holmqvist * dynamic table load.
1830174267aSFredrik Holmqvist *
1840174267aSFredrik Holmqvist ******************************************************************************/
1850174267aSFredrik Holmqvist
1860174267aSFredrik Holmqvist ACPI_STATUS
AcpiUpdateAllGpes(void)1870174267aSFredrik Holmqvist AcpiUpdateAllGpes (
1880174267aSFredrik Holmqvist void)
1890174267aSFredrik Holmqvist {
1900174267aSFredrik Holmqvist ACPI_STATUS Status;
19108c9948cSFredrik Holmqvist BOOLEAN IsPollingNeeded = FALSE;
1920174267aSFredrik Holmqvist
1930174267aSFredrik Holmqvist
1946822cda0SFredrik Holmqvist ACPI_FUNCTION_TRACE (AcpiUpdateAllGpes);
1950174267aSFredrik Holmqvist
1960174267aSFredrik Holmqvist
1970174267aSFredrik Holmqvist Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
1980174267aSFredrik Holmqvist if (ACPI_FAILURE (Status))
1990174267aSFredrik Holmqvist {
2000174267aSFredrik Holmqvist return_ACPI_STATUS (Status);
2010174267aSFredrik Holmqvist }
2020174267aSFredrik Holmqvist
2030174267aSFredrik Holmqvist if (AcpiGbl_AllGpesInitialized)
2040174267aSFredrik Holmqvist {
2050174267aSFredrik Holmqvist goto UnlockAndExit;
2060174267aSFredrik Holmqvist }
2070174267aSFredrik Holmqvist
20808c9948cSFredrik Holmqvist Status = AcpiEvWalkGpeList (AcpiEvInitializeGpeBlock,
20908c9948cSFredrik Holmqvist &IsPollingNeeded);
2100174267aSFredrik Holmqvist if (ACPI_SUCCESS (Status))
2110174267aSFredrik Holmqvist {
2120174267aSFredrik Holmqvist AcpiGbl_AllGpesInitialized = TRUE;
2130174267aSFredrik Holmqvist }
2140174267aSFredrik Holmqvist
2150174267aSFredrik Holmqvist UnlockAndExit:
2160174267aSFredrik Holmqvist (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
21708c9948cSFredrik Holmqvist
21808c9948cSFredrik Holmqvist if (IsPollingNeeded && AcpiGbl_AllGpesInitialized)
21908c9948cSFredrik Holmqvist {
22008c9948cSFredrik Holmqvist /* Poll GPEs to handle already triggered events */
22108c9948cSFredrik Holmqvist
22208c9948cSFredrik Holmqvist AcpiEvGpeDetect (AcpiGbl_GpeXruptListHead);
22308c9948cSFredrik Holmqvist }
2240174267aSFredrik Holmqvist return_ACPI_STATUS (Status);
2250174267aSFredrik Holmqvist }
2260174267aSFredrik Holmqvist
ACPI_EXPORT_SYMBOL(AcpiUpdateAllGpes)2270174267aSFredrik Holmqvist ACPI_EXPORT_SYMBOL (AcpiUpdateAllGpes)
2280174267aSFredrik Holmqvist
2290174267aSFredrik Holmqvist
2300174267aSFredrik Holmqvist /*******************************************************************************
2310174267aSFredrik Holmqvist *
2320174267aSFredrik Holmqvist * FUNCTION: AcpiEnableGpe
2330174267aSFredrik Holmqvist *
2340174267aSFredrik Holmqvist * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
2350174267aSFredrik Holmqvist * GpeNumber - GPE level within the GPE block
2360174267aSFredrik Holmqvist *
2370174267aSFredrik Holmqvist * RETURN: Status
2380174267aSFredrik Holmqvist *
2390174267aSFredrik Holmqvist * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
2400174267aSFredrik Holmqvist * hardware-enabled.
2410174267aSFredrik Holmqvist *
2420174267aSFredrik Holmqvist ******************************************************************************/
2430174267aSFredrik Holmqvist
2440174267aSFredrik Holmqvist ACPI_STATUS
2450174267aSFredrik Holmqvist AcpiEnableGpe (
2460174267aSFredrik Holmqvist ACPI_HANDLE GpeDevice,
2470174267aSFredrik Holmqvist UINT32 GpeNumber)
2480174267aSFredrik Holmqvist {
2490174267aSFredrik Holmqvist ACPI_STATUS Status = AE_BAD_PARAMETER;
2500174267aSFredrik Holmqvist ACPI_GPE_EVENT_INFO *GpeEventInfo;
2510174267aSFredrik Holmqvist ACPI_CPU_FLAGS Flags;
2520174267aSFredrik Holmqvist
2530174267aSFredrik Holmqvist
2540174267aSFredrik Holmqvist ACPI_FUNCTION_TRACE (AcpiEnableGpe);
2550174267aSFredrik Holmqvist
2560174267aSFredrik Holmqvist
2570174267aSFredrik Holmqvist Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
2580174267aSFredrik Holmqvist
259ad5bbfb8SFredrik Holmqvist /*
260ad5bbfb8SFredrik Holmqvist * Ensure that we have a valid GPE number and that there is some way
261ad5bbfb8SFredrik Holmqvist * of handling the GPE (handler or a GPE method). In other words, we
262ad5bbfb8SFredrik Holmqvist * won't allow a valid GPE to be enabled if there is no way to handle it.
263ad5bbfb8SFredrik Holmqvist */
2640174267aSFredrik Holmqvist GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
2650174267aSFredrik Holmqvist if (GpeEventInfo)
2660174267aSFredrik Holmqvist {
267e226d1d0SFredrik Holmqvist if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) !=
268ad5bbfb8SFredrik Holmqvist ACPI_GPE_DISPATCH_NONE)
269ad5bbfb8SFredrik Holmqvist {
2700ffed378SFredrik Holmqvist Status = AcpiEvAddGpeReference (GpeEventInfo, TRUE);
27108c9948cSFredrik Holmqvist if (ACPI_SUCCESS (Status) &&
27208c9948cSFredrik Holmqvist ACPI_GPE_IS_POLLING_NEEDED (GpeEventInfo))
27308c9948cSFredrik Holmqvist {
27408c9948cSFredrik Holmqvist /* Poll edge-triggered GPEs to handle existing events */
27508c9948cSFredrik Holmqvist
27608c9948cSFredrik Holmqvist AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
27708c9948cSFredrik Holmqvist (void) AcpiEvDetectGpe (
27808c9948cSFredrik Holmqvist GpeDevice, GpeEventInfo, GpeNumber);
27908c9948cSFredrik Holmqvist Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
28008c9948cSFredrik Holmqvist }
2810174267aSFredrik Holmqvist }
282ad5bbfb8SFredrik Holmqvist else
283ad5bbfb8SFredrik Holmqvist {
284ad5bbfb8SFredrik Holmqvist Status = AE_NO_HANDLER;
285ad5bbfb8SFredrik Holmqvist }
286ad5bbfb8SFredrik Holmqvist }
2870174267aSFredrik Holmqvist
2880174267aSFredrik Holmqvist AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
2890174267aSFredrik Holmqvist return_ACPI_STATUS (Status);
2900174267aSFredrik Holmqvist }
2910174267aSFredrik Holmqvist
ACPI_EXPORT_SYMBOL(AcpiEnableGpe)2920174267aSFredrik Holmqvist ACPI_EXPORT_SYMBOL (AcpiEnableGpe)
2930174267aSFredrik Holmqvist
2940174267aSFredrik Holmqvist
2950174267aSFredrik Holmqvist /*******************************************************************************
2960174267aSFredrik Holmqvist *
2970174267aSFredrik Holmqvist * FUNCTION: AcpiDisableGpe
2980174267aSFredrik Holmqvist *
2990174267aSFredrik Holmqvist * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
3000174267aSFredrik Holmqvist * GpeNumber - GPE level within the GPE block
3010174267aSFredrik Holmqvist *
3020174267aSFredrik Holmqvist * RETURN: Status
3030174267aSFredrik Holmqvist *
3040174267aSFredrik Holmqvist * DESCRIPTION: Remove a reference to a GPE. When the last reference is
3050174267aSFredrik Holmqvist * removed, only then is the GPE disabled (for runtime GPEs), or
3060174267aSFredrik Holmqvist * the GPE mask bit disabled (for wake GPEs)
3070174267aSFredrik Holmqvist *
3080174267aSFredrik Holmqvist ******************************************************************************/
3090174267aSFredrik Holmqvist
3100174267aSFredrik Holmqvist ACPI_STATUS
3110174267aSFredrik Holmqvist AcpiDisableGpe (
3120174267aSFredrik Holmqvist ACPI_HANDLE GpeDevice,
3130174267aSFredrik Holmqvist UINT32 GpeNumber)
3140174267aSFredrik Holmqvist {
3150174267aSFredrik Holmqvist ACPI_STATUS Status = AE_BAD_PARAMETER;
3160174267aSFredrik Holmqvist ACPI_GPE_EVENT_INFO *GpeEventInfo;
3170174267aSFredrik Holmqvist ACPI_CPU_FLAGS Flags;
3180174267aSFredrik Holmqvist
3190174267aSFredrik Holmqvist
3200174267aSFredrik Holmqvist ACPI_FUNCTION_TRACE (AcpiDisableGpe);
3210174267aSFredrik Holmqvist
3220174267aSFredrik Holmqvist
3230174267aSFredrik Holmqvist Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
3240174267aSFredrik Holmqvist
3250174267aSFredrik Holmqvist /* Ensure that we have a valid GPE number */
3260174267aSFredrik Holmqvist
3270174267aSFredrik Holmqvist GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
3280174267aSFredrik Holmqvist if (GpeEventInfo)
3290174267aSFredrik Holmqvist {
3300174267aSFredrik Holmqvist Status = AcpiEvRemoveGpeReference (GpeEventInfo);
3310174267aSFredrik Holmqvist }
3320174267aSFredrik Holmqvist
3330174267aSFredrik Holmqvist AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
3340174267aSFredrik Holmqvist return_ACPI_STATUS (Status);
3350174267aSFredrik Holmqvist }
3360174267aSFredrik Holmqvist
ACPI_EXPORT_SYMBOL(AcpiDisableGpe)3370174267aSFredrik Holmqvist ACPI_EXPORT_SYMBOL (AcpiDisableGpe)
3380174267aSFredrik Holmqvist
3390174267aSFredrik Holmqvist
3400174267aSFredrik Holmqvist /*******************************************************************************
3410174267aSFredrik Holmqvist *
3420174267aSFredrik Holmqvist * FUNCTION: AcpiSetGpe
3430174267aSFredrik Holmqvist *
3440174267aSFredrik Holmqvist * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
3450174267aSFredrik Holmqvist * GpeNumber - GPE level within the GPE block
3460174267aSFredrik Holmqvist * Action - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
3470174267aSFredrik Holmqvist *
3480174267aSFredrik Holmqvist * RETURN: Status
3490174267aSFredrik Holmqvist *
3500174267aSFredrik Holmqvist * DESCRIPTION: Enable or disable an individual GPE. This function bypasses
351e226d1d0SFredrik Holmqvist * the reference count mechanism used in the AcpiEnableGpe(),
352e226d1d0SFredrik Holmqvist * AcpiDisableGpe() interfaces.
353e226d1d0SFredrik Holmqvist * This API is typically used by the GPE raw handler mode driver
354e226d1d0SFredrik Holmqvist * to switch between the polling mode and the interrupt mode after
355e226d1d0SFredrik Holmqvist * the driver has enabled the GPE.
356e226d1d0SFredrik Holmqvist * The APIs should be invoked in this order:
357e226d1d0SFredrik Holmqvist * AcpiEnableGpe() <- Ensure the reference count > 0
358e226d1d0SFredrik Holmqvist * AcpiSetGpe(ACPI_GPE_DISABLE) <- Enter polling mode
359e226d1d0SFredrik Holmqvist * AcpiSetGpe(ACPI_GPE_ENABLE) <- Leave polling mode
360e226d1d0SFredrik Holmqvist * AcpiDisableGpe() <- Decrease the reference count
3610174267aSFredrik Holmqvist *
362e226d1d0SFredrik Holmqvist * Note: If a GPE is shared by 2 silicon components, then both the drivers
363e226d1d0SFredrik Holmqvist * should support GPE polling mode or disabling the GPE for long period
364e226d1d0SFredrik Holmqvist * for one driver may break the other. So use it with care since all
365e226d1d0SFredrik Holmqvist * firmware _Lxx/_Exx handlers currently rely on the GPE interrupt mode.
3660174267aSFredrik Holmqvist *
3670174267aSFredrik Holmqvist ******************************************************************************/
3680174267aSFredrik Holmqvist
3690174267aSFredrik Holmqvist ACPI_STATUS
3700174267aSFredrik Holmqvist AcpiSetGpe (
3710174267aSFredrik Holmqvist ACPI_HANDLE GpeDevice,
3720174267aSFredrik Holmqvist UINT32 GpeNumber,
3730174267aSFredrik Holmqvist UINT8 Action)
3740174267aSFredrik Holmqvist {
3750174267aSFredrik Holmqvist ACPI_GPE_EVENT_INFO *GpeEventInfo;
3760174267aSFredrik Holmqvist ACPI_STATUS Status;
3770174267aSFredrik Holmqvist ACPI_CPU_FLAGS Flags;
3780174267aSFredrik Holmqvist
3790174267aSFredrik Holmqvist
3800174267aSFredrik Holmqvist ACPI_FUNCTION_TRACE (AcpiSetGpe);
3810174267aSFredrik Holmqvist
3820174267aSFredrik Holmqvist
3830174267aSFredrik Holmqvist Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
3840174267aSFredrik Holmqvist
3850174267aSFredrik Holmqvist /* Ensure that we have a valid GPE number */
3860174267aSFredrik Holmqvist
3870174267aSFredrik Holmqvist GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
3880174267aSFredrik Holmqvist if (!GpeEventInfo)
3890174267aSFredrik Holmqvist {
3900174267aSFredrik Holmqvist Status = AE_BAD_PARAMETER;
3910174267aSFredrik Holmqvist goto UnlockAndExit;
3920174267aSFredrik Holmqvist }
3930174267aSFredrik Holmqvist
3940174267aSFredrik Holmqvist /* Perform the action */
3950174267aSFredrik Holmqvist
3960174267aSFredrik Holmqvist switch (Action)
3970174267aSFredrik Holmqvist {
3980174267aSFredrik Holmqvist case ACPI_GPE_ENABLE:
399c70258b7SJérôme Duval
400e226d1d0SFredrik Holmqvist Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE);
401ff2e2f81SFredrik Holmqvist GpeEventInfo->DisableForDispatch = FALSE;
4020174267aSFredrik Holmqvist break;
4030174267aSFredrik Holmqvist
4040174267aSFredrik Holmqvist case ACPI_GPE_DISABLE:
405c70258b7SJérôme Duval
4060174267aSFredrik Holmqvist Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
407ff2e2f81SFredrik Holmqvist GpeEventInfo->DisableForDispatch = TRUE;
4080174267aSFredrik Holmqvist break;
4090174267aSFredrik Holmqvist
4100174267aSFredrik Holmqvist default:
411c70258b7SJérôme Duval
4120174267aSFredrik Holmqvist Status = AE_BAD_PARAMETER;
4130174267aSFredrik Holmqvist break;
4140174267aSFredrik Holmqvist }
4150174267aSFredrik Holmqvist
4160174267aSFredrik Holmqvist UnlockAndExit:
4170174267aSFredrik Holmqvist AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
4180174267aSFredrik Holmqvist return_ACPI_STATUS (Status);
4190174267aSFredrik Holmqvist }
4200174267aSFredrik Holmqvist
ACPI_EXPORT_SYMBOL(AcpiSetGpe)4210174267aSFredrik Holmqvist ACPI_EXPORT_SYMBOL (AcpiSetGpe)
4220174267aSFredrik Holmqvist
4230174267aSFredrik Holmqvist
4240174267aSFredrik Holmqvist /*******************************************************************************
4250174267aSFredrik Holmqvist *
426ff2e2f81SFredrik Holmqvist * FUNCTION: AcpiMaskGpe
427ff2e2f81SFredrik Holmqvist *
428ff2e2f81SFredrik Holmqvist * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
429ff2e2f81SFredrik Holmqvist * GpeNumber - GPE level within the GPE block
430ff2e2f81SFredrik Holmqvist * IsMasked - Whether the GPE is masked or not
431ff2e2f81SFredrik Holmqvist *
432ff2e2f81SFredrik Holmqvist * RETURN: Status
433ff2e2f81SFredrik Holmqvist *
434ff2e2f81SFredrik Holmqvist * DESCRIPTION: Unconditionally mask/unmask the an individual GPE, ex., to
435ff2e2f81SFredrik Holmqvist * prevent a GPE flooding.
436ff2e2f81SFredrik Holmqvist *
437ff2e2f81SFredrik Holmqvist ******************************************************************************/
438ff2e2f81SFredrik Holmqvist
439ff2e2f81SFredrik Holmqvist ACPI_STATUS
440ff2e2f81SFredrik Holmqvist AcpiMaskGpe (
441ff2e2f81SFredrik Holmqvist ACPI_HANDLE GpeDevice,
442ff2e2f81SFredrik Holmqvist UINT32 GpeNumber,
443ff2e2f81SFredrik Holmqvist BOOLEAN IsMasked)
444ff2e2f81SFredrik Holmqvist {
445ff2e2f81SFredrik Holmqvist ACPI_GPE_EVENT_INFO *GpeEventInfo;
446ff2e2f81SFredrik Holmqvist ACPI_STATUS Status;
447ff2e2f81SFredrik Holmqvist ACPI_CPU_FLAGS Flags;
448ff2e2f81SFredrik Holmqvist
449ff2e2f81SFredrik Holmqvist
450ff2e2f81SFredrik Holmqvist ACPI_FUNCTION_TRACE (AcpiMaskGpe);
451ff2e2f81SFredrik Holmqvist
452ff2e2f81SFredrik Holmqvist
453ff2e2f81SFredrik Holmqvist Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
454ff2e2f81SFredrik Holmqvist
455ff2e2f81SFredrik Holmqvist /* Ensure that we have a valid GPE number */
456ff2e2f81SFredrik Holmqvist
457ff2e2f81SFredrik Holmqvist GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
458ff2e2f81SFredrik Holmqvist if (!GpeEventInfo)
459ff2e2f81SFredrik Holmqvist {
460ff2e2f81SFredrik Holmqvist Status = AE_BAD_PARAMETER;
461ff2e2f81SFredrik Holmqvist goto UnlockAndExit;
462ff2e2f81SFredrik Holmqvist }
463ff2e2f81SFredrik Holmqvist
464ff2e2f81SFredrik Holmqvist Status = AcpiEvMaskGpe (GpeEventInfo, IsMasked);
465ff2e2f81SFredrik Holmqvist
466ff2e2f81SFredrik Holmqvist UnlockAndExit:
467ff2e2f81SFredrik Holmqvist AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
468ff2e2f81SFredrik Holmqvist return_ACPI_STATUS (Status);
469ff2e2f81SFredrik Holmqvist }
470ff2e2f81SFredrik Holmqvist
ACPI_EXPORT_SYMBOL(AcpiMaskGpe)471ff2e2f81SFredrik Holmqvist ACPI_EXPORT_SYMBOL (AcpiMaskGpe)
472ff2e2f81SFredrik Holmqvist
473ff2e2f81SFredrik Holmqvist
474ff2e2f81SFredrik Holmqvist /*******************************************************************************
475ff2e2f81SFredrik Holmqvist *
476ad5bbfb8SFredrik Holmqvist * FUNCTION: AcpiMarkGpeForWake
477ad5bbfb8SFredrik Holmqvist *
478ad5bbfb8SFredrik Holmqvist * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
479ad5bbfb8SFredrik Holmqvist * GpeNumber - GPE level within the GPE block
480ad5bbfb8SFredrik Holmqvist *
481ad5bbfb8SFredrik Holmqvist * RETURN: Status
482ad5bbfb8SFredrik Holmqvist *
483ad5bbfb8SFredrik Holmqvist * DESCRIPTION: Mark a GPE as having the ability to wake the system. Simply
484ad5bbfb8SFredrik Holmqvist * sets the ACPI_GPE_CAN_WAKE flag.
485ad5bbfb8SFredrik Holmqvist *
486ad5bbfb8SFredrik Holmqvist * Some potential callers of AcpiSetupGpeForWake may know in advance that
487ad5bbfb8SFredrik Holmqvist * there won't be any notify handlers installed for device wake notifications
488ad5bbfb8SFredrik Holmqvist * from the given GPE (one example is a button GPE in Linux). For these cases,
489ad5bbfb8SFredrik Holmqvist * AcpiMarkGpeForWake should be used instead of AcpiSetupGpeForWake.
490ad5bbfb8SFredrik Holmqvist * This will set the ACPI_GPE_CAN_WAKE flag for the GPE without trying to
491ad5bbfb8SFredrik Holmqvist * setup implicit wake notification for it (since there's no handler method).
492ad5bbfb8SFredrik Holmqvist *
493ad5bbfb8SFredrik Holmqvist ******************************************************************************/
494ad5bbfb8SFredrik Holmqvist
495ad5bbfb8SFredrik Holmqvist ACPI_STATUS
496ad5bbfb8SFredrik Holmqvist AcpiMarkGpeForWake (
497ad5bbfb8SFredrik Holmqvist ACPI_HANDLE GpeDevice,
498ad5bbfb8SFredrik Holmqvist UINT32 GpeNumber)
499ad5bbfb8SFredrik Holmqvist {
500ad5bbfb8SFredrik Holmqvist ACPI_GPE_EVENT_INFO *GpeEventInfo;
501ad5bbfb8SFredrik Holmqvist ACPI_STATUS Status = AE_BAD_PARAMETER;
502ad5bbfb8SFredrik Holmqvist ACPI_CPU_FLAGS Flags;
503ad5bbfb8SFredrik Holmqvist
504ad5bbfb8SFredrik Holmqvist
505ad5bbfb8SFredrik Holmqvist ACPI_FUNCTION_TRACE (AcpiMarkGpeForWake);
506ad5bbfb8SFredrik Holmqvist
507ad5bbfb8SFredrik Holmqvist
508ad5bbfb8SFredrik Holmqvist Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
509ad5bbfb8SFredrik Holmqvist
510ad5bbfb8SFredrik Holmqvist /* Ensure that we have a valid GPE number */
511ad5bbfb8SFredrik Holmqvist
512ad5bbfb8SFredrik Holmqvist GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
513ad5bbfb8SFredrik Holmqvist if (GpeEventInfo)
514ad5bbfb8SFredrik Holmqvist {
515ad5bbfb8SFredrik Holmqvist /* Mark the GPE as a possible wake event */
516ad5bbfb8SFredrik Holmqvist
517ad5bbfb8SFredrik Holmqvist GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
518ad5bbfb8SFredrik Holmqvist Status = AE_OK;
519ad5bbfb8SFredrik Holmqvist }
520ad5bbfb8SFredrik Holmqvist
521ad5bbfb8SFredrik Holmqvist AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
522ad5bbfb8SFredrik Holmqvist return_ACPI_STATUS (Status);
523ad5bbfb8SFredrik Holmqvist }
524ad5bbfb8SFredrik Holmqvist
ACPI_EXPORT_SYMBOL(AcpiMarkGpeForWake)525ad5bbfb8SFredrik Holmqvist ACPI_EXPORT_SYMBOL (AcpiMarkGpeForWake)
526ad5bbfb8SFredrik Holmqvist
527ad5bbfb8SFredrik Holmqvist
528ad5bbfb8SFredrik Holmqvist /*******************************************************************************
529ad5bbfb8SFredrik Holmqvist *
5300174267aSFredrik Holmqvist * FUNCTION: AcpiSetupGpeForWake
5310174267aSFredrik Holmqvist *
5320174267aSFredrik Holmqvist * PARAMETERS: WakeDevice - Device associated with the GPE (via _PRW)
5330174267aSFredrik Holmqvist * GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
5340174267aSFredrik Holmqvist * GpeNumber - GPE level within the GPE block
5350174267aSFredrik Holmqvist *
5360174267aSFredrik Holmqvist * RETURN: Status
5370174267aSFredrik Holmqvist *
5380174267aSFredrik Holmqvist * DESCRIPTION: Mark a GPE as having the ability to wake the system. This
5390174267aSFredrik Holmqvist * interface is intended to be used as the host executes the
5400174267aSFredrik Holmqvist * _PRW methods (Power Resources for Wake) in the system tables.
5410174267aSFredrik Holmqvist * Each _PRW appears under a Device Object (The WakeDevice), and
5420174267aSFredrik Holmqvist * contains the info for the wake GPE associated with the
5430174267aSFredrik Holmqvist * WakeDevice.
5440174267aSFredrik Holmqvist *
5450174267aSFredrik Holmqvist ******************************************************************************/
5460174267aSFredrik Holmqvist
5470174267aSFredrik Holmqvist ACPI_STATUS
5480174267aSFredrik Holmqvist AcpiSetupGpeForWake (
5490174267aSFredrik Holmqvist ACPI_HANDLE WakeDevice,
5500174267aSFredrik Holmqvist ACPI_HANDLE GpeDevice,
5510174267aSFredrik Holmqvist UINT32 GpeNumber)
5520174267aSFredrik Holmqvist {
5536822cda0SFredrik Holmqvist ACPI_STATUS Status;
5540174267aSFredrik Holmqvist ACPI_GPE_EVENT_INFO *GpeEventInfo;
5550174267aSFredrik Holmqvist ACPI_NAMESPACE_NODE *DeviceNode;
5566822cda0SFredrik Holmqvist ACPI_GPE_NOTIFY_INFO *Notify;
5576822cda0SFredrik Holmqvist ACPI_GPE_NOTIFY_INFO *NewNotify;
5580174267aSFredrik Holmqvist ACPI_CPU_FLAGS Flags;
5590174267aSFredrik Holmqvist
5600174267aSFredrik Holmqvist
5610174267aSFredrik Holmqvist ACPI_FUNCTION_TRACE (AcpiSetupGpeForWake);
5620174267aSFredrik Holmqvist
5630174267aSFredrik Holmqvist
5640174267aSFredrik Holmqvist /* Parameter Validation */
5650174267aSFredrik Holmqvist
5660174267aSFredrik Holmqvist if (!WakeDevice)
5670174267aSFredrik Holmqvist {
5680174267aSFredrik Holmqvist /*
5690174267aSFredrik Holmqvist * By forcing WakeDevice to be valid, we automatically enable the
5700174267aSFredrik Holmqvist * implicit notify feature on all hosts.
5710174267aSFredrik Holmqvist */
5720174267aSFredrik Holmqvist return_ACPI_STATUS (AE_BAD_PARAMETER);
5730174267aSFredrik Holmqvist }
5740174267aSFredrik Holmqvist
5750174267aSFredrik Holmqvist /* Handle root object case */
5760174267aSFredrik Holmqvist
5770174267aSFredrik Holmqvist if (WakeDevice == ACPI_ROOT_OBJECT)
5780174267aSFredrik Holmqvist {
5790174267aSFredrik Holmqvist DeviceNode = AcpiGbl_RootNode;
5800174267aSFredrik Holmqvist }
5810174267aSFredrik Holmqvist else
5820174267aSFredrik Holmqvist {
5830174267aSFredrik Holmqvist DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, WakeDevice);
5840174267aSFredrik Holmqvist }
5850174267aSFredrik Holmqvist
5860174267aSFredrik Holmqvist /* Validate WakeDevice is of type Device */
5870174267aSFredrik Holmqvist
5880174267aSFredrik Holmqvist if (DeviceNode->Type != ACPI_TYPE_DEVICE)
5890174267aSFredrik Holmqvist {
5900174267aSFredrik Holmqvist return_ACPI_STATUS (AE_BAD_PARAMETER);
5910174267aSFredrik Holmqvist }
5920174267aSFredrik Holmqvist
5936822cda0SFredrik Holmqvist /*
5946822cda0SFredrik Holmqvist * Allocate a new notify object up front, in case it is needed.
5956822cda0SFredrik Holmqvist * Memory allocation while holding a spinlock is a big no-no
5966822cda0SFredrik Holmqvist * on some hosts.
5976822cda0SFredrik Holmqvist */
5986822cda0SFredrik Holmqvist NewNotify = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_NOTIFY_INFO));
5996822cda0SFredrik Holmqvist if (!NewNotify)
6006822cda0SFredrik Holmqvist {
6016822cda0SFredrik Holmqvist return_ACPI_STATUS (AE_NO_MEMORY);
6026822cda0SFredrik Holmqvist }
6036822cda0SFredrik Holmqvist
6040174267aSFredrik Holmqvist Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
6050174267aSFredrik Holmqvist
6060174267aSFredrik Holmqvist /* Ensure that we have a valid GPE number */
6070174267aSFredrik Holmqvist
6080174267aSFredrik Holmqvist GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
6096822cda0SFredrik Holmqvist if (!GpeEventInfo)
6100174267aSFredrik Holmqvist {
6116822cda0SFredrik Holmqvist Status = AE_BAD_PARAMETER;
6126822cda0SFredrik Holmqvist goto UnlockAndExit;
6136822cda0SFredrik Holmqvist }
6146822cda0SFredrik Holmqvist
6150174267aSFredrik Holmqvist /*
6160174267aSFredrik Holmqvist * If there is no method or handler for this GPE, then the
6176822cda0SFredrik Holmqvist * WakeDevice will be notified whenever this GPE fires. This is
6186822cda0SFredrik Holmqvist * known as an "implicit notify". Note: The GPE is assumed to be
6190174267aSFredrik Holmqvist * level-triggered (for windows compatibility).
6200174267aSFredrik Holmqvist */
621e226d1d0SFredrik Holmqvist if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
6220174267aSFredrik Holmqvist ACPI_GPE_DISPATCH_NONE)
6230174267aSFredrik Holmqvist {
6246822cda0SFredrik Holmqvist /*
6256822cda0SFredrik Holmqvist * This is the first device for implicit notify on this GPE.
6266822cda0SFredrik Holmqvist * Just set the flags here, and enter the NOTIFY block below.
6276822cda0SFredrik Holmqvist */
6280174267aSFredrik Holmqvist GpeEventInfo->Flags =
6290174267aSFredrik Holmqvist (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED);
6300174267aSFredrik Holmqvist }
63108c9948cSFredrik Holmqvist else if (GpeEventInfo->Flags & ACPI_GPE_AUTO_ENABLED)
63208c9948cSFredrik Holmqvist {
63308c9948cSFredrik Holmqvist /*
63408c9948cSFredrik Holmqvist * A reference to this GPE has been added during the GPE block
63508c9948cSFredrik Holmqvist * initialization, so drop it now to prevent the GPE from being
63608c9948cSFredrik Holmqvist * permanently enabled and clear its ACPI_GPE_AUTO_ENABLED flag.
63708c9948cSFredrik Holmqvist */
63808c9948cSFredrik Holmqvist (void) AcpiEvRemoveGpeReference (GpeEventInfo);
639*6dde014fSPulkoMandy GpeEventInfo->Flags &= ~ACPI_GPE_AUTO_ENABLED;
64008c9948cSFredrik Holmqvist }
6410174267aSFredrik Holmqvist
6426822cda0SFredrik Holmqvist /*
6436822cda0SFredrik Holmqvist * If we already have an implicit notify on this GPE, add
6446822cda0SFredrik Holmqvist * this device to the notify list.
6456822cda0SFredrik Holmqvist */
646e226d1d0SFredrik Holmqvist if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
6476822cda0SFredrik Holmqvist ACPI_GPE_DISPATCH_NOTIFY)
6486822cda0SFredrik Holmqvist {
6496822cda0SFredrik Holmqvist /* Ensure that the device is not already in the list */
6506822cda0SFredrik Holmqvist
6516822cda0SFredrik Holmqvist Notify = GpeEventInfo->Dispatch.NotifyList;
6526822cda0SFredrik Holmqvist while (Notify)
6536822cda0SFredrik Holmqvist {
6546822cda0SFredrik Holmqvist if (Notify->DeviceNode == DeviceNode)
6556822cda0SFredrik Holmqvist {
6566822cda0SFredrik Holmqvist Status = AE_ALREADY_EXISTS;
6576822cda0SFredrik Holmqvist goto UnlockAndExit;
6586822cda0SFredrik Holmqvist }
6596822cda0SFredrik Holmqvist Notify = Notify->Next;
6606822cda0SFredrik Holmqvist }
6616822cda0SFredrik Holmqvist
6626822cda0SFredrik Holmqvist /* Add this device to the notify list for this GPE */
6636822cda0SFredrik Holmqvist
6646822cda0SFredrik Holmqvist NewNotify->DeviceNode = DeviceNode;
6656822cda0SFredrik Holmqvist NewNotify->Next = GpeEventInfo->Dispatch.NotifyList;
6666822cda0SFredrik Holmqvist GpeEventInfo->Dispatch.NotifyList = NewNotify;
6676822cda0SFredrik Holmqvist NewNotify = NULL;
6686822cda0SFredrik Holmqvist }
6696822cda0SFredrik Holmqvist
6706822cda0SFredrik Holmqvist /* Mark the GPE as a possible wake event */
6716822cda0SFredrik Holmqvist
6720174267aSFredrik Holmqvist GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
6730174267aSFredrik Holmqvist Status = AE_OK;
6740174267aSFredrik Holmqvist
6756822cda0SFredrik Holmqvist
6766822cda0SFredrik Holmqvist UnlockAndExit:
6770174267aSFredrik Holmqvist AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
6786822cda0SFredrik Holmqvist
6796822cda0SFredrik Holmqvist /* Delete the notify object if it was not used above */
6806822cda0SFredrik Holmqvist
6816822cda0SFredrik Holmqvist if (NewNotify)
6826822cda0SFredrik Holmqvist {
6836822cda0SFredrik Holmqvist ACPI_FREE (NewNotify);
6846822cda0SFredrik Holmqvist }
6850174267aSFredrik Holmqvist return_ACPI_STATUS (Status);
6860174267aSFredrik Holmqvist }
6870174267aSFredrik Holmqvist
ACPI_EXPORT_SYMBOL(AcpiSetupGpeForWake)6880174267aSFredrik Holmqvist ACPI_EXPORT_SYMBOL (AcpiSetupGpeForWake)
6890174267aSFredrik Holmqvist
6900174267aSFredrik Holmqvist
6910174267aSFredrik Holmqvist /*******************************************************************************
6920174267aSFredrik Holmqvist *
6930174267aSFredrik Holmqvist * FUNCTION: AcpiSetGpeWakeMask
6940174267aSFredrik Holmqvist *
6950174267aSFredrik Holmqvist * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
6960174267aSFredrik Holmqvist * GpeNumber - GPE level within the GPE block
6970174267aSFredrik Holmqvist * Action - Enable or Disable
6980174267aSFredrik Holmqvist *
6990174267aSFredrik Holmqvist * RETURN: Status
7000174267aSFredrik Holmqvist *
7010174267aSFredrik Holmqvist * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must
7020174267aSFredrik Holmqvist * already be marked as a WAKE GPE.
7030174267aSFredrik Holmqvist *
7040174267aSFredrik Holmqvist ******************************************************************************/
7050174267aSFredrik Holmqvist
7060174267aSFredrik Holmqvist ACPI_STATUS
7070174267aSFredrik Holmqvist AcpiSetGpeWakeMask (
7080174267aSFredrik Holmqvist ACPI_HANDLE GpeDevice,
7090174267aSFredrik Holmqvist UINT32 GpeNumber,
7100174267aSFredrik Holmqvist UINT8 Action)
7110174267aSFredrik Holmqvist {
7120174267aSFredrik Holmqvist ACPI_STATUS Status = AE_OK;
7130174267aSFredrik Holmqvist ACPI_GPE_EVENT_INFO *GpeEventInfo;
7140174267aSFredrik Holmqvist ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
7150174267aSFredrik Holmqvist ACPI_CPU_FLAGS Flags;
7160174267aSFredrik Holmqvist UINT32 RegisterBit;
7170174267aSFredrik Holmqvist
7180174267aSFredrik Holmqvist
7190174267aSFredrik Holmqvist ACPI_FUNCTION_TRACE (AcpiSetGpeWakeMask);
7200174267aSFredrik Holmqvist
7210174267aSFredrik Holmqvist
7220174267aSFredrik Holmqvist Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
7230174267aSFredrik Holmqvist
7240174267aSFredrik Holmqvist /*
7250174267aSFredrik Holmqvist * Ensure that we have a valid GPE number and that this GPE is in
7260174267aSFredrik Holmqvist * fact a wake GPE
7270174267aSFredrik Holmqvist */
7280174267aSFredrik Holmqvist GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
7290174267aSFredrik Holmqvist if (!GpeEventInfo)
7300174267aSFredrik Holmqvist {
7310174267aSFredrik Holmqvist Status = AE_BAD_PARAMETER;
7320174267aSFredrik Holmqvist goto UnlockAndExit;
7330174267aSFredrik Holmqvist }
7340174267aSFredrik Holmqvist
7350174267aSFredrik Holmqvist if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE))
7360174267aSFredrik Holmqvist {
7370174267aSFredrik Holmqvist Status = AE_TYPE;
7380174267aSFredrik Holmqvist goto UnlockAndExit;
7390174267aSFredrik Holmqvist }
7400174267aSFredrik Holmqvist
7410174267aSFredrik Holmqvist GpeRegisterInfo = GpeEventInfo->RegisterInfo;
7420174267aSFredrik Holmqvist if (!GpeRegisterInfo)
7430174267aSFredrik Holmqvist {
7440174267aSFredrik Holmqvist Status = AE_NOT_EXIST;
7450174267aSFredrik Holmqvist goto UnlockAndExit;
7460174267aSFredrik Holmqvist }
7470174267aSFredrik Holmqvist
7489b0d045cSFredrik Holmqvist RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo);
7490174267aSFredrik Holmqvist
7500174267aSFredrik Holmqvist /* Perform the action */
7510174267aSFredrik Holmqvist
7520174267aSFredrik Holmqvist switch (Action)
7530174267aSFredrik Holmqvist {
7540174267aSFredrik Holmqvist case ACPI_GPE_ENABLE:
755c70258b7SJérôme Duval
7560174267aSFredrik Holmqvist ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
7570174267aSFredrik Holmqvist break;
7580174267aSFredrik Holmqvist
7590174267aSFredrik Holmqvist case ACPI_GPE_DISABLE:
760c70258b7SJérôme Duval
7610174267aSFredrik Holmqvist ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
7620174267aSFredrik Holmqvist break;
7630174267aSFredrik Holmqvist
7640174267aSFredrik Holmqvist default:
765c70258b7SJérôme Duval
7660174267aSFredrik Holmqvist ACPI_ERROR ((AE_INFO, "%u, Invalid action", Action));
7670174267aSFredrik Holmqvist Status = AE_BAD_PARAMETER;
7680174267aSFredrik Holmqvist break;
7690174267aSFredrik Holmqvist }
7700174267aSFredrik Holmqvist
7710174267aSFredrik Holmqvist UnlockAndExit:
7720174267aSFredrik Holmqvist AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
7730174267aSFredrik Holmqvist return_ACPI_STATUS (Status);
7740174267aSFredrik Holmqvist }
7750174267aSFredrik Holmqvist
ACPI_EXPORT_SYMBOL(AcpiSetGpeWakeMask)7760174267aSFredrik Holmqvist ACPI_EXPORT_SYMBOL (AcpiSetGpeWakeMask)
7770174267aSFredrik Holmqvist
7780174267aSFredrik Holmqvist
7790174267aSFredrik Holmqvist /*******************************************************************************
7800174267aSFredrik Holmqvist *
7810174267aSFredrik Holmqvist * FUNCTION: AcpiClearGpe
7820174267aSFredrik Holmqvist *
7830174267aSFredrik Holmqvist * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
7840174267aSFredrik Holmqvist * GpeNumber - GPE level within the GPE block
7850174267aSFredrik Holmqvist *
7860174267aSFredrik Holmqvist * RETURN: Status
7870174267aSFredrik Holmqvist *
7880174267aSFredrik Holmqvist * DESCRIPTION: Clear an ACPI event (general purpose)
7890174267aSFredrik Holmqvist *
7900174267aSFredrik Holmqvist ******************************************************************************/
7910174267aSFredrik Holmqvist
7920174267aSFredrik Holmqvist ACPI_STATUS
7930174267aSFredrik Holmqvist AcpiClearGpe (
7940174267aSFredrik Holmqvist ACPI_HANDLE GpeDevice,
7950174267aSFredrik Holmqvist UINT32 GpeNumber)
7960174267aSFredrik Holmqvist {
7970174267aSFredrik Holmqvist ACPI_STATUS Status = AE_OK;
7980174267aSFredrik Holmqvist ACPI_GPE_EVENT_INFO *GpeEventInfo;
7990174267aSFredrik Holmqvist ACPI_CPU_FLAGS Flags;
8000174267aSFredrik Holmqvist
8010174267aSFredrik Holmqvist
8020174267aSFredrik Holmqvist ACPI_FUNCTION_TRACE (AcpiClearGpe);
8030174267aSFredrik Holmqvist
8040174267aSFredrik Holmqvist
8050174267aSFredrik Holmqvist Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
8060174267aSFredrik Holmqvist
8070174267aSFredrik Holmqvist /* Ensure that we have a valid GPE number */
8080174267aSFredrik Holmqvist
8090174267aSFredrik Holmqvist GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
8100174267aSFredrik Holmqvist if (!GpeEventInfo)
8110174267aSFredrik Holmqvist {
8120174267aSFredrik Holmqvist Status = AE_BAD_PARAMETER;
8130174267aSFredrik Holmqvist goto UnlockAndExit;
8140174267aSFredrik Holmqvist }
8150174267aSFredrik Holmqvist
8160174267aSFredrik Holmqvist Status = AcpiHwClearGpe (GpeEventInfo);
8170174267aSFredrik Holmqvist
8180174267aSFredrik Holmqvist UnlockAndExit:
8190174267aSFredrik Holmqvist AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
8200174267aSFredrik Holmqvist return_ACPI_STATUS (Status);
8210174267aSFredrik Holmqvist }
8220174267aSFredrik Holmqvist
ACPI_EXPORT_SYMBOL(AcpiClearGpe)8230174267aSFredrik Holmqvist ACPI_EXPORT_SYMBOL (AcpiClearGpe)
8240174267aSFredrik Holmqvist
8250174267aSFredrik Holmqvist
8260174267aSFredrik Holmqvist /*******************************************************************************
8270174267aSFredrik Holmqvist *
8280174267aSFredrik Holmqvist * FUNCTION: AcpiGetGpeStatus
8290174267aSFredrik Holmqvist *
8300174267aSFredrik Holmqvist * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
8310174267aSFredrik Holmqvist * GpeNumber - GPE level within the GPE block
8320174267aSFredrik Holmqvist * EventStatus - Where the current status of the event
8330174267aSFredrik Holmqvist * will be returned
8340174267aSFredrik Holmqvist *
8350174267aSFredrik Holmqvist * RETURN: Status
8360174267aSFredrik Holmqvist *
8370174267aSFredrik Holmqvist * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled)
8380174267aSFredrik Holmqvist *
8390174267aSFredrik Holmqvist ******************************************************************************/
8400174267aSFredrik Holmqvist
8410174267aSFredrik Holmqvist ACPI_STATUS
8420174267aSFredrik Holmqvist AcpiGetGpeStatus (
8430174267aSFredrik Holmqvist ACPI_HANDLE GpeDevice,
8440174267aSFredrik Holmqvist UINT32 GpeNumber,
8450174267aSFredrik Holmqvist ACPI_EVENT_STATUS *EventStatus)
8460174267aSFredrik Holmqvist {
8470174267aSFredrik Holmqvist ACPI_STATUS Status = AE_OK;
8480174267aSFredrik Holmqvist ACPI_GPE_EVENT_INFO *GpeEventInfo;
8490174267aSFredrik Holmqvist ACPI_CPU_FLAGS Flags;
8500174267aSFredrik Holmqvist
8510174267aSFredrik Holmqvist
8520174267aSFredrik Holmqvist ACPI_FUNCTION_TRACE (AcpiGetGpeStatus);
8530174267aSFredrik Holmqvist
8540174267aSFredrik Holmqvist
8550174267aSFredrik Holmqvist Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
8560174267aSFredrik Holmqvist
8570174267aSFredrik Holmqvist /* Ensure that we have a valid GPE number */
8580174267aSFredrik Holmqvist
8590174267aSFredrik Holmqvist GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
8600174267aSFredrik Holmqvist if (!GpeEventInfo)
8610174267aSFredrik Holmqvist {
8620174267aSFredrik Holmqvist Status = AE_BAD_PARAMETER;
8630174267aSFredrik Holmqvist goto UnlockAndExit;
8640174267aSFredrik Holmqvist }
8650174267aSFredrik Holmqvist
8660174267aSFredrik Holmqvist /* Obtain status on the requested GPE number */
8670174267aSFredrik Holmqvist
8680174267aSFredrik Holmqvist Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus);
8690174267aSFredrik Holmqvist
8700174267aSFredrik Holmqvist UnlockAndExit:
8710174267aSFredrik Holmqvist AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
8720174267aSFredrik Holmqvist return_ACPI_STATUS (Status);
8730174267aSFredrik Holmqvist }
8740174267aSFredrik Holmqvist
ACPI_EXPORT_SYMBOL(AcpiGetGpeStatus)8750174267aSFredrik Holmqvist ACPI_EXPORT_SYMBOL (AcpiGetGpeStatus)
8760174267aSFredrik Holmqvist
8770174267aSFredrik Holmqvist
8780174267aSFredrik Holmqvist /*******************************************************************************
8790174267aSFredrik Holmqvist *
8800ffed378SFredrik Holmqvist * FUNCTION: AcpiDispatchGpe
8810ffed378SFredrik Holmqvist *
8820ffed378SFredrik Holmqvist * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
8830ffed378SFredrik Holmqvist * GpeNumber - GPE level within the GPE block
8840ffed378SFredrik Holmqvist *
8850ffed378SFredrik Holmqvist * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
8860ffed378SFredrik Holmqvist *
8870ffed378SFredrik Holmqvist * DESCRIPTION: Detect and dispatch a General Purpose Event to either a function
8880ffed378SFredrik Holmqvist * (e.g. EC) or method (e.g. _Lxx/_Exx) handler.
8890ffed378SFredrik Holmqvist *
8900ffed378SFredrik Holmqvist ******************************************************************************/
8910ffed378SFredrik Holmqvist
8920ffed378SFredrik Holmqvist UINT32
8930ffed378SFredrik Holmqvist AcpiDispatchGpe(
8940ffed378SFredrik Holmqvist ACPI_HANDLE GpeDevice,
8950ffed378SFredrik Holmqvist UINT32 GpeNumber)
8960ffed378SFredrik Holmqvist {
8970ffed378SFredrik Holmqvist ACPI_FUNCTION_TRACE(acpi_dispatch_gpe);
8980ffed378SFredrik Holmqvist
8990ffed378SFredrik Holmqvist return (AcpiEvDetectGpe (GpeDevice, NULL, GpeNumber));
9000ffed378SFredrik Holmqvist }
9010ffed378SFredrik Holmqvist
ACPI_EXPORT_SYMBOL(AcpiDispatchGpe)9020ffed378SFredrik Holmqvist ACPI_EXPORT_SYMBOL (AcpiDispatchGpe)
9030ffed378SFredrik Holmqvist
9040ffed378SFredrik Holmqvist
9050ffed378SFredrik Holmqvist /*******************************************************************************
9060ffed378SFredrik Holmqvist *
9070174267aSFredrik Holmqvist * FUNCTION: AcpiFinishGpe
9080174267aSFredrik Holmqvist *
9090174267aSFredrik Holmqvist * PARAMETERS: GpeDevice - Namespace node for the GPE Block
9100174267aSFredrik Holmqvist * (NULL for FADT defined GPEs)
9110174267aSFredrik Holmqvist * GpeNumber - GPE level within the GPE block
9120174267aSFredrik Holmqvist *
9130174267aSFredrik Holmqvist * RETURN: Status
9140174267aSFredrik Holmqvist *
9150ffed378SFredrik Holmqvist * DESCRIPTION: Clear and conditionally re-enable a GPE. This completes the GPE
9160174267aSFredrik Holmqvist * processing. Intended for use by asynchronous host-installed
9170ffed378SFredrik Holmqvist * GPE handlers. The GPE is only re-enabled if the EnableForRun bit
9180174267aSFredrik Holmqvist * is set in the GPE info.
9190174267aSFredrik Holmqvist *
9200174267aSFredrik Holmqvist ******************************************************************************/
9210174267aSFredrik Holmqvist
9220174267aSFredrik Holmqvist ACPI_STATUS
9230174267aSFredrik Holmqvist AcpiFinishGpe (
9240174267aSFredrik Holmqvist ACPI_HANDLE GpeDevice,
9250174267aSFredrik Holmqvist UINT32 GpeNumber)
9260174267aSFredrik Holmqvist {
9270174267aSFredrik Holmqvist ACPI_GPE_EVENT_INFO *GpeEventInfo;
9280174267aSFredrik Holmqvist ACPI_STATUS Status;
9290174267aSFredrik Holmqvist ACPI_CPU_FLAGS Flags;
9300174267aSFredrik Holmqvist
9310174267aSFredrik Holmqvist
9320174267aSFredrik Holmqvist ACPI_FUNCTION_TRACE (AcpiFinishGpe);
9330174267aSFredrik Holmqvist
9340174267aSFredrik Holmqvist
9350174267aSFredrik Holmqvist Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
9360174267aSFredrik Holmqvist
9370174267aSFredrik Holmqvist /* Ensure that we have a valid GPE number */
9380174267aSFredrik Holmqvist
9390174267aSFredrik Holmqvist GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
9400174267aSFredrik Holmqvist if (!GpeEventInfo)
9410174267aSFredrik Holmqvist {
9420174267aSFredrik Holmqvist Status = AE_BAD_PARAMETER;
9430174267aSFredrik Holmqvist goto UnlockAndExit;
9440174267aSFredrik Holmqvist }
9450174267aSFredrik Holmqvist
9460174267aSFredrik Holmqvist Status = AcpiEvFinishGpe (GpeEventInfo);
9470174267aSFredrik Holmqvist
9480174267aSFredrik Holmqvist UnlockAndExit:
9490174267aSFredrik Holmqvist AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
9500174267aSFredrik Holmqvist return_ACPI_STATUS (Status);
9510174267aSFredrik Holmqvist }
9520174267aSFredrik Holmqvist
ACPI_EXPORT_SYMBOL(AcpiFinishGpe)9530174267aSFredrik Holmqvist ACPI_EXPORT_SYMBOL (AcpiFinishGpe)
9540174267aSFredrik Holmqvist
9550174267aSFredrik Holmqvist
9560174267aSFredrik Holmqvist /******************************************************************************
9570174267aSFredrik Holmqvist *
9580174267aSFredrik Holmqvist * FUNCTION: AcpiDisableAllGpes
9590174267aSFredrik Holmqvist *
9600174267aSFredrik Holmqvist * PARAMETERS: None
9610174267aSFredrik Holmqvist *
9620174267aSFredrik Holmqvist * RETURN: Status
9630174267aSFredrik Holmqvist *
9640174267aSFredrik Holmqvist * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
9650174267aSFredrik Holmqvist *
9660174267aSFredrik Holmqvist ******************************************************************************/
9670174267aSFredrik Holmqvist
9680174267aSFredrik Holmqvist ACPI_STATUS
9690174267aSFredrik Holmqvist AcpiDisableAllGpes (
9700174267aSFredrik Holmqvist void)
9710174267aSFredrik Holmqvist {
9720174267aSFredrik Holmqvist ACPI_STATUS Status;
9730174267aSFredrik Holmqvist
9740174267aSFredrik Holmqvist
9750174267aSFredrik Holmqvist ACPI_FUNCTION_TRACE (AcpiDisableAllGpes);
9760174267aSFredrik Holmqvist
9770174267aSFredrik Holmqvist
9780174267aSFredrik Holmqvist Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
9790174267aSFredrik Holmqvist if (ACPI_FAILURE (Status))
9800174267aSFredrik Holmqvist {
9810174267aSFredrik Holmqvist return_ACPI_STATUS (Status);
9820174267aSFredrik Holmqvist }
9830174267aSFredrik Holmqvist
9840174267aSFredrik Holmqvist Status = AcpiHwDisableAllGpes ();
9850174267aSFredrik Holmqvist (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
9860174267aSFredrik Holmqvist
9870174267aSFredrik Holmqvist return_ACPI_STATUS (Status);
9880174267aSFredrik Holmqvist }
9890174267aSFredrik Holmqvist
ACPI_EXPORT_SYMBOL(AcpiDisableAllGpes)9900174267aSFredrik Holmqvist ACPI_EXPORT_SYMBOL (AcpiDisableAllGpes)
9910174267aSFredrik Holmqvist
9920174267aSFredrik Holmqvist
9930174267aSFredrik Holmqvist /******************************************************************************
9940174267aSFredrik Holmqvist *
9950174267aSFredrik Holmqvist * FUNCTION: AcpiEnableAllRuntimeGpes
9960174267aSFredrik Holmqvist *
9970174267aSFredrik Holmqvist * PARAMETERS: None
9980174267aSFredrik Holmqvist *
9990174267aSFredrik Holmqvist * RETURN: Status
10000174267aSFredrik Holmqvist *
10010174267aSFredrik Holmqvist * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
10020174267aSFredrik Holmqvist *
10030174267aSFredrik Holmqvist ******************************************************************************/
10040174267aSFredrik Holmqvist
10050174267aSFredrik Holmqvist ACPI_STATUS
10060174267aSFredrik Holmqvist AcpiEnableAllRuntimeGpes (
10070174267aSFredrik Holmqvist void)
10080174267aSFredrik Holmqvist {
10090174267aSFredrik Holmqvist ACPI_STATUS Status;
10100174267aSFredrik Holmqvist
10110174267aSFredrik Holmqvist
10120174267aSFredrik Holmqvist ACPI_FUNCTION_TRACE (AcpiEnableAllRuntimeGpes);
10130174267aSFredrik Holmqvist
10140174267aSFredrik Holmqvist
10150174267aSFredrik Holmqvist Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
10160174267aSFredrik Holmqvist if (ACPI_FAILURE (Status))
10170174267aSFredrik Holmqvist {
10180174267aSFredrik Holmqvist return_ACPI_STATUS (Status);
10190174267aSFredrik Holmqvist }
10200174267aSFredrik Holmqvist
10210174267aSFredrik Holmqvist Status = AcpiHwEnableAllRuntimeGpes ();
10220174267aSFredrik Holmqvist (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
10230174267aSFredrik Holmqvist
10240174267aSFredrik Holmqvist return_ACPI_STATUS (Status);
10250174267aSFredrik Holmqvist }
10260174267aSFredrik Holmqvist
ACPI_EXPORT_SYMBOL(AcpiEnableAllRuntimeGpes)10270174267aSFredrik Holmqvist ACPI_EXPORT_SYMBOL (AcpiEnableAllRuntimeGpes)
10280174267aSFredrik Holmqvist
10290174267aSFredrik Holmqvist
1030e226d1d0SFredrik Holmqvist /******************************************************************************
1031e226d1d0SFredrik Holmqvist *
1032e226d1d0SFredrik Holmqvist * FUNCTION: AcpiEnableAllWakeupGpes
1033e226d1d0SFredrik Holmqvist *
1034e226d1d0SFredrik Holmqvist * PARAMETERS: None
1035e226d1d0SFredrik Holmqvist *
1036e226d1d0SFredrik Holmqvist * RETURN: Status
1037e226d1d0SFredrik Holmqvist *
1038e226d1d0SFredrik Holmqvist * DESCRIPTION: Enable all "wakeup" GPEs and disable all of the other GPEs, in
1039e226d1d0SFredrik Holmqvist * all GPE blocks.
1040e226d1d0SFredrik Holmqvist *
1041e226d1d0SFredrik Holmqvist ******************************************************************************/
1042e226d1d0SFredrik Holmqvist
1043e226d1d0SFredrik Holmqvist ACPI_STATUS
1044e226d1d0SFredrik Holmqvist AcpiEnableAllWakeupGpes (
1045e226d1d0SFredrik Holmqvist void)
1046e226d1d0SFredrik Holmqvist {
1047e226d1d0SFredrik Holmqvist ACPI_STATUS Status;
1048e226d1d0SFredrik Holmqvist
1049e226d1d0SFredrik Holmqvist
1050e226d1d0SFredrik Holmqvist ACPI_FUNCTION_TRACE (AcpiEnableAllWakeupGpes);
1051e226d1d0SFredrik Holmqvist
1052e226d1d0SFredrik Holmqvist
1053e226d1d0SFredrik Holmqvist Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
1054e226d1d0SFredrik Holmqvist if (ACPI_FAILURE (Status))
1055e226d1d0SFredrik Holmqvist {
1056e226d1d0SFredrik Holmqvist return_ACPI_STATUS (Status);
1057e226d1d0SFredrik Holmqvist }
1058e226d1d0SFredrik Holmqvist
1059e226d1d0SFredrik Holmqvist Status = AcpiHwEnableAllWakeupGpes ();
1060e226d1d0SFredrik Holmqvist (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
1061e226d1d0SFredrik Holmqvist
1062e226d1d0SFredrik Holmqvist return_ACPI_STATUS (Status);
1063e226d1d0SFredrik Holmqvist }
1064e226d1d0SFredrik Holmqvist
ACPI_EXPORT_SYMBOL(AcpiEnableAllWakeupGpes)1065e226d1d0SFredrik Holmqvist ACPI_EXPORT_SYMBOL (AcpiEnableAllWakeupGpes)
1066e226d1d0SFredrik Holmqvist
1067e226d1d0SFredrik Holmqvist
10680ffed378SFredrik Holmqvist /******************************************************************************
10690ffed378SFredrik Holmqvist *
10700ffed378SFredrik Holmqvist * FUNCTION: AcpiAnyGpeStatusSet
10710ffed378SFredrik Holmqvist *
10720ffed378SFredrik Holmqvist * PARAMETERS: None
10730ffed378SFredrik Holmqvist *
10740ffed378SFredrik Holmqvist * RETURN: Whether or not the status bit is set for any GPE
10750ffed378SFredrik Holmqvist *
10760ffed378SFredrik Holmqvist * DESCRIPTION: Check the status bits of all enabled GPEs and return TRUE if any
10770ffed378SFredrik Holmqvist * of them is set or FALSE otherwise.
10780ffed378SFredrik Holmqvist *
10790ffed378SFredrik Holmqvist ******************************************************************************/
10800ffed378SFredrik Holmqvist
10810ffed378SFredrik Holmqvist UINT32
10820ffed378SFredrik Holmqvist AcpiAnyGpeStatusSet (
10830ffed378SFredrik Holmqvist void)
10840ffed378SFredrik Holmqvist {
10850ffed378SFredrik Holmqvist ACPI_STATUS Status;
10860ffed378SFredrik Holmqvist UINT8 Ret;
10870ffed378SFredrik Holmqvist
10880ffed378SFredrik Holmqvist
10890ffed378SFredrik Holmqvist ACPI_FUNCTION_TRACE (AcpiAnyGpeStatusSet);
10900ffed378SFredrik Holmqvist
10910ffed378SFredrik Holmqvist Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
10920ffed378SFredrik Holmqvist if (ACPI_FAILURE (Status))
10930ffed378SFredrik Holmqvist {
10940ffed378SFredrik Holmqvist return (FALSE);
10950ffed378SFredrik Holmqvist }
10960ffed378SFredrik Holmqvist
10970ffed378SFredrik Holmqvist Ret = AcpiHwCheckAllGpes ();
10980ffed378SFredrik Holmqvist (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
10990ffed378SFredrik Holmqvist
11000ffed378SFredrik Holmqvist return (Ret);
11010ffed378SFredrik Holmqvist }
11020ffed378SFredrik Holmqvist
ACPI_EXPORT_SYMBOL(AcpiAnyGpeStatusSet)11030ffed378SFredrik Holmqvist ACPI_EXPORT_SYMBOL(AcpiAnyGpeStatusSet)
11040ffed378SFredrik Holmqvist
11050ffed378SFredrik Holmqvist
11060174267aSFredrik Holmqvist /*******************************************************************************
11070174267aSFredrik Holmqvist *
11080174267aSFredrik Holmqvist * FUNCTION: AcpiInstallGpeBlock
11090174267aSFredrik Holmqvist *
11100174267aSFredrik Holmqvist * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device
11110174267aSFredrik Holmqvist * GpeBlockAddress - Address and SpaceID
11120174267aSFredrik Holmqvist * RegisterCount - Number of GPE register pairs in the block
11130174267aSFredrik Holmqvist * InterruptNumber - H/W interrupt for the block
11140174267aSFredrik Holmqvist *
11150174267aSFredrik Holmqvist * RETURN: Status
11160174267aSFredrik Holmqvist *
11170174267aSFredrik Holmqvist * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not
11180174267aSFredrik Holmqvist * enabled here.
11190174267aSFredrik Holmqvist *
11200174267aSFredrik Holmqvist ******************************************************************************/
11210174267aSFredrik Holmqvist
11220174267aSFredrik Holmqvist ACPI_STATUS
11230174267aSFredrik Holmqvist AcpiInstallGpeBlock (
11240174267aSFredrik Holmqvist ACPI_HANDLE GpeDevice,
11250174267aSFredrik Holmqvist ACPI_GENERIC_ADDRESS *GpeBlockAddress,
11260174267aSFredrik Holmqvist UINT32 RegisterCount,
11270174267aSFredrik Holmqvist UINT32 InterruptNumber)
11280174267aSFredrik Holmqvist {
11290174267aSFredrik Holmqvist ACPI_STATUS Status;
11300174267aSFredrik Holmqvist ACPI_OPERAND_OBJECT *ObjDesc;
11310174267aSFredrik Holmqvist ACPI_NAMESPACE_NODE *Node;
11320174267aSFredrik Holmqvist ACPI_GPE_BLOCK_INFO *GpeBlock;
11330174267aSFredrik Holmqvist
11340174267aSFredrik Holmqvist
11350174267aSFredrik Holmqvist ACPI_FUNCTION_TRACE (AcpiInstallGpeBlock);
11360174267aSFredrik Holmqvist
11370174267aSFredrik Holmqvist
11380174267aSFredrik Holmqvist if ((!GpeDevice) ||
11390174267aSFredrik Holmqvist (!GpeBlockAddress) ||
11400174267aSFredrik Holmqvist (!RegisterCount))
11410174267aSFredrik Holmqvist {
11420174267aSFredrik Holmqvist return_ACPI_STATUS (AE_BAD_PARAMETER);
11430174267aSFredrik Holmqvist }
11440174267aSFredrik Holmqvist
11450174267aSFredrik Holmqvist Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
11460174267aSFredrik Holmqvist if (ACPI_FAILURE (Status))
11470174267aSFredrik Holmqvist {
11489b0d045cSFredrik Holmqvist return_ACPI_STATUS (Status);
11490174267aSFredrik Holmqvist }
11500174267aSFredrik Holmqvist
11510174267aSFredrik Holmqvist Node = AcpiNsValidateHandle (GpeDevice);
11520174267aSFredrik Holmqvist if (!Node)
11530174267aSFredrik Holmqvist {
11540174267aSFredrik Holmqvist Status = AE_BAD_PARAMETER;
11550174267aSFredrik Holmqvist goto UnlockAndExit;
11560174267aSFredrik Holmqvist }
11570174267aSFredrik Holmqvist
1158ad5bbfb8SFredrik Holmqvist /* Validate the parent device */
1159ad5bbfb8SFredrik Holmqvist
1160ad5bbfb8SFredrik Holmqvist if (Node->Type != ACPI_TYPE_DEVICE)
1161ad5bbfb8SFredrik Holmqvist {
1162ad5bbfb8SFredrik Holmqvist Status = AE_TYPE;
1163ad5bbfb8SFredrik Holmqvist goto UnlockAndExit;
1164ad5bbfb8SFredrik Holmqvist }
1165ad5bbfb8SFredrik Holmqvist
1166ad5bbfb8SFredrik Holmqvist if (Node->Object)
1167ad5bbfb8SFredrik Holmqvist {
1168ad5bbfb8SFredrik Holmqvist Status = AE_ALREADY_EXISTS;
1169ad5bbfb8SFredrik Holmqvist goto UnlockAndExit;
1170ad5bbfb8SFredrik Holmqvist }
1171ad5bbfb8SFredrik Holmqvist
11720174267aSFredrik Holmqvist /*
11730174267aSFredrik Holmqvist * For user-installed GPE Block Devices, the GpeBlockBaseNumber
11740174267aSFredrik Holmqvist * is always zero
11750174267aSFredrik Holmqvist */
1176ad5bbfb8SFredrik Holmqvist Status = AcpiEvCreateGpeBlock (Node, GpeBlockAddress->Address,
1177ad5bbfb8SFredrik Holmqvist GpeBlockAddress->SpaceId, RegisterCount,
11780174267aSFredrik Holmqvist 0, InterruptNumber, &GpeBlock);
11790174267aSFredrik Holmqvist if (ACPI_FAILURE (Status))
11800174267aSFredrik Holmqvist {
11810174267aSFredrik Holmqvist goto UnlockAndExit;
11820174267aSFredrik Holmqvist }
11830174267aSFredrik Holmqvist
11840174267aSFredrik Holmqvist /* Install block in the DeviceObject attached to the node */
11850174267aSFredrik Holmqvist
11860174267aSFredrik Holmqvist ObjDesc = AcpiNsGetAttachedObject (Node);
11870174267aSFredrik Holmqvist if (!ObjDesc)
11880174267aSFredrik Holmqvist {
11890174267aSFredrik Holmqvist /*
11900174267aSFredrik Holmqvist * No object, create a new one (Device nodes do not always have
11910174267aSFredrik Holmqvist * an attached object)
11920174267aSFredrik Holmqvist */
11930174267aSFredrik Holmqvist ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_DEVICE);
11940174267aSFredrik Holmqvist if (!ObjDesc)
11950174267aSFredrik Holmqvist {
11960174267aSFredrik Holmqvist Status = AE_NO_MEMORY;
11970174267aSFredrik Holmqvist goto UnlockAndExit;
11980174267aSFredrik Holmqvist }
11990174267aSFredrik Holmqvist
12000174267aSFredrik Holmqvist Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_DEVICE);
12010174267aSFredrik Holmqvist
12020174267aSFredrik Holmqvist /* Remove local reference to the object */
12030174267aSFredrik Holmqvist
12040174267aSFredrik Holmqvist AcpiUtRemoveReference (ObjDesc);
12050174267aSFredrik Holmqvist if (ACPI_FAILURE (Status))
12060174267aSFredrik Holmqvist {
12070174267aSFredrik Holmqvist goto UnlockAndExit;
12080174267aSFredrik Holmqvist }
12090174267aSFredrik Holmqvist }
12100174267aSFredrik Holmqvist
12110174267aSFredrik Holmqvist /* Now install the GPE block in the DeviceObject */
12120174267aSFredrik Holmqvist
12130174267aSFredrik Holmqvist ObjDesc->Device.GpeBlock = GpeBlock;
12140174267aSFredrik Holmqvist
12150174267aSFredrik Holmqvist
12160174267aSFredrik Holmqvist UnlockAndExit:
12170174267aSFredrik Holmqvist (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
12180174267aSFredrik Holmqvist return_ACPI_STATUS (Status);
12190174267aSFredrik Holmqvist }
12200174267aSFredrik Holmqvist
ACPI_EXPORT_SYMBOL(AcpiInstallGpeBlock)12210174267aSFredrik Holmqvist ACPI_EXPORT_SYMBOL (AcpiInstallGpeBlock)
12220174267aSFredrik Holmqvist
12230174267aSFredrik Holmqvist
12240174267aSFredrik Holmqvist /*******************************************************************************
12250174267aSFredrik Holmqvist *
12260174267aSFredrik Holmqvist * FUNCTION: AcpiRemoveGpeBlock
12270174267aSFredrik Holmqvist *
12280174267aSFredrik Holmqvist * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device
12290174267aSFredrik Holmqvist *
12300174267aSFredrik Holmqvist * RETURN: Status
12310174267aSFredrik Holmqvist *
12320174267aSFredrik Holmqvist * DESCRIPTION: Remove a previously installed block of GPE registers
12330174267aSFredrik Holmqvist *
12340174267aSFredrik Holmqvist ******************************************************************************/
12350174267aSFredrik Holmqvist
12360174267aSFredrik Holmqvist ACPI_STATUS
12370174267aSFredrik Holmqvist AcpiRemoveGpeBlock (
12380174267aSFredrik Holmqvist ACPI_HANDLE GpeDevice)
12390174267aSFredrik Holmqvist {
12400174267aSFredrik Holmqvist ACPI_OPERAND_OBJECT *ObjDesc;
12410174267aSFredrik Holmqvist ACPI_STATUS Status;
12420174267aSFredrik Holmqvist ACPI_NAMESPACE_NODE *Node;
12430174267aSFredrik Holmqvist
12440174267aSFredrik Holmqvist
12450174267aSFredrik Holmqvist ACPI_FUNCTION_TRACE (AcpiRemoveGpeBlock);
12460174267aSFredrik Holmqvist
12470174267aSFredrik Holmqvist
12480174267aSFredrik Holmqvist if (!GpeDevice)
12490174267aSFredrik Holmqvist {
12500174267aSFredrik Holmqvist return_ACPI_STATUS (AE_BAD_PARAMETER);
12510174267aSFredrik Holmqvist }
12520174267aSFredrik Holmqvist
12530174267aSFredrik Holmqvist Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
12540174267aSFredrik Holmqvist if (ACPI_FAILURE (Status))
12550174267aSFredrik Holmqvist {
12569b0d045cSFredrik Holmqvist return_ACPI_STATUS (Status);
12570174267aSFredrik Holmqvist }
12580174267aSFredrik Holmqvist
12590174267aSFredrik Holmqvist Node = AcpiNsValidateHandle (GpeDevice);
12600174267aSFredrik Holmqvist if (!Node)
12610174267aSFredrik Holmqvist {
12620174267aSFredrik Holmqvist Status = AE_BAD_PARAMETER;
12630174267aSFredrik Holmqvist goto UnlockAndExit;
12640174267aSFredrik Holmqvist }
12650174267aSFredrik Holmqvist
1266ad5bbfb8SFredrik Holmqvist /* Validate the parent device */
1267ad5bbfb8SFredrik Holmqvist
1268ad5bbfb8SFredrik Holmqvist if (Node->Type != ACPI_TYPE_DEVICE)
1269ad5bbfb8SFredrik Holmqvist {
1270ad5bbfb8SFredrik Holmqvist Status = AE_TYPE;
1271ad5bbfb8SFredrik Holmqvist goto UnlockAndExit;
1272ad5bbfb8SFredrik Holmqvist }
1273ad5bbfb8SFredrik Holmqvist
12740174267aSFredrik Holmqvist /* Get the DeviceObject attached to the node */
12750174267aSFredrik Holmqvist
12760174267aSFredrik Holmqvist ObjDesc = AcpiNsGetAttachedObject (Node);
12770174267aSFredrik Holmqvist if (!ObjDesc ||
12780174267aSFredrik Holmqvist !ObjDesc->Device.GpeBlock)
12790174267aSFredrik Holmqvist {
12800174267aSFredrik Holmqvist return_ACPI_STATUS (AE_NULL_OBJECT);
12810174267aSFredrik Holmqvist }
12820174267aSFredrik Holmqvist
12830174267aSFredrik Holmqvist /* Delete the GPE block (but not the DeviceObject) */
12840174267aSFredrik Holmqvist
12850174267aSFredrik Holmqvist Status = AcpiEvDeleteGpeBlock (ObjDesc->Device.GpeBlock);
12860174267aSFredrik Holmqvist if (ACPI_SUCCESS (Status))
12870174267aSFredrik Holmqvist {
12880174267aSFredrik Holmqvist ObjDesc->Device.GpeBlock = NULL;
12890174267aSFredrik Holmqvist }
12900174267aSFredrik Holmqvist
12910174267aSFredrik Holmqvist UnlockAndExit:
12920174267aSFredrik Holmqvist (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
12930174267aSFredrik Holmqvist return_ACPI_STATUS (Status);
12940174267aSFredrik Holmqvist }
12950174267aSFredrik Holmqvist
ACPI_EXPORT_SYMBOL(AcpiRemoveGpeBlock)12960174267aSFredrik Holmqvist ACPI_EXPORT_SYMBOL (AcpiRemoveGpeBlock)
12970174267aSFredrik Holmqvist
12980174267aSFredrik Holmqvist
12990174267aSFredrik Holmqvist /*******************************************************************************
13000174267aSFredrik Holmqvist *
13010174267aSFredrik Holmqvist * FUNCTION: AcpiGetGpeDevice
13020174267aSFredrik Holmqvist *
13030174267aSFredrik Holmqvist * PARAMETERS: Index - System GPE index (0-CurrentGpeCount)
13040174267aSFredrik Holmqvist * GpeDevice - Where the parent GPE Device is returned
13050174267aSFredrik Holmqvist *
13060174267aSFredrik Holmqvist * RETURN: Status
13070174267aSFredrik Holmqvist *
13080174267aSFredrik Holmqvist * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
13090174267aSFredrik Holmqvist * gpe device indicates that the gpe number is contained in one of
13100174267aSFredrik Holmqvist * the FADT-defined gpe blocks. Otherwise, the GPE block device.
13110174267aSFredrik Holmqvist *
13120174267aSFredrik Holmqvist ******************************************************************************/
13130174267aSFredrik Holmqvist
13140174267aSFredrik Holmqvist ACPI_STATUS
13150174267aSFredrik Holmqvist AcpiGetGpeDevice (
13160174267aSFredrik Holmqvist UINT32 Index,
13170174267aSFredrik Holmqvist ACPI_HANDLE *GpeDevice)
13180174267aSFredrik Holmqvist {
13190174267aSFredrik Holmqvist ACPI_GPE_DEVICE_INFO Info;
13200174267aSFredrik Holmqvist ACPI_STATUS Status;
13210174267aSFredrik Holmqvist
13220174267aSFredrik Holmqvist
13230174267aSFredrik Holmqvist ACPI_FUNCTION_TRACE (AcpiGetGpeDevice);
13240174267aSFredrik Holmqvist
13250174267aSFredrik Holmqvist
13260174267aSFredrik Holmqvist if (!GpeDevice)
13270174267aSFredrik Holmqvist {
13280174267aSFredrik Holmqvist return_ACPI_STATUS (AE_BAD_PARAMETER);
13290174267aSFredrik Holmqvist }
13300174267aSFredrik Holmqvist
13310174267aSFredrik Holmqvist if (Index >= AcpiCurrentGpeCount)
13320174267aSFredrik Holmqvist {
13330174267aSFredrik Holmqvist return_ACPI_STATUS (AE_NOT_EXIST);
13340174267aSFredrik Holmqvist }
13350174267aSFredrik Holmqvist
13360174267aSFredrik Holmqvist /* Setup and walk the GPE list */
13370174267aSFredrik Holmqvist
13380174267aSFredrik Holmqvist Info.Index = Index;
13390174267aSFredrik Holmqvist Info.Status = AE_NOT_EXIST;
13400174267aSFredrik Holmqvist Info.GpeDevice = NULL;
13410174267aSFredrik Holmqvist Info.NextBlockBaseIndex = 0;
13420174267aSFredrik Holmqvist
13430174267aSFredrik Holmqvist Status = AcpiEvWalkGpeList (AcpiEvGetGpeDevice, &Info);
13440174267aSFredrik Holmqvist if (ACPI_FAILURE (Status))
13450174267aSFredrik Holmqvist {
13460174267aSFredrik Holmqvist return_ACPI_STATUS (Status);
13470174267aSFredrik Holmqvist }
13480174267aSFredrik Holmqvist
13490174267aSFredrik Holmqvist *GpeDevice = ACPI_CAST_PTR (ACPI_HANDLE, Info.GpeDevice);
13500174267aSFredrik Holmqvist return_ACPI_STATUS (Info.Status);
13510174267aSFredrik Holmqvist }
13520174267aSFredrik Holmqvist
13530174267aSFredrik Holmqvist ACPI_EXPORT_SYMBOL (AcpiGetGpeDevice)
13546822cda0SFredrik Holmqvist
13556822cda0SFredrik Holmqvist #endif /* !ACPI_REDUCED_HARDWARE */
1356