xref: /reactos/drivers/bus/acpi/acpica/events/evxfgpe.c (revision 03b24380)
1c2c66affSColin Finck /******************************************************************************
2c2c66affSColin Finck  *
3c2c66affSColin Finck  * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs)
4c2c66affSColin Finck  *
5c2c66affSColin Finck  *****************************************************************************/
6c2c66affSColin Finck 
7c2c66affSColin Finck /*
8*03b24380SThomas Faber  * Copyright (C) 2000 - 2022, Intel Corp.
9c2c66affSColin Finck  * All rights reserved.
10c2c66affSColin Finck  *
11c2c66affSColin Finck  * Redistribution and use in source and binary forms, with or without
12c2c66affSColin Finck  * modification, are permitted provided that the following conditions
13c2c66affSColin Finck  * are met:
14c2c66affSColin Finck  * 1. Redistributions of source code must retain the above copyright
15c2c66affSColin Finck  *    notice, this list of conditions, and the following disclaimer,
16c2c66affSColin Finck  *    without modification.
17c2c66affSColin Finck  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18c2c66affSColin Finck  *    substantially similar to the "NO WARRANTY" disclaimer below
19c2c66affSColin Finck  *    ("Disclaimer") and any redistribution must be conditioned upon
20c2c66affSColin Finck  *    including a substantially similar Disclaimer requirement for further
21c2c66affSColin Finck  *    binary redistribution.
22c2c66affSColin Finck  * 3. Neither the names of the above-listed copyright holders nor the names
23c2c66affSColin Finck  *    of any contributors may be used to endorse or promote products derived
24c2c66affSColin Finck  *    from this software without specific prior written permission.
25c2c66affSColin Finck  *
26c2c66affSColin Finck  * Alternatively, this software may be distributed under the terms of the
27c2c66affSColin Finck  * GNU General Public License ("GPL") version 2 as published by the Free
28c2c66affSColin Finck  * Software Foundation.
29c2c66affSColin Finck  *
30c2c66affSColin Finck  * NO WARRANTY
31c2c66affSColin Finck  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32c2c66affSColin Finck  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
336eb8cc49SThomas Faber  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34c2c66affSColin Finck  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35c2c66affSColin Finck  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36c2c66affSColin Finck  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37c2c66affSColin Finck  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38c2c66affSColin Finck  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39c2c66affSColin Finck  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40c2c66affSColin Finck  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41c2c66affSColin Finck  * POSSIBILITY OF SUCH DAMAGES.
42c2c66affSColin Finck  */
43c2c66affSColin Finck 
44c2c66affSColin Finck #define EXPORT_ACPI_INTERFACES
45c2c66affSColin Finck 
46c2c66affSColin Finck #include "acpi.h"
47c2c66affSColin Finck #include "accommon.h"
48c2c66affSColin Finck #include "acevents.h"
49c2c66affSColin Finck #include "acnamesp.h"
50c2c66affSColin Finck 
51c2c66affSColin Finck #define _COMPONENT          ACPI_EVENTS
52c2c66affSColin Finck         ACPI_MODULE_NAME    ("evxfgpe")
53c2c66affSColin Finck 
54c2c66affSColin Finck 
55c2c66affSColin Finck #if (!ACPI_REDUCED_HARDWARE) /* Entire module */
56c2c66affSColin Finck /*******************************************************************************
57c2c66affSColin Finck  *
58c2c66affSColin Finck  * FUNCTION:    AcpiUpdateAllGpes
59c2c66affSColin Finck  *
60c2c66affSColin Finck  * PARAMETERS:  None
61c2c66affSColin Finck  *
62c2c66affSColin Finck  * RETURN:      Status
63c2c66affSColin Finck  *
64c2c66affSColin Finck  * DESCRIPTION: Complete GPE initialization and enable all GPEs that have
65c2c66affSColin Finck  *              associated _Lxx or _Exx methods and are not pointed to by any
66c2c66affSColin Finck  *              device _PRW methods (this indicates that these GPEs are
67c2c66affSColin Finck  *              generally intended for system or device wakeup. Such GPEs
68c2c66affSColin Finck  *              have to be enabled directly when the devices whose _PRW
69c2c66affSColin Finck  *              methods point to them are set up for wakeup signaling.)
70c2c66affSColin Finck  *
71c2c66affSColin Finck  * NOTE: Should be called after any GPEs are added to the system. Primarily,
72c2c66affSColin Finck  * after the system _PRW methods have been run, but also after a GPE Block
73c2c66affSColin Finck  * Device has been added or if any new GPE methods have been added via a
74c2c66affSColin Finck  * dynamic table load.
75c2c66affSColin Finck  *
76c2c66affSColin Finck  ******************************************************************************/
77c2c66affSColin Finck 
78c2c66affSColin Finck ACPI_STATUS
AcpiUpdateAllGpes(void)79c2c66affSColin Finck AcpiUpdateAllGpes (
80c2c66affSColin Finck     void)
81c2c66affSColin Finck {
82c2c66affSColin Finck     ACPI_STATUS             Status;
836847cc3aSThomas Faber     BOOLEAN                 IsPollingNeeded = FALSE;
84c2c66affSColin Finck 
85c2c66affSColin Finck 
86c2c66affSColin Finck     ACPI_FUNCTION_TRACE (AcpiUpdateAllGpes);
87c2c66affSColin Finck 
88c2c66affSColin Finck 
89c2c66affSColin Finck     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
90c2c66affSColin Finck     if (ACPI_FAILURE (Status))
91c2c66affSColin Finck     {
92c2c66affSColin Finck         return_ACPI_STATUS (Status);
93c2c66affSColin Finck     }
94c2c66affSColin Finck 
95c2c66affSColin Finck     if (AcpiGbl_AllGpesInitialized)
96c2c66affSColin Finck     {
97c2c66affSColin Finck         goto UnlockAndExit;
98c2c66affSColin Finck     }
99c2c66affSColin Finck 
1006847cc3aSThomas Faber     Status = AcpiEvWalkGpeList (AcpiEvInitializeGpeBlock,
1016847cc3aSThomas Faber         &IsPollingNeeded);
102c2c66affSColin Finck     if (ACPI_SUCCESS (Status))
103c2c66affSColin Finck     {
104c2c66affSColin Finck         AcpiGbl_AllGpesInitialized = TRUE;
105c2c66affSColin Finck     }
106c2c66affSColin Finck 
107c2c66affSColin Finck UnlockAndExit:
108c2c66affSColin Finck     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
1096847cc3aSThomas Faber 
1106847cc3aSThomas Faber     if (IsPollingNeeded && AcpiGbl_AllGpesInitialized)
1116847cc3aSThomas Faber     {
1126847cc3aSThomas Faber         /* Poll GPEs to handle already triggered events */
1136847cc3aSThomas Faber 
1146847cc3aSThomas Faber         AcpiEvGpeDetect (AcpiGbl_GpeXruptListHead);
1156847cc3aSThomas Faber     }
116c2c66affSColin Finck     return_ACPI_STATUS (Status);
117c2c66affSColin Finck }
118c2c66affSColin Finck 
ACPI_EXPORT_SYMBOL(AcpiUpdateAllGpes)119c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiUpdateAllGpes)
120c2c66affSColin Finck 
121c2c66affSColin Finck 
122c2c66affSColin Finck /*******************************************************************************
123c2c66affSColin Finck  *
124c2c66affSColin Finck  * FUNCTION:    AcpiEnableGpe
125c2c66affSColin Finck  *
126c2c66affSColin Finck  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
127c2c66affSColin Finck  *              GpeNumber           - GPE level within the GPE block
128c2c66affSColin Finck  *
129c2c66affSColin Finck  * RETURN:      Status
130c2c66affSColin Finck  *
131c2c66affSColin Finck  * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
132c2c66affSColin Finck  *              hardware-enabled.
133c2c66affSColin Finck  *
134c2c66affSColin Finck  ******************************************************************************/
135c2c66affSColin Finck 
136c2c66affSColin Finck ACPI_STATUS
137c2c66affSColin Finck AcpiEnableGpe (
138c2c66affSColin Finck     ACPI_HANDLE             GpeDevice,
139c2c66affSColin Finck     UINT32                  GpeNumber)
140c2c66affSColin Finck {
141c2c66affSColin Finck     ACPI_STATUS             Status = AE_BAD_PARAMETER;
142c2c66affSColin Finck     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
143c2c66affSColin Finck     ACPI_CPU_FLAGS          Flags;
144c2c66affSColin Finck 
145c2c66affSColin Finck 
146c2c66affSColin Finck     ACPI_FUNCTION_TRACE (AcpiEnableGpe);
147c2c66affSColin Finck 
148c2c66affSColin Finck 
149c2c66affSColin Finck     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
150c2c66affSColin Finck 
151c2c66affSColin Finck     /*
152c2c66affSColin Finck      * Ensure that we have a valid GPE number and that there is some way
153c2c66affSColin Finck      * of handling the GPE (handler or a GPE method). In other words, we
154c2c66affSColin Finck      * won't allow a valid GPE to be enabled if there is no way to handle it.
155c2c66affSColin Finck      */
156c2c66affSColin Finck     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
157c2c66affSColin Finck     if (GpeEventInfo)
158c2c66affSColin Finck     {
159c2c66affSColin Finck         if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) !=
160c2c66affSColin Finck             ACPI_GPE_DISPATCH_NONE)
161c2c66affSColin Finck         {
162aa46da57SThomas Faber             Status = AcpiEvAddGpeReference (GpeEventInfo, TRUE);
1636847cc3aSThomas Faber             if (ACPI_SUCCESS (Status) &&
1646847cc3aSThomas Faber                 ACPI_GPE_IS_POLLING_NEEDED (GpeEventInfo))
1656847cc3aSThomas Faber             {
1666847cc3aSThomas Faber                 /* Poll edge-triggered GPEs to handle existing events */
1676847cc3aSThomas Faber 
1686847cc3aSThomas Faber                 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
1696847cc3aSThomas Faber                 (void) AcpiEvDetectGpe (
1706847cc3aSThomas Faber                     GpeDevice, GpeEventInfo, GpeNumber);
1716847cc3aSThomas Faber                 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
1726847cc3aSThomas Faber             }
173c2c66affSColin Finck         }
174c2c66affSColin Finck         else
175c2c66affSColin Finck         {
176c2c66affSColin Finck             Status = AE_NO_HANDLER;
177c2c66affSColin Finck         }
178c2c66affSColin Finck     }
179c2c66affSColin Finck 
180c2c66affSColin Finck     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
181c2c66affSColin Finck     return_ACPI_STATUS (Status);
182c2c66affSColin Finck }
183c2c66affSColin Finck 
ACPI_EXPORT_SYMBOL(AcpiEnableGpe)184c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiEnableGpe)
185c2c66affSColin Finck 
186c2c66affSColin Finck 
187c2c66affSColin Finck /*******************************************************************************
188c2c66affSColin Finck  *
189c2c66affSColin Finck  * FUNCTION:    AcpiDisableGpe
190c2c66affSColin Finck  *
191c2c66affSColin Finck  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
192c2c66affSColin Finck  *              GpeNumber           - GPE level within the GPE block
193c2c66affSColin Finck  *
194c2c66affSColin Finck  * RETURN:      Status
195c2c66affSColin Finck  *
196c2c66affSColin Finck  * DESCRIPTION: Remove a reference to a GPE. When the last reference is
197c2c66affSColin Finck  *              removed, only then is the GPE disabled (for runtime GPEs), or
198c2c66affSColin Finck  *              the GPE mask bit disabled (for wake GPEs)
199c2c66affSColin Finck  *
200c2c66affSColin Finck  ******************************************************************************/
201c2c66affSColin Finck 
202c2c66affSColin Finck ACPI_STATUS
203c2c66affSColin Finck AcpiDisableGpe (
204c2c66affSColin Finck     ACPI_HANDLE             GpeDevice,
205c2c66affSColin Finck     UINT32                  GpeNumber)
206c2c66affSColin Finck {
207c2c66affSColin Finck     ACPI_STATUS             Status = AE_BAD_PARAMETER;
208c2c66affSColin Finck     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
209c2c66affSColin Finck     ACPI_CPU_FLAGS          Flags;
210c2c66affSColin Finck 
211c2c66affSColin Finck 
212c2c66affSColin Finck     ACPI_FUNCTION_TRACE (AcpiDisableGpe);
213c2c66affSColin Finck 
214c2c66affSColin Finck 
215c2c66affSColin Finck     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
216c2c66affSColin Finck 
217c2c66affSColin Finck     /* Ensure that we have a valid GPE number */
218c2c66affSColin Finck 
219c2c66affSColin Finck     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
220c2c66affSColin Finck     if (GpeEventInfo)
221c2c66affSColin Finck     {
222c2c66affSColin Finck         Status = AcpiEvRemoveGpeReference (GpeEventInfo);
223c2c66affSColin Finck     }
224c2c66affSColin Finck 
225c2c66affSColin Finck     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
226c2c66affSColin Finck     return_ACPI_STATUS (Status);
227c2c66affSColin Finck }
228c2c66affSColin Finck 
ACPI_EXPORT_SYMBOL(AcpiDisableGpe)229c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiDisableGpe)
230c2c66affSColin Finck 
231c2c66affSColin Finck 
232c2c66affSColin Finck /*******************************************************************************
233c2c66affSColin Finck  *
234c2c66affSColin Finck  * FUNCTION:    AcpiSetGpe
235c2c66affSColin Finck  *
236c2c66affSColin Finck  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
237c2c66affSColin Finck  *              GpeNumber           - GPE level within the GPE block
238c2c66affSColin Finck  *              Action              - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
239c2c66affSColin Finck  *
240c2c66affSColin Finck  * RETURN:      Status
241c2c66affSColin Finck  *
242c2c66affSColin Finck  * DESCRIPTION: Enable or disable an individual GPE. This function bypasses
243c2c66affSColin Finck  *              the reference count mechanism used in the AcpiEnableGpe(),
244c2c66affSColin Finck  *              AcpiDisableGpe() interfaces.
245c2c66affSColin Finck  *              This API is typically used by the GPE raw handler mode driver
246c2c66affSColin Finck  *              to switch between the polling mode and the interrupt mode after
247c2c66affSColin Finck  *              the driver has enabled the GPE.
248c2c66affSColin Finck  *              The APIs should be invoked in this order:
249c2c66affSColin Finck  *               AcpiEnableGpe()              <- Ensure the reference count > 0
250c2c66affSColin Finck  *               AcpiSetGpe(ACPI_GPE_DISABLE) <- Enter polling mode
251c2c66affSColin Finck  *               AcpiSetGpe(ACPI_GPE_ENABLE)  <- Leave polling mode
252c2c66affSColin Finck  *               AcpiDisableGpe()             <- Decrease the reference count
253c2c66affSColin Finck  *
254c2c66affSColin Finck  * Note: If a GPE is shared by 2 silicon components, then both the drivers
255c2c66affSColin Finck  *       should support GPE polling mode or disabling the GPE for long period
256c2c66affSColin Finck  *       for one driver may break the other. So use it with care since all
257c2c66affSColin Finck  *       firmware _Lxx/_Exx handlers currently rely on the GPE interrupt mode.
258c2c66affSColin Finck  *
259c2c66affSColin Finck  ******************************************************************************/
260c2c66affSColin Finck 
261c2c66affSColin Finck ACPI_STATUS
262c2c66affSColin Finck AcpiSetGpe (
263c2c66affSColin Finck     ACPI_HANDLE             GpeDevice,
264c2c66affSColin Finck     UINT32                  GpeNumber,
265c2c66affSColin Finck     UINT8                   Action)
266c2c66affSColin Finck {
267c2c66affSColin Finck     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
268c2c66affSColin Finck     ACPI_STATUS             Status;
269c2c66affSColin Finck     ACPI_CPU_FLAGS          Flags;
270c2c66affSColin Finck 
271c2c66affSColin Finck 
272c2c66affSColin Finck     ACPI_FUNCTION_TRACE (AcpiSetGpe);
273c2c66affSColin Finck 
274c2c66affSColin Finck 
275c2c66affSColin Finck     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
276c2c66affSColin Finck 
277c2c66affSColin Finck     /* Ensure that we have a valid GPE number */
278c2c66affSColin Finck 
279c2c66affSColin Finck     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
280c2c66affSColin Finck     if (!GpeEventInfo)
281c2c66affSColin Finck     {
282c2c66affSColin Finck         Status = AE_BAD_PARAMETER;
283c2c66affSColin Finck         goto UnlockAndExit;
284c2c66affSColin Finck     }
285c2c66affSColin Finck 
286c2c66affSColin Finck     /* Perform the action */
287c2c66affSColin Finck 
288c2c66affSColin Finck     switch (Action)
289c2c66affSColin Finck     {
290c2c66affSColin Finck     case ACPI_GPE_ENABLE:
291c2c66affSColin Finck 
292c2c66affSColin Finck         Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE);
293c2c66affSColin Finck         GpeEventInfo->DisableForDispatch = FALSE;
294c2c66affSColin Finck         break;
295c2c66affSColin Finck 
296c2c66affSColin Finck     case ACPI_GPE_DISABLE:
297c2c66affSColin Finck 
298c2c66affSColin Finck         Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
299c2c66affSColin Finck         GpeEventInfo->DisableForDispatch = TRUE;
300c2c66affSColin Finck         break;
301c2c66affSColin Finck 
302c2c66affSColin Finck     default:
303c2c66affSColin Finck 
304c2c66affSColin Finck         Status = AE_BAD_PARAMETER;
305c2c66affSColin Finck         break;
306c2c66affSColin Finck     }
307c2c66affSColin Finck 
308c2c66affSColin Finck UnlockAndExit:
309c2c66affSColin Finck     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
310c2c66affSColin Finck     return_ACPI_STATUS (Status);
311c2c66affSColin Finck }
312c2c66affSColin Finck 
ACPI_EXPORT_SYMBOL(AcpiSetGpe)313c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiSetGpe)
314c2c66affSColin Finck 
315c2c66affSColin Finck 
316c2c66affSColin Finck /*******************************************************************************
317c2c66affSColin Finck  *
318c2c66affSColin Finck  * FUNCTION:    AcpiMaskGpe
319c2c66affSColin Finck  *
320c2c66affSColin Finck  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
321c2c66affSColin Finck  *              GpeNumber           - GPE level within the GPE block
322c2c66affSColin Finck  *              IsMasked            - Whether the GPE is masked or not
323c2c66affSColin Finck  *
324c2c66affSColin Finck  * RETURN:      Status
325c2c66affSColin Finck  *
326c2c66affSColin Finck  * DESCRIPTION: Unconditionally mask/unmask the an individual GPE, ex., to
327c2c66affSColin Finck  *              prevent a GPE flooding.
328c2c66affSColin Finck  *
329c2c66affSColin Finck  ******************************************************************************/
330c2c66affSColin Finck 
331c2c66affSColin Finck ACPI_STATUS
332c2c66affSColin Finck AcpiMaskGpe (
333c2c66affSColin Finck     ACPI_HANDLE             GpeDevice,
334c2c66affSColin Finck     UINT32                  GpeNumber,
335c2c66affSColin Finck     BOOLEAN                 IsMasked)
336c2c66affSColin Finck {
337c2c66affSColin Finck     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
338c2c66affSColin Finck     ACPI_STATUS             Status;
339c2c66affSColin Finck     ACPI_CPU_FLAGS          Flags;
340c2c66affSColin Finck 
341c2c66affSColin Finck 
342c2c66affSColin Finck     ACPI_FUNCTION_TRACE (AcpiMaskGpe);
343c2c66affSColin Finck 
344c2c66affSColin Finck 
345c2c66affSColin Finck     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
346c2c66affSColin Finck 
347c2c66affSColin Finck     /* Ensure that we have a valid GPE number */
348c2c66affSColin Finck 
349c2c66affSColin Finck     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
350c2c66affSColin Finck     if (!GpeEventInfo)
351c2c66affSColin Finck     {
352c2c66affSColin Finck         Status = AE_BAD_PARAMETER;
353c2c66affSColin Finck         goto UnlockAndExit;
354c2c66affSColin Finck     }
355c2c66affSColin Finck 
356c2c66affSColin Finck     Status = AcpiEvMaskGpe (GpeEventInfo, IsMasked);
357c2c66affSColin Finck 
358c2c66affSColin Finck UnlockAndExit:
359c2c66affSColin Finck     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
360c2c66affSColin Finck     return_ACPI_STATUS (Status);
361c2c66affSColin Finck }
362c2c66affSColin Finck 
ACPI_EXPORT_SYMBOL(AcpiMaskGpe)363c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiMaskGpe)
364c2c66affSColin Finck 
365c2c66affSColin Finck 
366c2c66affSColin Finck /*******************************************************************************
367c2c66affSColin Finck  *
368c2c66affSColin Finck  * FUNCTION:    AcpiMarkGpeForWake
369c2c66affSColin Finck  *
370c2c66affSColin Finck  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
371c2c66affSColin Finck  *              GpeNumber           - GPE level within the GPE block
372c2c66affSColin Finck  *
373c2c66affSColin Finck  * RETURN:      Status
374c2c66affSColin Finck  *
375c2c66affSColin Finck  * DESCRIPTION: Mark a GPE as having the ability to wake the system. Simply
376c2c66affSColin Finck  *              sets the ACPI_GPE_CAN_WAKE flag.
377c2c66affSColin Finck  *
378c2c66affSColin Finck  * Some potential callers of AcpiSetupGpeForWake may know in advance that
379c2c66affSColin Finck  * there won't be any notify handlers installed for device wake notifications
380c2c66affSColin Finck  * from the given GPE (one example is a button GPE in Linux). For these cases,
381c2c66affSColin Finck  * AcpiMarkGpeForWake should be used instead of AcpiSetupGpeForWake.
382c2c66affSColin Finck  * This will set the ACPI_GPE_CAN_WAKE flag for the GPE without trying to
383c2c66affSColin Finck  * setup implicit wake notification for it (since there's no handler method).
384c2c66affSColin Finck  *
385c2c66affSColin Finck  ******************************************************************************/
386c2c66affSColin Finck 
387c2c66affSColin Finck ACPI_STATUS
388c2c66affSColin Finck AcpiMarkGpeForWake (
389c2c66affSColin Finck     ACPI_HANDLE             GpeDevice,
390c2c66affSColin Finck     UINT32                  GpeNumber)
391c2c66affSColin Finck {
392c2c66affSColin Finck     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
393c2c66affSColin Finck     ACPI_STATUS             Status = AE_BAD_PARAMETER;
394c2c66affSColin Finck     ACPI_CPU_FLAGS          Flags;
395c2c66affSColin Finck 
396c2c66affSColin Finck 
397c2c66affSColin Finck     ACPI_FUNCTION_TRACE (AcpiMarkGpeForWake);
398c2c66affSColin Finck 
399c2c66affSColin Finck 
400c2c66affSColin Finck     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
401c2c66affSColin Finck 
402c2c66affSColin Finck     /* Ensure that we have a valid GPE number */
403c2c66affSColin Finck 
404c2c66affSColin Finck     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
405c2c66affSColin Finck     if (GpeEventInfo)
406c2c66affSColin Finck     {
407c2c66affSColin Finck         /* Mark the GPE as a possible wake event */
408c2c66affSColin Finck 
409c2c66affSColin Finck         GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
410c2c66affSColin Finck         Status = AE_OK;
411c2c66affSColin Finck     }
412c2c66affSColin Finck 
413c2c66affSColin Finck     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
414c2c66affSColin Finck     return_ACPI_STATUS (Status);
415c2c66affSColin Finck }
416c2c66affSColin Finck 
ACPI_EXPORT_SYMBOL(AcpiMarkGpeForWake)417c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiMarkGpeForWake)
418c2c66affSColin Finck 
419c2c66affSColin Finck 
420c2c66affSColin Finck /*******************************************************************************
421c2c66affSColin Finck  *
422c2c66affSColin Finck  * FUNCTION:    AcpiSetupGpeForWake
423c2c66affSColin Finck  *
424c2c66affSColin Finck  * PARAMETERS:  WakeDevice          - Device associated with the GPE (via _PRW)
425c2c66affSColin Finck  *              GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
426c2c66affSColin Finck  *              GpeNumber           - GPE level within the GPE block
427c2c66affSColin Finck  *
428c2c66affSColin Finck  * RETURN:      Status
429c2c66affSColin Finck  *
430c2c66affSColin Finck  * DESCRIPTION: Mark a GPE as having the ability to wake the system. This
431c2c66affSColin Finck  *              interface is intended to be used as the host executes the
432c2c66affSColin Finck  *              _PRW methods (Power Resources for Wake) in the system tables.
433c2c66affSColin Finck  *              Each _PRW appears under a Device Object (The WakeDevice), and
434c2c66affSColin Finck  *              contains the info for the wake GPE associated with the
435c2c66affSColin Finck  *              WakeDevice.
436c2c66affSColin Finck  *
437c2c66affSColin Finck  ******************************************************************************/
438c2c66affSColin Finck 
439c2c66affSColin Finck ACPI_STATUS
440c2c66affSColin Finck AcpiSetupGpeForWake (
441c2c66affSColin Finck     ACPI_HANDLE             WakeDevice,
442c2c66affSColin Finck     ACPI_HANDLE             GpeDevice,
443c2c66affSColin Finck     UINT32                  GpeNumber)
444c2c66affSColin Finck {
445c2c66affSColin Finck     ACPI_STATUS             Status;
446c2c66affSColin Finck     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
447c2c66affSColin Finck     ACPI_NAMESPACE_NODE     *DeviceNode;
448c2c66affSColin Finck     ACPI_GPE_NOTIFY_INFO    *Notify;
449c2c66affSColin Finck     ACPI_GPE_NOTIFY_INFO    *NewNotify;
450c2c66affSColin Finck     ACPI_CPU_FLAGS          Flags;
451c2c66affSColin Finck 
452c2c66affSColin Finck 
453c2c66affSColin Finck     ACPI_FUNCTION_TRACE (AcpiSetupGpeForWake);
454c2c66affSColin Finck 
455c2c66affSColin Finck 
456c2c66affSColin Finck     /* Parameter Validation */
457c2c66affSColin Finck 
458c2c66affSColin Finck     if (!WakeDevice)
459c2c66affSColin Finck     {
460c2c66affSColin Finck         /*
461c2c66affSColin Finck          * By forcing WakeDevice to be valid, we automatically enable the
462c2c66affSColin Finck          * implicit notify feature on all hosts.
463c2c66affSColin Finck          */
464c2c66affSColin Finck         return_ACPI_STATUS (AE_BAD_PARAMETER);
465c2c66affSColin Finck     }
466c2c66affSColin Finck 
467c2c66affSColin Finck     /* Handle root object case */
468c2c66affSColin Finck 
469c2c66affSColin Finck     if (WakeDevice == ACPI_ROOT_OBJECT)
470c2c66affSColin Finck     {
471c2c66affSColin Finck         DeviceNode = AcpiGbl_RootNode;
472c2c66affSColin Finck     }
473c2c66affSColin Finck     else
474c2c66affSColin Finck     {
475c2c66affSColin Finck         DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, WakeDevice);
476c2c66affSColin Finck     }
477c2c66affSColin Finck 
478c2c66affSColin Finck     /* Validate WakeDevice is of type Device */
479c2c66affSColin Finck 
480c2c66affSColin Finck     if (DeviceNode->Type != ACPI_TYPE_DEVICE)
481c2c66affSColin Finck     {
482c2c66affSColin Finck         return_ACPI_STATUS (AE_BAD_PARAMETER);
483c2c66affSColin Finck     }
484c2c66affSColin Finck 
485c2c66affSColin Finck     /*
486c2c66affSColin Finck      * Allocate a new notify object up front, in case it is needed.
487c2c66affSColin Finck      * Memory allocation while holding a spinlock is a big no-no
488c2c66affSColin Finck      * on some hosts.
489c2c66affSColin Finck      */
490c2c66affSColin Finck     NewNotify = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_NOTIFY_INFO));
491c2c66affSColin Finck     if (!NewNotify)
492c2c66affSColin Finck     {
493c2c66affSColin Finck         return_ACPI_STATUS (AE_NO_MEMORY);
494c2c66affSColin Finck     }
495c2c66affSColin Finck 
496c2c66affSColin Finck     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
497c2c66affSColin Finck 
498c2c66affSColin Finck     /* Ensure that we have a valid GPE number */
499c2c66affSColin Finck 
500c2c66affSColin Finck     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
501c2c66affSColin Finck     if (!GpeEventInfo)
502c2c66affSColin Finck     {
503c2c66affSColin Finck         Status = AE_BAD_PARAMETER;
504c2c66affSColin Finck         goto UnlockAndExit;
505c2c66affSColin Finck     }
506c2c66affSColin Finck 
507c2c66affSColin Finck     /*
508c2c66affSColin Finck      * If there is no method or handler for this GPE, then the
509c2c66affSColin Finck      * WakeDevice will be notified whenever this GPE fires. This is
510c2c66affSColin Finck      * known as an "implicit notify". Note: The GPE is assumed to be
511c2c66affSColin Finck      * level-triggered (for windows compatibility).
512c2c66affSColin Finck      */
513c2c66affSColin Finck     if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
514c2c66affSColin Finck         ACPI_GPE_DISPATCH_NONE)
515c2c66affSColin Finck     {
516c2c66affSColin Finck         /*
517c2c66affSColin Finck          * This is the first device for implicit notify on this GPE.
518c2c66affSColin Finck          * Just set the flags here, and enter the NOTIFY block below.
519c2c66affSColin Finck          */
520c2c66affSColin Finck         GpeEventInfo->Flags =
521c2c66affSColin Finck             (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED);
522c2c66affSColin Finck     }
5236847cc3aSThomas Faber     else if (GpeEventInfo->Flags & ACPI_GPE_AUTO_ENABLED)
5246847cc3aSThomas Faber     {
5256847cc3aSThomas Faber         /*
5266847cc3aSThomas Faber          * A reference to this GPE has been added during the GPE block
5276847cc3aSThomas Faber          * initialization, so drop it now to prevent the GPE from being
5286847cc3aSThomas Faber          * permanently enabled and clear its ACPI_GPE_AUTO_ENABLED flag.
5296847cc3aSThomas Faber          */
5306847cc3aSThomas Faber         (void) AcpiEvRemoveGpeReference (GpeEventInfo);
5316847cc3aSThomas Faber         GpeEventInfo->Flags &= ~~ACPI_GPE_AUTO_ENABLED;
5326847cc3aSThomas Faber     }
533c2c66affSColin Finck 
534c2c66affSColin Finck     /*
535c2c66affSColin Finck      * If we already have an implicit notify on this GPE, add
536c2c66affSColin Finck      * this device to the notify list.
537c2c66affSColin Finck      */
538c2c66affSColin Finck     if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
539c2c66affSColin Finck         ACPI_GPE_DISPATCH_NOTIFY)
540c2c66affSColin Finck     {
541c2c66affSColin Finck         /* Ensure that the device is not already in the list */
542c2c66affSColin Finck 
543c2c66affSColin Finck         Notify = GpeEventInfo->Dispatch.NotifyList;
544c2c66affSColin Finck         while (Notify)
545c2c66affSColin Finck         {
546c2c66affSColin Finck             if (Notify->DeviceNode == DeviceNode)
547c2c66affSColin Finck             {
548c2c66affSColin Finck                 Status = AE_ALREADY_EXISTS;
549c2c66affSColin Finck                 goto UnlockAndExit;
550c2c66affSColin Finck             }
551c2c66affSColin Finck             Notify = Notify->Next;
552c2c66affSColin Finck         }
553c2c66affSColin Finck 
554c2c66affSColin Finck         /* Add this device to the notify list for this GPE */
555c2c66affSColin Finck 
556c2c66affSColin Finck         NewNotify->DeviceNode = DeviceNode;
557c2c66affSColin Finck         NewNotify->Next = GpeEventInfo->Dispatch.NotifyList;
558c2c66affSColin Finck         GpeEventInfo->Dispatch.NotifyList = NewNotify;
559c2c66affSColin Finck         NewNotify = NULL;
560c2c66affSColin Finck     }
561c2c66affSColin Finck 
562c2c66affSColin Finck     /* Mark the GPE as a possible wake event */
563c2c66affSColin Finck 
564c2c66affSColin Finck     GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
565c2c66affSColin Finck     Status = AE_OK;
566c2c66affSColin Finck 
567c2c66affSColin Finck 
568c2c66affSColin Finck UnlockAndExit:
569c2c66affSColin Finck     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
570c2c66affSColin Finck 
571c2c66affSColin Finck     /* Delete the notify object if it was not used above */
572c2c66affSColin Finck 
573c2c66affSColin Finck     if (NewNotify)
574c2c66affSColin Finck     {
575c2c66affSColin Finck         ACPI_FREE (NewNotify);
576c2c66affSColin Finck     }
577c2c66affSColin Finck     return_ACPI_STATUS (Status);
578c2c66affSColin Finck }
579c2c66affSColin Finck 
ACPI_EXPORT_SYMBOL(AcpiSetupGpeForWake)580c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiSetupGpeForWake)
581c2c66affSColin Finck 
582c2c66affSColin Finck 
583c2c66affSColin Finck /*******************************************************************************
584c2c66affSColin Finck  *
585c2c66affSColin Finck  * FUNCTION:    AcpiSetGpeWakeMask
586c2c66affSColin Finck  *
587c2c66affSColin Finck  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
588c2c66affSColin Finck  *              GpeNumber           - GPE level within the GPE block
589c2c66affSColin Finck  *              Action              - Enable or Disable
590c2c66affSColin Finck  *
591c2c66affSColin Finck  * RETURN:      Status
592c2c66affSColin Finck  *
593c2c66affSColin Finck  * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must
594c2c66affSColin Finck  *              already be marked as a WAKE GPE.
595c2c66affSColin Finck  *
596c2c66affSColin Finck  ******************************************************************************/
597c2c66affSColin Finck 
598c2c66affSColin Finck ACPI_STATUS
599c2c66affSColin Finck AcpiSetGpeWakeMask (
600c2c66affSColin Finck     ACPI_HANDLE             GpeDevice,
601c2c66affSColin Finck     UINT32                  GpeNumber,
602c2c66affSColin Finck     UINT8                   Action)
603c2c66affSColin Finck {
604c2c66affSColin Finck     ACPI_STATUS             Status = AE_OK;
605c2c66affSColin Finck     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
606c2c66affSColin Finck     ACPI_GPE_REGISTER_INFO  *GpeRegisterInfo;
607c2c66affSColin Finck     ACPI_CPU_FLAGS          Flags;
608c2c66affSColin Finck     UINT32                  RegisterBit;
609c2c66affSColin Finck 
610c2c66affSColin Finck 
611c2c66affSColin Finck     ACPI_FUNCTION_TRACE (AcpiSetGpeWakeMask);
612c2c66affSColin Finck 
613c2c66affSColin Finck 
614c2c66affSColin Finck     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
615c2c66affSColin Finck 
616c2c66affSColin Finck     /*
617c2c66affSColin Finck      * Ensure that we have a valid GPE number and that this GPE is in
618c2c66affSColin Finck      * fact a wake GPE
619c2c66affSColin Finck      */
620c2c66affSColin Finck     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
621c2c66affSColin Finck     if (!GpeEventInfo)
622c2c66affSColin Finck     {
623c2c66affSColin Finck         Status = AE_BAD_PARAMETER;
624c2c66affSColin Finck         goto UnlockAndExit;
625c2c66affSColin Finck     }
626c2c66affSColin Finck 
627c2c66affSColin Finck     if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE))
628c2c66affSColin Finck     {
629c2c66affSColin Finck         Status = AE_TYPE;
630c2c66affSColin Finck         goto UnlockAndExit;
631c2c66affSColin Finck     }
632c2c66affSColin Finck 
633c2c66affSColin Finck     GpeRegisterInfo = GpeEventInfo->RegisterInfo;
634c2c66affSColin Finck     if (!GpeRegisterInfo)
635c2c66affSColin Finck     {
636c2c66affSColin Finck         Status = AE_NOT_EXIST;
637c2c66affSColin Finck         goto UnlockAndExit;
638c2c66affSColin Finck     }
639c2c66affSColin Finck 
640c2c66affSColin Finck     RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo);
641c2c66affSColin Finck 
642c2c66affSColin Finck     /* Perform the action */
643c2c66affSColin Finck 
644c2c66affSColin Finck     switch (Action)
645c2c66affSColin Finck     {
646c2c66affSColin Finck     case ACPI_GPE_ENABLE:
647c2c66affSColin Finck 
648c2c66affSColin Finck         ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
649c2c66affSColin Finck         break;
650c2c66affSColin Finck 
651c2c66affSColin Finck     case ACPI_GPE_DISABLE:
652c2c66affSColin Finck 
653c2c66affSColin Finck         ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
654c2c66affSColin Finck         break;
655c2c66affSColin Finck 
656c2c66affSColin Finck     default:
657c2c66affSColin Finck 
658c2c66affSColin Finck         ACPI_ERROR ((AE_INFO, "%u, Invalid action", Action));
659c2c66affSColin Finck         Status = AE_BAD_PARAMETER;
660c2c66affSColin Finck         break;
661c2c66affSColin Finck     }
662c2c66affSColin Finck 
663c2c66affSColin Finck UnlockAndExit:
664c2c66affSColin Finck     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
665c2c66affSColin Finck     return_ACPI_STATUS (Status);
666c2c66affSColin Finck }
667c2c66affSColin Finck 
ACPI_EXPORT_SYMBOL(AcpiSetGpeWakeMask)668c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiSetGpeWakeMask)
669c2c66affSColin Finck 
670c2c66affSColin Finck 
671c2c66affSColin Finck /*******************************************************************************
672c2c66affSColin Finck  *
673c2c66affSColin Finck  * FUNCTION:    AcpiClearGpe
674c2c66affSColin Finck  *
675c2c66affSColin Finck  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
676c2c66affSColin Finck  *              GpeNumber           - GPE level within the GPE block
677c2c66affSColin Finck  *
678c2c66affSColin Finck  * RETURN:      Status
679c2c66affSColin Finck  *
680c2c66affSColin Finck  * DESCRIPTION: Clear an ACPI event (general purpose)
681c2c66affSColin Finck  *
682c2c66affSColin Finck  ******************************************************************************/
683c2c66affSColin Finck 
684c2c66affSColin Finck ACPI_STATUS
685c2c66affSColin Finck AcpiClearGpe (
686c2c66affSColin Finck     ACPI_HANDLE             GpeDevice,
687c2c66affSColin Finck     UINT32                  GpeNumber)
688c2c66affSColin Finck {
689c2c66affSColin Finck     ACPI_STATUS             Status = AE_OK;
690c2c66affSColin Finck     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
691c2c66affSColin Finck     ACPI_CPU_FLAGS          Flags;
692c2c66affSColin Finck 
693c2c66affSColin Finck 
694c2c66affSColin Finck     ACPI_FUNCTION_TRACE (AcpiClearGpe);
695c2c66affSColin Finck 
696c2c66affSColin Finck 
697c2c66affSColin Finck     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
698c2c66affSColin Finck 
699c2c66affSColin Finck     /* Ensure that we have a valid GPE number */
700c2c66affSColin Finck 
701c2c66affSColin Finck     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
702c2c66affSColin Finck     if (!GpeEventInfo)
703c2c66affSColin Finck     {
704c2c66affSColin Finck         Status = AE_BAD_PARAMETER;
705c2c66affSColin Finck         goto UnlockAndExit;
706c2c66affSColin Finck     }
707c2c66affSColin Finck 
708c2c66affSColin Finck     Status = AcpiHwClearGpe (GpeEventInfo);
709c2c66affSColin Finck 
710c2c66affSColin Finck UnlockAndExit:
711c2c66affSColin Finck     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
712c2c66affSColin Finck     return_ACPI_STATUS (Status);
713c2c66affSColin Finck }
714c2c66affSColin Finck 
ACPI_EXPORT_SYMBOL(AcpiClearGpe)715c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiClearGpe)
716c2c66affSColin Finck 
717c2c66affSColin Finck 
718c2c66affSColin Finck /*******************************************************************************
719c2c66affSColin Finck  *
720c2c66affSColin Finck  * FUNCTION:    AcpiGetGpeStatus
721c2c66affSColin Finck  *
722c2c66affSColin Finck  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
723c2c66affSColin Finck  *              GpeNumber           - GPE level within the GPE block
724c2c66affSColin Finck  *              EventStatus         - Where the current status of the event
725c2c66affSColin Finck  *                                    will be returned
726c2c66affSColin Finck  *
727c2c66affSColin Finck  * RETURN:      Status
728c2c66affSColin Finck  *
729c2c66affSColin Finck  * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled)
730c2c66affSColin Finck  *
731c2c66affSColin Finck  ******************************************************************************/
732c2c66affSColin Finck 
733c2c66affSColin Finck ACPI_STATUS
734c2c66affSColin Finck AcpiGetGpeStatus (
735c2c66affSColin Finck     ACPI_HANDLE             GpeDevice,
736c2c66affSColin Finck     UINT32                  GpeNumber,
737c2c66affSColin Finck     ACPI_EVENT_STATUS       *EventStatus)
738c2c66affSColin Finck {
739c2c66affSColin Finck     ACPI_STATUS             Status = AE_OK;
740c2c66affSColin Finck     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
741c2c66affSColin Finck     ACPI_CPU_FLAGS          Flags;
742c2c66affSColin Finck 
743c2c66affSColin Finck 
744c2c66affSColin Finck     ACPI_FUNCTION_TRACE (AcpiGetGpeStatus);
745c2c66affSColin Finck 
746c2c66affSColin Finck 
747c2c66affSColin Finck     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
748c2c66affSColin Finck 
749c2c66affSColin Finck     /* Ensure that we have a valid GPE number */
750c2c66affSColin Finck 
751c2c66affSColin Finck     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
752c2c66affSColin Finck     if (!GpeEventInfo)
753c2c66affSColin Finck     {
754c2c66affSColin Finck         Status = AE_BAD_PARAMETER;
755c2c66affSColin Finck         goto UnlockAndExit;
756c2c66affSColin Finck     }
757c2c66affSColin Finck 
758c2c66affSColin Finck     /* Obtain status on the requested GPE number */
759c2c66affSColin Finck 
760c2c66affSColin Finck     Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus);
761c2c66affSColin Finck 
762c2c66affSColin Finck UnlockAndExit:
763c2c66affSColin Finck     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
764c2c66affSColin Finck     return_ACPI_STATUS (Status);
765c2c66affSColin Finck }
766c2c66affSColin Finck 
ACPI_EXPORT_SYMBOL(AcpiGetGpeStatus)767c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiGetGpeStatus)
768c2c66affSColin Finck 
769c2c66affSColin Finck 
770c2c66affSColin Finck /*******************************************************************************
771c2c66affSColin Finck  *
7725d4f13f6SThomas Faber  * FUNCTION:    AcpiDispatchGpe
7735d4f13f6SThomas Faber  *
7745d4f13f6SThomas Faber  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
7755d4f13f6SThomas Faber  *              GpeNumber           - GPE level within the GPE block
7765d4f13f6SThomas Faber  *
7775d4f13f6SThomas Faber  * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
7785d4f13f6SThomas Faber  *
7795d4f13f6SThomas Faber  * DESCRIPTION: Detect and dispatch a General Purpose Event to either a function
7805d4f13f6SThomas Faber  *              (e.g. EC) or method (e.g. _Lxx/_Exx) handler.
7815d4f13f6SThomas Faber  *
7825d4f13f6SThomas Faber  ******************************************************************************/
7835d4f13f6SThomas Faber 
7845d4f13f6SThomas Faber UINT32
7855d4f13f6SThomas Faber AcpiDispatchGpe(
7865d4f13f6SThomas Faber     ACPI_HANDLE             GpeDevice,
7875d4f13f6SThomas Faber     UINT32                  GpeNumber)
7885d4f13f6SThomas Faber {
7895d4f13f6SThomas Faber     ACPI_FUNCTION_TRACE(acpi_dispatch_gpe);
7905d4f13f6SThomas Faber 
7915d4f13f6SThomas Faber     return (AcpiEvDetectGpe (GpeDevice, NULL, GpeNumber));
7925d4f13f6SThomas Faber }
7935d4f13f6SThomas Faber 
ACPI_EXPORT_SYMBOL(AcpiDispatchGpe)7945d4f13f6SThomas Faber ACPI_EXPORT_SYMBOL (AcpiDispatchGpe)
7955d4f13f6SThomas Faber 
7965d4f13f6SThomas Faber 
7975d4f13f6SThomas Faber /*******************************************************************************
7985d4f13f6SThomas Faber  *
799c2c66affSColin Finck  * FUNCTION:    AcpiFinishGpe
800c2c66affSColin Finck  *
801c2c66affSColin Finck  * PARAMETERS:  GpeDevice           - Namespace node for the GPE Block
802c2c66affSColin Finck  *                                    (NULL for FADT defined GPEs)
803c2c66affSColin Finck  *              GpeNumber           - GPE level within the GPE block
804c2c66affSColin Finck  *
805c2c66affSColin Finck  * RETURN:      Status
806c2c66affSColin Finck  *
8079d53c935SThomas Faber  * DESCRIPTION: Clear and conditionally re-enable a GPE. This completes the GPE
808c2c66affSColin Finck  *              processing. Intended for use by asynchronous host-installed
8099d53c935SThomas Faber  *              GPE handlers. The GPE is only re-enabled if the EnableForRun bit
810c2c66affSColin Finck  *              is set in the GPE info.
811c2c66affSColin Finck  *
812c2c66affSColin Finck  ******************************************************************************/
813c2c66affSColin Finck 
814c2c66affSColin Finck ACPI_STATUS
815c2c66affSColin Finck AcpiFinishGpe (
816c2c66affSColin Finck     ACPI_HANDLE             GpeDevice,
817c2c66affSColin Finck     UINT32                  GpeNumber)
818c2c66affSColin Finck {
819c2c66affSColin Finck     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
820c2c66affSColin Finck     ACPI_STATUS             Status;
821c2c66affSColin Finck     ACPI_CPU_FLAGS          Flags;
822c2c66affSColin Finck 
823c2c66affSColin Finck 
824c2c66affSColin Finck     ACPI_FUNCTION_TRACE (AcpiFinishGpe);
825c2c66affSColin Finck 
826c2c66affSColin Finck 
827c2c66affSColin Finck     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
828c2c66affSColin Finck 
829c2c66affSColin Finck     /* Ensure that we have a valid GPE number */
830c2c66affSColin Finck 
831c2c66affSColin Finck     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
832c2c66affSColin Finck     if (!GpeEventInfo)
833c2c66affSColin Finck     {
834c2c66affSColin Finck         Status = AE_BAD_PARAMETER;
835c2c66affSColin Finck         goto UnlockAndExit;
836c2c66affSColin Finck     }
837c2c66affSColin Finck 
838c2c66affSColin Finck     Status = AcpiEvFinishGpe (GpeEventInfo);
839c2c66affSColin Finck 
840c2c66affSColin Finck UnlockAndExit:
841c2c66affSColin Finck     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
842c2c66affSColin Finck     return_ACPI_STATUS (Status);
843c2c66affSColin Finck }
844c2c66affSColin Finck 
ACPI_EXPORT_SYMBOL(AcpiFinishGpe)845c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiFinishGpe)
846c2c66affSColin Finck 
847c2c66affSColin Finck 
848c2c66affSColin Finck /******************************************************************************
849c2c66affSColin Finck  *
850c2c66affSColin Finck  * FUNCTION:    AcpiDisableAllGpes
851c2c66affSColin Finck  *
852c2c66affSColin Finck  * PARAMETERS:  None
853c2c66affSColin Finck  *
854c2c66affSColin Finck  * RETURN:      Status
855c2c66affSColin Finck  *
856c2c66affSColin Finck  * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
857c2c66affSColin Finck  *
858c2c66affSColin Finck  ******************************************************************************/
859c2c66affSColin Finck 
860c2c66affSColin Finck ACPI_STATUS
861c2c66affSColin Finck AcpiDisableAllGpes (
862c2c66affSColin Finck     void)
863c2c66affSColin Finck {
864c2c66affSColin Finck     ACPI_STATUS             Status;
865c2c66affSColin Finck 
866c2c66affSColin Finck 
867c2c66affSColin Finck     ACPI_FUNCTION_TRACE (AcpiDisableAllGpes);
868c2c66affSColin Finck 
869c2c66affSColin Finck 
870c2c66affSColin Finck     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
871c2c66affSColin Finck     if (ACPI_FAILURE (Status))
872c2c66affSColin Finck     {
873c2c66affSColin Finck         return_ACPI_STATUS (Status);
874c2c66affSColin Finck     }
875c2c66affSColin Finck 
876c2c66affSColin Finck     Status = AcpiHwDisableAllGpes ();
877c2c66affSColin Finck     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
878c2c66affSColin Finck 
879c2c66affSColin Finck     return_ACPI_STATUS (Status);
880c2c66affSColin Finck }
881c2c66affSColin Finck 
ACPI_EXPORT_SYMBOL(AcpiDisableAllGpes)882c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiDisableAllGpes)
883c2c66affSColin Finck 
884c2c66affSColin Finck 
885c2c66affSColin Finck /******************************************************************************
886c2c66affSColin Finck  *
887c2c66affSColin Finck  * FUNCTION:    AcpiEnableAllRuntimeGpes
888c2c66affSColin Finck  *
889c2c66affSColin Finck  * PARAMETERS:  None
890c2c66affSColin Finck  *
891c2c66affSColin Finck  * RETURN:      Status
892c2c66affSColin Finck  *
893c2c66affSColin Finck  * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
894c2c66affSColin Finck  *
895c2c66affSColin Finck  ******************************************************************************/
896c2c66affSColin Finck 
897c2c66affSColin Finck ACPI_STATUS
898c2c66affSColin Finck AcpiEnableAllRuntimeGpes (
899c2c66affSColin Finck     void)
900c2c66affSColin Finck {
901c2c66affSColin Finck     ACPI_STATUS             Status;
902c2c66affSColin Finck 
903c2c66affSColin Finck 
904c2c66affSColin Finck     ACPI_FUNCTION_TRACE (AcpiEnableAllRuntimeGpes);
905c2c66affSColin Finck 
906c2c66affSColin Finck 
907c2c66affSColin Finck     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
908c2c66affSColin Finck     if (ACPI_FAILURE (Status))
909c2c66affSColin Finck     {
910c2c66affSColin Finck         return_ACPI_STATUS (Status);
911c2c66affSColin Finck     }
912c2c66affSColin Finck 
913c2c66affSColin Finck     Status = AcpiHwEnableAllRuntimeGpes ();
914c2c66affSColin Finck     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
915c2c66affSColin Finck 
916c2c66affSColin Finck     return_ACPI_STATUS (Status);
917c2c66affSColin Finck }
918c2c66affSColin Finck 
ACPI_EXPORT_SYMBOL(AcpiEnableAllRuntimeGpes)919c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiEnableAllRuntimeGpes)
920c2c66affSColin Finck 
921c2c66affSColin Finck 
922c2c66affSColin Finck /******************************************************************************
923c2c66affSColin Finck  *
924c2c66affSColin Finck  * FUNCTION:    AcpiEnableAllWakeupGpes
925c2c66affSColin Finck  *
926c2c66affSColin Finck  * PARAMETERS:  None
927c2c66affSColin Finck  *
928c2c66affSColin Finck  * RETURN:      Status
929c2c66affSColin Finck  *
930c2c66affSColin Finck  * DESCRIPTION: Enable all "wakeup" GPEs and disable all of the other GPEs, in
931c2c66affSColin Finck  *              all GPE blocks.
932c2c66affSColin Finck  *
933c2c66affSColin Finck  ******************************************************************************/
934c2c66affSColin Finck 
935c2c66affSColin Finck ACPI_STATUS
936c2c66affSColin Finck AcpiEnableAllWakeupGpes (
937c2c66affSColin Finck     void)
938c2c66affSColin Finck {
939c2c66affSColin Finck     ACPI_STATUS             Status;
940c2c66affSColin Finck 
941c2c66affSColin Finck 
942c2c66affSColin Finck     ACPI_FUNCTION_TRACE (AcpiEnableAllWakeupGpes);
943c2c66affSColin Finck 
944c2c66affSColin Finck 
945c2c66affSColin Finck     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
946c2c66affSColin Finck     if (ACPI_FAILURE (Status))
947c2c66affSColin Finck     {
948c2c66affSColin Finck         return_ACPI_STATUS (Status);
949c2c66affSColin Finck     }
950c2c66affSColin Finck 
951c2c66affSColin Finck     Status = AcpiHwEnableAllWakeupGpes ();
952c2c66affSColin Finck     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
953c2c66affSColin Finck 
954c2c66affSColin Finck     return_ACPI_STATUS (Status);
955c2c66affSColin Finck }
956c2c66affSColin Finck 
ACPI_EXPORT_SYMBOL(AcpiEnableAllWakeupGpes)957c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiEnableAllWakeupGpes)
958c2c66affSColin Finck 
959c2c66affSColin Finck 
960696cdc63SThomas Faber /******************************************************************************
961696cdc63SThomas Faber  *
962696cdc63SThomas Faber  * FUNCTION:    AcpiAnyGpeStatusSet
963696cdc63SThomas Faber  *
964696cdc63SThomas Faber  * PARAMETERS:  None
965696cdc63SThomas Faber  *
966696cdc63SThomas Faber  * RETURN:      Whether or not the status bit is set for any GPE
967696cdc63SThomas Faber  *
968696cdc63SThomas Faber  * DESCRIPTION: Check the status bits of all enabled GPEs and return TRUE if any
969696cdc63SThomas Faber  *              of them is set or FALSE otherwise.
970696cdc63SThomas Faber  *
971696cdc63SThomas Faber  ******************************************************************************/
972696cdc63SThomas Faber 
973696cdc63SThomas Faber UINT32
974696cdc63SThomas Faber AcpiAnyGpeStatusSet (
975696cdc63SThomas Faber     void)
976696cdc63SThomas Faber {
977696cdc63SThomas Faber     ACPI_STATUS                Status;
978696cdc63SThomas Faber     UINT8                      Ret;
979696cdc63SThomas Faber 
980696cdc63SThomas Faber 
981696cdc63SThomas Faber     ACPI_FUNCTION_TRACE (AcpiAnyGpeStatusSet);
982696cdc63SThomas Faber 
983696cdc63SThomas Faber     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
984696cdc63SThomas Faber     if (ACPI_FAILURE (Status))
985696cdc63SThomas Faber     {
986696cdc63SThomas Faber         return (FALSE);
987696cdc63SThomas Faber     }
988696cdc63SThomas Faber 
989696cdc63SThomas Faber     Ret = AcpiHwCheckAllGpes ();
990696cdc63SThomas Faber     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
991696cdc63SThomas Faber 
992696cdc63SThomas Faber     return (Ret);
993696cdc63SThomas Faber }
994696cdc63SThomas Faber 
ACPI_EXPORT_SYMBOL(AcpiAnyGpeStatusSet)995696cdc63SThomas Faber ACPI_EXPORT_SYMBOL(AcpiAnyGpeStatusSet)
996696cdc63SThomas Faber 
997696cdc63SThomas Faber 
998c2c66affSColin Finck /*******************************************************************************
999c2c66affSColin Finck  *
1000c2c66affSColin Finck  * FUNCTION:    AcpiInstallGpeBlock
1001c2c66affSColin Finck  *
1002c2c66affSColin Finck  * PARAMETERS:  GpeDevice           - Handle to the parent GPE Block Device
1003c2c66affSColin Finck  *              GpeBlockAddress     - Address and SpaceID
1004c2c66affSColin Finck  *              RegisterCount       - Number of GPE register pairs in the block
1005c2c66affSColin Finck  *              InterruptNumber     - H/W interrupt for the block
1006c2c66affSColin Finck  *
1007c2c66affSColin Finck  * RETURN:      Status
1008c2c66affSColin Finck  *
1009c2c66affSColin Finck  * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not
1010c2c66affSColin Finck  *              enabled here.
1011c2c66affSColin Finck  *
1012c2c66affSColin Finck  ******************************************************************************/
1013c2c66affSColin Finck 
1014c2c66affSColin Finck ACPI_STATUS
1015c2c66affSColin Finck AcpiInstallGpeBlock (
1016c2c66affSColin Finck     ACPI_HANDLE             GpeDevice,
1017c2c66affSColin Finck     ACPI_GENERIC_ADDRESS    *GpeBlockAddress,
1018c2c66affSColin Finck     UINT32                  RegisterCount,
1019c2c66affSColin Finck     UINT32                  InterruptNumber)
1020c2c66affSColin Finck {
1021c2c66affSColin Finck     ACPI_STATUS             Status;
1022c2c66affSColin Finck     ACPI_OPERAND_OBJECT     *ObjDesc;
1023c2c66affSColin Finck     ACPI_NAMESPACE_NODE     *Node;
1024c2c66affSColin Finck     ACPI_GPE_BLOCK_INFO     *GpeBlock;
1025c2c66affSColin Finck 
1026c2c66affSColin Finck 
1027c2c66affSColin Finck     ACPI_FUNCTION_TRACE (AcpiInstallGpeBlock);
1028c2c66affSColin Finck 
1029c2c66affSColin Finck 
1030c2c66affSColin Finck     if ((!GpeDevice)       ||
1031c2c66affSColin Finck         (!GpeBlockAddress) ||
1032c2c66affSColin Finck         (!RegisterCount))
1033c2c66affSColin Finck     {
1034c2c66affSColin Finck         return_ACPI_STATUS (AE_BAD_PARAMETER);
1035c2c66affSColin Finck     }
1036c2c66affSColin Finck 
1037c2c66affSColin Finck     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
1038c2c66affSColin Finck     if (ACPI_FAILURE (Status))
1039c2c66affSColin Finck     {
1040c2c66affSColin Finck         return_ACPI_STATUS (Status);
1041c2c66affSColin Finck     }
1042c2c66affSColin Finck 
1043c2c66affSColin Finck     Node = AcpiNsValidateHandle (GpeDevice);
1044c2c66affSColin Finck     if (!Node)
1045c2c66affSColin Finck     {
1046c2c66affSColin Finck         Status = AE_BAD_PARAMETER;
1047c2c66affSColin Finck         goto UnlockAndExit;
1048c2c66affSColin Finck     }
1049c2c66affSColin Finck 
1050c2c66affSColin Finck     /* Validate the parent device */
1051c2c66affSColin Finck 
1052c2c66affSColin Finck     if (Node->Type != ACPI_TYPE_DEVICE)
1053c2c66affSColin Finck     {
1054c2c66affSColin Finck         Status = AE_TYPE;
1055c2c66affSColin Finck         goto UnlockAndExit;
1056c2c66affSColin Finck     }
1057c2c66affSColin Finck 
1058c2c66affSColin Finck     if (Node->Object)
1059c2c66affSColin Finck     {
1060c2c66affSColin Finck         Status = AE_ALREADY_EXISTS;
1061c2c66affSColin Finck         goto UnlockAndExit;
1062c2c66affSColin Finck     }
1063c2c66affSColin Finck 
1064c2c66affSColin Finck     /*
1065c2c66affSColin Finck      * For user-installed GPE Block Devices, the GpeBlockBaseNumber
1066c2c66affSColin Finck      * is always zero
1067c2c66affSColin Finck      */
1068c2c66affSColin Finck     Status = AcpiEvCreateGpeBlock (Node, GpeBlockAddress->Address,
1069c2c66affSColin Finck         GpeBlockAddress->SpaceId, RegisterCount,
1070c2c66affSColin Finck         0, InterruptNumber, &GpeBlock);
1071c2c66affSColin Finck     if (ACPI_FAILURE (Status))
1072c2c66affSColin Finck     {
1073c2c66affSColin Finck         goto UnlockAndExit;
1074c2c66affSColin Finck     }
1075c2c66affSColin Finck 
1076c2c66affSColin Finck     /* Install block in the DeviceObject attached to the node */
1077c2c66affSColin Finck 
1078c2c66affSColin Finck     ObjDesc = AcpiNsGetAttachedObject (Node);
1079c2c66affSColin Finck     if (!ObjDesc)
1080c2c66affSColin Finck     {
1081c2c66affSColin Finck         /*
1082c2c66affSColin Finck          * No object, create a new one (Device nodes do not always have
1083c2c66affSColin Finck          * an attached object)
1084c2c66affSColin Finck          */
1085c2c66affSColin Finck         ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_DEVICE);
1086c2c66affSColin Finck         if (!ObjDesc)
1087c2c66affSColin Finck         {
1088c2c66affSColin Finck             Status = AE_NO_MEMORY;
1089c2c66affSColin Finck             goto UnlockAndExit;
1090c2c66affSColin Finck         }
1091c2c66affSColin Finck 
1092c2c66affSColin Finck         Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_DEVICE);
1093c2c66affSColin Finck 
1094c2c66affSColin Finck         /* Remove local reference to the object */
1095c2c66affSColin Finck 
1096c2c66affSColin Finck         AcpiUtRemoveReference (ObjDesc);
1097c2c66affSColin Finck         if (ACPI_FAILURE (Status))
1098c2c66affSColin Finck         {
1099c2c66affSColin Finck             goto UnlockAndExit;
1100c2c66affSColin Finck         }
1101c2c66affSColin Finck     }
1102c2c66affSColin Finck 
1103c2c66affSColin Finck     /* Now install the GPE block in the DeviceObject */
1104c2c66affSColin Finck 
1105c2c66affSColin Finck     ObjDesc->Device.GpeBlock = GpeBlock;
1106c2c66affSColin Finck 
1107c2c66affSColin Finck 
1108c2c66affSColin Finck UnlockAndExit:
1109c2c66affSColin Finck     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
1110c2c66affSColin Finck     return_ACPI_STATUS (Status);
1111c2c66affSColin Finck }
1112c2c66affSColin Finck 
ACPI_EXPORT_SYMBOL(AcpiInstallGpeBlock)1113c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiInstallGpeBlock)
1114c2c66affSColin Finck 
1115c2c66affSColin Finck 
1116c2c66affSColin Finck /*******************************************************************************
1117c2c66affSColin Finck  *
1118c2c66affSColin Finck  * FUNCTION:    AcpiRemoveGpeBlock
1119c2c66affSColin Finck  *
1120c2c66affSColin Finck  * PARAMETERS:  GpeDevice           - Handle to the parent GPE Block Device
1121c2c66affSColin Finck  *
1122c2c66affSColin Finck  * RETURN:      Status
1123c2c66affSColin Finck  *
1124c2c66affSColin Finck  * DESCRIPTION: Remove a previously installed block of GPE registers
1125c2c66affSColin Finck  *
1126c2c66affSColin Finck  ******************************************************************************/
1127c2c66affSColin Finck 
1128c2c66affSColin Finck ACPI_STATUS
1129c2c66affSColin Finck AcpiRemoveGpeBlock (
1130c2c66affSColin Finck     ACPI_HANDLE             GpeDevice)
1131c2c66affSColin Finck {
1132c2c66affSColin Finck     ACPI_OPERAND_OBJECT     *ObjDesc;
1133c2c66affSColin Finck     ACPI_STATUS             Status;
1134c2c66affSColin Finck     ACPI_NAMESPACE_NODE     *Node;
1135c2c66affSColin Finck 
1136c2c66affSColin Finck 
1137c2c66affSColin Finck     ACPI_FUNCTION_TRACE (AcpiRemoveGpeBlock);
1138c2c66affSColin Finck 
1139c2c66affSColin Finck 
1140c2c66affSColin Finck     if (!GpeDevice)
1141c2c66affSColin Finck     {
1142c2c66affSColin Finck         return_ACPI_STATUS (AE_BAD_PARAMETER);
1143c2c66affSColin Finck     }
1144c2c66affSColin Finck 
1145c2c66affSColin Finck     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
1146c2c66affSColin Finck     if (ACPI_FAILURE (Status))
1147c2c66affSColin Finck     {
1148c2c66affSColin Finck         return_ACPI_STATUS (Status);
1149c2c66affSColin Finck     }
1150c2c66affSColin Finck 
1151c2c66affSColin Finck     Node = AcpiNsValidateHandle (GpeDevice);
1152c2c66affSColin Finck     if (!Node)
1153c2c66affSColin Finck     {
1154c2c66affSColin Finck         Status = AE_BAD_PARAMETER;
1155c2c66affSColin Finck         goto UnlockAndExit;
1156c2c66affSColin Finck     }
1157c2c66affSColin Finck 
1158c2c66affSColin Finck     /* Validate the parent device */
1159c2c66affSColin Finck 
1160c2c66affSColin Finck     if (Node->Type != ACPI_TYPE_DEVICE)
1161c2c66affSColin Finck     {
1162c2c66affSColin Finck         Status = AE_TYPE;
1163c2c66affSColin Finck         goto UnlockAndExit;
1164c2c66affSColin Finck     }
1165c2c66affSColin Finck 
1166c2c66affSColin Finck     /* Get the DeviceObject attached to the node */
1167c2c66affSColin Finck 
1168c2c66affSColin Finck     ObjDesc = AcpiNsGetAttachedObject (Node);
1169c2c66affSColin Finck     if (!ObjDesc ||
1170c2c66affSColin Finck         !ObjDesc->Device.GpeBlock)
1171c2c66affSColin Finck     {
1172c2c66affSColin Finck         return_ACPI_STATUS (AE_NULL_OBJECT);
1173c2c66affSColin Finck     }
1174c2c66affSColin Finck 
1175c2c66affSColin Finck     /* Delete the GPE block (but not the DeviceObject) */
1176c2c66affSColin Finck 
1177c2c66affSColin Finck     Status = AcpiEvDeleteGpeBlock (ObjDesc->Device.GpeBlock);
1178c2c66affSColin Finck     if (ACPI_SUCCESS (Status))
1179c2c66affSColin Finck     {
1180c2c66affSColin Finck         ObjDesc->Device.GpeBlock = NULL;
1181c2c66affSColin Finck     }
1182c2c66affSColin Finck 
1183c2c66affSColin Finck UnlockAndExit:
1184c2c66affSColin Finck     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
1185c2c66affSColin Finck     return_ACPI_STATUS (Status);
1186c2c66affSColin Finck }
1187c2c66affSColin Finck 
ACPI_EXPORT_SYMBOL(AcpiRemoveGpeBlock)1188c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiRemoveGpeBlock)
1189c2c66affSColin Finck 
1190c2c66affSColin Finck 
1191c2c66affSColin Finck /*******************************************************************************
1192c2c66affSColin Finck  *
1193c2c66affSColin Finck  * FUNCTION:    AcpiGetGpeDevice
1194c2c66affSColin Finck  *
1195c2c66affSColin Finck  * PARAMETERS:  Index               - System GPE index (0-CurrentGpeCount)
1196c2c66affSColin Finck  *              GpeDevice           - Where the parent GPE Device is returned
1197c2c66affSColin Finck  *
1198c2c66affSColin Finck  * RETURN:      Status
1199c2c66affSColin Finck  *
1200c2c66affSColin Finck  * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
1201c2c66affSColin Finck  *              gpe device indicates that the gpe number is contained in one of
1202c2c66affSColin Finck  *              the FADT-defined gpe blocks. Otherwise, the GPE block device.
1203c2c66affSColin Finck  *
1204c2c66affSColin Finck  ******************************************************************************/
1205c2c66affSColin Finck 
1206c2c66affSColin Finck ACPI_STATUS
1207c2c66affSColin Finck AcpiGetGpeDevice (
1208c2c66affSColin Finck     UINT32                  Index,
1209c2c66affSColin Finck     ACPI_HANDLE             *GpeDevice)
1210c2c66affSColin Finck {
1211c2c66affSColin Finck     ACPI_GPE_DEVICE_INFO    Info;
1212c2c66affSColin Finck     ACPI_STATUS             Status;
1213c2c66affSColin Finck 
1214c2c66affSColin Finck 
1215c2c66affSColin Finck     ACPI_FUNCTION_TRACE (AcpiGetGpeDevice);
1216c2c66affSColin Finck 
1217c2c66affSColin Finck 
1218c2c66affSColin Finck     if (!GpeDevice)
1219c2c66affSColin Finck     {
1220c2c66affSColin Finck         return_ACPI_STATUS (AE_BAD_PARAMETER);
1221c2c66affSColin Finck     }
1222c2c66affSColin Finck 
1223c2c66affSColin Finck     if (Index >= AcpiCurrentGpeCount)
1224c2c66affSColin Finck     {
1225c2c66affSColin Finck         return_ACPI_STATUS (AE_NOT_EXIST);
1226c2c66affSColin Finck     }
1227c2c66affSColin Finck 
1228c2c66affSColin Finck     /* Setup and walk the GPE list */
1229c2c66affSColin Finck 
1230c2c66affSColin Finck     Info.Index = Index;
1231c2c66affSColin Finck     Info.Status = AE_NOT_EXIST;
1232c2c66affSColin Finck     Info.GpeDevice = NULL;
1233c2c66affSColin Finck     Info.NextBlockBaseIndex = 0;
1234c2c66affSColin Finck 
1235c2c66affSColin Finck     Status = AcpiEvWalkGpeList (AcpiEvGetGpeDevice, &Info);
1236c2c66affSColin Finck     if (ACPI_FAILURE (Status))
1237c2c66affSColin Finck     {
1238c2c66affSColin Finck         return_ACPI_STATUS (Status);
1239c2c66affSColin Finck     }
1240c2c66affSColin Finck 
1241c2c66affSColin Finck     *GpeDevice = ACPI_CAST_PTR (ACPI_HANDLE, Info.GpeDevice);
1242c2c66affSColin Finck     return_ACPI_STATUS (Info.Status);
1243c2c66affSColin Finck }
1244c2c66affSColin Finck 
1245c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiGetGpeDevice)
1246c2c66affSColin Finck 
1247c2c66affSColin Finck #endif /* !ACPI_REDUCED_HARDWARE */
1248