1bc36eafdSMike Gerdts /******************************************************************************
2bc36eafdSMike Gerdts  *
3bc36eafdSMike Gerdts  * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs)
4bc36eafdSMike Gerdts  *
5bc36eafdSMike Gerdts  *****************************************************************************/
6bc36eafdSMike Gerdts 
7*35786f68SRobert Mustacchi /******************************************************************************
8*35786f68SRobert Mustacchi  *
9*35786f68SRobert Mustacchi  * 1. Copyright Notice
10*35786f68SRobert Mustacchi  *
11*35786f68SRobert Mustacchi  * Some or all of this work - Copyright (c) 1999 - 2018, Intel Corp.
12bc36eafdSMike Gerdts  * All rights reserved.
13bc36eafdSMike Gerdts  *
14*35786f68SRobert Mustacchi  * 2. License
15*35786f68SRobert Mustacchi  *
16*35786f68SRobert Mustacchi  * 2.1. This is your license from Intel Corp. under its intellectual property
17*35786f68SRobert Mustacchi  * rights. You may have additional license terms from the party that provided
18*35786f68SRobert Mustacchi  * you this software, covering your right to use that party's intellectual
19*35786f68SRobert Mustacchi  * property rights.
20*35786f68SRobert Mustacchi  *
21*35786f68SRobert Mustacchi  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22*35786f68SRobert Mustacchi  * copy of the source code appearing in this file ("Covered Code") an
23*35786f68SRobert Mustacchi  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24*35786f68SRobert Mustacchi  * base code distributed originally by Intel ("Original Intel Code") to copy,
25*35786f68SRobert Mustacchi  * make derivatives, distribute, use and display any portion of the Covered
26*35786f68SRobert Mustacchi  * Code in any form, with the right to sublicense such rights; and
27*35786f68SRobert Mustacchi  *
28*35786f68SRobert Mustacchi  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29*35786f68SRobert Mustacchi  * license (with the right to sublicense), under only those claims of Intel
30*35786f68SRobert Mustacchi  * patents that are infringed by the Original Intel Code, to make, use, sell,
31*35786f68SRobert Mustacchi  * offer to sell, and import the Covered Code and derivative works thereof
32*35786f68SRobert Mustacchi  * solely to the minimum extent necessary to exercise the above copyright
33*35786f68SRobert Mustacchi  * license, and in no event shall the patent license extend to any additions
34*35786f68SRobert Mustacchi  * to or modifications of the Original Intel Code. No other license or right
35*35786f68SRobert Mustacchi  * is granted directly or by implication, estoppel or otherwise;
36*35786f68SRobert Mustacchi  *
37*35786f68SRobert Mustacchi  * The above copyright and patent license is granted only if the following
38*35786f68SRobert Mustacchi  * conditions are met:
39*35786f68SRobert Mustacchi  *
40*35786f68SRobert Mustacchi  * 3. Conditions
41*35786f68SRobert Mustacchi  *
42*35786f68SRobert Mustacchi  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43*35786f68SRobert Mustacchi  * Redistribution of source code of any substantial portion of the Covered
44*35786f68SRobert Mustacchi  * Code or modification with rights to further distribute source must include
45*35786f68SRobert Mustacchi  * the above Copyright Notice, the above License, this list of Conditions,
46*35786f68SRobert Mustacchi  * and the following Disclaimer and Export Compliance provision. In addition,
47*35786f68SRobert Mustacchi  * Licensee must cause all Covered Code to which Licensee contributes to
48*35786f68SRobert Mustacchi  * contain a file documenting the changes Licensee made to create that Covered
49*35786f68SRobert Mustacchi  * Code and the date of any change. Licensee must include in that file the
50*35786f68SRobert Mustacchi  * documentation of any changes made by any predecessor Licensee. Licensee
51*35786f68SRobert Mustacchi  * must include a prominent statement that the modification is derived,
52*35786f68SRobert Mustacchi  * directly or indirectly, from Original Intel Code.
53*35786f68SRobert Mustacchi  *
54*35786f68SRobert Mustacchi  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55*35786f68SRobert Mustacchi  * Redistribution of source code of any substantial portion of the Covered
56*35786f68SRobert Mustacchi  * Code or modification without rights to further distribute source must
57*35786f68SRobert Mustacchi  * include the following Disclaimer and Export Compliance provision in the
58*35786f68SRobert Mustacchi  * documentation and/or other materials provided with distribution. In
59*35786f68SRobert Mustacchi  * addition, Licensee may not authorize further sublicense of source of any
60*35786f68SRobert Mustacchi  * portion of the Covered Code, and must include terms to the effect that the
61*35786f68SRobert Mustacchi  * license from Licensee to its licensee is limited to the intellectual
62*35786f68SRobert Mustacchi  * property embodied in the software Licensee provides to its licensee, and
63*35786f68SRobert Mustacchi  * not to intellectual property embodied in modifications its licensee may
64*35786f68SRobert Mustacchi  * make.
65*35786f68SRobert Mustacchi  *
66*35786f68SRobert Mustacchi  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67*35786f68SRobert Mustacchi  * substantial portion of the Covered Code or modification must reproduce the
68*35786f68SRobert Mustacchi  * above Copyright Notice, and the following Disclaimer and Export Compliance
69*35786f68SRobert Mustacchi  * provision in the documentation and/or other materials provided with the
70*35786f68SRobert Mustacchi  * distribution.
71*35786f68SRobert Mustacchi  *
72*35786f68SRobert Mustacchi  * 3.4. Intel retains all right, title, and interest in and to the Original
73*35786f68SRobert Mustacchi  * Intel Code.
74*35786f68SRobert Mustacchi  *
75*35786f68SRobert Mustacchi  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76*35786f68SRobert Mustacchi  * Intel shall be used in advertising or otherwise to promote the sale, use or
77*35786f68SRobert Mustacchi  * other dealings in products derived from or relating to the Covered Code
78*35786f68SRobert Mustacchi  * without prior written authorization from Intel.
79*35786f68SRobert Mustacchi  *
80*35786f68SRobert Mustacchi  * 4. Disclaimer and Export Compliance
81*35786f68SRobert Mustacchi  *
82*35786f68SRobert Mustacchi  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83*35786f68SRobert Mustacchi  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84*35786f68SRobert Mustacchi  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85*35786f68SRobert Mustacchi  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86*35786f68SRobert Mustacchi  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87*35786f68SRobert Mustacchi  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88*35786f68SRobert Mustacchi  * PARTICULAR PURPOSE.
89*35786f68SRobert Mustacchi  *
90*35786f68SRobert Mustacchi  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91*35786f68SRobert Mustacchi  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92*35786f68SRobert Mustacchi  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93*35786f68SRobert Mustacchi  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94*35786f68SRobert Mustacchi  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95*35786f68SRobert Mustacchi  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96*35786f68SRobert Mustacchi  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97*35786f68SRobert Mustacchi  * LIMITED REMEDY.
98*35786f68SRobert Mustacchi  *
99*35786f68SRobert Mustacchi  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100*35786f68SRobert Mustacchi  * software or system incorporating such software without first obtaining any
101*35786f68SRobert Mustacchi  * required license or other approval from the U. S. Department of Commerce or
102*35786f68SRobert Mustacchi  * any other agency or department of the United States Government. In the
103*35786f68SRobert Mustacchi  * event Licensee exports any such software from the United States or
104*35786f68SRobert Mustacchi  * re-exports any such software from a foreign destination, Licensee shall
105*35786f68SRobert Mustacchi  * ensure that the distribution and export/re-export of the software is in
106*35786f68SRobert Mustacchi  * compliance with all laws, regulations, orders, or other restrictions of the
107*35786f68SRobert Mustacchi  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108*35786f68SRobert Mustacchi  * any of its subsidiaries will export/re-export any technical data, process,
109*35786f68SRobert Mustacchi  * software, or service, directly or indirectly, to any country for which the
110*35786f68SRobert Mustacchi  * United States government or any agency thereof requires an export license,
111*35786f68SRobert Mustacchi  * other governmental approval, or letter of assurance, without first obtaining
112*35786f68SRobert Mustacchi  * such license, approval or letter.
113*35786f68SRobert Mustacchi  *
114*35786f68SRobert Mustacchi  *****************************************************************************
115*35786f68SRobert Mustacchi  *
116*35786f68SRobert Mustacchi  * Alternatively, you may choose to be licensed under the terms of the
117*35786f68SRobert Mustacchi  * following license:
118*35786f68SRobert Mustacchi  *
119bc36eafdSMike Gerdts  * Redistribution and use in source and binary forms, with or without
120bc36eafdSMike Gerdts  * modification, are permitted provided that the following conditions
121bc36eafdSMike Gerdts  * are met:
122bc36eafdSMike Gerdts  * 1. Redistributions of source code must retain the above copyright
123bc36eafdSMike Gerdts  *    notice, this list of conditions, and the following disclaimer,
124bc36eafdSMike Gerdts  *    without modification.
125bc36eafdSMike Gerdts  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126bc36eafdSMike Gerdts  *    substantially similar to the "NO WARRANTY" disclaimer below
127bc36eafdSMike Gerdts  *    ("Disclaimer") and any redistribution must be conditioned upon
128bc36eafdSMike Gerdts  *    including a substantially similar Disclaimer requirement for further
129bc36eafdSMike Gerdts  *    binary redistribution.
130bc36eafdSMike Gerdts  * 3. Neither the names of the above-listed copyright holders nor the names
131bc36eafdSMike Gerdts  *    of any contributors may be used to endorse or promote products derived
132bc36eafdSMike Gerdts  *    from this software without specific prior written permission.
133bc36eafdSMike Gerdts  *
134*35786f68SRobert Mustacchi  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135*35786f68SRobert Mustacchi  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136*35786f68SRobert Mustacchi  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137*35786f68SRobert Mustacchi  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138*35786f68SRobert Mustacchi  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139*35786f68SRobert Mustacchi  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140*35786f68SRobert Mustacchi  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141*35786f68SRobert Mustacchi  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142*35786f68SRobert Mustacchi  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143*35786f68SRobert Mustacchi  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144*35786f68SRobert Mustacchi  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145*35786f68SRobert Mustacchi  *
146*35786f68SRobert Mustacchi  * Alternatively, you may choose to be licensed under the terms of the
147bc36eafdSMike Gerdts  * GNU General Public License ("GPL") version 2 as published by the Free
148bc36eafdSMike Gerdts  * Software Foundation.
149bc36eafdSMike Gerdts  *
150*35786f68SRobert Mustacchi  *****************************************************************************/
151bc36eafdSMike Gerdts 
152bc36eafdSMike Gerdts #define EXPORT_ACPI_INTERFACES
153bc36eafdSMike Gerdts 
154bc36eafdSMike Gerdts #include "acpi.h"
155bc36eafdSMike Gerdts #include "accommon.h"
156bc36eafdSMike Gerdts #include "acevents.h"
157bc36eafdSMike Gerdts #include "acnamesp.h"
158bc36eafdSMike Gerdts 
159bc36eafdSMike Gerdts #define _COMPONENT          ACPI_EVENTS
160bc36eafdSMike Gerdts         ACPI_MODULE_NAME    ("evxfgpe")
161bc36eafdSMike Gerdts 
162bc36eafdSMike Gerdts 
163bc36eafdSMike Gerdts #if (!ACPI_REDUCED_HARDWARE) /* Entire module */
164bc36eafdSMike Gerdts /*******************************************************************************
165bc36eafdSMike Gerdts  *
166bc36eafdSMike Gerdts  * FUNCTION:    AcpiUpdateAllGpes
167bc36eafdSMike Gerdts  *
168bc36eafdSMike Gerdts  * PARAMETERS:  None
169bc36eafdSMike Gerdts  *
170bc36eafdSMike Gerdts  * RETURN:      Status
171bc36eafdSMike Gerdts  *
172bc36eafdSMike Gerdts  * DESCRIPTION: Complete GPE initialization and enable all GPEs that have
173bc36eafdSMike Gerdts  *              associated _Lxx or _Exx methods and are not pointed to by any
174bc36eafdSMike Gerdts  *              device _PRW methods (this indicates that these GPEs are
175bc36eafdSMike Gerdts  *              generally intended for system or device wakeup. Such GPEs
176bc36eafdSMike Gerdts  *              have to be enabled directly when the devices whose _PRW
177bc36eafdSMike Gerdts  *              methods point to them are set up for wakeup signaling.)
178bc36eafdSMike Gerdts  *
179bc36eafdSMike Gerdts  * NOTE: Should be called after any GPEs are added to the system. Primarily,
180bc36eafdSMike Gerdts  * after the system _PRW methods have been run, but also after a GPE Block
181bc36eafdSMike Gerdts  * Device has been added or if any new GPE methods have been added via a
182bc36eafdSMike Gerdts  * dynamic table load.
183bc36eafdSMike Gerdts  *
184bc36eafdSMike Gerdts  ******************************************************************************/
185bc36eafdSMike Gerdts 
186bc36eafdSMike Gerdts ACPI_STATUS
AcpiUpdateAllGpes(void)187bc36eafdSMike Gerdts AcpiUpdateAllGpes (
188bc36eafdSMike Gerdts     void)
189bc36eafdSMike Gerdts {
190bc36eafdSMike Gerdts     ACPI_STATUS             Status;
191*35786f68SRobert Mustacchi     BOOLEAN                 IsPollingNeeded = FALSE;
192bc36eafdSMike Gerdts 
193bc36eafdSMike Gerdts 
194bc36eafdSMike Gerdts     ACPI_FUNCTION_TRACE (AcpiUpdateAllGpes);
195bc36eafdSMike Gerdts 
196bc36eafdSMike Gerdts 
197bc36eafdSMike Gerdts     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
198bc36eafdSMike Gerdts     if (ACPI_FAILURE (Status))
199bc36eafdSMike Gerdts     {
200bc36eafdSMike Gerdts         return_ACPI_STATUS (Status);
201bc36eafdSMike Gerdts     }
202bc36eafdSMike Gerdts 
203bc36eafdSMike Gerdts     if (AcpiGbl_AllGpesInitialized)
204bc36eafdSMike Gerdts     {
205bc36eafdSMike Gerdts         goto UnlockAndExit;
206bc36eafdSMike Gerdts     }
207bc36eafdSMike Gerdts 
208*35786f68SRobert Mustacchi     Status = AcpiEvWalkGpeList (AcpiEvInitializeGpeBlock,
209*35786f68SRobert Mustacchi         &IsPollingNeeded);
210bc36eafdSMike Gerdts     if (ACPI_SUCCESS (Status))
211bc36eafdSMike Gerdts     {
212bc36eafdSMike Gerdts         AcpiGbl_AllGpesInitialized = TRUE;
213bc36eafdSMike Gerdts     }
214bc36eafdSMike Gerdts 
215bc36eafdSMike Gerdts UnlockAndExit:
216bc36eafdSMike Gerdts     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
217*35786f68SRobert Mustacchi 
218*35786f68SRobert Mustacchi     if (IsPollingNeeded && AcpiGbl_AllGpesInitialized)
219*35786f68SRobert Mustacchi     {
220*35786f68SRobert Mustacchi         /* Poll GPEs to handle already triggered events */
221*35786f68SRobert Mustacchi 
222*35786f68SRobert Mustacchi         AcpiEvGpeDetect (AcpiGbl_GpeXruptListHead);
223*35786f68SRobert Mustacchi     }
224bc36eafdSMike Gerdts     return_ACPI_STATUS (Status);
225bc36eafdSMike Gerdts }
226bc36eafdSMike Gerdts 
ACPI_EXPORT_SYMBOL(AcpiUpdateAllGpes)227bc36eafdSMike Gerdts ACPI_EXPORT_SYMBOL (AcpiUpdateAllGpes)
228bc36eafdSMike Gerdts 
229bc36eafdSMike Gerdts 
230bc36eafdSMike Gerdts /*******************************************************************************
231bc36eafdSMike Gerdts  *
232bc36eafdSMike Gerdts  * FUNCTION:    AcpiEnableGpe
233bc36eafdSMike Gerdts  *
234bc36eafdSMike Gerdts  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
235bc36eafdSMike Gerdts  *              GpeNumber           - GPE level within the GPE block
236bc36eafdSMike Gerdts  *
237bc36eafdSMike Gerdts  * RETURN:      Status
238bc36eafdSMike Gerdts  *
239bc36eafdSMike Gerdts  * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
240bc36eafdSMike Gerdts  *              hardware-enabled.
241bc36eafdSMike Gerdts  *
242bc36eafdSMike Gerdts  ******************************************************************************/
243bc36eafdSMike Gerdts 
244bc36eafdSMike Gerdts ACPI_STATUS
245bc36eafdSMike Gerdts AcpiEnableGpe (
246bc36eafdSMike Gerdts     ACPI_HANDLE             GpeDevice,
247bc36eafdSMike Gerdts     UINT32                  GpeNumber)
248bc36eafdSMike Gerdts {
249bc36eafdSMike Gerdts     ACPI_STATUS             Status = AE_BAD_PARAMETER;
250bc36eafdSMike Gerdts     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
251bc36eafdSMike Gerdts     ACPI_CPU_FLAGS          Flags;
252bc36eafdSMike Gerdts 
253bc36eafdSMike Gerdts 
254bc36eafdSMike Gerdts     ACPI_FUNCTION_TRACE (AcpiEnableGpe);
255bc36eafdSMike Gerdts 
256bc36eafdSMike Gerdts 
257bc36eafdSMike Gerdts     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
258bc36eafdSMike Gerdts 
259bc36eafdSMike Gerdts     /*
260bc36eafdSMike Gerdts      * Ensure that we have a valid GPE number and that there is some way
261bc36eafdSMike Gerdts      * of handling the GPE (handler or a GPE method). In other words, we
262bc36eafdSMike Gerdts      * won't allow a valid GPE to be enabled if there is no way to handle it.
263bc36eafdSMike Gerdts      */
264bc36eafdSMike Gerdts     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
265bc36eafdSMike Gerdts     if (GpeEventInfo)
266bc36eafdSMike Gerdts     {
267bc36eafdSMike Gerdts         if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) !=
268bc36eafdSMike Gerdts             ACPI_GPE_DISPATCH_NONE)
269bc36eafdSMike Gerdts         {
270bc36eafdSMike Gerdts             Status = AcpiEvAddGpeReference (GpeEventInfo);
271*35786f68SRobert Mustacchi             if (ACPI_SUCCESS (Status) &&
272*35786f68SRobert Mustacchi                 ACPI_GPE_IS_POLLING_NEEDED (GpeEventInfo))
273*35786f68SRobert Mustacchi             {
274*35786f68SRobert Mustacchi                 /* Poll edge-triggered GPEs to handle existing events */
275*35786f68SRobert Mustacchi 
276*35786f68SRobert Mustacchi                 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
277*35786f68SRobert Mustacchi                 (void) AcpiEvDetectGpe (
278*35786f68SRobert Mustacchi                     GpeDevice, GpeEventInfo, GpeNumber);
279*35786f68SRobert Mustacchi                 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
280*35786f68SRobert Mustacchi             }
281bc36eafdSMike Gerdts         }
282bc36eafdSMike Gerdts         else
283bc36eafdSMike Gerdts         {
284bc36eafdSMike Gerdts             Status = AE_NO_HANDLER;
285bc36eafdSMike Gerdts         }
286bc36eafdSMike Gerdts     }
287bc36eafdSMike Gerdts 
288bc36eafdSMike Gerdts     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
289bc36eafdSMike Gerdts     return_ACPI_STATUS (Status);
290bc36eafdSMike Gerdts }
291bc36eafdSMike Gerdts 
ACPI_EXPORT_SYMBOL(AcpiEnableGpe)292bc36eafdSMike Gerdts ACPI_EXPORT_SYMBOL (AcpiEnableGpe)
293bc36eafdSMike Gerdts 
294bc36eafdSMike Gerdts 
295bc36eafdSMike Gerdts /*******************************************************************************
296bc36eafdSMike Gerdts  *
297bc36eafdSMike Gerdts  * FUNCTION:    AcpiDisableGpe
298bc36eafdSMike Gerdts  *
299bc36eafdSMike Gerdts  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
300bc36eafdSMike Gerdts  *              GpeNumber           - GPE level within the GPE block
301bc36eafdSMike Gerdts  *
302bc36eafdSMike Gerdts  * RETURN:      Status
303bc36eafdSMike Gerdts  *
304bc36eafdSMike Gerdts  * DESCRIPTION: Remove a reference to a GPE. When the last reference is
305bc36eafdSMike Gerdts  *              removed, only then is the GPE disabled (for runtime GPEs), or
306bc36eafdSMike Gerdts  *              the GPE mask bit disabled (for wake GPEs)
307bc36eafdSMike Gerdts  *
308bc36eafdSMike Gerdts  ******************************************************************************/
309bc36eafdSMike Gerdts 
310bc36eafdSMike Gerdts ACPI_STATUS
311bc36eafdSMike Gerdts AcpiDisableGpe (
312bc36eafdSMike Gerdts     ACPI_HANDLE             GpeDevice,
313bc36eafdSMike Gerdts     UINT32                  GpeNumber)
314bc36eafdSMike Gerdts {
315bc36eafdSMike Gerdts     ACPI_STATUS             Status = AE_BAD_PARAMETER;
316bc36eafdSMike Gerdts     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
317bc36eafdSMike Gerdts     ACPI_CPU_FLAGS          Flags;
318bc36eafdSMike Gerdts 
319bc36eafdSMike Gerdts 
320bc36eafdSMike Gerdts     ACPI_FUNCTION_TRACE (AcpiDisableGpe);
321bc36eafdSMike Gerdts 
322bc36eafdSMike Gerdts 
323bc36eafdSMike Gerdts     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
324bc36eafdSMike Gerdts 
325bc36eafdSMike Gerdts     /* Ensure that we have a valid GPE number */
326bc36eafdSMike Gerdts 
327bc36eafdSMike Gerdts     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
328bc36eafdSMike Gerdts     if (GpeEventInfo)
329bc36eafdSMike Gerdts     {
330bc36eafdSMike Gerdts         Status = AcpiEvRemoveGpeReference (GpeEventInfo);
331bc36eafdSMike Gerdts     }
332bc36eafdSMike Gerdts 
333bc36eafdSMike Gerdts     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
334bc36eafdSMike Gerdts     return_ACPI_STATUS (Status);
335bc36eafdSMike Gerdts }
336bc36eafdSMike Gerdts 
ACPI_EXPORT_SYMBOL(AcpiDisableGpe)337bc36eafdSMike Gerdts ACPI_EXPORT_SYMBOL (AcpiDisableGpe)
338bc36eafdSMike Gerdts 
339bc36eafdSMike Gerdts 
340bc36eafdSMike Gerdts /*******************************************************************************
341bc36eafdSMike Gerdts  *
342bc36eafdSMike Gerdts  * FUNCTION:    AcpiSetGpe
343bc36eafdSMike Gerdts  *
344bc36eafdSMike Gerdts  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
345bc36eafdSMike Gerdts  *              GpeNumber           - GPE level within the GPE block
346bc36eafdSMike Gerdts  *              Action              - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
347bc36eafdSMike Gerdts  *
348bc36eafdSMike Gerdts  * RETURN:      Status
349bc36eafdSMike Gerdts  *
350bc36eafdSMike Gerdts  * DESCRIPTION: Enable or disable an individual GPE. This function bypasses
351bc36eafdSMike Gerdts  *              the reference count mechanism used in the AcpiEnableGpe(),
352bc36eafdSMike Gerdts  *              AcpiDisableGpe() interfaces.
353bc36eafdSMike Gerdts  *              This API is typically used by the GPE raw handler mode driver
354bc36eafdSMike Gerdts  *              to switch between the polling mode and the interrupt mode after
355bc36eafdSMike Gerdts  *              the driver has enabled the GPE.
356bc36eafdSMike Gerdts  *              The APIs should be invoked in this order:
357bc36eafdSMike Gerdts  *               AcpiEnableGpe()              <- Ensure the reference count > 0
358bc36eafdSMike Gerdts  *               AcpiSetGpe(ACPI_GPE_DISABLE) <- Enter polling mode
359bc36eafdSMike Gerdts  *               AcpiSetGpe(ACPI_GPE_ENABLE)  <- Leave polling mode
360bc36eafdSMike Gerdts  *               AcpiDisableGpe()             <- Decrease the reference count
361bc36eafdSMike Gerdts  *
362bc36eafdSMike Gerdts  * Note: If a GPE is shared by 2 silicon components, then both the drivers
363bc36eafdSMike Gerdts  *       should support GPE polling mode or disabling the GPE for long period
364bc36eafdSMike Gerdts  *       for one driver may break the other. So use it with care since all
365bc36eafdSMike Gerdts  *       firmware _Lxx/_Exx handlers currently rely on the GPE interrupt mode.
366bc36eafdSMike Gerdts  *
367bc36eafdSMike Gerdts  ******************************************************************************/
368bc36eafdSMike Gerdts 
369bc36eafdSMike Gerdts ACPI_STATUS
370bc36eafdSMike Gerdts AcpiSetGpe (
371bc36eafdSMike Gerdts     ACPI_HANDLE             GpeDevice,
372bc36eafdSMike Gerdts     UINT32                  GpeNumber,
373bc36eafdSMike Gerdts     UINT8                   Action)
374bc36eafdSMike Gerdts {
375bc36eafdSMike Gerdts     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
376bc36eafdSMike Gerdts     ACPI_STATUS             Status;
377bc36eafdSMike Gerdts     ACPI_CPU_FLAGS          Flags;
378bc36eafdSMike Gerdts 
379bc36eafdSMike Gerdts 
380bc36eafdSMike Gerdts     ACPI_FUNCTION_TRACE (AcpiSetGpe);
381bc36eafdSMike Gerdts 
382bc36eafdSMike Gerdts 
383bc36eafdSMike Gerdts     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
384bc36eafdSMike Gerdts 
385bc36eafdSMike Gerdts     /* Ensure that we have a valid GPE number */
386bc36eafdSMike Gerdts 
387bc36eafdSMike Gerdts     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
388bc36eafdSMike Gerdts     if (!GpeEventInfo)
389bc36eafdSMike Gerdts     {
390bc36eafdSMike Gerdts         Status = AE_BAD_PARAMETER;
391bc36eafdSMike Gerdts         goto UnlockAndExit;
392bc36eafdSMike Gerdts     }
393bc36eafdSMike Gerdts 
394bc36eafdSMike Gerdts     /* Perform the action */
395bc36eafdSMike Gerdts 
396bc36eafdSMike Gerdts     switch (Action)
397bc36eafdSMike Gerdts     {
398bc36eafdSMike Gerdts     case ACPI_GPE_ENABLE:
399bc36eafdSMike Gerdts 
400bc36eafdSMike Gerdts         Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE);
401*35786f68SRobert Mustacchi         GpeEventInfo->DisableForDispatch = FALSE;
402bc36eafdSMike Gerdts         break;
403bc36eafdSMike Gerdts 
404bc36eafdSMike Gerdts     case ACPI_GPE_DISABLE:
405bc36eafdSMike Gerdts 
406bc36eafdSMike Gerdts         Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
407*35786f68SRobert Mustacchi         GpeEventInfo->DisableForDispatch = TRUE;
408bc36eafdSMike Gerdts         break;
409bc36eafdSMike Gerdts 
410bc36eafdSMike Gerdts     default:
411bc36eafdSMike Gerdts 
412bc36eafdSMike Gerdts         Status = AE_BAD_PARAMETER;
413bc36eafdSMike Gerdts         break;
414bc36eafdSMike Gerdts     }
415bc36eafdSMike Gerdts 
416bc36eafdSMike Gerdts UnlockAndExit:
417bc36eafdSMike Gerdts     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
418bc36eafdSMike Gerdts     return_ACPI_STATUS (Status);
419bc36eafdSMike Gerdts }
420bc36eafdSMike Gerdts 
ACPI_EXPORT_SYMBOL(AcpiSetGpe)421bc36eafdSMike Gerdts ACPI_EXPORT_SYMBOL (AcpiSetGpe)
422bc36eafdSMike Gerdts 
423bc36eafdSMike Gerdts 
424bc36eafdSMike Gerdts /*******************************************************************************
425bc36eafdSMike Gerdts  *
426*35786f68SRobert Mustacchi  * FUNCTION:    AcpiMaskGpe
427*35786f68SRobert Mustacchi  *
428*35786f68SRobert Mustacchi  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
429*35786f68SRobert Mustacchi  *              GpeNumber           - GPE level within the GPE block
430*35786f68SRobert Mustacchi  *              IsMasked            - Whether the GPE is masked or not
431*35786f68SRobert Mustacchi  *
432*35786f68SRobert Mustacchi  * RETURN:      Status
433*35786f68SRobert Mustacchi  *
434*35786f68SRobert Mustacchi  * DESCRIPTION: Unconditionally mask/unmask the an individual GPE, ex., to
435*35786f68SRobert Mustacchi  *              prevent a GPE flooding.
436*35786f68SRobert Mustacchi  *
437*35786f68SRobert Mustacchi  ******************************************************************************/
438*35786f68SRobert Mustacchi 
439*35786f68SRobert Mustacchi ACPI_STATUS
440*35786f68SRobert Mustacchi AcpiMaskGpe (
441*35786f68SRobert Mustacchi     ACPI_HANDLE             GpeDevice,
442*35786f68SRobert Mustacchi     UINT32                  GpeNumber,
443*35786f68SRobert Mustacchi     BOOLEAN                 IsMasked)
444*35786f68SRobert Mustacchi {
445*35786f68SRobert Mustacchi     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
446*35786f68SRobert Mustacchi     ACPI_STATUS             Status;
447*35786f68SRobert Mustacchi     ACPI_CPU_FLAGS          Flags;
448*35786f68SRobert Mustacchi 
449*35786f68SRobert Mustacchi 
450*35786f68SRobert Mustacchi     ACPI_FUNCTION_TRACE (AcpiMaskGpe);
451*35786f68SRobert Mustacchi 
452*35786f68SRobert Mustacchi 
453*35786f68SRobert Mustacchi     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
454*35786f68SRobert Mustacchi 
455*35786f68SRobert Mustacchi     /* Ensure that we have a valid GPE number */
456*35786f68SRobert Mustacchi 
457*35786f68SRobert Mustacchi     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
458*35786f68SRobert Mustacchi     if (!GpeEventInfo)
459*35786f68SRobert Mustacchi     {
460*35786f68SRobert Mustacchi         Status = AE_BAD_PARAMETER;
461*35786f68SRobert Mustacchi         goto UnlockAndExit;
462*35786f68SRobert Mustacchi     }
463*35786f68SRobert Mustacchi 
464*35786f68SRobert Mustacchi     Status = AcpiEvMaskGpe (GpeEventInfo, IsMasked);
465*35786f68SRobert Mustacchi 
466*35786f68SRobert Mustacchi UnlockAndExit:
467*35786f68SRobert Mustacchi     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
468*35786f68SRobert Mustacchi     return_ACPI_STATUS (Status);
469*35786f68SRobert Mustacchi }
470*35786f68SRobert Mustacchi 
ACPI_EXPORT_SYMBOL(AcpiMaskGpe)471*35786f68SRobert Mustacchi ACPI_EXPORT_SYMBOL (AcpiMaskGpe)
472*35786f68SRobert Mustacchi 
473*35786f68SRobert Mustacchi 
474*35786f68SRobert Mustacchi /*******************************************************************************
475*35786f68SRobert Mustacchi  *
476bc36eafdSMike Gerdts  * FUNCTION:    AcpiMarkGpeForWake
477bc36eafdSMike Gerdts  *
478bc36eafdSMike Gerdts  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
479bc36eafdSMike Gerdts  *              GpeNumber           - GPE level within the GPE block
480bc36eafdSMike Gerdts  *
481bc36eafdSMike Gerdts  * RETURN:      Status
482bc36eafdSMike Gerdts  *
483bc36eafdSMike Gerdts  * DESCRIPTION: Mark a GPE as having the ability to wake the system. Simply
484bc36eafdSMike Gerdts  *              sets the ACPI_GPE_CAN_WAKE flag.
485bc36eafdSMike Gerdts  *
486bc36eafdSMike Gerdts  * Some potential callers of AcpiSetupGpeForWake may know in advance that
487bc36eafdSMike Gerdts  * there won't be any notify handlers installed for device wake notifications
488bc36eafdSMike Gerdts  * from the given GPE (one example is a button GPE in Linux). For these cases,
489bc36eafdSMike Gerdts  * AcpiMarkGpeForWake should be used instead of AcpiSetupGpeForWake.
490bc36eafdSMike Gerdts  * This will set the ACPI_GPE_CAN_WAKE flag for the GPE without trying to
491bc36eafdSMike Gerdts  * setup implicit wake notification for it (since there's no handler method).
492bc36eafdSMike Gerdts  *
493bc36eafdSMike Gerdts  ******************************************************************************/
494bc36eafdSMike Gerdts 
495bc36eafdSMike Gerdts ACPI_STATUS
496bc36eafdSMike Gerdts AcpiMarkGpeForWake (
497bc36eafdSMike Gerdts     ACPI_HANDLE             GpeDevice,
498bc36eafdSMike Gerdts     UINT32                  GpeNumber)
499bc36eafdSMike Gerdts {
500bc36eafdSMike Gerdts     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
501bc36eafdSMike Gerdts     ACPI_STATUS             Status = AE_BAD_PARAMETER;
502bc36eafdSMike Gerdts     ACPI_CPU_FLAGS          Flags;
503bc36eafdSMike Gerdts 
504bc36eafdSMike Gerdts 
505bc36eafdSMike Gerdts     ACPI_FUNCTION_TRACE (AcpiMarkGpeForWake);
506bc36eafdSMike Gerdts 
507bc36eafdSMike Gerdts 
508bc36eafdSMike Gerdts     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
509bc36eafdSMike Gerdts 
510bc36eafdSMike Gerdts     /* Ensure that we have a valid GPE number */
511bc36eafdSMike Gerdts 
512bc36eafdSMike Gerdts     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
513bc36eafdSMike Gerdts     if (GpeEventInfo)
514bc36eafdSMike Gerdts     {
515bc36eafdSMike Gerdts         /* Mark the GPE as a possible wake event */
516bc36eafdSMike Gerdts 
517bc36eafdSMike Gerdts         GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
518bc36eafdSMike Gerdts         Status = AE_OK;
519bc36eafdSMike Gerdts     }
520bc36eafdSMike Gerdts 
521bc36eafdSMike Gerdts     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
522bc36eafdSMike Gerdts     return_ACPI_STATUS (Status);
523bc36eafdSMike Gerdts }
524bc36eafdSMike Gerdts 
ACPI_EXPORT_SYMBOL(AcpiMarkGpeForWake)525bc36eafdSMike Gerdts ACPI_EXPORT_SYMBOL (AcpiMarkGpeForWake)
526bc36eafdSMike Gerdts 
527bc36eafdSMike Gerdts 
528bc36eafdSMike Gerdts /*******************************************************************************
529bc36eafdSMike Gerdts  *
530bc36eafdSMike Gerdts  * FUNCTION:    AcpiSetupGpeForWake
531bc36eafdSMike Gerdts  *
532bc36eafdSMike Gerdts  * PARAMETERS:  WakeDevice          - Device associated with the GPE (via _PRW)
533bc36eafdSMike Gerdts  *              GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
534bc36eafdSMike Gerdts  *              GpeNumber           - GPE level within the GPE block
535bc36eafdSMike Gerdts  *
536bc36eafdSMike Gerdts  * RETURN:      Status
537bc36eafdSMike Gerdts  *
538bc36eafdSMike Gerdts  * DESCRIPTION: Mark a GPE as having the ability to wake the system. This
539bc36eafdSMike Gerdts  *              interface is intended to be used as the host executes the
540bc36eafdSMike Gerdts  *              _PRW methods (Power Resources for Wake) in the system tables.
541bc36eafdSMike Gerdts  *              Each _PRW appears under a Device Object (The WakeDevice), and
542bc36eafdSMike Gerdts  *              contains the info for the wake GPE associated with the
543bc36eafdSMike Gerdts  *              WakeDevice.
544bc36eafdSMike Gerdts  *
545bc36eafdSMike Gerdts  ******************************************************************************/
546bc36eafdSMike Gerdts 
547bc36eafdSMike Gerdts ACPI_STATUS
548bc36eafdSMike Gerdts AcpiSetupGpeForWake (
549bc36eafdSMike Gerdts     ACPI_HANDLE             WakeDevice,
550bc36eafdSMike Gerdts     ACPI_HANDLE             GpeDevice,
551bc36eafdSMike Gerdts     UINT32                  GpeNumber)
552bc36eafdSMike Gerdts {
553bc36eafdSMike Gerdts     ACPI_STATUS             Status;
554bc36eafdSMike Gerdts     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
555bc36eafdSMike Gerdts     ACPI_NAMESPACE_NODE     *DeviceNode;
556bc36eafdSMike Gerdts     ACPI_GPE_NOTIFY_INFO    *Notify;
557bc36eafdSMike Gerdts     ACPI_GPE_NOTIFY_INFO    *NewNotify;
558bc36eafdSMike Gerdts     ACPI_CPU_FLAGS          Flags;
559bc36eafdSMike Gerdts 
560bc36eafdSMike Gerdts 
561bc36eafdSMike Gerdts     ACPI_FUNCTION_TRACE (AcpiSetupGpeForWake);
562bc36eafdSMike Gerdts 
563bc36eafdSMike Gerdts 
564bc36eafdSMike Gerdts     /* Parameter Validation */
565bc36eafdSMike Gerdts 
566bc36eafdSMike Gerdts     if (!WakeDevice)
567bc36eafdSMike Gerdts     {
568bc36eafdSMike Gerdts         /*
569bc36eafdSMike Gerdts          * By forcing WakeDevice to be valid, we automatically enable the
570bc36eafdSMike Gerdts          * implicit notify feature on all hosts.
571bc36eafdSMike Gerdts          */
572bc36eafdSMike Gerdts         return_ACPI_STATUS (AE_BAD_PARAMETER);
573bc36eafdSMike Gerdts     }
574bc36eafdSMike Gerdts 
575bc36eafdSMike Gerdts     /* Handle root object case */
576bc36eafdSMike Gerdts 
577bc36eafdSMike Gerdts     if (WakeDevice == ACPI_ROOT_OBJECT)
578bc36eafdSMike Gerdts     {
579bc36eafdSMike Gerdts         DeviceNode = AcpiGbl_RootNode;
580bc36eafdSMike Gerdts     }
581bc36eafdSMike Gerdts     else
582bc36eafdSMike Gerdts     {
583bc36eafdSMike Gerdts         DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, WakeDevice);
584bc36eafdSMike Gerdts     }
585bc36eafdSMike Gerdts 
586bc36eafdSMike Gerdts     /* Validate WakeDevice is of type Device */
587bc36eafdSMike Gerdts 
588bc36eafdSMike Gerdts     if (DeviceNode->Type != ACPI_TYPE_DEVICE)
589bc36eafdSMike Gerdts     {
590bc36eafdSMike Gerdts         return_ACPI_STATUS (AE_BAD_PARAMETER);
591bc36eafdSMike Gerdts     }
592bc36eafdSMike Gerdts 
593bc36eafdSMike Gerdts     /*
594bc36eafdSMike Gerdts      * Allocate a new notify object up front, in case it is needed.
595bc36eafdSMike Gerdts      * Memory allocation while holding a spinlock is a big no-no
596bc36eafdSMike Gerdts      * on some hosts.
597bc36eafdSMike Gerdts      */
598bc36eafdSMike Gerdts     NewNotify = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_NOTIFY_INFO));
599bc36eafdSMike Gerdts     if (!NewNotify)
600bc36eafdSMike Gerdts     {
601bc36eafdSMike Gerdts         return_ACPI_STATUS (AE_NO_MEMORY);
602bc36eafdSMike Gerdts     }
603bc36eafdSMike Gerdts 
604bc36eafdSMike Gerdts     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
605bc36eafdSMike Gerdts 
606bc36eafdSMike Gerdts     /* Ensure that we have a valid GPE number */
607bc36eafdSMike Gerdts 
608bc36eafdSMike Gerdts     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
609bc36eafdSMike Gerdts     if (!GpeEventInfo)
610bc36eafdSMike Gerdts     {
611bc36eafdSMike Gerdts         Status = AE_BAD_PARAMETER;
612bc36eafdSMike Gerdts         goto UnlockAndExit;
613bc36eafdSMike Gerdts     }
614bc36eafdSMike Gerdts 
615bc36eafdSMike Gerdts     /*
616bc36eafdSMike Gerdts      * If there is no method or handler for this GPE, then the
617bc36eafdSMike Gerdts      * WakeDevice will be notified whenever this GPE fires. This is
618bc36eafdSMike Gerdts      * known as an "implicit notify". Note: The GPE is assumed to be
619bc36eafdSMike Gerdts      * level-triggered (for windows compatibility).
620bc36eafdSMike Gerdts      */
621bc36eafdSMike Gerdts     if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
622bc36eafdSMike Gerdts         ACPI_GPE_DISPATCH_NONE)
623bc36eafdSMike Gerdts     {
624bc36eafdSMike Gerdts         /*
625bc36eafdSMike Gerdts          * This is the first device for implicit notify on this GPE.
626bc36eafdSMike Gerdts          * Just set the flags here, and enter the NOTIFY block below.
627bc36eafdSMike Gerdts          */
628bc36eafdSMike Gerdts         GpeEventInfo->Flags =
629bc36eafdSMike Gerdts             (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED);
630bc36eafdSMike Gerdts     }
631*35786f68SRobert Mustacchi     else if (GpeEventInfo->Flags & ACPI_GPE_AUTO_ENABLED)
632*35786f68SRobert Mustacchi     {
633*35786f68SRobert Mustacchi         /*
634*35786f68SRobert Mustacchi          * A reference to this GPE has been added during the GPE block
635*35786f68SRobert Mustacchi          * initialization, so drop it now to prevent the GPE from being
636*35786f68SRobert Mustacchi          * permanently enabled and clear its ACPI_GPE_AUTO_ENABLED flag.
637*35786f68SRobert Mustacchi          */
638*35786f68SRobert Mustacchi         (void) AcpiEvRemoveGpeReference (GpeEventInfo);
639*35786f68SRobert Mustacchi         GpeEventInfo->Flags &= ~~ACPI_GPE_AUTO_ENABLED;
640*35786f68SRobert Mustacchi     }
641bc36eafdSMike Gerdts 
642bc36eafdSMike Gerdts     /*
643bc36eafdSMike Gerdts      * If we already have an implicit notify on this GPE, add
644bc36eafdSMike Gerdts      * this device to the notify list.
645bc36eafdSMike Gerdts      */
646bc36eafdSMike Gerdts     if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
647bc36eafdSMike Gerdts         ACPI_GPE_DISPATCH_NOTIFY)
648bc36eafdSMike Gerdts     {
649bc36eafdSMike Gerdts         /* Ensure that the device is not already in the list */
650bc36eafdSMike Gerdts 
651bc36eafdSMike Gerdts         Notify = GpeEventInfo->Dispatch.NotifyList;
652bc36eafdSMike Gerdts         while (Notify)
653bc36eafdSMike Gerdts         {
654bc36eafdSMike Gerdts             if (Notify->DeviceNode == DeviceNode)
655bc36eafdSMike Gerdts             {
656bc36eafdSMike Gerdts                 Status = AE_ALREADY_EXISTS;
657bc36eafdSMike Gerdts                 goto UnlockAndExit;
658bc36eafdSMike Gerdts             }
659bc36eafdSMike Gerdts             Notify = Notify->Next;
660bc36eafdSMike Gerdts         }
661bc36eafdSMike Gerdts 
662bc36eafdSMike Gerdts         /* Add this device to the notify list for this GPE */
663bc36eafdSMike Gerdts 
664bc36eafdSMike Gerdts         NewNotify->DeviceNode = DeviceNode;
665bc36eafdSMike Gerdts         NewNotify->Next = GpeEventInfo->Dispatch.NotifyList;
666bc36eafdSMike Gerdts         GpeEventInfo->Dispatch.NotifyList = NewNotify;
667bc36eafdSMike Gerdts         NewNotify = NULL;
668bc36eafdSMike Gerdts     }
669bc36eafdSMike Gerdts 
670bc36eafdSMike Gerdts     /* Mark the GPE as a possible wake event */
671bc36eafdSMike Gerdts 
672bc36eafdSMike Gerdts     GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
673bc36eafdSMike Gerdts     Status = AE_OK;
674bc36eafdSMike Gerdts 
675bc36eafdSMike Gerdts 
676bc36eafdSMike Gerdts UnlockAndExit:
677bc36eafdSMike Gerdts     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
678bc36eafdSMike Gerdts 
679bc36eafdSMike Gerdts     /* Delete the notify object if it was not used above */
680bc36eafdSMike Gerdts 
681bc36eafdSMike Gerdts     if (NewNotify)
682bc36eafdSMike Gerdts     {
683bc36eafdSMike Gerdts         ACPI_FREE (NewNotify);
684bc36eafdSMike Gerdts     }
685bc36eafdSMike Gerdts     return_ACPI_STATUS (Status);
686bc36eafdSMike Gerdts }
687bc36eafdSMike Gerdts 
ACPI_EXPORT_SYMBOL(AcpiSetupGpeForWake)688bc36eafdSMike Gerdts ACPI_EXPORT_SYMBOL (AcpiSetupGpeForWake)
689bc36eafdSMike Gerdts 
690bc36eafdSMike Gerdts 
691bc36eafdSMike Gerdts /*******************************************************************************
692bc36eafdSMike Gerdts  *
693bc36eafdSMike Gerdts  * FUNCTION:    AcpiSetGpeWakeMask
694bc36eafdSMike Gerdts  *
695bc36eafdSMike Gerdts  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
696bc36eafdSMike Gerdts  *              GpeNumber           - GPE level within the GPE block
697bc36eafdSMike Gerdts  *              Action              - Enable or Disable
698bc36eafdSMike Gerdts  *
699bc36eafdSMike Gerdts  * RETURN:      Status
700bc36eafdSMike Gerdts  *
701bc36eafdSMike Gerdts  * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must
702bc36eafdSMike Gerdts  *              already be marked as a WAKE GPE.
703bc36eafdSMike Gerdts  *
704bc36eafdSMike Gerdts  ******************************************************************************/
705bc36eafdSMike Gerdts 
706bc36eafdSMike Gerdts ACPI_STATUS
707bc36eafdSMike Gerdts AcpiSetGpeWakeMask (
708bc36eafdSMike Gerdts     ACPI_HANDLE             GpeDevice,
709bc36eafdSMike Gerdts     UINT32                  GpeNumber,
710bc36eafdSMike Gerdts     UINT8                   Action)
711bc36eafdSMike Gerdts {
712bc36eafdSMike Gerdts     ACPI_STATUS             Status = AE_OK;
713bc36eafdSMike Gerdts     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
714bc36eafdSMike Gerdts     ACPI_GPE_REGISTER_INFO  *GpeRegisterInfo;
715bc36eafdSMike Gerdts     ACPI_CPU_FLAGS          Flags;
716bc36eafdSMike Gerdts     UINT32                  RegisterBit;
717bc36eafdSMike Gerdts 
718bc36eafdSMike Gerdts 
719bc36eafdSMike Gerdts     ACPI_FUNCTION_TRACE (AcpiSetGpeWakeMask);
720bc36eafdSMike Gerdts 
721bc36eafdSMike Gerdts 
722bc36eafdSMike Gerdts     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
723bc36eafdSMike Gerdts 
724bc36eafdSMike Gerdts     /*
725bc36eafdSMike Gerdts      * Ensure that we have a valid GPE number and that this GPE is in
726bc36eafdSMike Gerdts      * fact a wake GPE
727bc36eafdSMike Gerdts      */
728bc36eafdSMike Gerdts     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
729bc36eafdSMike Gerdts     if (!GpeEventInfo)
730bc36eafdSMike Gerdts     {
731bc36eafdSMike Gerdts         Status = AE_BAD_PARAMETER;
732bc36eafdSMike Gerdts         goto UnlockAndExit;
733bc36eafdSMike Gerdts     }
734bc36eafdSMike Gerdts 
735bc36eafdSMike Gerdts     if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE))
736bc36eafdSMike Gerdts     {
737bc36eafdSMike Gerdts         Status = AE_TYPE;
738bc36eafdSMike Gerdts         goto UnlockAndExit;
739bc36eafdSMike Gerdts     }
740bc36eafdSMike Gerdts 
741bc36eafdSMike Gerdts     GpeRegisterInfo = GpeEventInfo->RegisterInfo;
742bc36eafdSMike Gerdts     if (!GpeRegisterInfo)
743bc36eafdSMike Gerdts     {
744bc36eafdSMike Gerdts         Status = AE_NOT_EXIST;
745bc36eafdSMike Gerdts         goto UnlockAndExit;
746bc36eafdSMike Gerdts     }
747bc36eafdSMike Gerdts 
748bc36eafdSMike Gerdts     RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo);
749bc36eafdSMike Gerdts 
750bc36eafdSMike Gerdts     /* Perform the action */
751bc36eafdSMike Gerdts 
752bc36eafdSMike Gerdts     switch (Action)
753bc36eafdSMike Gerdts     {
754bc36eafdSMike Gerdts     case ACPI_GPE_ENABLE:
755bc36eafdSMike Gerdts 
756bc36eafdSMike Gerdts         ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
757bc36eafdSMike Gerdts         break;
758bc36eafdSMike Gerdts 
759bc36eafdSMike Gerdts     case ACPI_GPE_DISABLE:
760bc36eafdSMike Gerdts 
761bc36eafdSMike Gerdts         ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
762bc36eafdSMike Gerdts         break;
763bc36eafdSMike Gerdts 
764bc36eafdSMike Gerdts     default:
765bc36eafdSMike Gerdts 
766bc36eafdSMike Gerdts         ACPI_ERROR ((AE_INFO, "%u, Invalid action", Action));
767bc36eafdSMike Gerdts         Status = AE_BAD_PARAMETER;
768bc36eafdSMike Gerdts         break;
769bc36eafdSMike Gerdts     }
770bc36eafdSMike Gerdts 
771bc36eafdSMike Gerdts UnlockAndExit:
772bc36eafdSMike Gerdts     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
773bc36eafdSMike Gerdts     return_ACPI_STATUS (Status);
774bc36eafdSMike Gerdts }
775bc36eafdSMike Gerdts 
ACPI_EXPORT_SYMBOL(AcpiSetGpeWakeMask)776bc36eafdSMike Gerdts ACPI_EXPORT_SYMBOL (AcpiSetGpeWakeMask)
777bc36eafdSMike Gerdts 
778bc36eafdSMike Gerdts 
779bc36eafdSMike Gerdts /*******************************************************************************
780bc36eafdSMike Gerdts  *
781bc36eafdSMike Gerdts  * FUNCTION:    AcpiClearGpe
782bc36eafdSMike Gerdts  *
783bc36eafdSMike Gerdts  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
784bc36eafdSMike Gerdts  *              GpeNumber           - GPE level within the GPE block
785bc36eafdSMike Gerdts  *
786bc36eafdSMike Gerdts  * RETURN:      Status
787bc36eafdSMike Gerdts  *
788bc36eafdSMike Gerdts  * DESCRIPTION: Clear an ACPI event (general purpose)
789bc36eafdSMike Gerdts  *
790bc36eafdSMike Gerdts  ******************************************************************************/
791bc36eafdSMike Gerdts 
792bc36eafdSMike Gerdts ACPI_STATUS
793bc36eafdSMike Gerdts AcpiClearGpe (
794bc36eafdSMike Gerdts     ACPI_HANDLE             GpeDevice,
795bc36eafdSMike Gerdts     UINT32                  GpeNumber)
796bc36eafdSMike Gerdts {
797bc36eafdSMike Gerdts     ACPI_STATUS             Status = AE_OK;
798bc36eafdSMike Gerdts     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
799bc36eafdSMike Gerdts     ACPI_CPU_FLAGS          Flags;
800bc36eafdSMike Gerdts 
801bc36eafdSMike Gerdts 
802bc36eafdSMike Gerdts     ACPI_FUNCTION_TRACE (AcpiClearGpe);
803bc36eafdSMike Gerdts 
804bc36eafdSMike Gerdts 
805bc36eafdSMike Gerdts     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
806bc36eafdSMike Gerdts 
807bc36eafdSMike Gerdts     /* Ensure that we have a valid GPE number */
808bc36eafdSMike Gerdts 
809bc36eafdSMike Gerdts     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
810bc36eafdSMike Gerdts     if (!GpeEventInfo)
811bc36eafdSMike Gerdts     {
812bc36eafdSMike Gerdts         Status = AE_BAD_PARAMETER;
813bc36eafdSMike Gerdts         goto UnlockAndExit;
814bc36eafdSMike Gerdts     }
815bc36eafdSMike Gerdts 
816bc36eafdSMike Gerdts     Status = AcpiHwClearGpe (GpeEventInfo);
817bc36eafdSMike Gerdts 
818bc36eafdSMike Gerdts UnlockAndExit:
819bc36eafdSMike Gerdts     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
820bc36eafdSMike Gerdts     return_ACPI_STATUS (Status);
821bc36eafdSMike Gerdts }
822bc36eafdSMike Gerdts 
ACPI_EXPORT_SYMBOL(AcpiClearGpe)823bc36eafdSMike Gerdts ACPI_EXPORT_SYMBOL (AcpiClearGpe)
824bc36eafdSMike Gerdts 
825bc36eafdSMike Gerdts 
826bc36eafdSMike Gerdts /*******************************************************************************
827bc36eafdSMike Gerdts  *
828bc36eafdSMike Gerdts  * FUNCTION:    AcpiGetGpeStatus
829bc36eafdSMike Gerdts  *
830bc36eafdSMike Gerdts  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
831bc36eafdSMike Gerdts  *              GpeNumber           - GPE level within the GPE block
832bc36eafdSMike Gerdts  *              EventStatus         - Where the current status of the event
833bc36eafdSMike Gerdts  *                                    will be returned
834bc36eafdSMike Gerdts  *
835bc36eafdSMike Gerdts  * RETURN:      Status
836bc36eafdSMike Gerdts  *
837bc36eafdSMike Gerdts  * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled)
838bc36eafdSMike Gerdts  *
839bc36eafdSMike Gerdts  ******************************************************************************/
840bc36eafdSMike Gerdts 
841bc36eafdSMike Gerdts ACPI_STATUS
842bc36eafdSMike Gerdts AcpiGetGpeStatus (
843bc36eafdSMike Gerdts     ACPI_HANDLE             GpeDevice,
844bc36eafdSMike Gerdts     UINT32                  GpeNumber,
845bc36eafdSMike Gerdts     ACPI_EVENT_STATUS       *EventStatus)
846bc36eafdSMike Gerdts {
847bc36eafdSMike Gerdts     ACPI_STATUS             Status = AE_OK;
848bc36eafdSMike Gerdts     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
849bc36eafdSMike Gerdts     ACPI_CPU_FLAGS          Flags;
850bc36eafdSMike Gerdts 
851bc36eafdSMike Gerdts 
852bc36eafdSMike Gerdts     ACPI_FUNCTION_TRACE (AcpiGetGpeStatus);
853bc36eafdSMike Gerdts 
854bc36eafdSMike Gerdts 
855bc36eafdSMike Gerdts     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
856bc36eafdSMike Gerdts 
857bc36eafdSMike Gerdts     /* Ensure that we have a valid GPE number */
858bc36eafdSMike Gerdts 
859bc36eafdSMike Gerdts     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
860bc36eafdSMike Gerdts     if (!GpeEventInfo)
861bc36eafdSMike Gerdts     {
862bc36eafdSMike Gerdts         Status = AE_BAD_PARAMETER;
863bc36eafdSMike Gerdts         goto UnlockAndExit;
864bc36eafdSMike Gerdts     }
865bc36eafdSMike Gerdts 
866bc36eafdSMike Gerdts     /* Obtain status on the requested GPE number */
867bc36eafdSMike Gerdts 
868bc36eafdSMike Gerdts     Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus);
869bc36eafdSMike Gerdts 
870bc36eafdSMike Gerdts UnlockAndExit:
871bc36eafdSMike Gerdts     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
872bc36eafdSMike Gerdts     return_ACPI_STATUS (Status);
873bc36eafdSMike Gerdts }
874bc36eafdSMike Gerdts 
ACPI_EXPORT_SYMBOL(AcpiGetGpeStatus)875bc36eafdSMike Gerdts ACPI_EXPORT_SYMBOL (AcpiGetGpeStatus)
876bc36eafdSMike Gerdts 
877bc36eafdSMike Gerdts 
878bc36eafdSMike Gerdts /*******************************************************************************
879bc36eafdSMike Gerdts  *
880bc36eafdSMike Gerdts  * FUNCTION:    AcpiFinishGpe
881bc36eafdSMike Gerdts  *
882bc36eafdSMike Gerdts  * PARAMETERS:  GpeDevice           - Namespace node for the GPE Block
883bc36eafdSMike Gerdts  *                                    (NULL for FADT defined GPEs)
884bc36eafdSMike Gerdts  *              GpeNumber           - GPE level within the GPE block
885bc36eafdSMike Gerdts  *
886bc36eafdSMike Gerdts  * RETURN:      Status
887bc36eafdSMike Gerdts  *
888bc36eafdSMike Gerdts  * DESCRIPTION: Clear and conditionally reenable a GPE. This completes the GPE
889bc36eafdSMike Gerdts  *              processing. Intended for use by asynchronous host-installed
890bc36eafdSMike Gerdts  *              GPE handlers. The GPE is only reenabled if the EnableForRun bit
891bc36eafdSMike Gerdts  *              is set in the GPE info.
892bc36eafdSMike Gerdts  *
893bc36eafdSMike Gerdts  ******************************************************************************/
894bc36eafdSMike Gerdts 
895bc36eafdSMike Gerdts ACPI_STATUS
896bc36eafdSMike Gerdts AcpiFinishGpe (
897bc36eafdSMike Gerdts     ACPI_HANDLE             GpeDevice,
898bc36eafdSMike Gerdts     UINT32                  GpeNumber)
899bc36eafdSMike Gerdts {
900bc36eafdSMike Gerdts     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
901bc36eafdSMike Gerdts     ACPI_STATUS             Status;
902bc36eafdSMike Gerdts     ACPI_CPU_FLAGS          Flags;
903bc36eafdSMike Gerdts 
904bc36eafdSMike Gerdts 
905bc36eafdSMike Gerdts     ACPI_FUNCTION_TRACE (AcpiFinishGpe);
906bc36eafdSMike Gerdts 
907bc36eafdSMike Gerdts 
908bc36eafdSMike Gerdts     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
909bc36eafdSMike Gerdts 
910bc36eafdSMike Gerdts     /* Ensure that we have a valid GPE number */
911bc36eafdSMike Gerdts 
912bc36eafdSMike Gerdts     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
913bc36eafdSMike Gerdts     if (!GpeEventInfo)
914bc36eafdSMike Gerdts     {
915bc36eafdSMike Gerdts         Status = AE_BAD_PARAMETER;
916bc36eafdSMike Gerdts         goto UnlockAndExit;
917bc36eafdSMike Gerdts     }
918bc36eafdSMike Gerdts 
919bc36eafdSMike Gerdts     Status = AcpiEvFinishGpe (GpeEventInfo);
920bc36eafdSMike Gerdts 
921bc36eafdSMike Gerdts UnlockAndExit:
922bc36eafdSMike Gerdts     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
923bc36eafdSMike Gerdts     return_ACPI_STATUS (Status);
924bc36eafdSMike Gerdts }
925bc36eafdSMike Gerdts 
ACPI_EXPORT_SYMBOL(AcpiFinishGpe)926bc36eafdSMike Gerdts ACPI_EXPORT_SYMBOL (AcpiFinishGpe)
927bc36eafdSMike Gerdts 
928bc36eafdSMike Gerdts 
929bc36eafdSMike Gerdts /******************************************************************************
930bc36eafdSMike Gerdts  *
931bc36eafdSMike Gerdts  * FUNCTION:    AcpiDisableAllGpes
932bc36eafdSMike Gerdts  *
933bc36eafdSMike Gerdts  * PARAMETERS:  None
934bc36eafdSMike Gerdts  *
935bc36eafdSMike Gerdts  * RETURN:      Status
936bc36eafdSMike Gerdts  *
937bc36eafdSMike Gerdts  * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
938bc36eafdSMike Gerdts  *
939bc36eafdSMike Gerdts  ******************************************************************************/
940bc36eafdSMike Gerdts 
941bc36eafdSMike Gerdts ACPI_STATUS
942bc36eafdSMike Gerdts AcpiDisableAllGpes (
943bc36eafdSMike Gerdts     void)
944bc36eafdSMike Gerdts {
945bc36eafdSMike Gerdts     ACPI_STATUS             Status;
946bc36eafdSMike Gerdts 
947bc36eafdSMike Gerdts 
948bc36eafdSMike Gerdts     ACPI_FUNCTION_TRACE (AcpiDisableAllGpes);
949bc36eafdSMike Gerdts 
950bc36eafdSMike Gerdts 
951bc36eafdSMike Gerdts     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
952bc36eafdSMike Gerdts     if (ACPI_FAILURE (Status))
953bc36eafdSMike Gerdts     {
954bc36eafdSMike Gerdts         return_ACPI_STATUS (Status);
955bc36eafdSMike Gerdts     }
956bc36eafdSMike Gerdts 
957bc36eafdSMike Gerdts     Status = AcpiHwDisableAllGpes ();
958bc36eafdSMike Gerdts     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
959bc36eafdSMike Gerdts 
960bc36eafdSMike Gerdts     return_ACPI_STATUS (Status);
961bc36eafdSMike Gerdts }
962bc36eafdSMike Gerdts 
ACPI_EXPORT_SYMBOL(AcpiDisableAllGpes)963bc36eafdSMike Gerdts ACPI_EXPORT_SYMBOL (AcpiDisableAllGpes)
964bc36eafdSMike Gerdts 
965bc36eafdSMike Gerdts 
966bc36eafdSMike Gerdts /******************************************************************************
967bc36eafdSMike Gerdts  *
968bc36eafdSMike Gerdts  * FUNCTION:    AcpiEnableAllRuntimeGpes
969bc36eafdSMike Gerdts  *
970bc36eafdSMike Gerdts  * PARAMETERS:  None
971bc36eafdSMike Gerdts  *
972bc36eafdSMike Gerdts  * RETURN:      Status
973bc36eafdSMike Gerdts  *
974bc36eafdSMike Gerdts  * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
975bc36eafdSMike Gerdts  *
976bc36eafdSMike Gerdts  ******************************************************************************/
977bc36eafdSMike Gerdts 
978bc36eafdSMike Gerdts ACPI_STATUS
979bc36eafdSMike Gerdts AcpiEnableAllRuntimeGpes (
980bc36eafdSMike Gerdts     void)
981bc36eafdSMike Gerdts {
982bc36eafdSMike Gerdts     ACPI_STATUS             Status;
983bc36eafdSMike Gerdts 
984bc36eafdSMike Gerdts 
985bc36eafdSMike Gerdts     ACPI_FUNCTION_TRACE (AcpiEnableAllRuntimeGpes);
986bc36eafdSMike Gerdts 
987bc36eafdSMike Gerdts 
988bc36eafdSMike Gerdts     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
989bc36eafdSMike Gerdts     if (ACPI_FAILURE (Status))
990bc36eafdSMike Gerdts     {
991bc36eafdSMike Gerdts         return_ACPI_STATUS (Status);
992bc36eafdSMike Gerdts     }
993bc36eafdSMike Gerdts 
994bc36eafdSMike Gerdts     Status = AcpiHwEnableAllRuntimeGpes ();
995bc36eafdSMike Gerdts     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
996bc36eafdSMike Gerdts 
997bc36eafdSMike Gerdts     return_ACPI_STATUS (Status);
998bc36eafdSMike Gerdts }
999bc36eafdSMike Gerdts 
ACPI_EXPORT_SYMBOL(AcpiEnableAllRuntimeGpes)1000bc36eafdSMike Gerdts ACPI_EXPORT_SYMBOL (AcpiEnableAllRuntimeGpes)
1001bc36eafdSMike Gerdts 
1002bc36eafdSMike Gerdts 
1003bc36eafdSMike Gerdts /******************************************************************************
1004bc36eafdSMike Gerdts  *
1005bc36eafdSMike Gerdts  * FUNCTION:    AcpiEnableAllWakeupGpes
1006bc36eafdSMike Gerdts  *
1007bc36eafdSMike Gerdts  * PARAMETERS:  None
1008bc36eafdSMike Gerdts  *
1009bc36eafdSMike Gerdts  * RETURN:      Status
1010bc36eafdSMike Gerdts  *
1011bc36eafdSMike Gerdts  * DESCRIPTION: Enable all "wakeup" GPEs and disable all of the other GPEs, in
1012bc36eafdSMike Gerdts  *              all GPE blocks.
1013bc36eafdSMike Gerdts  *
1014bc36eafdSMike Gerdts  ******************************************************************************/
1015bc36eafdSMike Gerdts 
1016bc36eafdSMike Gerdts ACPI_STATUS
1017bc36eafdSMike Gerdts AcpiEnableAllWakeupGpes (
1018bc36eafdSMike Gerdts     void)
1019bc36eafdSMike Gerdts {
1020bc36eafdSMike Gerdts     ACPI_STATUS             Status;
1021bc36eafdSMike Gerdts 
1022bc36eafdSMike Gerdts 
1023bc36eafdSMike Gerdts     ACPI_FUNCTION_TRACE (AcpiEnableAllWakeupGpes);
1024bc36eafdSMike Gerdts 
1025bc36eafdSMike Gerdts 
1026bc36eafdSMike Gerdts     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
1027bc36eafdSMike Gerdts     if (ACPI_FAILURE (Status))
1028bc36eafdSMike Gerdts     {
1029bc36eafdSMike Gerdts         return_ACPI_STATUS (Status);
1030bc36eafdSMike Gerdts     }
1031bc36eafdSMike Gerdts 
1032bc36eafdSMike Gerdts     Status = AcpiHwEnableAllWakeupGpes ();
1033bc36eafdSMike Gerdts     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
1034bc36eafdSMike Gerdts 
1035bc36eafdSMike Gerdts     return_ACPI_STATUS (Status);
1036bc36eafdSMike Gerdts }
1037bc36eafdSMike Gerdts 
ACPI_EXPORT_SYMBOL(AcpiEnableAllWakeupGpes)1038bc36eafdSMike Gerdts ACPI_EXPORT_SYMBOL (AcpiEnableAllWakeupGpes)
1039bc36eafdSMike Gerdts 
1040bc36eafdSMike Gerdts 
1041bc36eafdSMike Gerdts /*******************************************************************************
1042bc36eafdSMike Gerdts  *
1043bc36eafdSMike Gerdts  * FUNCTION:    AcpiInstallGpeBlock
1044bc36eafdSMike Gerdts  *
1045bc36eafdSMike Gerdts  * PARAMETERS:  GpeDevice           - Handle to the parent GPE Block Device
1046bc36eafdSMike Gerdts  *              GpeBlockAddress     - Address and SpaceID
1047bc36eafdSMike Gerdts  *              RegisterCount       - Number of GPE register pairs in the block
1048bc36eafdSMike Gerdts  *              InterruptNumber     - H/W interrupt for the block
1049bc36eafdSMike Gerdts  *
1050bc36eafdSMike Gerdts  * RETURN:      Status
1051bc36eafdSMike Gerdts  *
1052bc36eafdSMike Gerdts  * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not
1053bc36eafdSMike Gerdts  *              enabled here.
1054bc36eafdSMike Gerdts  *
1055bc36eafdSMike Gerdts  ******************************************************************************/
1056bc36eafdSMike Gerdts 
1057bc36eafdSMike Gerdts ACPI_STATUS
1058bc36eafdSMike Gerdts AcpiInstallGpeBlock (
1059bc36eafdSMike Gerdts     ACPI_HANDLE             GpeDevice,
1060bc36eafdSMike Gerdts     ACPI_GENERIC_ADDRESS    *GpeBlockAddress,
1061bc36eafdSMike Gerdts     UINT32                  RegisterCount,
1062bc36eafdSMike Gerdts     UINT32                  InterruptNumber)
1063bc36eafdSMike Gerdts {
1064bc36eafdSMike Gerdts     ACPI_STATUS             Status;
1065bc36eafdSMike Gerdts     ACPI_OPERAND_OBJECT     *ObjDesc;
1066bc36eafdSMike Gerdts     ACPI_NAMESPACE_NODE     *Node;
1067bc36eafdSMike Gerdts     ACPI_GPE_BLOCK_INFO     *GpeBlock;
1068bc36eafdSMike Gerdts 
1069bc36eafdSMike Gerdts 
1070bc36eafdSMike Gerdts     ACPI_FUNCTION_TRACE (AcpiInstallGpeBlock);
1071bc36eafdSMike Gerdts 
1072bc36eafdSMike Gerdts 
1073bc36eafdSMike Gerdts     if ((!GpeDevice)       ||
1074bc36eafdSMike Gerdts         (!GpeBlockAddress) ||
1075bc36eafdSMike Gerdts         (!RegisterCount))
1076bc36eafdSMike Gerdts     {
1077bc36eafdSMike Gerdts         return_ACPI_STATUS (AE_BAD_PARAMETER);
1078bc36eafdSMike Gerdts     }
1079bc36eafdSMike Gerdts 
1080bc36eafdSMike Gerdts     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
1081bc36eafdSMike Gerdts     if (ACPI_FAILURE (Status))
1082bc36eafdSMike Gerdts     {
1083bc36eafdSMike Gerdts         return_ACPI_STATUS (Status);
1084bc36eafdSMike Gerdts     }
1085bc36eafdSMike Gerdts 
1086bc36eafdSMike Gerdts     Node = AcpiNsValidateHandle (GpeDevice);
1087bc36eafdSMike Gerdts     if (!Node)
1088bc36eafdSMike Gerdts     {
1089bc36eafdSMike Gerdts         Status = AE_BAD_PARAMETER;
1090bc36eafdSMike Gerdts         goto UnlockAndExit;
1091bc36eafdSMike Gerdts     }
1092bc36eafdSMike Gerdts 
1093bc36eafdSMike Gerdts     /* Validate the parent device */
1094bc36eafdSMike Gerdts 
1095bc36eafdSMike Gerdts     if (Node->Type != ACPI_TYPE_DEVICE)
1096bc36eafdSMike Gerdts     {
1097bc36eafdSMike Gerdts         Status = AE_TYPE;
1098bc36eafdSMike Gerdts         goto UnlockAndExit;
1099bc36eafdSMike Gerdts     }
1100bc36eafdSMike Gerdts 
1101bc36eafdSMike Gerdts     if (Node->Object)
1102bc36eafdSMike Gerdts     {
1103bc36eafdSMike Gerdts         Status = AE_ALREADY_EXISTS;
1104bc36eafdSMike Gerdts         goto UnlockAndExit;
1105bc36eafdSMike Gerdts     }
1106bc36eafdSMike Gerdts 
1107bc36eafdSMike Gerdts     /*
1108bc36eafdSMike Gerdts      * For user-installed GPE Block Devices, the GpeBlockBaseNumber
1109bc36eafdSMike Gerdts      * is always zero
1110bc36eafdSMike Gerdts      */
1111bc36eafdSMike Gerdts     Status = AcpiEvCreateGpeBlock (Node, GpeBlockAddress->Address,
1112bc36eafdSMike Gerdts         GpeBlockAddress->SpaceId, RegisterCount,
1113bc36eafdSMike Gerdts         0, InterruptNumber, &GpeBlock);
1114bc36eafdSMike Gerdts     if (ACPI_FAILURE (Status))
1115bc36eafdSMike Gerdts     {
1116bc36eafdSMike Gerdts         goto UnlockAndExit;
1117bc36eafdSMike Gerdts     }
1118bc36eafdSMike Gerdts 
1119bc36eafdSMike Gerdts     /* Install block in the DeviceObject attached to the node */
1120bc36eafdSMike Gerdts 
1121bc36eafdSMike Gerdts     ObjDesc = AcpiNsGetAttachedObject (Node);
1122bc36eafdSMike Gerdts     if (!ObjDesc)
1123bc36eafdSMike Gerdts     {
1124bc36eafdSMike Gerdts         /*
1125bc36eafdSMike Gerdts          * No object, create a new one (Device nodes do not always have
1126bc36eafdSMike Gerdts          * an attached object)
1127bc36eafdSMike Gerdts          */
1128bc36eafdSMike Gerdts         ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_DEVICE);
1129bc36eafdSMike Gerdts         if (!ObjDesc)
1130bc36eafdSMike Gerdts         {
1131bc36eafdSMike Gerdts             Status = AE_NO_MEMORY;
1132bc36eafdSMike Gerdts             goto UnlockAndExit;
1133bc36eafdSMike Gerdts         }
1134bc36eafdSMike Gerdts 
1135bc36eafdSMike Gerdts         Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_DEVICE);
1136bc36eafdSMike Gerdts 
1137bc36eafdSMike Gerdts         /* Remove local reference to the object */
1138bc36eafdSMike Gerdts 
1139bc36eafdSMike Gerdts         AcpiUtRemoveReference (ObjDesc);
1140bc36eafdSMike Gerdts         if (ACPI_FAILURE (Status))
1141bc36eafdSMike Gerdts         {
1142bc36eafdSMike Gerdts             goto UnlockAndExit;
1143bc36eafdSMike Gerdts         }
1144bc36eafdSMike Gerdts     }
1145bc36eafdSMike Gerdts 
1146bc36eafdSMike Gerdts     /* Now install the GPE block in the DeviceObject */
1147bc36eafdSMike Gerdts 
1148bc36eafdSMike Gerdts     ObjDesc->Device.GpeBlock = GpeBlock;
1149bc36eafdSMike Gerdts 
1150bc36eafdSMike Gerdts 
1151bc36eafdSMike Gerdts UnlockAndExit:
1152bc36eafdSMike Gerdts     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
1153bc36eafdSMike Gerdts     return_ACPI_STATUS (Status);
1154bc36eafdSMike Gerdts }
1155bc36eafdSMike Gerdts 
ACPI_EXPORT_SYMBOL(AcpiInstallGpeBlock)1156bc36eafdSMike Gerdts ACPI_EXPORT_SYMBOL (AcpiInstallGpeBlock)
1157bc36eafdSMike Gerdts 
1158bc36eafdSMike Gerdts 
1159bc36eafdSMike Gerdts /*******************************************************************************
1160bc36eafdSMike Gerdts  *
1161bc36eafdSMike Gerdts  * FUNCTION:    AcpiRemoveGpeBlock
1162bc36eafdSMike Gerdts  *
1163bc36eafdSMike Gerdts  * PARAMETERS:  GpeDevice           - Handle to the parent GPE Block Device
1164bc36eafdSMike Gerdts  *
1165bc36eafdSMike Gerdts  * RETURN:      Status
1166bc36eafdSMike Gerdts  *
1167bc36eafdSMike Gerdts  * DESCRIPTION: Remove a previously installed block of GPE registers
1168bc36eafdSMike Gerdts  *
1169bc36eafdSMike Gerdts  ******************************************************************************/
1170bc36eafdSMike Gerdts 
1171bc36eafdSMike Gerdts ACPI_STATUS
1172bc36eafdSMike Gerdts AcpiRemoveGpeBlock (
1173bc36eafdSMike Gerdts     ACPI_HANDLE             GpeDevice)
1174bc36eafdSMike Gerdts {
1175bc36eafdSMike Gerdts     ACPI_OPERAND_OBJECT     *ObjDesc;
1176bc36eafdSMike Gerdts     ACPI_STATUS             Status;
1177bc36eafdSMike Gerdts     ACPI_NAMESPACE_NODE     *Node;
1178bc36eafdSMike Gerdts 
1179bc36eafdSMike Gerdts 
1180bc36eafdSMike Gerdts     ACPI_FUNCTION_TRACE (AcpiRemoveGpeBlock);
1181bc36eafdSMike Gerdts 
1182bc36eafdSMike Gerdts 
1183bc36eafdSMike Gerdts     if (!GpeDevice)
1184bc36eafdSMike Gerdts     {
1185bc36eafdSMike Gerdts         return_ACPI_STATUS (AE_BAD_PARAMETER);
1186bc36eafdSMike Gerdts     }
1187bc36eafdSMike Gerdts 
1188bc36eafdSMike Gerdts     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
1189bc36eafdSMike Gerdts     if (ACPI_FAILURE (Status))
1190bc36eafdSMike Gerdts     {
1191bc36eafdSMike Gerdts         return_ACPI_STATUS (Status);
1192bc36eafdSMike Gerdts     }
1193bc36eafdSMike Gerdts 
1194bc36eafdSMike Gerdts     Node = AcpiNsValidateHandle (GpeDevice);
1195bc36eafdSMike Gerdts     if (!Node)
1196bc36eafdSMike Gerdts     {
1197bc36eafdSMike Gerdts         Status = AE_BAD_PARAMETER;
1198bc36eafdSMike Gerdts         goto UnlockAndExit;
1199bc36eafdSMike Gerdts     }
1200bc36eafdSMike Gerdts 
1201bc36eafdSMike Gerdts     /* Validate the parent device */
1202bc36eafdSMike Gerdts 
1203bc36eafdSMike Gerdts     if (Node->Type != ACPI_TYPE_DEVICE)
1204bc36eafdSMike Gerdts     {
1205bc36eafdSMike Gerdts         Status = AE_TYPE;
1206bc36eafdSMike Gerdts         goto UnlockAndExit;
1207bc36eafdSMike Gerdts     }
1208bc36eafdSMike Gerdts 
1209bc36eafdSMike Gerdts     /* Get the DeviceObject attached to the node */
1210bc36eafdSMike Gerdts 
1211bc36eafdSMike Gerdts     ObjDesc = AcpiNsGetAttachedObject (Node);
1212bc36eafdSMike Gerdts     if (!ObjDesc ||
1213bc36eafdSMike Gerdts         !ObjDesc->Device.GpeBlock)
1214bc36eafdSMike Gerdts     {
1215bc36eafdSMike Gerdts         return_ACPI_STATUS (AE_NULL_OBJECT);
1216bc36eafdSMike Gerdts     }
1217bc36eafdSMike Gerdts 
1218bc36eafdSMike Gerdts     /* Delete the GPE block (but not the DeviceObject) */
1219bc36eafdSMike Gerdts 
1220bc36eafdSMike Gerdts     Status = AcpiEvDeleteGpeBlock (ObjDesc->Device.GpeBlock);
1221bc36eafdSMike Gerdts     if (ACPI_SUCCESS (Status))
1222bc36eafdSMike Gerdts     {
1223bc36eafdSMike Gerdts         ObjDesc->Device.GpeBlock = NULL;
1224bc36eafdSMike Gerdts     }
1225bc36eafdSMike Gerdts 
1226bc36eafdSMike Gerdts UnlockAndExit:
1227bc36eafdSMike Gerdts     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
1228bc36eafdSMike Gerdts     return_ACPI_STATUS (Status);
1229bc36eafdSMike Gerdts }
1230bc36eafdSMike Gerdts 
ACPI_EXPORT_SYMBOL(AcpiRemoveGpeBlock)1231bc36eafdSMike Gerdts ACPI_EXPORT_SYMBOL (AcpiRemoveGpeBlock)
1232bc36eafdSMike Gerdts 
1233bc36eafdSMike Gerdts 
1234bc36eafdSMike Gerdts /*******************************************************************************
1235bc36eafdSMike Gerdts  *
1236bc36eafdSMike Gerdts  * FUNCTION:    AcpiGetGpeDevice
1237bc36eafdSMike Gerdts  *
1238bc36eafdSMike Gerdts  * PARAMETERS:  Index               - System GPE index (0-CurrentGpeCount)
1239bc36eafdSMike Gerdts  *              GpeDevice           - Where the parent GPE Device is returned
1240bc36eafdSMike Gerdts  *
1241bc36eafdSMike Gerdts  * RETURN:      Status
1242bc36eafdSMike Gerdts  *
1243bc36eafdSMike Gerdts  * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
1244bc36eafdSMike Gerdts  *              gpe device indicates that the gpe number is contained in one of
1245bc36eafdSMike Gerdts  *              the FADT-defined gpe blocks. Otherwise, the GPE block device.
1246bc36eafdSMike Gerdts  *
1247bc36eafdSMike Gerdts  ******************************************************************************/
1248bc36eafdSMike Gerdts 
1249bc36eafdSMike Gerdts ACPI_STATUS
1250bc36eafdSMike Gerdts AcpiGetGpeDevice (
1251bc36eafdSMike Gerdts     UINT32                  Index,
1252bc36eafdSMike Gerdts     ACPI_HANDLE             *GpeDevice)
1253bc36eafdSMike Gerdts {
1254bc36eafdSMike Gerdts     ACPI_GPE_DEVICE_INFO    Info;
1255bc36eafdSMike Gerdts     ACPI_STATUS             Status;
1256bc36eafdSMike Gerdts 
1257bc36eafdSMike Gerdts 
1258bc36eafdSMike Gerdts     ACPI_FUNCTION_TRACE (AcpiGetGpeDevice);
1259bc36eafdSMike Gerdts 
1260bc36eafdSMike Gerdts 
1261bc36eafdSMike Gerdts     if (!GpeDevice)
1262bc36eafdSMike Gerdts     {
1263bc36eafdSMike Gerdts         return_ACPI_STATUS (AE_BAD_PARAMETER);
1264bc36eafdSMike Gerdts     }
1265bc36eafdSMike Gerdts 
1266bc36eafdSMike Gerdts     if (Index >= AcpiCurrentGpeCount)
1267bc36eafdSMike Gerdts     {
1268bc36eafdSMike Gerdts         return_ACPI_STATUS (AE_NOT_EXIST);
1269bc36eafdSMike Gerdts     }
1270bc36eafdSMike Gerdts 
1271bc36eafdSMike Gerdts     /* Setup and walk the GPE list */
1272bc36eafdSMike Gerdts 
1273bc36eafdSMike Gerdts     Info.Index = Index;
1274bc36eafdSMike Gerdts     Info.Status = AE_NOT_EXIST;
1275bc36eafdSMike Gerdts     Info.GpeDevice = NULL;
1276bc36eafdSMike Gerdts     Info.NextBlockBaseIndex = 0;
1277bc36eafdSMike Gerdts 
1278bc36eafdSMike Gerdts     Status = AcpiEvWalkGpeList (AcpiEvGetGpeDevice, &Info);
1279bc36eafdSMike Gerdts     if (ACPI_FAILURE (Status))
1280bc36eafdSMike Gerdts     {
1281bc36eafdSMike Gerdts         return_ACPI_STATUS (Status);
1282bc36eafdSMike Gerdts     }
1283bc36eafdSMike Gerdts 
1284bc36eafdSMike Gerdts     *GpeDevice = ACPI_CAST_PTR (ACPI_HANDLE, Info.GpeDevice);
1285bc36eafdSMike Gerdts     return_ACPI_STATUS (Info.Status);
1286bc36eafdSMike Gerdts }
1287bc36eafdSMike Gerdts 
1288bc36eafdSMike Gerdts ACPI_EXPORT_SYMBOL (AcpiGetGpeDevice)
1289bc36eafdSMike Gerdts 
1290bc36eafdSMike Gerdts #endif /* !ACPI_REDUCED_HARDWARE */
1291