blob: a3d148e4d39f381a2625ade191fd276eae54d107 [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 Moore4a90c7e2006-01-13 16:22:00 -05008 * Copyright (C) 2000 - 2006, R. Byron Moore
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>
45#include <acpi/acevents.h>
46#include <acpi/acnamesp.h>
47
48#define _COMPONENT ACPI_EVENTS
Len Brown4be44fc2005-08-05 00:44:28 -040049ACPI_MODULE_NAME("evxfevnt")
Linus Torvalds1da177e2005-04-16 15:20:36 -070050
51/*******************************************************************************
52 *
53 * FUNCTION: acpi_enable
54 *
55 * PARAMETERS: None
56 *
57 * RETURN: Status
58 *
59 * DESCRIPTION: Transfers the system into ACPI mode.
60 *
61 ******************************************************************************/
Len Brown4be44fc2005-08-05 00:44:28 -040062acpi_status acpi_enable(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -070063{
Len Brown4be44fc2005-08-05 00:44:28 -040064 acpi_status status = AE_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -070065
Bob Mooreb229cf92006-04-21 17:15:00 -040066 ACPI_FUNCTION_TRACE(acpi_enable);
Linus Torvalds1da177e2005-04-16 15:20:36 -070067
Linus Torvalds1da177e2005-04-16 15:20:36 -070068 if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) {
Len Brown4be44fc2005-08-05 00:44:28 -040069 ACPI_DEBUG_PRINT((ACPI_DB_INIT,
70 "System is already in ACPI mode\n"));
71 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -070072 /* Transition to ACPI mode */
73
Len Brown4be44fc2005-08-05 00:44:28 -040074 status = acpi_hw_set_mode(ACPI_SYS_MODE_ACPI);
75 if (ACPI_FAILURE(status)) {
Bob Mooreb8e4d892006-01-27 16:43:00 -050076 ACPI_ERROR((AE_INFO,
77 "Could not transition to ACPI mode"));
Len Brown4be44fc2005-08-05 00:44:28 -040078 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070079 }
80
Len Brown4be44fc2005-08-05 00:44:28 -040081 ACPI_DEBUG_PRINT((ACPI_DB_INIT,
82 "Transition to ACPI mode successful\n"));
Linus Torvalds1da177e2005-04-16 15:20:36 -070083 }
84
Len Brown4be44fc2005-08-05 00:44:28 -040085 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070086}
87
Bob Moore83135242006-10-03 00:00:00 -040088ACPI_EXPORT_SYMBOL(acpi_enable)
89
Linus Torvalds1da177e2005-04-16 15:20:36 -070090/*******************************************************************************
91 *
92 * FUNCTION: acpi_disable
93 *
94 * PARAMETERS: None
95 *
96 * RETURN: Status
97 *
Robert Moore44f6c012005-04-18 22:49:35 -040098 * DESCRIPTION: Transfers the system into LEGACY (non-ACPI) mode.
Linus Torvalds1da177e2005-04-16 15:20:36 -070099 *
100 ******************************************************************************/
Len Brown4be44fc2005-08-05 00:44:28 -0400101acpi_status acpi_disable(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102{
Len Brown4be44fc2005-08-05 00:44:28 -0400103 acpi_status status = AE_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104
Bob Mooreb229cf92006-04-21 17:15:00 -0400105 ACPI_FUNCTION_TRACE(acpi_disable);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107 if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) {
Len Brown4be44fc2005-08-05 00:44:28 -0400108 ACPI_DEBUG_PRINT((ACPI_DB_INIT,
109 "System is already in legacy (non-ACPI) mode\n"));
110 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111 /* Transition to LEGACY mode */
112
Len Brown4be44fc2005-08-05 00:44:28 -0400113 status = acpi_hw_set_mode(ACPI_SYS_MODE_LEGACY);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114
Len Brown4be44fc2005-08-05 00:44:28 -0400115 if (ACPI_FAILURE(status)) {
Bob Mooreb8e4d892006-01-27 16:43:00 -0500116 ACPI_ERROR((AE_INFO,
117 "Could not exit ACPI mode to legacy mode"));
Len Brown4be44fc2005-08-05 00:44:28 -0400118 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119 }
120
Len Brown4be44fc2005-08-05 00:44:28 -0400121 ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI mode disabled\n"));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122 }
123
Len Brown4be44fc2005-08-05 00:44:28 -0400124 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125}
126
Bob Moore83135242006-10-03 00:00:00 -0400127ACPI_EXPORT_SYMBOL(acpi_disable)
128
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129/*******************************************************************************
130 *
131 * FUNCTION: acpi_enable_event
132 *
133 * PARAMETERS: Event - The fixed eventto be enabled
134 * Flags - Reserved
135 *
136 * RETURN: Status
137 *
138 * DESCRIPTION: Enable an ACPI event (fixed)
139 *
140 ******************************************************************************/
Len Brown4be44fc2005-08-05 00:44:28 -0400141acpi_status acpi_enable_event(u32 event, u32 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142{
Len Brown4be44fc2005-08-05 00:44:28 -0400143 acpi_status status = AE_OK;
144 u32 value;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700145
Bob Mooreb229cf92006-04-21 17:15:00 -0400146 ACPI_FUNCTION_TRACE(acpi_enable_event);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700147
148 /* Decode the Fixed Event */
149
150 if (event > ACPI_EVENT_MAX) {
Len Brown4be44fc2005-08-05 00:44:28 -0400151 return_ACPI_STATUS(AE_BAD_PARAMETER);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700152 }
153
154 /*
155 * Enable the requested fixed event (by writing a one to the
156 * enable register bit)
157 */
Len Brown4be44fc2005-08-05 00:44:28 -0400158 status =
159 acpi_set_register(acpi_gbl_fixed_event_info[event].
Bob Moored8c71b62007-02-02 19:48:21 +0300160 enable_register_id, 1);
Len Brown4be44fc2005-08-05 00:44:28 -0400161 if (ACPI_FAILURE(status)) {
162 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700163 }
164
165 /* Make sure that the hardware responded */
166
Len Brown4be44fc2005-08-05 00:44:28 -0400167 status =
168 acpi_get_register(acpi_gbl_fixed_event_info[event].
Bob Moored8c71b62007-02-02 19:48:21 +0300169 enable_register_id, &value);
Len Brown4be44fc2005-08-05 00:44:28 -0400170 if (ACPI_FAILURE(status)) {
171 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172 }
173
174 if (value != 1) {
Bob Mooreb8e4d892006-01-27 16:43:00 -0500175 ACPI_ERROR((AE_INFO,
176 "Could not enable %s event",
177 acpi_ut_get_event_name(event)));
Len Brown4be44fc2005-08-05 00:44:28 -0400178 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179 }
180
Len Brown4be44fc2005-08-05 00:44:28 -0400181 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700183
Bob Moore83135242006-10-03 00:00:00 -0400184ACPI_EXPORT_SYMBOL(acpi_enable_event)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185
186/*******************************************************************************
187 *
188 * FUNCTION: acpi_set_gpe_type
189 *
190 * PARAMETERS: gpe_device - Parent GPE Device
191 * gpe_number - GPE level within the GPE block
192 * Type - New GPE type
193 *
194 * RETURN: Status
195 *
Robert Moore44f6c012005-04-18 22:49:35 -0400196 * DESCRIPTION: Set the type of an individual GPE
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197 *
198 ******************************************************************************/
Len Brown4be44fc2005-08-05 00:44:28 -0400199acpi_status acpi_set_gpe_type(acpi_handle gpe_device, u32 gpe_number, u8 type)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200{
Len Brown4be44fc2005-08-05 00:44:28 -0400201 acpi_status status = AE_OK;
202 struct acpi_gpe_event_info *gpe_event_info;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203
Bob Mooreb229cf92006-04-21 17:15:00 -0400204 ACPI_FUNCTION_TRACE(acpi_set_gpe_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205
206 /* Ensure that we have a valid GPE number */
207
Len Brown4be44fc2005-08-05 00:44:28 -0400208 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209 if (!gpe_event_info) {
210 status = AE_BAD_PARAMETER;
211 goto unlock_and_exit;
212 }
213
214 if ((gpe_event_info->flags & ACPI_GPE_TYPE_MASK) == type) {
Len Brown4be44fc2005-08-05 00:44:28 -0400215 return_ACPI_STATUS(AE_OK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216 }
217
218 /* Set the new type (will disable GPE if currently enabled) */
219
Len Brown4be44fc2005-08-05 00:44:28 -0400220 status = acpi_ev_set_gpe_type(gpe_event_info, type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700221
Len Brown4be44fc2005-08-05 00:44:28 -0400222 unlock_and_exit:
223 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225
Bob Moore83135242006-10-03 00:00:00 -0400226ACPI_EXPORT_SYMBOL(acpi_set_gpe_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227
228/*******************************************************************************
229 *
230 * FUNCTION: acpi_enable_gpe
231 *
232 * PARAMETERS: gpe_device - Parent GPE Device
233 * gpe_number - GPE level within the GPE block
234 * Flags - Just enable, or also wake enable?
235 * Called from ISR or not
236 *
237 * RETURN: Status
238 *
239 * DESCRIPTION: Enable an ACPI event (general purpose)
240 *
241 ******************************************************************************/
Len Brown4be44fc2005-08-05 00:44:28 -0400242acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700243{
Len Brown4be44fc2005-08-05 00:44:28 -0400244 acpi_status status = AE_OK;
245 struct acpi_gpe_event_info *gpe_event_info;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246
Bob Mooreb229cf92006-04-21 17:15:00 -0400247 ACPI_FUNCTION_TRACE(acpi_enable_gpe);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700248
249 /* Use semaphore lock if not executing at interrupt level */
250
251 if (flags & ACPI_NOT_ISR) {
Len Brown4be44fc2005-08-05 00:44:28 -0400252 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
253 if (ACPI_FAILURE(status)) {
254 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700255 }
256 }
257
258 /* Ensure that we have a valid GPE number */
259
Len Brown4be44fc2005-08-05 00:44:28 -0400260 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261 if (!gpe_event_info) {
262 status = AE_BAD_PARAMETER;
263 goto unlock_and_exit;
264 }
265
266 /* Perform the enable */
267
Len Brown4be44fc2005-08-05 00:44:28 -0400268 status = acpi_ev_enable_gpe(gpe_event_info, TRUE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700269
Len Brown4be44fc2005-08-05 00:44:28 -0400270 unlock_and_exit:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271 if (flags & ACPI_NOT_ISR) {
Len Brown4be44fc2005-08-05 00:44:28 -0400272 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700273 }
Len Brown4be44fc2005-08-05 00:44:28 -0400274 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700275}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276
Bob Moore83135242006-10-03 00:00:00 -0400277ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278
279/*******************************************************************************
280 *
281 * FUNCTION: acpi_disable_gpe
282 *
283 * PARAMETERS: gpe_device - Parent GPE Device
284 * gpe_number - GPE level within the GPE block
285 * Flags - Just disable, or also wake disable?
286 * Called from ISR or not
287 *
288 * RETURN: Status
289 *
290 * DESCRIPTION: Disable an ACPI event (general purpose)
291 *
292 ******************************************************************************/
Len Brown4be44fc2005-08-05 00:44:28 -0400293acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700294{
Len Brown4be44fc2005-08-05 00:44:28 -0400295 acpi_status status = AE_OK;
296 struct acpi_gpe_event_info *gpe_event_info;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700297
Bob Mooreb229cf92006-04-21 17:15:00 -0400298 ACPI_FUNCTION_TRACE(acpi_disable_gpe);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299
300 /* Use semaphore lock if not executing at interrupt level */
301
302 if (flags & ACPI_NOT_ISR) {
Len Brown4be44fc2005-08-05 00:44:28 -0400303 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
304 if (ACPI_FAILURE(status)) {
305 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700306 }
307 }
308
309 /* Ensure that we have a valid GPE number */
310
Len Brown4be44fc2005-08-05 00:44:28 -0400311 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700312 if (!gpe_event_info) {
313 status = AE_BAD_PARAMETER;
314 goto unlock_and_exit;
315 }
316
Len Brown4be44fc2005-08-05 00:44:28 -0400317 status = acpi_ev_disable_gpe(gpe_event_info);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318
Len Brown4be44fc2005-08-05 00:44:28 -0400319 unlock_and_exit:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700320 if (flags & ACPI_NOT_ISR) {
Len Brown4be44fc2005-08-05 00:44:28 -0400321 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700322 }
Len Brown4be44fc2005-08-05 00:44:28 -0400323 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324}
325
Bob Moore83135242006-10-03 00:00:00 -0400326ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
327
Linus Torvalds1da177e2005-04-16 15:20:36 -0700328/*******************************************************************************
329 *
330 * FUNCTION: acpi_disable_event
331 *
332 * PARAMETERS: Event - The fixed eventto be enabled
333 * Flags - Reserved
334 *
335 * RETURN: Status
336 *
337 * DESCRIPTION: Disable an ACPI event (fixed)
338 *
339 ******************************************************************************/
Len Brown4be44fc2005-08-05 00:44:28 -0400340acpi_status acpi_disable_event(u32 event, u32 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341{
Len Brown4be44fc2005-08-05 00:44:28 -0400342 acpi_status status = AE_OK;
343 u32 value;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344
Bob Mooreb229cf92006-04-21 17:15:00 -0400345 ACPI_FUNCTION_TRACE(acpi_disable_event);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700346
347 /* Decode the Fixed Event */
348
349 if (event > ACPI_EVENT_MAX) {
Len Brown4be44fc2005-08-05 00:44:28 -0400350 return_ACPI_STATUS(AE_BAD_PARAMETER);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351 }
352
353 /*
354 * Disable the requested fixed event (by writing a zero to the
355 * enable register bit)
356 */
Len Brown4be44fc2005-08-05 00:44:28 -0400357 status =
358 acpi_set_register(acpi_gbl_fixed_event_info[event].
Bob Moored8c71b62007-02-02 19:48:21 +0300359 enable_register_id, 0);
Len Brown4be44fc2005-08-05 00:44:28 -0400360 if (ACPI_FAILURE(status)) {
361 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700362 }
363
Len Brown4be44fc2005-08-05 00:44:28 -0400364 status =
365 acpi_get_register(acpi_gbl_fixed_event_info[event].
Bob Moored8c71b62007-02-02 19:48:21 +0300366 enable_register_id, &value);
Len Brown4be44fc2005-08-05 00:44:28 -0400367 if (ACPI_FAILURE(status)) {
368 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369 }
370
371 if (value != 0) {
Bob Mooreb8e4d892006-01-27 16:43:00 -0500372 ACPI_ERROR((AE_INFO,
373 "Could not disable %s events",
374 acpi_ut_get_event_name(event)));
Len Brown4be44fc2005-08-05 00:44:28 -0400375 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376 }
377
Len Brown4be44fc2005-08-05 00:44:28 -0400378 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380
Bob Moore83135242006-10-03 00:00:00 -0400381ACPI_EXPORT_SYMBOL(acpi_disable_event)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382
383/*******************************************************************************
384 *
385 * FUNCTION: acpi_clear_event
386 *
387 * PARAMETERS: Event - The fixed event to be cleared
388 *
389 * RETURN: Status
390 *
391 * DESCRIPTION: Clear an ACPI event (fixed)
392 *
393 ******************************************************************************/
Len Brown4be44fc2005-08-05 00:44:28 -0400394acpi_status acpi_clear_event(u32 event)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395{
Len Brown4be44fc2005-08-05 00:44:28 -0400396 acpi_status status = AE_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397
Bob Mooreb229cf92006-04-21 17:15:00 -0400398 ACPI_FUNCTION_TRACE(acpi_clear_event);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399
400 /* Decode the Fixed Event */
401
402 if (event > ACPI_EVENT_MAX) {
Len Brown4be44fc2005-08-05 00:44:28 -0400403 return_ACPI_STATUS(AE_BAD_PARAMETER);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404 }
405
406 /*
407 * Clear the requested fixed event (By writing a one to the
408 * status register bit)
409 */
Len Brown4be44fc2005-08-05 00:44:28 -0400410 status =
411 acpi_set_register(acpi_gbl_fixed_event_info[event].
Bob Moored8c71b62007-02-02 19:48:21 +0300412 status_register_id, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413
Len Brown4be44fc2005-08-05 00:44:28 -0400414 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416
Bob Moore83135242006-10-03 00:00:00 -0400417ACPI_EXPORT_SYMBOL(acpi_clear_event)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418
419/*******************************************************************************
420 *
421 * FUNCTION: acpi_clear_gpe
422 *
423 * PARAMETERS: gpe_device - Parent GPE Device
424 * gpe_number - GPE level within the GPE block
425 * Flags - Called from an ISR or not
426 *
427 * RETURN: Status
428 *
429 * DESCRIPTION: Clear an ACPI event (general purpose)
430 *
431 ******************************************************************************/
Len Brown4be44fc2005-08-05 00:44:28 -0400432acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433{
Len Brown4be44fc2005-08-05 00:44:28 -0400434 acpi_status status = AE_OK;
435 struct acpi_gpe_event_info *gpe_event_info;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700436
Bob Mooreb229cf92006-04-21 17:15:00 -0400437 ACPI_FUNCTION_TRACE(acpi_clear_gpe);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438
439 /* Use semaphore lock if not executing at interrupt level */
440
441 if (flags & ACPI_NOT_ISR) {
Len Brown4be44fc2005-08-05 00:44:28 -0400442 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
443 if (ACPI_FAILURE(status)) {
444 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445 }
446 }
447
448 /* Ensure that we have a valid GPE number */
449
Len Brown4be44fc2005-08-05 00:44:28 -0400450 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451 if (!gpe_event_info) {
452 status = AE_BAD_PARAMETER;
453 goto unlock_and_exit;
454 }
455
Len Brown4be44fc2005-08-05 00:44:28 -0400456 status = acpi_hw_clear_gpe(gpe_event_info);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700457
Len Brown4be44fc2005-08-05 00:44:28 -0400458 unlock_and_exit:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459 if (flags & ACPI_NOT_ISR) {
Len Brown4be44fc2005-08-05 00:44:28 -0400460 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461 }
Len Brown4be44fc2005-08-05 00:44:28 -0400462 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463}
464
Bob Moore83135242006-10-03 00:00:00 -0400465ACPI_EXPORT_SYMBOL(acpi_clear_gpe)
466
Linus Torvalds1da177e2005-04-16 15:20:36 -0700467#ifdef ACPI_FUTURE_USAGE
Linus Torvalds1da177e2005-04-16 15:20:36 -0700468/*******************************************************************************
469 *
470 * FUNCTION: acpi_get_event_status
471 *
472 * PARAMETERS: Event - The fixed event
Robert Moore44f6c012005-04-18 22:49:35 -0400473 * event_status - Where the current status of the event will
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474 * be returned
475 *
476 * RETURN: Status
477 *
478 * DESCRIPTION: Obtains and returns the current status of the event
479 *
480 ******************************************************************************/
Len Brown4be44fc2005-08-05 00:44:28 -0400481acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700482{
Len Brown4be44fc2005-08-05 00:44:28 -0400483 acpi_status status = AE_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700484
Bob Mooreb229cf92006-04-21 17:15:00 -0400485 ACPI_FUNCTION_TRACE(acpi_get_event_status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700486
487 if (!event_status) {
Len Brown4be44fc2005-08-05 00:44:28 -0400488 return_ACPI_STATUS(AE_BAD_PARAMETER);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489 }
490
491 /* Decode the Fixed Event */
492
493 if (event > ACPI_EVENT_MAX) {
Len Brown4be44fc2005-08-05 00:44:28 -0400494 return_ACPI_STATUS(AE_BAD_PARAMETER);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700495 }
496
497 /* Get the status of the requested fixed event */
498
Len Brown4be44fc2005-08-05 00:44:28 -0400499 status =
500 acpi_get_register(acpi_gbl_fixed_event_info[event].
Bob Moored8c71b62007-02-02 19:48:21 +0300501 status_register_id, event_status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502
Len Brown4be44fc2005-08-05 00:44:28 -0400503 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700504}
505
Bob Moore83135242006-10-03 00:00:00 -0400506ACPI_EXPORT_SYMBOL(acpi_get_event_status)
507
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508/*******************************************************************************
509 *
510 * FUNCTION: acpi_get_gpe_status
511 *
512 * PARAMETERS: gpe_device - Parent GPE Device
513 * gpe_number - GPE level within the GPE block
514 * Flags - Called from an ISR or not
Robert Moore44f6c012005-04-18 22:49:35 -0400515 * event_status - Where the current status of the event will
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516 * be returned
517 *
518 * RETURN: Status
519 *
520 * DESCRIPTION: Get status of an event (general purpose)
521 *
522 ******************************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400524acpi_get_gpe_status(acpi_handle gpe_device,
525 u32 gpe_number, u32 flags, acpi_event_status * event_status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526{
Len Brown4be44fc2005-08-05 00:44:28 -0400527 acpi_status status = AE_OK;
528 struct acpi_gpe_event_info *gpe_event_info;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529
Bob Mooreb229cf92006-04-21 17:15:00 -0400530 ACPI_FUNCTION_TRACE(acpi_get_gpe_status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531
532 /* Use semaphore lock if not executing at interrupt level */
533
534 if (flags & ACPI_NOT_ISR) {
Len Brown4be44fc2005-08-05 00:44:28 -0400535 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
536 if (ACPI_FAILURE(status)) {
537 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700538 }
539 }
540
541 /* Ensure that we have a valid GPE number */
542
Len Brown4be44fc2005-08-05 00:44:28 -0400543 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700544 if (!gpe_event_info) {
545 status = AE_BAD_PARAMETER;
546 goto unlock_and_exit;
547 }
548
549 /* Obtain status on the requested GPE number */
550
Len Brown4be44fc2005-08-05 00:44:28 -0400551 status = acpi_hw_get_gpe_status(gpe_event_info, event_status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700552
Len Brown4be44fc2005-08-05 00:44:28 -0400553 unlock_and_exit:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700554 if (flags & ACPI_NOT_ISR) {
Len Brown4be44fc2005-08-05 00:44:28 -0400555 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556 }
Len Brown4be44fc2005-08-05 00:44:28 -0400557 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558}
Bob Moore83135242006-10-03 00:00:00 -0400559
560ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)
Len Brown4be44fc2005-08-05 00:44:28 -0400561#endif /* ACPI_FUTURE_USAGE */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562
563/*******************************************************************************
564 *
565 * FUNCTION: acpi_install_gpe_block
566 *
567 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device
568 * gpe_block_address - Address and space_iD
569 * register_count - Number of GPE register pairs in the block
Robert Moore6f42ccf2005-05-13 00:00:00 -0400570 * interrupt_number - H/W interrupt for the block
Linus Torvalds1da177e2005-04-16 15:20:36 -0700571 *
572 * RETURN: Status
573 *
574 * DESCRIPTION: Create and Install a block of GPE registers
575 *
576 ******************************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400578acpi_install_gpe_block(acpi_handle gpe_device,
579 struct acpi_generic_address *gpe_block_address,
580 u32 register_count, u32 interrupt_number)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581{
Len Brown4be44fc2005-08-05 00:44:28 -0400582 acpi_status status;
583 union acpi_operand_object *obj_desc;
584 struct acpi_namespace_node *node;
585 struct acpi_gpe_block_info *gpe_block;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586
Bob Mooreb229cf92006-04-21 17:15:00 -0400587 ACPI_FUNCTION_TRACE(acpi_install_gpe_block);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588
Len Brown4be44fc2005-08-05 00:44:28 -0400589 if ((!gpe_device) || (!gpe_block_address) || (!register_count)) {
590 return_ACPI_STATUS(AE_BAD_PARAMETER);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700591 }
592
Len Brown4be44fc2005-08-05 00:44:28 -0400593 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
594 if (ACPI_FAILURE(status)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700595 return (status);
596 }
597
Len Brown4be44fc2005-08-05 00:44:28 -0400598 node = acpi_ns_map_handle_to_node(gpe_device);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599 if (!node) {
600 status = AE_BAD_PARAMETER;
601 goto unlock_and_exit;
602 }
603
604 /*
605 * For user-installed GPE Block Devices, the gpe_block_base_number
606 * is always zero
607 */
Len Brown4be44fc2005-08-05 00:44:28 -0400608 status =
609 acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0,
610 interrupt_number, &gpe_block);
611 if (ACPI_FAILURE(status)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612 goto unlock_and_exit;
613 }
614
Bob Moore96db2552005-11-02 00:00:00 -0500615 /* Run the _PRW methods and enable the GPEs */
616
617 status = acpi_ev_initialize_gpe_block(node, gpe_block);
618 if (ACPI_FAILURE(status)) {
619 goto unlock_and_exit;
620 }
621
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622 /* Get the device_object attached to the node */
623
Len Brown4be44fc2005-08-05 00:44:28 -0400624 obj_desc = acpi_ns_get_attached_object(node);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700625 if (!obj_desc) {
Bob Moore52fc0b02006-10-02 00:00:00 -0400626
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627 /* No object, create a new one */
628
Len Brown4be44fc2005-08-05 00:44:28 -0400629 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630 if (!obj_desc) {
631 status = AE_NO_MEMORY;
632 goto unlock_and_exit;
633 }
634
Len Brown4be44fc2005-08-05 00:44:28 -0400635 status =
636 acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637
638 /* Remove local reference to the object */
639
Len Brown4be44fc2005-08-05 00:44:28 -0400640 acpi_ut_remove_reference(obj_desc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700641
Len Brown4be44fc2005-08-05 00:44:28 -0400642 if (ACPI_FAILURE(status)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700643 goto unlock_and_exit;
644 }
645 }
646
647 /* Install the GPE block in the device_object */
648
649 obj_desc->device.gpe_block = gpe_block;
650
Len Brown4be44fc2005-08-05 00:44:28 -0400651 unlock_and_exit:
652 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
653 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700654}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700655
Bob Moore83135242006-10-03 00:00:00 -0400656ACPI_EXPORT_SYMBOL(acpi_install_gpe_block)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657
658/*******************************************************************************
659 *
660 * FUNCTION: acpi_remove_gpe_block
661 *
662 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device
663 *
664 * RETURN: Status
665 *
666 * DESCRIPTION: Remove a previously installed block of GPE registers
667 *
668 ******************************************************************************/
Len Brown4be44fc2005-08-05 00:44:28 -0400669acpi_status acpi_remove_gpe_block(acpi_handle gpe_device)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700670{
Len Brown4be44fc2005-08-05 00:44:28 -0400671 union acpi_operand_object *obj_desc;
672 acpi_status status;
673 struct acpi_namespace_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700674
Bob Mooreb229cf92006-04-21 17:15:00 -0400675 ACPI_FUNCTION_TRACE(acpi_remove_gpe_block);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700676
677 if (!gpe_device) {
Len Brown4be44fc2005-08-05 00:44:28 -0400678 return_ACPI_STATUS(AE_BAD_PARAMETER);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700679 }
680
Len Brown4be44fc2005-08-05 00:44:28 -0400681 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
682 if (ACPI_FAILURE(status)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700683 return (status);
684 }
685
Len Brown4be44fc2005-08-05 00:44:28 -0400686 node = acpi_ns_map_handle_to_node(gpe_device);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700687 if (!node) {
688 status = AE_BAD_PARAMETER;
689 goto unlock_and_exit;
690 }
691
692 /* Get the device_object attached to the node */
693
Len Brown4be44fc2005-08-05 00:44:28 -0400694 obj_desc = acpi_ns_get_attached_object(node);
695 if (!obj_desc || !obj_desc->device.gpe_block) {
696 return_ACPI_STATUS(AE_NULL_OBJECT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700697 }
698
699 /* Delete the GPE block (but not the device_object) */
700
Len Brown4be44fc2005-08-05 00:44:28 -0400701 status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block);
702 if (ACPI_SUCCESS(status)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700703 obj_desc->device.gpe_block = NULL;
704 }
705
Len Brown4be44fc2005-08-05 00:44:28 -0400706 unlock_and_exit:
707 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
708 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709}
Robert Moore44f6c012005-04-18 22:49:35 -0400710
Bob Moore83135242006-10-03 00:00:00 -0400711ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block)