Deleted Added
full compact
evxfgpe.c (237652) evxfgpe.c (238381)
1/******************************************************************************
2 *
3 * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs)
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2012, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44
45#define __EVXFGPE_C__
46
47#include <contrib/dev/acpica/include/acpi.h>
48#include <contrib/dev/acpica/include/accommon.h>
49#include <contrib/dev/acpica/include/acevents.h>
50#include <contrib/dev/acpica/include/acnamesp.h>
51
52#define _COMPONENT ACPI_EVENTS
53 ACPI_MODULE_NAME ("evxfgpe")
54
55
56#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
57/*******************************************************************************
58 *
59 * FUNCTION: AcpiUpdateAllGpes
60 *
61 * PARAMETERS: None
62 *
63 * RETURN: Status
64 *
65 * DESCRIPTION: Complete GPE initialization and enable all GPEs that have
66 * associated _Lxx or _Exx methods and are not pointed to by any
67 * device _PRW methods (this indicates that these GPEs are
68 * generally intended for system or device wakeup. Such GPEs
69 * have to be enabled directly when the devices whose _PRW
70 * methods point to them are set up for wakeup signaling.)
71 *
72 * NOTE: Should be called after any GPEs are added to the system. Primarily,
73 * after the system _PRW methods have been run, but also after a GPE Block
74 * Device has been added or if any new GPE methods have been added via a
75 * dynamic table load.
76 *
77 ******************************************************************************/
78
79ACPI_STATUS
80AcpiUpdateAllGpes (
81 void)
82{
83 ACPI_STATUS Status;
84
85
1/******************************************************************************
2 *
3 * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs)
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2012, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44
45#define __EVXFGPE_C__
46
47#include <contrib/dev/acpica/include/acpi.h>
48#include <contrib/dev/acpica/include/accommon.h>
49#include <contrib/dev/acpica/include/acevents.h>
50#include <contrib/dev/acpica/include/acnamesp.h>
51
52#define _COMPONENT ACPI_EVENTS
53 ACPI_MODULE_NAME ("evxfgpe")
54
55
56#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
57/*******************************************************************************
58 *
59 * FUNCTION: AcpiUpdateAllGpes
60 *
61 * PARAMETERS: None
62 *
63 * RETURN: Status
64 *
65 * DESCRIPTION: Complete GPE initialization and enable all GPEs that have
66 * associated _Lxx or _Exx methods and are not pointed to by any
67 * device _PRW methods (this indicates that these GPEs are
68 * generally intended for system or device wakeup. Such GPEs
69 * have to be enabled directly when the devices whose _PRW
70 * methods point to them are set up for wakeup signaling.)
71 *
72 * NOTE: Should be called after any GPEs are added to the system. Primarily,
73 * after the system _PRW methods have been run, but also after a GPE Block
74 * Device has been added or if any new GPE methods have been added via a
75 * dynamic table load.
76 *
77 ******************************************************************************/
78
79ACPI_STATUS
80AcpiUpdateAllGpes (
81 void)
82{
83 ACPI_STATUS Status;
84
85
86 ACPI_FUNCTION_TRACE (AcpiUpdateGpes);
86 ACPI_FUNCTION_TRACE (AcpiUpdateAllGpes);
87
88
89 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
90 if (ACPI_FAILURE (Status))
91 {
92 return_ACPI_STATUS (Status);
93 }
94
95 if (AcpiGbl_AllGpesInitialized)
96 {
97 goto UnlockAndExit;
98 }
99
100 Status = AcpiEvWalkGpeList (AcpiEvInitializeGpeBlock, NULL);
101 if (ACPI_SUCCESS (Status))
102 {
103 AcpiGbl_AllGpesInitialized = TRUE;
104 }
105
106UnlockAndExit:
107 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
108 return_ACPI_STATUS (Status);
109}
110
111ACPI_EXPORT_SYMBOL (AcpiUpdateAllGpes)
112
113
114/*******************************************************************************
115 *
116 * FUNCTION: AcpiEnableGpe
117 *
118 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
119 * GpeNumber - GPE level within the GPE block
120 *
121 * RETURN: Status
122 *
123 * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
124 * hardware-enabled.
125 *
126 ******************************************************************************/
127
128ACPI_STATUS
129AcpiEnableGpe (
130 ACPI_HANDLE GpeDevice,
131 UINT32 GpeNumber)
132{
133 ACPI_STATUS Status = AE_BAD_PARAMETER;
134 ACPI_GPE_EVENT_INFO *GpeEventInfo;
135 ACPI_CPU_FLAGS Flags;
136
137
138 ACPI_FUNCTION_TRACE (AcpiEnableGpe);
139
140
141 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
142
143 /* Ensure that we have a valid GPE number */
144
145 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
146 if (GpeEventInfo)
147 {
148 Status = AcpiEvAddGpeReference (GpeEventInfo);
149 }
150
151 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
152 return_ACPI_STATUS (Status);
153}
154
155ACPI_EXPORT_SYMBOL (AcpiEnableGpe)
156
157
158/*******************************************************************************
159 *
160 * FUNCTION: AcpiDisableGpe
161 *
162 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
163 * GpeNumber - GPE level within the GPE block
164 *
165 * RETURN: Status
166 *
167 * DESCRIPTION: Remove a reference to a GPE. When the last reference is
168 * removed, only then is the GPE disabled (for runtime GPEs), or
169 * the GPE mask bit disabled (for wake GPEs)
170 *
171 ******************************************************************************/
172
173ACPI_STATUS
174AcpiDisableGpe (
175 ACPI_HANDLE GpeDevice,
176 UINT32 GpeNumber)
177{
178 ACPI_STATUS Status = AE_BAD_PARAMETER;
179 ACPI_GPE_EVENT_INFO *GpeEventInfo;
180 ACPI_CPU_FLAGS Flags;
181
182
183 ACPI_FUNCTION_TRACE (AcpiDisableGpe);
184
185
186 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
187
188 /* Ensure that we have a valid GPE number */
189
190 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
191 if (GpeEventInfo)
192 {
193 Status = AcpiEvRemoveGpeReference (GpeEventInfo);
194 }
195
196 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
197 return_ACPI_STATUS (Status);
198}
199
200ACPI_EXPORT_SYMBOL (AcpiDisableGpe)
201
202
203/*******************************************************************************
204 *
205 * FUNCTION: AcpiSetGpe
206 *
207 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
208 * GpeNumber - GPE level within the GPE block
209 * Action - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
210 *
211 * RETURN: Status
212 *
213 * DESCRIPTION: Enable or disable an individual GPE. This function bypasses
214 * the reference count mechanism used in the AcpiEnableGpe and
215 * AcpiDisableGpe interfaces -- and should be used with care.
216 *
217 * Note: Typically used to disable a runtime GPE for short period of time,
218 * then re-enable it, without disturbing the existing reference counts. This
219 * is useful, for example, in the Embedded Controller (EC) driver.
220 *
221 ******************************************************************************/
222
223ACPI_STATUS
224AcpiSetGpe (
225 ACPI_HANDLE GpeDevice,
226 UINT32 GpeNumber,
227 UINT8 Action)
228{
229 ACPI_GPE_EVENT_INFO *GpeEventInfo;
230 ACPI_STATUS Status;
231 ACPI_CPU_FLAGS Flags;
232
233
234 ACPI_FUNCTION_TRACE (AcpiSetGpe);
235
236
237 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
238
239 /* Ensure that we have a valid GPE number */
240
241 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
242 if (!GpeEventInfo)
243 {
244 Status = AE_BAD_PARAMETER;
245 goto UnlockAndExit;
246 }
247
248 /* Perform the action */
249
250 switch (Action)
251 {
252 case ACPI_GPE_ENABLE:
253 Status = AcpiEvEnableGpe (GpeEventInfo);
254 break;
255
256 case ACPI_GPE_DISABLE:
257 Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
258 break;
259
260 default:
261 Status = AE_BAD_PARAMETER;
262 break;
263 }
264
265UnlockAndExit:
266 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
267 return_ACPI_STATUS (Status);
268}
269
270ACPI_EXPORT_SYMBOL (AcpiSetGpe)
271
272
273/*******************************************************************************
274 *
275 * FUNCTION: AcpiSetupGpeForWake
276 *
277 * PARAMETERS: WakeDevice - Device associated with the GPE (via _PRW)
278 * GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
279 * GpeNumber - GPE level within the GPE block
280 *
281 * RETURN: Status
282 *
283 * DESCRIPTION: Mark a GPE as having the ability to wake the system. This
284 * interface is intended to be used as the host executes the
285 * _PRW methods (Power Resources for Wake) in the system tables.
286 * Each _PRW appears under a Device Object (The WakeDevice), and
287 * contains the info for the wake GPE associated with the
288 * WakeDevice.
289 *
290 ******************************************************************************/
291
292ACPI_STATUS
293AcpiSetupGpeForWake (
294 ACPI_HANDLE WakeDevice,
295 ACPI_HANDLE GpeDevice,
296 UINT32 GpeNumber)
297{
298 ACPI_STATUS Status;
299 ACPI_GPE_EVENT_INFO *GpeEventInfo;
300 ACPI_NAMESPACE_NODE *DeviceNode;
87
88
89 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
90 if (ACPI_FAILURE (Status))
91 {
92 return_ACPI_STATUS (Status);
93 }
94
95 if (AcpiGbl_AllGpesInitialized)
96 {
97 goto UnlockAndExit;
98 }
99
100 Status = AcpiEvWalkGpeList (AcpiEvInitializeGpeBlock, NULL);
101 if (ACPI_SUCCESS (Status))
102 {
103 AcpiGbl_AllGpesInitialized = TRUE;
104 }
105
106UnlockAndExit:
107 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
108 return_ACPI_STATUS (Status);
109}
110
111ACPI_EXPORT_SYMBOL (AcpiUpdateAllGpes)
112
113
114/*******************************************************************************
115 *
116 * FUNCTION: AcpiEnableGpe
117 *
118 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
119 * GpeNumber - GPE level within the GPE block
120 *
121 * RETURN: Status
122 *
123 * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
124 * hardware-enabled.
125 *
126 ******************************************************************************/
127
128ACPI_STATUS
129AcpiEnableGpe (
130 ACPI_HANDLE GpeDevice,
131 UINT32 GpeNumber)
132{
133 ACPI_STATUS Status = AE_BAD_PARAMETER;
134 ACPI_GPE_EVENT_INFO *GpeEventInfo;
135 ACPI_CPU_FLAGS Flags;
136
137
138 ACPI_FUNCTION_TRACE (AcpiEnableGpe);
139
140
141 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
142
143 /* Ensure that we have a valid GPE number */
144
145 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
146 if (GpeEventInfo)
147 {
148 Status = AcpiEvAddGpeReference (GpeEventInfo);
149 }
150
151 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
152 return_ACPI_STATUS (Status);
153}
154
155ACPI_EXPORT_SYMBOL (AcpiEnableGpe)
156
157
158/*******************************************************************************
159 *
160 * FUNCTION: AcpiDisableGpe
161 *
162 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
163 * GpeNumber - GPE level within the GPE block
164 *
165 * RETURN: Status
166 *
167 * DESCRIPTION: Remove a reference to a GPE. When the last reference is
168 * removed, only then is the GPE disabled (for runtime GPEs), or
169 * the GPE mask bit disabled (for wake GPEs)
170 *
171 ******************************************************************************/
172
173ACPI_STATUS
174AcpiDisableGpe (
175 ACPI_HANDLE GpeDevice,
176 UINT32 GpeNumber)
177{
178 ACPI_STATUS Status = AE_BAD_PARAMETER;
179 ACPI_GPE_EVENT_INFO *GpeEventInfo;
180 ACPI_CPU_FLAGS Flags;
181
182
183 ACPI_FUNCTION_TRACE (AcpiDisableGpe);
184
185
186 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
187
188 /* Ensure that we have a valid GPE number */
189
190 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
191 if (GpeEventInfo)
192 {
193 Status = AcpiEvRemoveGpeReference (GpeEventInfo);
194 }
195
196 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
197 return_ACPI_STATUS (Status);
198}
199
200ACPI_EXPORT_SYMBOL (AcpiDisableGpe)
201
202
203/*******************************************************************************
204 *
205 * FUNCTION: AcpiSetGpe
206 *
207 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
208 * GpeNumber - GPE level within the GPE block
209 * Action - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
210 *
211 * RETURN: Status
212 *
213 * DESCRIPTION: Enable or disable an individual GPE. This function bypasses
214 * the reference count mechanism used in the AcpiEnableGpe and
215 * AcpiDisableGpe interfaces -- and should be used with care.
216 *
217 * Note: Typically used to disable a runtime GPE for short period of time,
218 * then re-enable it, without disturbing the existing reference counts. This
219 * is useful, for example, in the Embedded Controller (EC) driver.
220 *
221 ******************************************************************************/
222
223ACPI_STATUS
224AcpiSetGpe (
225 ACPI_HANDLE GpeDevice,
226 UINT32 GpeNumber,
227 UINT8 Action)
228{
229 ACPI_GPE_EVENT_INFO *GpeEventInfo;
230 ACPI_STATUS Status;
231 ACPI_CPU_FLAGS Flags;
232
233
234 ACPI_FUNCTION_TRACE (AcpiSetGpe);
235
236
237 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
238
239 /* Ensure that we have a valid GPE number */
240
241 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
242 if (!GpeEventInfo)
243 {
244 Status = AE_BAD_PARAMETER;
245 goto UnlockAndExit;
246 }
247
248 /* Perform the action */
249
250 switch (Action)
251 {
252 case ACPI_GPE_ENABLE:
253 Status = AcpiEvEnableGpe (GpeEventInfo);
254 break;
255
256 case ACPI_GPE_DISABLE:
257 Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
258 break;
259
260 default:
261 Status = AE_BAD_PARAMETER;
262 break;
263 }
264
265UnlockAndExit:
266 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
267 return_ACPI_STATUS (Status);
268}
269
270ACPI_EXPORT_SYMBOL (AcpiSetGpe)
271
272
273/*******************************************************************************
274 *
275 * FUNCTION: AcpiSetupGpeForWake
276 *
277 * PARAMETERS: WakeDevice - Device associated with the GPE (via _PRW)
278 * GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
279 * GpeNumber - GPE level within the GPE block
280 *
281 * RETURN: Status
282 *
283 * DESCRIPTION: Mark a GPE as having the ability to wake the system. This
284 * interface is intended to be used as the host executes the
285 * _PRW methods (Power Resources for Wake) in the system tables.
286 * Each _PRW appears under a Device Object (The WakeDevice), and
287 * contains the info for the wake GPE associated with the
288 * WakeDevice.
289 *
290 ******************************************************************************/
291
292ACPI_STATUS
293AcpiSetupGpeForWake (
294 ACPI_HANDLE WakeDevice,
295 ACPI_HANDLE GpeDevice,
296 UINT32 GpeNumber)
297{
298 ACPI_STATUS Status;
299 ACPI_GPE_EVENT_INFO *GpeEventInfo;
300 ACPI_NAMESPACE_NODE *DeviceNode;
301 ACPI_GPE_NOTIFY_INFO *NewNotify, *Notify;
301 ACPI_GPE_NOTIFY_INFO *Notify;
302 ACPI_GPE_NOTIFY_INFO *NewNotify;
302 ACPI_CPU_FLAGS Flags;
303
304
305 ACPI_FUNCTION_TRACE (AcpiSetupGpeForWake);
306
307
308 /* Parameter Validation */
309
310 if (!WakeDevice)
311 {
312 /*
313 * By forcing WakeDevice to be valid, we automatically enable the
314 * implicit notify feature on all hosts.
315 */
316 return_ACPI_STATUS (AE_BAD_PARAMETER);
317 }
318
319 /* Handle root object case */
320
321 if (WakeDevice == ACPI_ROOT_OBJECT)
322 {
323 DeviceNode = AcpiGbl_RootNode;
324 }
325 else
326 {
327 DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, WakeDevice);
328 }
329
330 /* Validate WakeDevice is of type Device */
331
332 if (DeviceNode->Type != ACPI_TYPE_DEVICE)
333 {
334 return_ACPI_STATUS (AE_BAD_PARAMETER);
335 }
336
303 ACPI_CPU_FLAGS Flags;
304
305
306 ACPI_FUNCTION_TRACE (AcpiSetupGpeForWake);
307
308
309 /* Parameter Validation */
310
311 if (!WakeDevice)
312 {
313 /*
314 * By forcing WakeDevice to be valid, we automatically enable the
315 * implicit notify feature on all hosts.
316 */
317 return_ACPI_STATUS (AE_BAD_PARAMETER);
318 }
319
320 /* Handle root object case */
321
322 if (WakeDevice == ACPI_ROOT_OBJECT)
323 {
324 DeviceNode = AcpiGbl_RootNode;
325 }
326 else
327 {
328 DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, WakeDevice);
329 }
330
331 /* Validate WakeDevice is of type Device */
332
333 if (DeviceNode->Type != ACPI_TYPE_DEVICE)
334 {
335 return_ACPI_STATUS (AE_BAD_PARAMETER);
336 }
337
338 /*
339 * Allocate a new notify object up front, in case it is needed.
340 * Memory allocation while holding a spinlock is a big no-no
341 * on some hosts.
342 */
337 NewNotify = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_NOTIFY_INFO));
338 if (!NewNotify)
339 {
340 return_ACPI_STATUS (AE_NO_MEMORY);
341 }
342
343 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
344
345 /* Ensure that we have a valid GPE number */
346
347 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
348 if (!GpeEventInfo)
349 {
350 Status = AE_BAD_PARAMETER;
351 goto UnlockAndExit;
352 }
353
354 /*
355 * If there is no method or handler for this GPE, then the
356 * WakeDevice will be notified whenever this GPE fires. This is
357 * known as an "implicit notify". Note: The GPE is assumed to be
358 * level-triggered (for windows compatibility).
359 */
360 if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
361 ACPI_GPE_DISPATCH_NONE)
362 {
363 /*
364 * This is the first device for implicit notify on this GPE.
365 * Just set the flags here, and enter the NOTIFY block below.
366 */
367 GpeEventInfo->Flags =
368 (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED);
369 }
370
371 /*
372 * If we already have an implicit notify on this GPE, add
373 * this device to the notify list.
374 */
375 if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
376 ACPI_GPE_DISPATCH_NOTIFY)
377 {
378 /* Ensure that the device is not already in the list */
379
380 Notify = GpeEventInfo->Dispatch.NotifyList;
381 while (Notify)
382 {
383 if (Notify->DeviceNode == DeviceNode)
384 {
385 Status = AE_ALREADY_EXISTS;
386 goto UnlockAndExit;
387 }
388 Notify = Notify->Next;
389 }
390
391 /* Add this device to the notify list for this GPE */
392
393 NewNotify->DeviceNode = DeviceNode;
394 NewNotify->Next = GpeEventInfo->Dispatch.NotifyList;
395 GpeEventInfo->Dispatch.NotifyList = NewNotify;
396 NewNotify = NULL;
397 }
398
399 /* Mark the GPE as a possible wake event */
400
401 GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
402 Status = AE_OK;
403
343 NewNotify = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_NOTIFY_INFO));
344 if (!NewNotify)
345 {
346 return_ACPI_STATUS (AE_NO_MEMORY);
347 }
348
349 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
350
351 /* Ensure that we have a valid GPE number */
352
353 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
354 if (!GpeEventInfo)
355 {
356 Status = AE_BAD_PARAMETER;
357 goto UnlockAndExit;
358 }
359
360 /*
361 * If there is no method or handler for this GPE, then the
362 * WakeDevice will be notified whenever this GPE fires. This is
363 * known as an "implicit notify". Note: The GPE is assumed to be
364 * level-triggered (for windows compatibility).
365 */
366 if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
367 ACPI_GPE_DISPATCH_NONE)
368 {
369 /*
370 * This is the first device for implicit notify on this GPE.
371 * Just set the flags here, and enter the NOTIFY block below.
372 */
373 GpeEventInfo->Flags =
374 (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED);
375 }
376
377 /*
378 * If we already have an implicit notify on this GPE, add
379 * this device to the notify list.
380 */
381 if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
382 ACPI_GPE_DISPATCH_NOTIFY)
383 {
384 /* Ensure that the device is not already in the list */
385
386 Notify = GpeEventInfo->Dispatch.NotifyList;
387 while (Notify)
388 {
389 if (Notify->DeviceNode == DeviceNode)
390 {
391 Status = AE_ALREADY_EXISTS;
392 goto UnlockAndExit;
393 }
394 Notify = Notify->Next;
395 }
396
397 /* Add this device to the notify list for this GPE */
398
399 NewNotify->DeviceNode = DeviceNode;
400 NewNotify->Next = GpeEventInfo->Dispatch.NotifyList;
401 GpeEventInfo->Dispatch.NotifyList = NewNotify;
402 NewNotify = NULL;
403 }
404
405 /* Mark the GPE as a possible wake event */
406
407 GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
408 Status = AE_OK;
409
410
404UnlockAndExit:
405 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
411UnlockAndExit:
412 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
413
414 /* Delete the notify object if it was not used above */
415
406 if (NewNotify)
407 {
408 ACPI_FREE (NewNotify);
409 }
410 return_ACPI_STATUS (Status);
411}
412
413ACPI_EXPORT_SYMBOL (AcpiSetupGpeForWake)
414
415
416/*******************************************************************************
417 *
418 * FUNCTION: AcpiSetGpeWakeMask
419 *
420 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
421 * GpeNumber - GPE level within the GPE block
422 * Action - Enable or Disable
423 *
424 * RETURN: Status
425 *
426 * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must
427 * already be marked as a WAKE GPE.
428 *
429 ******************************************************************************/
430
431ACPI_STATUS
432AcpiSetGpeWakeMask (
433 ACPI_HANDLE GpeDevice,
434 UINT32 GpeNumber,
435 UINT8 Action)
436{
437 ACPI_STATUS Status = AE_OK;
438 ACPI_GPE_EVENT_INFO *GpeEventInfo;
439 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
440 ACPI_CPU_FLAGS Flags;
441 UINT32 RegisterBit;
442
443
444 ACPI_FUNCTION_TRACE (AcpiSetGpeWakeMask);
445
446
447 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
448
449 /*
450 * Ensure that we have a valid GPE number and that this GPE is in
451 * fact a wake GPE
452 */
453 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
454 if (!GpeEventInfo)
455 {
456 Status = AE_BAD_PARAMETER;
457 goto UnlockAndExit;
458 }
459
460 if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE))
461 {
462 Status = AE_TYPE;
463 goto UnlockAndExit;
464 }
465
466 GpeRegisterInfo = GpeEventInfo->RegisterInfo;
467 if (!GpeRegisterInfo)
468 {
469 Status = AE_NOT_EXIST;
470 goto UnlockAndExit;
471 }
472
473 RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo, GpeRegisterInfo);
474
475 /* Perform the action */
476
477 switch (Action)
478 {
479 case ACPI_GPE_ENABLE:
480 ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
481 break;
482
483 case ACPI_GPE_DISABLE:
484 ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
485 break;
486
487 default:
488 ACPI_ERROR ((AE_INFO, "%u, Invalid action", Action));
489 Status = AE_BAD_PARAMETER;
490 break;
491 }
492
493UnlockAndExit:
494 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
495 return_ACPI_STATUS (Status);
496}
497
498ACPI_EXPORT_SYMBOL (AcpiSetGpeWakeMask)
499
500
501/*******************************************************************************
502 *
503 * FUNCTION: AcpiClearGpe
504 *
505 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
506 * GpeNumber - GPE level within the GPE block
507 *
508 * RETURN: Status
509 *
510 * DESCRIPTION: Clear an ACPI event (general purpose)
511 *
512 ******************************************************************************/
513
514ACPI_STATUS
515AcpiClearGpe (
516 ACPI_HANDLE GpeDevice,
517 UINT32 GpeNumber)
518{
519 ACPI_STATUS Status = AE_OK;
520 ACPI_GPE_EVENT_INFO *GpeEventInfo;
521 ACPI_CPU_FLAGS Flags;
522
523
524 ACPI_FUNCTION_TRACE (AcpiClearGpe);
525
526
527 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
528
529 /* Ensure that we have a valid GPE number */
530
531 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
532 if (!GpeEventInfo)
533 {
534 Status = AE_BAD_PARAMETER;
535 goto UnlockAndExit;
536 }
537
538 Status = AcpiHwClearGpe (GpeEventInfo);
539
540UnlockAndExit:
541 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
542 return_ACPI_STATUS (Status);
543}
544
545ACPI_EXPORT_SYMBOL (AcpiClearGpe)
546
547
548/*******************************************************************************
549 *
550 * FUNCTION: AcpiGetGpeStatus
551 *
552 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
553 * GpeNumber - GPE level within the GPE block
554 * EventStatus - Where the current status of the event
555 * will be returned
556 *
557 * RETURN: Status
558 *
559 * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled)
560 *
561 ******************************************************************************/
562
563ACPI_STATUS
564AcpiGetGpeStatus (
565 ACPI_HANDLE GpeDevice,
566 UINT32 GpeNumber,
567 ACPI_EVENT_STATUS *EventStatus)
568{
569 ACPI_STATUS Status = AE_OK;
570 ACPI_GPE_EVENT_INFO *GpeEventInfo;
571 ACPI_CPU_FLAGS Flags;
572
573
574 ACPI_FUNCTION_TRACE (AcpiGetGpeStatus);
575
576
577 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
578
579 /* Ensure that we have a valid GPE number */
580
581 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
582 if (!GpeEventInfo)
583 {
584 Status = AE_BAD_PARAMETER;
585 goto UnlockAndExit;
586 }
587
588 /* Obtain status on the requested GPE number */
589
590 Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus);
591
592UnlockAndExit:
593 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
594 return_ACPI_STATUS (Status);
595}
596
597ACPI_EXPORT_SYMBOL (AcpiGetGpeStatus)
598
599
600/*******************************************************************************
601 *
602 * FUNCTION: AcpiFinishGpe
603 *
604 * PARAMETERS: GpeDevice - Namespace node for the GPE Block
605 * (NULL for FADT defined GPEs)
606 * GpeNumber - GPE level within the GPE block
607 *
608 * RETURN: Status
609 *
610 * DESCRIPTION: Clear and conditionally reenable a GPE. This completes the GPE
611 * processing. Intended for use by asynchronous host-installed
612 * GPE handlers. The GPE is only reenabled if the EnableForRun bit
613 * is set in the GPE info.
614 *
615 ******************************************************************************/
616
617ACPI_STATUS
618AcpiFinishGpe (
619 ACPI_HANDLE GpeDevice,
620 UINT32 GpeNumber)
621{
622 ACPI_GPE_EVENT_INFO *GpeEventInfo;
623 ACPI_STATUS Status;
624 ACPI_CPU_FLAGS Flags;
625
626
627 ACPI_FUNCTION_TRACE (AcpiFinishGpe);
628
629
630 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
631
632 /* Ensure that we have a valid GPE number */
633
634 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
635 if (!GpeEventInfo)
636 {
637 Status = AE_BAD_PARAMETER;
638 goto UnlockAndExit;
639 }
640
641 Status = AcpiEvFinishGpe (GpeEventInfo);
642
643UnlockAndExit:
644 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
645 return_ACPI_STATUS (Status);
646}
647
648ACPI_EXPORT_SYMBOL (AcpiFinishGpe)
649
650
651/******************************************************************************
652 *
653 * FUNCTION: AcpiDisableAllGpes
654 *
655 * PARAMETERS: None
656 *
657 * RETURN: Status
658 *
659 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
660 *
661 ******************************************************************************/
662
663ACPI_STATUS
664AcpiDisableAllGpes (
665 void)
666{
667 ACPI_STATUS Status;
668
669
670 ACPI_FUNCTION_TRACE (AcpiDisableAllGpes);
671
672
673 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
674 if (ACPI_FAILURE (Status))
675 {
676 return_ACPI_STATUS (Status);
677 }
678
679 Status = AcpiHwDisableAllGpes ();
680 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
681
682 return_ACPI_STATUS (Status);
683}
684
685ACPI_EXPORT_SYMBOL (AcpiDisableAllGpes)
686
687
688/******************************************************************************
689 *
690 * FUNCTION: AcpiEnableAllRuntimeGpes
691 *
692 * PARAMETERS: None
693 *
694 * RETURN: Status
695 *
696 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
697 *
698 ******************************************************************************/
699
700ACPI_STATUS
701AcpiEnableAllRuntimeGpes (
702 void)
703{
704 ACPI_STATUS Status;
705
706
707 ACPI_FUNCTION_TRACE (AcpiEnableAllRuntimeGpes);
708
709
710 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
711 if (ACPI_FAILURE (Status))
712 {
713 return_ACPI_STATUS (Status);
714 }
715
716 Status = AcpiHwEnableAllRuntimeGpes ();
717 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
718
719 return_ACPI_STATUS (Status);
720}
721
722ACPI_EXPORT_SYMBOL (AcpiEnableAllRuntimeGpes)
723
724
725/*******************************************************************************
726 *
727 * FUNCTION: AcpiInstallGpeBlock
728 *
729 * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device
730 * GpeBlockAddress - Address and SpaceID
731 * RegisterCount - Number of GPE register pairs in the block
732 * InterruptNumber - H/W interrupt for the block
733 *
734 * RETURN: Status
735 *
736 * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not
737 * enabled here.
738 *
739 ******************************************************************************/
740
741ACPI_STATUS
742AcpiInstallGpeBlock (
743 ACPI_HANDLE GpeDevice,
744 ACPI_GENERIC_ADDRESS *GpeBlockAddress,
745 UINT32 RegisterCount,
746 UINT32 InterruptNumber)
747{
748 ACPI_STATUS Status;
749 ACPI_OPERAND_OBJECT *ObjDesc;
750 ACPI_NAMESPACE_NODE *Node;
751 ACPI_GPE_BLOCK_INFO *GpeBlock;
752
753
754 ACPI_FUNCTION_TRACE (AcpiInstallGpeBlock);
755
756
757 if ((!GpeDevice) ||
758 (!GpeBlockAddress) ||
759 (!RegisterCount))
760 {
761 return_ACPI_STATUS (AE_BAD_PARAMETER);
762 }
763
764 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
765 if (ACPI_FAILURE (Status))
766 {
767 return (Status);
768 }
769
770 Node = AcpiNsValidateHandle (GpeDevice);
771 if (!Node)
772 {
773 Status = AE_BAD_PARAMETER;
774 goto UnlockAndExit;
775 }
776
777 /*
778 * For user-installed GPE Block Devices, the GpeBlockBaseNumber
779 * is always zero
780 */
781 Status = AcpiEvCreateGpeBlock (Node, GpeBlockAddress, RegisterCount,
782 0, InterruptNumber, &GpeBlock);
783 if (ACPI_FAILURE (Status))
784 {
785 goto UnlockAndExit;
786 }
787
788 /* Install block in the DeviceObject attached to the node */
789
790 ObjDesc = AcpiNsGetAttachedObject (Node);
791 if (!ObjDesc)
792 {
793 /*
794 * No object, create a new one (Device nodes do not always have
795 * an attached object)
796 */
797 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_DEVICE);
798 if (!ObjDesc)
799 {
800 Status = AE_NO_MEMORY;
801 goto UnlockAndExit;
802 }
803
804 Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_DEVICE);
805
806 /* Remove local reference to the object */
807
808 AcpiUtRemoveReference (ObjDesc);
809 if (ACPI_FAILURE (Status))
810 {
811 goto UnlockAndExit;
812 }
813 }
814
815 /* Now install the GPE block in the DeviceObject */
816
817 ObjDesc->Device.GpeBlock = GpeBlock;
818
819
820UnlockAndExit:
821 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
822 return_ACPI_STATUS (Status);
823}
824
825ACPI_EXPORT_SYMBOL (AcpiInstallGpeBlock)
826
827
828/*******************************************************************************
829 *
830 * FUNCTION: AcpiRemoveGpeBlock
831 *
832 * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device
833 *
834 * RETURN: Status
835 *
836 * DESCRIPTION: Remove a previously installed block of GPE registers
837 *
838 ******************************************************************************/
839
840ACPI_STATUS
841AcpiRemoveGpeBlock (
842 ACPI_HANDLE GpeDevice)
843{
844 ACPI_OPERAND_OBJECT *ObjDesc;
845 ACPI_STATUS Status;
846 ACPI_NAMESPACE_NODE *Node;
847
848
849 ACPI_FUNCTION_TRACE (AcpiRemoveGpeBlock);
850
851
852 if (!GpeDevice)
853 {
854 return_ACPI_STATUS (AE_BAD_PARAMETER);
855 }
856
857 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
858 if (ACPI_FAILURE (Status))
859 {
860 return (Status);
861 }
862
863 Node = AcpiNsValidateHandle (GpeDevice);
864 if (!Node)
865 {
866 Status = AE_BAD_PARAMETER;
867 goto UnlockAndExit;
868 }
869
870 /* Get the DeviceObject attached to the node */
871
872 ObjDesc = AcpiNsGetAttachedObject (Node);
873 if (!ObjDesc ||
874 !ObjDesc->Device.GpeBlock)
875 {
876 return_ACPI_STATUS (AE_NULL_OBJECT);
877 }
878
879 /* Delete the GPE block (but not the DeviceObject) */
880
881 Status = AcpiEvDeleteGpeBlock (ObjDesc->Device.GpeBlock);
882 if (ACPI_SUCCESS (Status))
883 {
884 ObjDesc->Device.GpeBlock = NULL;
885 }
886
887UnlockAndExit:
888 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
889 return_ACPI_STATUS (Status);
890}
891
892ACPI_EXPORT_SYMBOL (AcpiRemoveGpeBlock)
893
894
895/*******************************************************************************
896 *
897 * FUNCTION: AcpiGetGpeDevice
898 *
899 * PARAMETERS: Index - System GPE index (0-CurrentGpeCount)
900 * GpeDevice - Where the parent GPE Device is returned
901 *
902 * RETURN: Status
903 *
904 * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
905 * gpe device indicates that the gpe number is contained in one of
906 * the FADT-defined gpe blocks. Otherwise, the GPE block device.
907 *
908 ******************************************************************************/
909
910ACPI_STATUS
911AcpiGetGpeDevice (
912 UINT32 Index,
913 ACPI_HANDLE *GpeDevice)
914{
915 ACPI_GPE_DEVICE_INFO Info;
916 ACPI_STATUS Status;
917
918
919 ACPI_FUNCTION_TRACE (AcpiGetGpeDevice);
920
921
922 if (!GpeDevice)
923 {
924 return_ACPI_STATUS (AE_BAD_PARAMETER);
925 }
926
927 if (Index >= AcpiCurrentGpeCount)
928 {
929 return_ACPI_STATUS (AE_NOT_EXIST);
930 }
931
932 /* Setup and walk the GPE list */
933
934 Info.Index = Index;
935 Info.Status = AE_NOT_EXIST;
936 Info.GpeDevice = NULL;
937 Info.NextBlockBaseIndex = 0;
938
939 Status = AcpiEvWalkGpeList (AcpiEvGetGpeDevice, &Info);
940 if (ACPI_FAILURE (Status))
941 {
942 return_ACPI_STATUS (Status);
943 }
944
945 *GpeDevice = ACPI_CAST_PTR (ACPI_HANDLE, Info.GpeDevice);
946 return_ACPI_STATUS (Info.Status);
947}
948
949ACPI_EXPORT_SYMBOL (AcpiGetGpeDevice)
950
951#endif /* !ACPI_REDUCED_HARDWARE */
416 if (NewNotify)
417 {
418 ACPI_FREE (NewNotify);
419 }
420 return_ACPI_STATUS (Status);
421}
422
423ACPI_EXPORT_SYMBOL (AcpiSetupGpeForWake)
424
425
426/*******************************************************************************
427 *
428 * FUNCTION: AcpiSetGpeWakeMask
429 *
430 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
431 * GpeNumber - GPE level within the GPE block
432 * Action - Enable or Disable
433 *
434 * RETURN: Status
435 *
436 * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must
437 * already be marked as a WAKE GPE.
438 *
439 ******************************************************************************/
440
441ACPI_STATUS
442AcpiSetGpeWakeMask (
443 ACPI_HANDLE GpeDevice,
444 UINT32 GpeNumber,
445 UINT8 Action)
446{
447 ACPI_STATUS Status = AE_OK;
448 ACPI_GPE_EVENT_INFO *GpeEventInfo;
449 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
450 ACPI_CPU_FLAGS Flags;
451 UINT32 RegisterBit;
452
453
454 ACPI_FUNCTION_TRACE (AcpiSetGpeWakeMask);
455
456
457 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
458
459 /*
460 * Ensure that we have a valid GPE number and that this GPE is in
461 * fact a wake GPE
462 */
463 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
464 if (!GpeEventInfo)
465 {
466 Status = AE_BAD_PARAMETER;
467 goto UnlockAndExit;
468 }
469
470 if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE))
471 {
472 Status = AE_TYPE;
473 goto UnlockAndExit;
474 }
475
476 GpeRegisterInfo = GpeEventInfo->RegisterInfo;
477 if (!GpeRegisterInfo)
478 {
479 Status = AE_NOT_EXIST;
480 goto UnlockAndExit;
481 }
482
483 RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo, GpeRegisterInfo);
484
485 /* Perform the action */
486
487 switch (Action)
488 {
489 case ACPI_GPE_ENABLE:
490 ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
491 break;
492
493 case ACPI_GPE_DISABLE:
494 ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
495 break;
496
497 default:
498 ACPI_ERROR ((AE_INFO, "%u, Invalid action", Action));
499 Status = AE_BAD_PARAMETER;
500 break;
501 }
502
503UnlockAndExit:
504 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
505 return_ACPI_STATUS (Status);
506}
507
508ACPI_EXPORT_SYMBOL (AcpiSetGpeWakeMask)
509
510
511/*******************************************************************************
512 *
513 * FUNCTION: AcpiClearGpe
514 *
515 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
516 * GpeNumber - GPE level within the GPE block
517 *
518 * RETURN: Status
519 *
520 * DESCRIPTION: Clear an ACPI event (general purpose)
521 *
522 ******************************************************************************/
523
524ACPI_STATUS
525AcpiClearGpe (
526 ACPI_HANDLE GpeDevice,
527 UINT32 GpeNumber)
528{
529 ACPI_STATUS Status = AE_OK;
530 ACPI_GPE_EVENT_INFO *GpeEventInfo;
531 ACPI_CPU_FLAGS Flags;
532
533
534 ACPI_FUNCTION_TRACE (AcpiClearGpe);
535
536
537 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
538
539 /* Ensure that we have a valid GPE number */
540
541 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
542 if (!GpeEventInfo)
543 {
544 Status = AE_BAD_PARAMETER;
545 goto UnlockAndExit;
546 }
547
548 Status = AcpiHwClearGpe (GpeEventInfo);
549
550UnlockAndExit:
551 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
552 return_ACPI_STATUS (Status);
553}
554
555ACPI_EXPORT_SYMBOL (AcpiClearGpe)
556
557
558/*******************************************************************************
559 *
560 * FUNCTION: AcpiGetGpeStatus
561 *
562 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
563 * GpeNumber - GPE level within the GPE block
564 * EventStatus - Where the current status of the event
565 * will be returned
566 *
567 * RETURN: Status
568 *
569 * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled)
570 *
571 ******************************************************************************/
572
573ACPI_STATUS
574AcpiGetGpeStatus (
575 ACPI_HANDLE GpeDevice,
576 UINT32 GpeNumber,
577 ACPI_EVENT_STATUS *EventStatus)
578{
579 ACPI_STATUS Status = AE_OK;
580 ACPI_GPE_EVENT_INFO *GpeEventInfo;
581 ACPI_CPU_FLAGS Flags;
582
583
584 ACPI_FUNCTION_TRACE (AcpiGetGpeStatus);
585
586
587 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
588
589 /* Ensure that we have a valid GPE number */
590
591 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
592 if (!GpeEventInfo)
593 {
594 Status = AE_BAD_PARAMETER;
595 goto UnlockAndExit;
596 }
597
598 /* Obtain status on the requested GPE number */
599
600 Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus);
601
602UnlockAndExit:
603 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
604 return_ACPI_STATUS (Status);
605}
606
607ACPI_EXPORT_SYMBOL (AcpiGetGpeStatus)
608
609
610/*******************************************************************************
611 *
612 * FUNCTION: AcpiFinishGpe
613 *
614 * PARAMETERS: GpeDevice - Namespace node for the GPE Block
615 * (NULL for FADT defined GPEs)
616 * GpeNumber - GPE level within the GPE block
617 *
618 * RETURN: Status
619 *
620 * DESCRIPTION: Clear and conditionally reenable a GPE. This completes the GPE
621 * processing. Intended for use by asynchronous host-installed
622 * GPE handlers. The GPE is only reenabled if the EnableForRun bit
623 * is set in the GPE info.
624 *
625 ******************************************************************************/
626
627ACPI_STATUS
628AcpiFinishGpe (
629 ACPI_HANDLE GpeDevice,
630 UINT32 GpeNumber)
631{
632 ACPI_GPE_EVENT_INFO *GpeEventInfo;
633 ACPI_STATUS Status;
634 ACPI_CPU_FLAGS Flags;
635
636
637 ACPI_FUNCTION_TRACE (AcpiFinishGpe);
638
639
640 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
641
642 /* Ensure that we have a valid GPE number */
643
644 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
645 if (!GpeEventInfo)
646 {
647 Status = AE_BAD_PARAMETER;
648 goto UnlockAndExit;
649 }
650
651 Status = AcpiEvFinishGpe (GpeEventInfo);
652
653UnlockAndExit:
654 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
655 return_ACPI_STATUS (Status);
656}
657
658ACPI_EXPORT_SYMBOL (AcpiFinishGpe)
659
660
661/******************************************************************************
662 *
663 * FUNCTION: AcpiDisableAllGpes
664 *
665 * PARAMETERS: None
666 *
667 * RETURN: Status
668 *
669 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
670 *
671 ******************************************************************************/
672
673ACPI_STATUS
674AcpiDisableAllGpes (
675 void)
676{
677 ACPI_STATUS Status;
678
679
680 ACPI_FUNCTION_TRACE (AcpiDisableAllGpes);
681
682
683 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
684 if (ACPI_FAILURE (Status))
685 {
686 return_ACPI_STATUS (Status);
687 }
688
689 Status = AcpiHwDisableAllGpes ();
690 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
691
692 return_ACPI_STATUS (Status);
693}
694
695ACPI_EXPORT_SYMBOL (AcpiDisableAllGpes)
696
697
698/******************************************************************************
699 *
700 * FUNCTION: AcpiEnableAllRuntimeGpes
701 *
702 * PARAMETERS: None
703 *
704 * RETURN: Status
705 *
706 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
707 *
708 ******************************************************************************/
709
710ACPI_STATUS
711AcpiEnableAllRuntimeGpes (
712 void)
713{
714 ACPI_STATUS Status;
715
716
717 ACPI_FUNCTION_TRACE (AcpiEnableAllRuntimeGpes);
718
719
720 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
721 if (ACPI_FAILURE (Status))
722 {
723 return_ACPI_STATUS (Status);
724 }
725
726 Status = AcpiHwEnableAllRuntimeGpes ();
727 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
728
729 return_ACPI_STATUS (Status);
730}
731
732ACPI_EXPORT_SYMBOL (AcpiEnableAllRuntimeGpes)
733
734
735/*******************************************************************************
736 *
737 * FUNCTION: AcpiInstallGpeBlock
738 *
739 * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device
740 * GpeBlockAddress - Address and SpaceID
741 * RegisterCount - Number of GPE register pairs in the block
742 * InterruptNumber - H/W interrupt for the block
743 *
744 * RETURN: Status
745 *
746 * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not
747 * enabled here.
748 *
749 ******************************************************************************/
750
751ACPI_STATUS
752AcpiInstallGpeBlock (
753 ACPI_HANDLE GpeDevice,
754 ACPI_GENERIC_ADDRESS *GpeBlockAddress,
755 UINT32 RegisterCount,
756 UINT32 InterruptNumber)
757{
758 ACPI_STATUS Status;
759 ACPI_OPERAND_OBJECT *ObjDesc;
760 ACPI_NAMESPACE_NODE *Node;
761 ACPI_GPE_BLOCK_INFO *GpeBlock;
762
763
764 ACPI_FUNCTION_TRACE (AcpiInstallGpeBlock);
765
766
767 if ((!GpeDevice) ||
768 (!GpeBlockAddress) ||
769 (!RegisterCount))
770 {
771 return_ACPI_STATUS (AE_BAD_PARAMETER);
772 }
773
774 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
775 if (ACPI_FAILURE (Status))
776 {
777 return (Status);
778 }
779
780 Node = AcpiNsValidateHandle (GpeDevice);
781 if (!Node)
782 {
783 Status = AE_BAD_PARAMETER;
784 goto UnlockAndExit;
785 }
786
787 /*
788 * For user-installed GPE Block Devices, the GpeBlockBaseNumber
789 * is always zero
790 */
791 Status = AcpiEvCreateGpeBlock (Node, GpeBlockAddress, RegisterCount,
792 0, InterruptNumber, &GpeBlock);
793 if (ACPI_FAILURE (Status))
794 {
795 goto UnlockAndExit;
796 }
797
798 /* Install block in the DeviceObject attached to the node */
799
800 ObjDesc = AcpiNsGetAttachedObject (Node);
801 if (!ObjDesc)
802 {
803 /*
804 * No object, create a new one (Device nodes do not always have
805 * an attached object)
806 */
807 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_DEVICE);
808 if (!ObjDesc)
809 {
810 Status = AE_NO_MEMORY;
811 goto UnlockAndExit;
812 }
813
814 Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_DEVICE);
815
816 /* Remove local reference to the object */
817
818 AcpiUtRemoveReference (ObjDesc);
819 if (ACPI_FAILURE (Status))
820 {
821 goto UnlockAndExit;
822 }
823 }
824
825 /* Now install the GPE block in the DeviceObject */
826
827 ObjDesc->Device.GpeBlock = GpeBlock;
828
829
830UnlockAndExit:
831 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
832 return_ACPI_STATUS (Status);
833}
834
835ACPI_EXPORT_SYMBOL (AcpiInstallGpeBlock)
836
837
838/*******************************************************************************
839 *
840 * FUNCTION: AcpiRemoveGpeBlock
841 *
842 * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device
843 *
844 * RETURN: Status
845 *
846 * DESCRIPTION: Remove a previously installed block of GPE registers
847 *
848 ******************************************************************************/
849
850ACPI_STATUS
851AcpiRemoveGpeBlock (
852 ACPI_HANDLE GpeDevice)
853{
854 ACPI_OPERAND_OBJECT *ObjDesc;
855 ACPI_STATUS Status;
856 ACPI_NAMESPACE_NODE *Node;
857
858
859 ACPI_FUNCTION_TRACE (AcpiRemoveGpeBlock);
860
861
862 if (!GpeDevice)
863 {
864 return_ACPI_STATUS (AE_BAD_PARAMETER);
865 }
866
867 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
868 if (ACPI_FAILURE (Status))
869 {
870 return (Status);
871 }
872
873 Node = AcpiNsValidateHandle (GpeDevice);
874 if (!Node)
875 {
876 Status = AE_BAD_PARAMETER;
877 goto UnlockAndExit;
878 }
879
880 /* Get the DeviceObject attached to the node */
881
882 ObjDesc = AcpiNsGetAttachedObject (Node);
883 if (!ObjDesc ||
884 !ObjDesc->Device.GpeBlock)
885 {
886 return_ACPI_STATUS (AE_NULL_OBJECT);
887 }
888
889 /* Delete the GPE block (but not the DeviceObject) */
890
891 Status = AcpiEvDeleteGpeBlock (ObjDesc->Device.GpeBlock);
892 if (ACPI_SUCCESS (Status))
893 {
894 ObjDesc->Device.GpeBlock = NULL;
895 }
896
897UnlockAndExit:
898 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
899 return_ACPI_STATUS (Status);
900}
901
902ACPI_EXPORT_SYMBOL (AcpiRemoveGpeBlock)
903
904
905/*******************************************************************************
906 *
907 * FUNCTION: AcpiGetGpeDevice
908 *
909 * PARAMETERS: Index - System GPE index (0-CurrentGpeCount)
910 * GpeDevice - Where the parent GPE Device is returned
911 *
912 * RETURN: Status
913 *
914 * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
915 * gpe device indicates that the gpe number is contained in one of
916 * the FADT-defined gpe blocks. Otherwise, the GPE block device.
917 *
918 ******************************************************************************/
919
920ACPI_STATUS
921AcpiGetGpeDevice (
922 UINT32 Index,
923 ACPI_HANDLE *GpeDevice)
924{
925 ACPI_GPE_DEVICE_INFO Info;
926 ACPI_STATUS Status;
927
928
929 ACPI_FUNCTION_TRACE (AcpiGetGpeDevice);
930
931
932 if (!GpeDevice)
933 {
934 return_ACPI_STATUS (AE_BAD_PARAMETER);
935 }
936
937 if (Index >= AcpiCurrentGpeCount)
938 {
939 return_ACPI_STATUS (AE_NOT_EXIST);
940 }
941
942 /* Setup and walk the GPE list */
943
944 Info.Index = Index;
945 Info.Status = AE_NOT_EXIST;
946 Info.GpeDevice = NULL;
947 Info.NextBlockBaseIndex = 0;
948
949 Status = AcpiEvWalkGpeList (AcpiEvGetGpeDevice, &Info);
950 if (ACPI_FAILURE (Status))
951 {
952 return_ACPI_STATUS (Status);
953 }
954
955 *GpeDevice = ACPI_CAST_PTR (ACPI_HANDLE, Info.GpeDevice);
956 return_ACPI_STATUS (Info.Status);
957}
958
959ACPI_EXPORT_SYMBOL (AcpiGetGpeDevice)
960
961#endif /* !ACPI_REDUCED_HARDWARE */