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