blob: 0fb9e94878d91a114e2ccf2f55f9e11eec19f3ab [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/******************************************************************************
2 *
3 * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable
4 *
5 *****************************************************************************/
6
7/*
Bob Moorea8357b02010-01-22 19:07:36 +08008 * Copyright (C) 2000 - 2010, Intel Corp.
Linus Torvalds1da177e2005-04-16 15:20:36 -07009 * 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
Linus Torvalds1da177e2005-04-16 15:20:36 -070044#include <acpi/acpi.h>
Len Browne2f7a772009-01-09 00:30:03 -050045#include "accommon.h"
46#include "acevents.h"
47#include "acnamesp.h"
48#include "actables.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070049
50#define _COMPONENT ACPI_EVENTS
Len Brown4be44fc2005-08-05 00:44:28 -040051ACPI_MODULE_NAME("evxfevnt")
Linus Torvalds1da177e2005-04-16 15:20:36 -070052
Bob Mooree97d6bf2008-12-30 09:45:17 +080053/* Local prototypes */
Bob Mooree4c1ebf2009-04-22 13:02:06 +080054static acpi_status
Bob Mooree97d6bf2008-12-30 09:45:17 +080055acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
56 struct acpi_gpe_block_info *gpe_block, void *context);
57
Linus Torvalds1da177e2005-04-16 15:20:36 -070058/*******************************************************************************
59 *
60 * FUNCTION: acpi_enable
61 *
62 * PARAMETERS: None
63 *
64 * RETURN: Status
65 *
66 * DESCRIPTION: Transfers the system into ACPI mode.
67 *
68 ******************************************************************************/
Bob Mooree97d6bf2008-12-30 09:45:17 +080069
Len Brown4be44fc2005-08-05 00:44:28 -040070acpi_status acpi_enable(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -070071{
Len Brownb430acb2010-05-06 17:41:08 -040072 acpi_status status;
Linus Torvalds1da177e2005-04-16 15:20:36 -070073
Bob Mooreb229cf92006-04-21 17:15:00 -040074 ACPI_FUNCTION_TRACE(acpi_enable);
Linus Torvalds1da177e2005-04-16 15:20:36 -070075
Bob Moorec8573032007-02-02 19:48:23 +030076 /* ACPI tables must be present */
77
78 if (!acpi_tb_tables_loaded()) {
79 return_ACPI_STATUS(AE_NO_ACPI_TABLES);
80 }
81
82 /* Check current mode */
83
Linus Torvalds1da177e2005-04-16 15:20:36 -070084 if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) {
Len Brown4be44fc2005-08-05 00:44:28 -040085 ACPI_DEBUG_PRINT((ACPI_DB_INIT,
86 "System is already in ACPI mode\n"));
Len Brownb430acb2010-05-06 17:41:08 -040087 return_ACPI_STATUS(AE_OK);
Linus Torvalds1da177e2005-04-16 15:20:36 -070088 }
89
Len Brownb430acb2010-05-06 17:41:08 -040090 /* Transition to ACPI mode */
91
92 status = acpi_hw_set_mode(ACPI_SYS_MODE_ACPI);
93 if (ACPI_FAILURE(status)) {
94 ACPI_ERROR((AE_INFO,
95 "Could not transition to ACPI mode"));
96 return_ACPI_STATUS(status);
97 }
98
99 /* Sanity check that transition succeeded */
100
101 if (acpi_hw_get_mode() != ACPI_SYS_MODE_ACPI) {
102 ACPI_ERROR((AE_INFO,
103 "Hardware did not enter ACPI mode"));
104 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
105 }
106
107 ACPI_DEBUG_PRINT((ACPI_DB_INIT,
108 "Transition to ACPI mode successful\n"));
109
110 return_ACPI_STATUS(AE_OK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111}
112
Bob Moore83135242006-10-03 00:00:00 -0400113ACPI_EXPORT_SYMBOL(acpi_enable)
114
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115/*******************************************************************************
116 *
117 * FUNCTION: acpi_disable
118 *
119 * PARAMETERS: None
120 *
121 * RETURN: Status
122 *
Robert Moore44f6c012005-04-18 22:49:35 -0400123 * DESCRIPTION: Transfers the system into LEGACY (non-ACPI) mode.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124 *
125 ******************************************************************************/
Len Brown4be44fc2005-08-05 00:44:28 -0400126acpi_status acpi_disable(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127{
Len Brown4be44fc2005-08-05 00:44:28 -0400128 acpi_status status = AE_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129
Bob Mooreb229cf92006-04-21 17:15:00 -0400130 ACPI_FUNCTION_TRACE(acpi_disable);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132 if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) {
Len Brown4be44fc2005-08-05 00:44:28 -0400133 ACPI_DEBUG_PRINT((ACPI_DB_INIT,
134 "System is already in legacy (non-ACPI) mode\n"));
135 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136 /* Transition to LEGACY mode */
137
Len Brown4be44fc2005-08-05 00:44:28 -0400138 status = acpi_hw_set_mode(ACPI_SYS_MODE_LEGACY);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700139
Len Brown4be44fc2005-08-05 00:44:28 -0400140 if (ACPI_FAILURE(status)) {
Bob Mooreb8e4d892006-01-27 16:43:00 -0500141 ACPI_ERROR((AE_INFO,
142 "Could not exit ACPI mode to legacy mode"));
Len Brown4be44fc2005-08-05 00:44:28 -0400143 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144 }
145
Len Brown4be44fc2005-08-05 00:44:28 -0400146 ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI mode disabled\n"));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700147 }
148
Len Brown4be44fc2005-08-05 00:44:28 -0400149 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150}
151
Bob Moore83135242006-10-03 00:00:00 -0400152ACPI_EXPORT_SYMBOL(acpi_disable)
153
Linus Torvalds1da177e2005-04-16 15:20:36 -0700154/*******************************************************************************
155 *
156 * FUNCTION: acpi_enable_event
157 *
158 * PARAMETERS: Event - The fixed eventto be enabled
159 * Flags - Reserved
160 *
161 * RETURN: Status
162 *
163 * DESCRIPTION: Enable an ACPI event (fixed)
164 *
165 ******************************************************************************/
Len Brown4be44fc2005-08-05 00:44:28 -0400166acpi_status acpi_enable_event(u32 event, u32 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700167{
Len Brown4be44fc2005-08-05 00:44:28 -0400168 acpi_status status = AE_OK;
169 u32 value;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170
Bob Mooreb229cf92006-04-21 17:15:00 -0400171 ACPI_FUNCTION_TRACE(acpi_enable_event);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172
173 /* Decode the Fixed Event */
174
175 if (event > ACPI_EVENT_MAX) {
Len Brown4be44fc2005-08-05 00:44:28 -0400176 return_ACPI_STATUS(AE_BAD_PARAMETER);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700177 }
178
179 /*
Bob Moore9f15fc62008-11-12 16:01:56 +0800180 * Enable the requested fixed event (by writing a one to the enable
181 * register bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182 */
Len Brown4be44fc2005-08-05 00:44:28 -0400183 status =
Bob Moore50ffba12009-02-23 15:02:07 +0800184 acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
Bob Moore768aaaf2009-03-06 09:49:25 +0800185 enable_register_id, ACPI_ENABLE_EVENT);
Len Brown4be44fc2005-08-05 00:44:28 -0400186 if (ACPI_FAILURE(status)) {
187 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188 }
189
190 /* Make sure that the hardware responded */
191
Len Brown4be44fc2005-08-05 00:44:28 -0400192 status =
Bob Moore50ffba12009-02-23 15:02:07 +0800193 acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
194 enable_register_id, &value);
Len Brown4be44fc2005-08-05 00:44:28 -0400195 if (ACPI_FAILURE(status)) {
196 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197 }
198
199 if (value != 1) {
Bob Mooreb8e4d892006-01-27 16:43:00 -0500200 ACPI_ERROR((AE_INFO,
201 "Could not enable %s event",
202 acpi_ut_get_event_name(event)));
Len Brown4be44fc2005-08-05 00:44:28 -0400203 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204 }
205
Len Brown4be44fc2005-08-05 00:44:28 -0400206 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700207}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208
Bob Moore83135242006-10-03 00:00:00 -0400209ACPI_EXPORT_SYMBOL(acpi_enable_event)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210
211/*******************************************************************************
212 *
Rafael J. Wysockie8b6f972010-06-25 01:18:39 +0200213 * FUNCTION: acpi_gpe_wakeup
214 *
215 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
216 * gpe_number - GPE level within the GPE block
217 * Action - Enable or Disable
218 *
219 * RETURN: Status
220 *
221 * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit.
222 *
223 ******************************************************************************/
224acpi_status acpi_gpe_wakeup(acpi_handle gpe_device, u32 gpe_number, u8 action)
225{
226 acpi_status status = AE_OK;
227 struct acpi_gpe_event_info *gpe_event_info;
228 struct acpi_gpe_register_info *gpe_register_info;
229 acpi_cpu_flags flags;
230 u32 register_bit;
231
232 ACPI_FUNCTION_TRACE(acpi_gpe_wakeup);
233
234 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
235
236 /* Ensure that we have a valid GPE number */
237
238 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
Rafael J. Wysocki9ce10df2010-07-08 00:45:34 +0200239 if (!gpe_event_info || !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
Rafael J. Wysockie8b6f972010-06-25 01:18:39 +0200240 status = AE_BAD_PARAMETER;
241 goto unlock_and_exit;
242 }
243
244 gpe_register_info = gpe_event_info->register_info;
245 if (!gpe_register_info) {
246 status = AE_NOT_EXIST;
247 goto unlock_and_exit;
248 }
249
250 register_bit =
251 acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info);
252
253 /* Perform the action */
254
255 switch (action) {
256 case ACPI_GPE_ENABLE:
Rafael J. Wysockia44061a2010-07-01 10:11:45 +0800257 ACPI_SET_BIT(gpe_register_info->enable_for_wake,
258 (u8)register_bit);
Rafael J. Wysockie8b6f972010-06-25 01:18:39 +0200259 break;
260
261 case ACPI_GPE_DISABLE:
262 ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake,
Rafael J. Wysockia44061a2010-07-01 10:11:45 +0800263 (u8)register_bit);
Rafael J. Wysockie8b6f972010-06-25 01:18:39 +0200264 break;
265
266 default:
267 ACPI_ERROR((AE_INFO, "%u, Invalid action", action));
268 status = AE_BAD_PARAMETER;
269 break;
270 }
271
272unlock_and_exit:
273 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
274 return_ACPI_STATUS(status);
275}
276
277ACPI_EXPORT_SYMBOL(acpi_gpe_wakeup)
278
279/*******************************************************************************
280 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700281 * FUNCTION: acpi_enable_gpe
282 *
Lin Ming0f849d22010-04-06 14:52:37 +0800283 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
Linus Torvalds1da177e2005-04-16 15:20:36 -0700284 * gpe_number - GPE level within the GPE block
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285 *
286 * RETURN: Status
287 *
Lin Ming0f849d22010-04-06 14:52:37 +0800288 * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
Rafael J. Wysockia44061a2010-07-01 10:11:45 +0800289 * hardware-enabled.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290 *
291 ******************************************************************************/
Rafael J. Wysockia44061a2010-07-01 10:11:45 +0800292acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293{
Rafael J. Wysocki28f4f8a2010-08-03 23:55:14 +0200294 acpi_status status = AE_BAD_PARAMETER;
Len Brown4be44fc2005-08-05 00:44:28 -0400295 struct acpi_gpe_event_info *gpe_event_info;
Lin Ming0f849d22010-04-06 14:52:37 +0800296 acpi_cpu_flags flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700297
Bob Mooreb229cf92006-04-21 17:15:00 -0400298 ACPI_FUNCTION_TRACE(acpi_enable_gpe);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299
Alexey Starikovskiy0b7084a2008-10-25 21:48:46 +0400300 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301
302 /* Ensure that we have a valid GPE number */
303
Len Brown4be44fc2005-08-05 00:44:28 -0400304 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
Rafael J. Wysocki28f4f8a2010-08-03 23:55:14 +0200305 if (gpe_event_info) {
306 status = acpi_raw_enable_gpe(gpe_event_info);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700307 }
308
Alexey Starikovskiy0b7084a2008-10-25 21:48:46 +0400309 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
Len Brown4be44fc2005-08-05 00:44:28 -0400310 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700311}
Bob Moore83135242006-10-03 00:00:00 -0400312ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700313
314/*******************************************************************************
315 *
316 * FUNCTION: acpi_disable_gpe
317 *
Lin Ming0f849d22010-04-06 14:52:37 +0800318 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
Linus Torvalds1da177e2005-04-16 15:20:36 -0700319 * gpe_number - GPE level within the GPE block
Linus Torvalds1da177e2005-04-16 15:20:36 -0700320 *
321 * RETURN: Status
322 *
Lin Ming0f849d22010-04-06 14:52:37 +0800323 * DESCRIPTION: Remove a reference to a GPE. When the last reference is
324 * removed, only then is the GPE disabled (for runtime GPEs), or
325 * the GPE mask bit disabled (for wake GPEs)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326 *
327 ******************************************************************************/
Rafael J. Wysockia44061a2010-07-01 10:11:45 +0800328acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700329{
Rafael J. Wysocki28f4f8a2010-08-03 23:55:14 +0200330 acpi_status status = AE_BAD_PARAMETER;
Len Brown4be44fc2005-08-05 00:44:28 -0400331 struct acpi_gpe_event_info *gpe_event_info;
Lin Ming0f849d22010-04-06 14:52:37 +0800332 acpi_cpu_flags flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700333
Bob Mooreb229cf92006-04-21 17:15:00 -0400334 ACPI_FUNCTION_TRACE(acpi_disable_gpe);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700335
Alexey Starikovskiy0b7084a2008-10-25 21:48:46 +0400336 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
Lin Ming0f849d22010-04-06 14:52:37 +0800337
Linus Torvalds1da177e2005-04-16 15:20:36 -0700338 /* Ensure that we have a valid GPE number */
339
Len Brown4be44fc2005-08-05 00:44:28 -0400340 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
Rafael J. Wysocki28f4f8a2010-08-03 23:55:14 +0200341 if (gpe_event_info) {
342 status = acpi_raw_disable_gpe(gpe_event_info) ;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700343 }
344
Alexey Starikovskiy0b7084a2008-10-25 21:48:46 +0400345 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
Len Brown4be44fc2005-08-05 00:44:28 -0400346 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347}
Bob Moore83135242006-10-03 00:00:00 -0400348ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
349
Linus Torvalds1da177e2005-04-16 15:20:36 -0700350/*******************************************************************************
351 *
Rafael J. Wysocki98746472010-07-08 00:43:36 +0200352 * FUNCTION: acpi_gpe_can_wake
353 *
354 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
355 * gpe_number - GPE level within the GPE block
356 *
357 * RETURN: Status
358 *
359 * DESCRIPTION: Set the ACPI_GPE_CAN_WAKE flag for the given GPE. If the GPE
360 * has a corresponding method and is currently enabled, disable it
361 * (GPEs with corresponding methods are enabled unconditionally
362 * during initialization, but GPEs that can wake up are expected
363 * to be initially disabled).
364 *
365 ******************************************************************************/
366acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number)
367{
368 acpi_status status = AE_OK;
369 struct acpi_gpe_event_info *gpe_event_info;
370 acpi_cpu_flags flags;
Rafael J. Wysocki98746472010-07-08 00:43:36 +0200371
372 ACPI_FUNCTION_TRACE(acpi_gpe_can_wake);
373
374 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
375
376 /* Ensure that we have a valid GPE number */
377
378 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
379 if (!gpe_event_info) {
380 status = AE_BAD_PARAMETER;
381 goto unlock_and_exit;
382 }
383
384 if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) {
385 goto unlock_and_exit;
386 }
387
388 gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
Rafael J. Wysocki28f4f8a2010-08-03 23:55:14 +0200389 if (gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD) {
390 (void)acpi_raw_disable_gpe(gpe_event_info);
391 }
Rafael J. Wysocki98746472010-07-08 00:43:36 +0200392
393unlock_and_exit:
394 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
Rafael J. Wysocki98746472010-07-08 00:43:36 +0200395 return_ACPI_STATUS(status);
396}
397ACPI_EXPORT_SYMBOL(acpi_gpe_can_wake)
398
399/*******************************************************************************
400 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401 * FUNCTION: acpi_disable_event
402 *
403 * PARAMETERS: Event - The fixed eventto be enabled
404 * Flags - Reserved
405 *
406 * RETURN: Status
407 *
408 * DESCRIPTION: Disable an ACPI event (fixed)
409 *
410 ******************************************************************************/
Len Brown4be44fc2005-08-05 00:44:28 -0400411acpi_status acpi_disable_event(u32 event, u32 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412{
Len Brown4be44fc2005-08-05 00:44:28 -0400413 acpi_status status = AE_OK;
414 u32 value;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415
Bob Mooreb229cf92006-04-21 17:15:00 -0400416 ACPI_FUNCTION_TRACE(acpi_disable_event);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417
418 /* Decode the Fixed Event */
419
420 if (event > ACPI_EVENT_MAX) {
Len Brown4be44fc2005-08-05 00:44:28 -0400421 return_ACPI_STATUS(AE_BAD_PARAMETER);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422 }
423
424 /*
Bob Moore9f15fc62008-11-12 16:01:56 +0800425 * Disable the requested fixed event (by writing a zero to the enable
426 * register bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427 */
Len Brown4be44fc2005-08-05 00:44:28 -0400428 status =
Bob Moore50ffba12009-02-23 15:02:07 +0800429 acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
Bob Moore768aaaf2009-03-06 09:49:25 +0800430 enable_register_id, ACPI_DISABLE_EVENT);
Len Brown4be44fc2005-08-05 00:44:28 -0400431 if (ACPI_FAILURE(status)) {
432 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433 }
434
Len Brown4be44fc2005-08-05 00:44:28 -0400435 status =
Bob Moore50ffba12009-02-23 15:02:07 +0800436 acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
437 enable_register_id, &value);
Len Brown4be44fc2005-08-05 00:44:28 -0400438 if (ACPI_FAILURE(status)) {
439 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440 }
441
442 if (value != 0) {
Bob Mooreb8e4d892006-01-27 16:43:00 -0500443 ACPI_ERROR((AE_INFO,
444 "Could not disable %s events",
445 acpi_ut_get_event_name(event)));
Len Brown4be44fc2005-08-05 00:44:28 -0400446 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447 }
448
Len Brown4be44fc2005-08-05 00:44:28 -0400449 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700450}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451
Bob Moore83135242006-10-03 00:00:00 -0400452ACPI_EXPORT_SYMBOL(acpi_disable_event)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453
454/*******************************************************************************
455 *
456 * FUNCTION: acpi_clear_event
457 *
458 * PARAMETERS: Event - The fixed event to be cleared
459 *
460 * RETURN: Status
461 *
462 * DESCRIPTION: Clear an ACPI event (fixed)
463 *
464 ******************************************************************************/
Len Brown4be44fc2005-08-05 00:44:28 -0400465acpi_status acpi_clear_event(u32 event)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466{
Len Brown4be44fc2005-08-05 00:44:28 -0400467 acpi_status status = AE_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700468
Bob Mooreb229cf92006-04-21 17:15:00 -0400469 ACPI_FUNCTION_TRACE(acpi_clear_event);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470
471 /* Decode the Fixed Event */
472
473 if (event > ACPI_EVENT_MAX) {
Len Brown4be44fc2005-08-05 00:44:28 -0400474 return_ACPI_STATUS(AE_BAD_PARAMETER);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700475 }
476
477 /*
Bob Moore9f15fc62008-11-12 16:01:56 +0800478 * Clear the requested fixed event (By writing a one to the status
479 * register bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480 */
Len Brown4be44fc2005-08-05 00:44:28 -0400481 status =
Bob Moore50ffba12009-02-23 15:02:07 +0800482 acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
Bob Moore768aaaf2009-03-06 09:49:25 +0800483 status_register_id, ACPI_CLEAR_STATUS);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700484
Len Brown4be44fc2005-08-05 00:44:28 -0400485 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700486}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487
Bob Moore83135242006-10-03 00:00:00 -0400488ACPI_EXPORT_SYMBOL(acpi_clear_event)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489
490/*******************************************************************************
491 *
492 * FUNCTION: acpi_clear_gpe
493 *
Lin Ming0f849d22010-04-06 14:52:37 +0800494 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
Linus Torvalds1da177e2005-04-16 15:20:36 -0700495 * gpe_number - GPE level within the GPE block
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496 *
497 * RETURN: Status
498 *
499 * DESCRIPTION: Clear an ACPI event (general purpose)
500 *
501 ******************************************************************************/
Lin Ming0f849d22010-04-06 14:52:37 +0800502acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503{
Len Brown4be44fc2005-08-05 00:44:28 -0400504 acpi_status status = AE_OK;
505 struct acpi_gpe_event_info *gpe_event_info;
Lin Ming0f849d22010-04-06 14:52:37 +0800506 acpi_cpu_flags flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507
Bob Mooreb229cf92006-04-21 17:15:00 -0400508 ACPI_FUNCTION_TRACE(acpi_clear_gpe);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509
Lin Ming0f849d22010-04-06 14:52:37 +0800510 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511
512 /* Ensure that we have a valid GPE number */
513
Len Brown4be44fc2005-08-05 00:44:28 -0400514 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700515 if (!gpe_event_info) {
516 status = AE_BAD_PARAMETER;
517 goto unlock_and_exit;
518 }
519
Len Brown4be44fc2005-08-05 00:44:28 -0400520 status = acpi_hw_clear_gpe(gpe_event_info);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521
Len Brown4be44fc2005-08-05 00:44:28 -0400522 unlock_and_exit:
Lin Ming0f849d22010-04-06 14:52:37 +0800523 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
Len Brown4be44fc2005-08-05 00:44:28 -0400524 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525}
526
Bob Moore83135242006-10-03 00:00:00 -0400527ACPI_EXPORT_SYMBOL(acpi_clear_gpe)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528/*******************************************************************************
529 *
530 * FUNCTION: acpi_get_event_status
531 *
532 * PARAMETERS: Event - The fixed event
Robert Moore44f6c012005-04-18 22:49:35 -0400533 * event_status - Where the current status of the event will
Linus Torvalds1da177e2005-04-16 15:20:36 -0700534 * be returned
535 *
536 * RETURN: Status
537 *
538 * DESCRIPTION: Obtains and returns the current status of the event
539 *
540 ******************************************************************************/
Len Brown4be44fc2005-08-05 00:44:28 -0400541acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542{
Len Brown4be44fc2005-08-05 00:44:28 -0400543 acpi_status status = AE_OK;
Zhang Rui71b58cb2008-06-20 09:42:47 +0800544 u32 value;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545
Bob Mooreb229cf92006-04-21 17:15:00 -0400546 ACPI_FUNCTION_TRACE(acpi_get_event_status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700547
548 if (!event_status) {
Len Brown4be44fc2005-08-05 00:44:28 -0400549 return_ACPI_STATUS(AE_BAD_PARAMETER);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700550 }
551
552 /* Decode the Fixed Event */
553
554 if (event > ACPI_EVENT_MAX) {
Len Brown4be44fc2005-08-05 00:44:28 -0400555 return_ACPI_STATUS(AE_BAD_PARAMETER);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556 }
557
558 /* Get the status of the requested fixed event */
559
Len Brown4be44fc2005-08-05 00:44:28 -0400560 status =
Bob Moore50ffba12009-02-23 15:02:07 +0800561 acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
Zhang Rui71b58cb2008-06-20 09:42:47 +0800562 enable_register_id, &value);
563 if (ACPI_FAILURE(status))
564 return_ACPI_STATUS(status);
565
566 *event_status = value;
567
568 status =
Bob Moore50ffba12009-02-23 15:02:07 +0800569 acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
Zhang Rui71b58cb2008-06-20 09:42:47 +0800570 status_register_id, &value);
571 if (ACPI_FAILURE(status))
572 return_ACPI_STATUS(status);
573
574 if (value)
575 *event_status |= ACPI_EVENT_FLAG_SET;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700576
Zhang Ruied206fa2008-10-27 14:01:02 -0700577 if (acpi_gbl_fixed_event_handlers[event].handler)
578 *event_status |= ACPI_EVENT_FLAG_HANDLE;
579
Len Brown4be44fc2005-08-05 00:44:28 -0400580 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581}
582
Bob Moore83135242006-10-03 00:00:00 -0400583ACPI_EXPORT_SYMBOL(acpi_get_event_status)
584
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585/*******************************************************************************
586 *
587 * FUNCTION: acpi_get_gpe_status
588 *
Lin Ming0f849d22010-04-06 14:52:37 +0800589 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590 * gpe_number - GPE level within the GPE block
Robert Moore44f6c012005-04-18 22:49:35 -0400591 * event_status - Where the current status of the event will
Linus Torvalds1da177e2005-04-16 15:20:36 -0700592 * be returned
593 *
594 * RETURN: Status
595 *
596 * DESCRIPTION: Get status of an event (general purpose)
597 *
598 ******************************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400600acpi_get_gpe_status(acpi_handle gpe_device,
Lin Ming0f849d22010-04-06 14:52:37 +0800601 u32 gpe_number, acpi_event_status *event_status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602{
Len Brown4be44fc2005-08-05 00:44:28 -0400603 acpi_status status = AE_OK;
604 struct acpi_gpe_event_info *gpe_event_info;
Lin Ming0f849d22010-04-06 14:52:37 +0800605 acpi_cpu_flags flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606
Bob Mooreb229cf92006-04-21 17:15:00 -0400607 ACPI_FUNCTION_TRACE(acpi_get_gpe_status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608
Lin Ming0f849d22010-04-06 14:52:37 +0800609 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610
611 /* Ensure that we have a valid GPE number */
612
Len Brown4be44fc2005-08-05 00:44:28 -0400613 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614 if (!gpe_event_info) {
615 status = AE_BAD_PARAMETER;
616 goto unlock_and_exit;
617 }
618
619 /* Obtain status on the requested GPE number */
620
Len Brown4be44fc2005-08-05 00:44:28 -0400621 status = acpi_hw_get_gpe_status(gpe_event_info, event_status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622
Zhang Ruied206fa2008-10-27 14:01:02 -0700623 if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)
624 *event_status |= ACPI_EVENT_FLAG_HANDLE;
625
Len Brown4be44fc2005-08-05 00:44:28 -0400626 unlock_and_exit:
Lin Ming0f849d22010-04-06 14:52:37 +0800627 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
Len Brown4be44fc2005-08-05 00:44:28 -0400628 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700629}
Bob Moore83135242006-10-03 00:00:00 -0400630
631ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700632/*******************************************************************************
633 *
634 * FUNCTION: acpi_install_gpe_block
635 *
636 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device
637 * gpe_block_address - Address and space_iD
638 * register_count - Number of GPE register pairs in the block
Robert Moore6f42ccf2005-05-13 00:00:00 -0400639 * interrupt_number - H/W interrupt for the block
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640 *
641 * RETURN: Status
642 *
643 * DESCRIPTION: Create and Install a block of GPE registers
644 *
645 ******************************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400647acpi_install_gpe_block(acpi_handle gpe_device,
648 struct acpi_generic_address *gpe_block_address,
649 u32 register_count, u32 interrupt_number)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650{
Len Brown4be44fc2005-08-05 00:44:28 -0400651 acpi_status status;
652 union acpi_operand_object *obj_desc;
653 struct acpi_namespace_node *node;
654 struct acpi_gpe_block_info *gpe_block;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700655
Bob Mooreb229cf92006-04-21 17:15:00 -0400656 ACPI_FUNCTION_TRACE(acpi_install_gpe_block);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657
Len Brown4be44fc2005-08-05 00:44:28 -0400658 if ((!gpe_device) || (!gpe_block_address) || (!register_count)) {
659 return_ACPI_STATUS(AE_BAD_PARAMETER);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660 }
661
Len Brown4be44fc2005-08-05 00:44:28 -0400662 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
663 if (ACPI_FAILURE(status)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664 return (status);
665 }
666
Bob Mooref24b6642009-12-11 14:57:00 +0800667 node = acpi_ns_validate_handle(gpe_device);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700668 if (!node) {
669 status = AE_BAD_PARAMETER;
670 goto unlock_and_exit;
671 }
672
673 /*
674 * For user-installed GPE Block Devices, the gpe_block_base_number
675 * is always zero
676 */
Len Brown4be44fc2005-08-05 00:44:28 -0400677 status =
678 acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0,
679 interrupt_number, &gpe_block);
680 if (ACPI_FAILURE(status)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681 goto unlock_and_exit;
682 }
683
Lin Ming0f849d22010-04-06 14:52:37 +0800684 /* Install block in the device_object attached to the node */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700685
Len Brown4be44fc2005-08-05 00:44:28 -0400686 obj_desc = acpi_ns_get_attached_object(node);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700687 if (!obj_desc) {
Bob Moore52fc0b02006-10-02 00:00:00 -0400688
Lin Ming0f849d22010-04-06 14:52:37 +0800689 /*
690 * No object, create a new one (Device nodes do not always have
691 * an attached object)
692 */
Len Brown4be44fc2005-08-05 00:44:28 -0400693 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700694 if (!obj_desc) {
695 status = AE_NO_MEMORY;
696 goto unlock_and_exit;
697 }
698
Len Brown4be44fc2005-08-05 00:44:28 -0400699 status =
700 acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700701
702 /* Remove local reference to the object */
703
Len Brown4be44fc2005-08-05 00:44:28 -0400704 acpi_ut_remove_reference(obj_desc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700705
Len Brown4be44fc2005-08-05 00:44:28 -0400706 if (ACPI_FAILURE(status)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700707 goto unlock_and_exit;
708 }
709 }
710
Lin Ming0f849d22010-04-06 14:52:37 +0800711 /* Now install the GPE block in the device_object */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700712
713 obj_desc->device.gpe_block = gpe_block;
714
Rafael J. Wysocki98746472010-07-08 00:43:36 +0200715 /* Enable the runtime GPEs in the new block */
Lin Ming0f849d22010-04-06 14:52:37 +0800716
717 status = acpi_ev_initialize_gpe_block(node, gpe_block);
718
Len Brown4be44fc2005-08-05 00:44:28 -0400719 unlock_and_exit:
720 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
721 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700723
Bob Moore83135242006-10-03 00:00:00 -0400724ACPI_EXPORT_SYMBOL(acpi_install_gpe_block)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700725
726/*******************************************************************************
727 *
728 * FUNCTION: acpi_remove_gpe_block
729 *
730 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device
731 *
732 * RETURN: Status
733 *
734 * DESCRIPTION: Remove a previously installed block of GPE registers
735 *
736 ******************************************************************************/
Len Brown4be44fc2005-08-05 00:44:28 -0400737acpi_status acpi_remove_gpe_block(acpi_handle gpe_device)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700738{
Len Brown4be44fc2005-08-05 00:44:28 -0400739 union acpi_operand_object *obj_desc;
740 acpi_status status;
741 struct acpi_namespace_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700742
Bob Mooreb229cf92006-04-21 17:15:00 -0400743 ACPI_FUNCTION_TRACE(acpi_remove_gpe_block);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700744
745 if (!gpe_device) {
Len Brown4be44fc2005-08-05 00:44:28 -0400746 return_ACPI_STATUS(AE_BAD_PARAMETER);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700747 }
748
Len Brown4be44fc2005-08-05 00:44:28 -0400749 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
750 if (ACPI_FAILURE(status)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700751 return (status);
752 }
753
Bob Mooref24b6642009-12-11 14:57:00 +0800754 node = acpi_ns_validate_handle(gpe_device);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700755 if (!node) {
756 status = AE_BAD_PARAMETER;
757 goto unlock_and_exit;
758 }
759
760 /* Get the device_object attached to the node */
761
Len Brown4be44fc2005-08-05 00:44:28 -0400762 obj_desc = acpi_ns_get_attached_object(node);
763 if (!obj_desc || !obj_desc->device.gpe_block) {
764 return_ACPI_STATUS(AE_NULL_OBJECT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765 }
766
767 /* Delete the GPE block (but not the device_object) */
768
Len Brown4be44fc2005-08-05 00:44:28 -0400769 status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block);
770 if (ACPI_SUCCESS(status)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771 obj_desc->device.gpe_block = NULL;
772 }
773
Len Brown4be44fc2005-08-05 00:44:28 -0400774 unlock_and_exit:
775 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
776 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700777}
Robert Moore44f6c012005-04-18 22:49:35 -0400778
Bob Moore83135242006-10-03 00:00:00 -0400779ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block)
Bob Mooree97d6bf2008-12-30 09:45:17 +0800780
781/*******************************************************************************
782 *
783 * FUNCTION: acpi_get_gpe_device
784 *
785 * PARAMETERS: Index - System GPE index (0-current_gpe_count)
786 * gpe_device - Where the parent GPE Device is returned
787 *
788 * RETURN: Status
789 *
790 * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
791 * gpe device indicates that the gpe number is contained in one of
792 * the FADT-defined gpe blocks. Otherwise, the GPE block device.
793 *
794 ******************************************************************************/
795acpi_status
796acpi_get_gpe_device(u32 index, acpi_handle *gpe_device)
797{
798 struct acpi_gpe_device_info info;
799 acpi_status status;
800
801 ACPI_FUNCTION_TRACE(acpi_get_gpe_device);
802
803 if (!gpe_device) {
804 return_ACPI_STATUS(AE_BAD_PARAMETER);
805 }
806
807 if (index >= acpi_current_gpe_count) {
808 return_ACPI_STATUS(AE_NOT_EXIST);
809 }
810
811 /* Setup and walk the GPE list */
812
813 info.index = index;
814 info.status = AE_NOT_EXIST;
815 info.gpe_device = NULL;
816 info.next_block_base_index = 0;
817
818 status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info);
819 if (ACPI_FAILURE(status)) {
820 return_ACPI_STATUS(status);
821 }
822
823 *gpe_device = info.gpe_device;
824 return_ACPI_STATUS(info.status);
825}
826
827ACPI_EXPORT_SYMBOL(acpi_get_gpe_device)
828
829/*******************************************************************************
830 *
831 * FUNCTION: acpi_ev_get_gpe_device
832 *
833 * PARAMETERS: GPE_WALK_CALLBACK
834 *
835 * RETURN: Status
836 *
837 * DESCRIPTION: Matches the input GPE index (0-current_gpe_count) with a GPE
838 * block device. NULL if the GPE is one of the FADT-defined GPEs.
839 *
840 ******************************************************************************/
Bob Mooree4c1ebf2009-04-22 13:02:06 +0800841static acpi_status
Bob Mooree97d6bf2008-12-30 09:45:17 +0800842acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
843 struct acpi_gpe_block_info *gpe_block, void *context)
844{
845 struct acpi_gpe_device_info *info = context;
846
847 /* Increment Index by the number of GPEs in this block */
848
Lin Ming0f849d22010-04-06 14:52:37 +0800849 info->next_block_base_index += gpe_block->gpe_count;
Bob Mooree97d6bf2008-12-30 09:45:17 +0800850
851 if (info->index < info->next_block_base_index) {
852 /*
853 * The GPE index is within this block, get the node. Leave the node
854 * NULL for the FADT-defined GPEs
855 */
856 if ((gpe_block->node)->type == ACPI_TYPE_DEVICE) {
857 info->gpe_device = gpe_block->node;
858 }
859
860 info->status = AE_OK;
861 return (AE_CTRL_END);
862 }
863
864 return (AE_OK);
865}
Bob Moore08ac07b2008-12-30 09:55:48 +0800866
867/******************************************************************************
868 *
869 * FUNCTION: acpi_disable_all_gpes
870 *
871 * PARAMETERS: None
872 *
873 * RETURN: Status
874 *
875 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
876 *
877 ******************************************************************************/
878
879acpi_status acpi_disable_all_gpes(void)
880{
881 acpi_status status;
882
883 ACPI_FUNCTION_TRACE(acpi_disable_all_gpes);
884
885 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
886 if (ACPI_FAILURE(status)) {
887 return_ACPI_STATUS(status);
888 }
889
890 status = acpi_hw_disable_all_gpes();
891 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
892
893 return_ACPI_STATUS(status);
894}
895
896/******************************************************************************
897 *
898 * FUNCTION: acpi_enable_all_runtime_gpes
899 *
900 * PARAMETERS: None
901 *
902 * RETURN: Status
903 *
904 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
905 *
906 ******************************************************************************/
907
908acpi_status acpi_enable_all_runtime_gpes(void)
909{
910 acpi_status status;
911
912 ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes);
913
914 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
915 if (ACPI_FAILURE(status)) {
916 return_ACPI_STATUS(status);
917 }
918
919 status = acpi_hw_enable_all_runtime_gpes();
920 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
921
922 return_ACPI_STATUS(status);
923}