Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /****************************************************************************** |
2 | * | |
3 | * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable | |
4 | * | |
5 | *****************************************************************************/ | |
6 | ||
7 | /* | |
75a44ce0 | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
1da177e4 LT |
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 | ||
1da177e4 LT |
44 | #include <acpi/acpi.h> |
45 | #include <acpi/acevents.h> | |
46 | #include <acpi/acnamesp.h> | |
1a666f8b | 47 | #include <acpi/actables.h> |
1da177e4 LT |
48 | |
49 | #define _COMPONENT ACPI_EVENTS | |
4be44fcd | 50 | ACPI_MODULE_NAME("evxfevnt") |
1da177e4 LT |
51 | |
52 | /******************************************************************************* | |
53 | * | |
54 | * FUNCTION: acpi_enable | |
55 | * | |
56 | * PARAMETERS: None | |
57 | * | |
58 | * RETURN: Status | |
59 | * | |
60 | * DESCRIPTION: Transfers the system into ACPI mode. | |
61 | * | |
62 | ******************************************************************************/ | |
4be44fcd | 63 | acpi_status acpi_enable(void) |
1da177e4 | 64 | { |
4be44fcd | 65 | acpi_status status = AE_OK; |
1da177e4 | 66 | |
b229cf92 | 67 | ACPI_FUNCTION_TRACE(acpi_enable); |
1da177e4 | 68 | |
c857303a BM |
69 | /* ACPI tables must be present */ |
70 | ||
71 | if (!acpi_tb_tables_loaded()) { | |
72 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); | |
73 | } | |
74 | ||
75 | /* Check current mode */ | |
76 | ||
1da177e4 | 77 | if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) { |
4be44fcd LB |
78 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, |
79 | "System is already in ACPI mode\n")); | |
80 | } else { | |
1da177e4 LT |
81 | /* Transition to ACPI mode */ |
82 | ||
4be44fcd LB |
83 | status = acpi_hw_set_mode(ACPI_SYS_MODE_ACPI); |
84 | if (ACPI_FAILURE(status)) { | |
b8e4d893 BM |
85 | ACPI_ERROR((AE_INFO, |
86 | "Could not transition to ACPI mode")); | |
4be44fcd | 87 | return_ACPI_STATUS(status); |
1da177e4 LT |
88 | } |
89 | ||
4be44fcd LB |
90 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, |
91 | "Transition to ACPI mode successful\n")); | |
1da177e4 LT |
92 | } |
93 | ||
4be44fcd | 94 | return_ACPI_STATUS(status); |
1da177e4 LT |
95 | } |
96 | ||
8313524a BM |
97 | ACPI_EXPORT_SYMBOL(acpi_enable) |
98 | ||
1da177e4 LT |
99 | /******************************************************************************* |
100 | * | |
101 | * FUNCTION: acpi_disable | |
102 | * | |
103 | * PARAMETERS: None | |
104 | * | |
105 | * RETURN: Status | |
106 | * | |
44f6c012 | 107 | * DESCRIPTION: Transfers the system into LEGACY (non-ACPI) mode. |
1da177e4 LT |
108 | * |
109 | ******************************************************************************/ | |
4be44fcd | 110 | acpi_status acpi_disable(void) |
1da177e4 | 111 | { |
4be44fcd | 112 | acpi_status status = AE_OK; |
1da177e4 | 113 | |
b229cf92 | 114 | ACPI_FUNCTION_TRACE(acpi_disable); |
1da177e4 | 115 | |
1da177e4 | 116 | if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) { |
4be44fcd LB |
117 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, |
118 | "System is already in legacy (non-ACPI) mode\n")); | |
119 | } else { | |
1da177e4 LT |
120 | /* Transition to LEGACY mode */ |
121 | ||
4be44fcd | 122 | status = acpi_hw_set_mode(ACPI_SYS_MODE_LEGACY); |
1da177e4 | 123 | |
4be44fcd | 124 | if (ACPI_FAILURE(status)) { |
b8e4d893 BM |
125 | ACPI_ERROR((AE_INFO, |
126 | "Could not exit ACPI mode to legacy mode")); | |
4be44fcd | 127 | return_ACPI_STATUS(status); |
1da177e4 LT |
128 | } |
129 | ||
4be44fcd | 130 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI mode disabled\n")); |
1da177e4 LT |
131 | } |
132 | ||
4be44fcd | 133 | return_ACPI_STATUS(status); |
1da177e4 LT |
134 | } |
135 | ||
8313524a BM |
136 | ACPI_EXPORT_SYMBOL(acpi_disable) |
137 | ||
1da177e4 LT |
138 | /******************************************************************************* |
139 | * | |
140 | * FUNCTION: acpi_enable_event | |
141 | * | |
142 | * PARAMETERS: Event - The fixed eventto be enabled | |
143 | * Flags - Reserved | |
144 | * | |
145 | * RETURN: Status | |
146 | * | |
147 | * DESCRIPTION: Enable an ACPI event (fixed) | |
148 | * | |
149 | ******************************************************************************/ | |
4be44fcd | 150 | acpi_status acpi_enable_event(u32 event, u32 flags) |
1da177e4 | 151 | { |
4be44fcd LB |
152 | acpi_status status = AE_OK; |
153 | u32 value; | |
1da177e4 | 154 | |
b229cf92 | 155 | ACPI_FUNCTION_TRACE(acpi_enable_event); |
1da177e4 LT |
156 | |
157 | /* Decode the Fixed Event */ | |
158 | ||
159 | if (event > ACPI_EVENT_MAX) { | |
4be44fcd | 160 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
1da177e4 LT |
161 | } |
162 | ||
163 | /* | |
164 | * Enable the requested fixed event (by writing a one to the | |
165 | * enable register bit) | |
166 | */ | |
4be44fcd LB |
167 | status = |
168 | acpi_set_register(acpi_gbl_fixed_event_info[event]. | |
d8c71b6d | 169 | enable_register_id, 1); |
4be44fcd LB |
170 | if (ACPI_FAILURE(status)) { |
171 | return_ACPI_STATUS(status); | |
1da177e4 LT |
172 | } |
173 | ||
174 | /* Make sure that the hardware responded */ | |
175 | ||
4be44fcd LB |
176 | status = |
177 | acpi_get_register(acpi_gbl_fixed_event_info[event]. | |
d8c71b6d | 178 | enable_register_id, &value); |
4be44fcd LB |
179 | if (ACPI_FAILURE(status)) { |
180 | return_ACPI_STATUS(status); | |
1da177e4 LT |
181 | } |
182 | ||
183 | if (value != 1) { | |
b8e4d893 BM |
184 | ACPI_ERROR((AE_INFO, |
185 | "Could not enable %s event", | |
186 | acpi_ut_get_event_name(event))); | |
4be44fcd | 187 | return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); |
1da177e4 LT |
188 | } |
189 | ||
4be44fcd | 190 | return_ACPI_STATUS(status); |
1da177e4 | 191 | } |
1da177e4 | 192 | |
8313524a | 193 | ACPI_EXPORT_SYMBOL(acpi_enable_event) |
1da177e4 LT |
194 | |
195 | /******************************************************************************* | |
196 | * | |
197 | * FUNCTION: acpi_set_gpe_type | |
198 | * | |
199 | * PARAMETERS: gpe_device - Parent GPE Device | |
200 | * gpe_number - GPE level within the GPE block | |
201 | * Type - New GPE type | |
202 | * | |
203 | * RETURN: Status | |
204 | * | |
44f6c012 | 205 | * DESCRIPTION: Set the type of an individual GPE |
1da177e4 LT |
206 | * |
207 | ******************************************************************************/ | |
4be44fcd | 208 | acpi_status acpi_set_gpe_type(acpi_handle gpe_device, u32 gpe_number, u8 type) |
1da177e4 | 209 | { |
4be44fcd LB |
210 | acpi_status status = AE_OK; |
211 | struct acpi_gpe_event_info *gpe_event_info; | |
1da177e4 | 212 | |
b229cf92 | 213 | ACPI_FUNCTION_TRACE(acpi_set_gpe_type); |
1da177e4 LT |
214 | |
215 | /* Ensure that we have a valid GPE number */ | |
216 | ||
4be44fcd | 217 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); |
1da177e4 LT |
218 | if (!gpe_event_info) { |
219 | status = AE_BAD_PARAMETER; | |
220 | goto unlock_and_exit; | |
221 | } | |
222 | ||
223 | if ((gpe_event_info->flags & ACPI_GPE_TYPE_MASK) == type) { | |
4be44fcd | 224 | return_ACPI_STATUS(AE_OK); |
1da177e4 LT |
225 | } |
226 | ||
227 | /* Set the new type (will disable GPE if currently enabled) */ | |
228 | ||
4be44fcd | 229 | status = acpi_ev_set_gpe_type(gpe_event_info, type); |
1da177e4 | 230 | |
4be44fcd LB |
231 | unlock_and_exit: |
232 | return_ACPI_STATUS(status); | |
1da177e4 | 233 | } |
1da177e4 | 234 | |
8313524a | 235 | ACPI_EXPORT_SYMBOL(acpi_set_gpe_type) |
1da177e4 LT |
236 | |
237 | /******************************************************************************* | |
238 | * | |
239 | * FUNCTION: acpi_enable_gpe | |
240 | * | |
241 | * PARAMETERS: gpe_device - Parent GPE Device | |
242 | * gpe_number - GPE level within the GPE block | |
243 | * Flags - Just enable, or also wake enable? | |
244 | * Called from ISR or not | |
245 | * | |
246 | * RETURN: Status | |
247 | * | |
248 | * DESCRIPTION: Enable an ACPI event (general purpose) | |
249 | * | |
250 | ******************************************************************************/ | |
4be44fcd | 251 | acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags) |
1da177e4 | 252 | { |
4be44fcd LB |
253 | acpi_status status = AE_OK; |
254 | struct acpi_gpe_event_info *gpe_event_info; | |
1da177e4 | 255 | |
b229cf92 | 256 | ACPI_FUNCTION_TRACE(acpi_enable_gpe); |
1da177e4 LT |
257 | |
258 | /* Use semaphore lock if not executing at interrupt level */ | |
259 | ||
260 | if (flags & ACPI_NOT_ISR) { | |
4be44fcd LB |
261 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); |
262 | if (ACPI_FAILURE(status)) { | |
263 | return_ACPI_STATUS(status); | |
1da177e4 LT |
264 | } |
265 | } | |
266 | ||
267 | /* Ensure that we have a valid GPE number */ | |
268 | ||
4be44fcd | 269 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); |
1da177e4 LT |
270 | if (!gpe_event_info) { |
271 | status = AE_BAD_PARAMETER; | |
272 | goto unlock_and_exit; | |
273 | } | |
274 | ||
275 | /* Perform the enable */ | |
276 | ||
4be44fcd | 277 | status = acpi_ev_enable_gpe(gpe_event_info, TRUE); |
1da177e4 | 278 | |
4be44fcd | 279 | unlock_and_exit: |
1da177e4 | 280 | if (flags & ACPI_NOT_ISR) { |
4be44fcd | 281 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); |
1da177e4 | 282 | } |
4be44fcd | 283 | return_ACPI_STATUS(status); |
1da177e4 | 284 | } |
1da177e4 | 285 | |
8313524a | 286 | ACPI_EXPORT_SYMBOL(acpi_enable_gpe) |
1da177e4 LT |
287 | |
288 | /******************************************************************************* | |
289 | * | |
290 | * FUNCTION: acpi_disable_gpe | |
291 | * | |
292 | * PARAMETERS: gpe_device - Parent GPE Device | |
293 | * gpe_number - GPE level within the GPE block | |
294 | * Flags - Just disable, or also wake disable? | |
295 | * Called from ISR or not | |
296 | * | |
297 | * RETURN: Status | |
298 | * | |
299 | * DESCRIPTION: Disable an ACPI event (general purpose) | |
300 | * | |
301 | ******************************************************************************/ | |
4be44fcd | 302 | acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags) |
1da177e4 | 303 | { |
4be44fcd LB |
304 | acpi_status status = AE_OK; |
305 | struct acpi_gpe_event_info *gpe_event_info; | |
1da177e4 | 306 | |
b229cf92 | 307 | ACPI_FUNCTION_TRACE(acpi_disable_gpe); |
1da177e4 LT |
308 | |
309 | /* Use semaphore lock if not executing at interrupt level */ | |
310 | ||
311 | if (flags & ACPI_NOT_ISR) { | |
4be44fcd LB |
312 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); |
313 | if (ACPI_FAILURE(status)) { | |
314 | return_ACPI_STATUS(status); | |
1da177e4 LT |
315 | } |
316 | } | |
317 | ||
318 | /* Ensure that we have a valid GPE number */ | |
319 | ||
4be44fcd | 320 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); |
1da177e4 LT |
321 | if (!gpe_event_info) { |
322 | status = AE_BAD_PARAMETER; | |
323 | goto unlock_and_exit; | |
324 | } | |
325 | ||
4be44fcd | 326 | status = acpi_ev_disable_gpe(gpe_event_info); |
1da177e4 | 327 | |
4be44fcd | 328 | unlock_and_exit: |
1da177e4 | 329 | if (flags & ACPI_NOT_ISR) { |
4be44fcd | 330 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); |
1da177e4 | 331 | } |
4be44fcd | 332 | return_ACPI_STATUS(status); |
1da177e4 LT |
333 | } |
334 | ||
8313524a BM |
335 | ACPI_EXPORT_SYMBOL(acpi_disable_gpe) |
336 | ||
1da177e4 LT |
337 | /******************************************************************************* |
338 | * | |
339 | * FUNCTION: acpi_disable_event | |
340 | * | |
341 | * PARAMETERS: Event - The fixed eventto be enabled | |
342 | * Flags - Reserved | |
343 | * | |
344 | * RETURN: Status | |
345 | * | |
346 | * DESCRIPTION: Disable an ACPI event (fixed) | |
347 | * | |
348 | ******************************************************************************/ | |
4be44fcd | 349 | acpi_status acpi_disable_event(u32 event, u32 flags) |
1da177e4 | 350 | { |
4be44fcd LB |
351 | acpi_status status = AE_OK; |
352 | u32 value; | |
1da177e4 | 353 | |
b229cf92 | 354 | ACPI_FUNCTION_TRACE(acpi_disable_event); |
1da177e4 LT |
355 | |
356 | /* Decode the Fixed Event */ | |
357 | ||
358 | if (event > ACPI_EVENT_MAX) { | |
4be44fcd | 359 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
1da177e4 LT |
360 | } |
361 | ||
362 | /* | |
363 | * Disable the requested fixed event (by writing a zero to the | |
364 | * enable register bit) | |
365 | */ | |
4be44fcd LB |
366 | status = |
367 | acpi_set_register(acpi_gbl_fixed_event_info[event]. | |
d8c71b6d | 368 | enable_register_id, 0); |
4be44fcd LB |
369 | if (ACPI_FAILURE(status)) { |
370 | return_ACPI_STATUS(status); | |
1da177e4 LT |
371 | } |
372 | ||
4be44fcd LB |
373 | status = |
374 | acpi_get_register(acpi_gbl_fixed_event_info[event]. | |
d8c71b6d | 375 | enable_register_id, &value); |
4be44fcd LB |
376 | if (ACPI_FAILURE(status)) { |
377 | return_ACPI_STATUS(status); | |
1da177e4 LT |
378 | } |
379 | ||
380 | if (value != 0) { | |
b8e4d893 BM |
381 | ACPI_ERROR((AE_INFO, |
382 | "Could not disable %s events", | |
383 | acpi_ut_get_event_name(event))); | |
4be44fcd | 384 | return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); |
1da177e4 LT |
385 | } |
386 | ||
4be44fcd | 387 | return_ACPI_STATUS(status); |
1da177e4 | 388 | } |
1da177e4 | 389 | |
8313524a | 390 | ACPI_EXPORT_SYMBOL(acpi_disable_event) |
1da177e4 LT |
391 | |
392 | /******************************************************************************* | |
393 | * | |
394 | * FUNCTION: acpi_clear_event | |
395 | * | |
396 | * PARAMETERS: Event - The fixed event to be cleared | |
397 | * | |
398 | * RETURN: Status | |
399 | * | |
400 | * DESCRIPTION: Clear an ACPI event (fixed) | |
401 | * | |
402 | ******************************************************************************/ | |
4be44fcd | 403 | acpi_status acpi_clear_event(u32 event) |
1da177e4 | 404 | { |
4be44fcd | 405 | acpi_status status = AE_OK; |
1da177e4 | 406 | |
b229cf92 | 407 | ACPI_FUNCTION_TRACE(acpi_clear_event); |
1da177e4 LT |
408 | |
409 | /* Decode the Fixed Event */ | |
410 | ||
411 | if (event > ACPI_EVENT_MAX) { | |
4be44fcd | 412 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
1da177e4 LT |
413 | } |
414 | ||
415 | /* | |
416 | * Clear the requested fixed event (By writing a one to the | |
417 | * status register bit) | |
418 | */ | |
4be44fcd LB |
419 | status = |
420 | acpi_set_register(acpi_gbl_fixed_event_info[event]. | |
d8c71b6d | 421 | status_register_id, 1); |
1da177e4 | 422 | |
4be44fcd | 423 | return_ACPI_STATUS(status); |
1da177e4 | 424 | } |
1da177e4 | 425 | |
8313524a | 426 | ACPI_EXPORT_SYMBOL(acpi_clear_event) |
1da177e4 LT |
427 | |
428 | /******************************************************************************* | |
429 | * | |
430 | * FUNCTION: acpi_clear_gpe | |
431 | * | |
432 | * PARAMETERS: gpe_device - Parent GPE Device | |
433 | * gpe_number - GPE level within the GPE block | |
434 | * Flags - Called from an ISR or not | |
435 | * | |
436 | * RETURN: Status | |
437 | * | |
438 | * DESCRIPTION: Clear an ACPI event (general purpose) | |
439 | * | |
440 | ******************************************************************************/ | |
4be44fcd | 441 | acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags) |
1da177e4 | 442 | { |
4be44fcd LB |
443 | acpi_status status = AE_OK; |
444 | struct acpi_gpe_event_info *gpe_event_info; | |
1da177e4 | 445 | |
b229cf92 | 446 | ACPI_FUNCTION_TRACE(acpi_clear_gpe); |
1da177e4 LT |
447 | |
448 | /* Use semaphore lock if not executing at interrupt level */ | |
449 | ||
450 | if (flags & ACPI_NOT_ISR) { | |
4be44fcd LB |
451 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); |
452 | if (ACPI_FAILURE(status)) { | |
453 | return_ACPI_STATUS(status); | |
1da177e4 LT |
454 | } |
455 | } | |
456 | ||
457 | /* Ensure that we have a valid GPE number */ | |
458 | ||
4be44fcd | 459 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); |
1da177e4 LT |
460 | if (!gpe_event_info) { |
461 | status = AE_BAD_PARAMETER; | |
462 | goto unlock_and_exit; | |
463 | } | |
464 | ||
4be44fcd | 465 | status = acpi_hw_clear_gpe(gpe_event_info); |
1da177e4 | 466 | |
4be44fcd | 467 | unlock_and_exit: |
1da177e4 | 468 | if (flags & ACPI_NOT_ISR) { |
4be44fcd | 469 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); |
1da177e4 | 470 | } |
4be44fcd | 471 | return_ACPI_STATUS(status); |
1da177e4 LT |
472 | } |
473 | ||
8313524a | 474 | ACPI_EXPORT_SYMBOL(acpi_clear_gpe) |
1da177e4 | 475 | #ifdef ACPI_FUTURE_USAGE |
1da177e4 LT |
476 | /******************************************************************************* |
477 | * | |
478 | * FUNCTION: acpi_get_event_status | |
479 | * | |
480 | * PARAMETERS: Event - The fixed event | |
44f6c012 | 481 | * event_status - Where the current status of the event will |
1da177e4 LT |
482 | * be returned |
483 | * | |
484 | * RETURN: Status | |
485 | * | |
486 | * DESCRIPTION: Obtains and returns the current status of the event | |
487 | * | |
488 | ******************************************************************************/ | |
4be44fcd | 489 | acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status) |
1da177e4 | 490 | { |
4be44fcd | 491 | acpi_status status = AE_OK; |
1da177e4 | 492 | |
b229cf92 | 493 | ACPI_FUNCTION_TRACE(acpi_get_event_status); |
1da177e4 LT |
494 | |
495 | if (!event_status) { | |
4be44fcd | 496 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
1da177e4 LT |
497 | } |
498 | ||
499 | /* Decode the Fixed Event */ | |
500 | ||
501 | if (event > ACPI_EVENT_MAX) { | |
4be44fcd | 502 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
1da177e4 LT |
503 | } |
504 | ||
505 | /* Get the status of the requested fixed event */ | |
506 | ||
4be44fcd LB |
507 | status = |
508 | acpi_get_register(acpi_gbl_fixed_event_info[event]. | |
d8c71b6d | 509 | status_register_id, event_status); |
1da177e4 | 510 | |
4be44fcd | 511 | return_ACPI_STATUS(status); |
1da177e4 LT |
512 | } |
513 | ||
8313524a BM |
514 | ACPI_EXPORT_SYMBOL(acpi_get_event_status) |
515 | ||
1da177e4 LT |
516 | /******************************************************************************* |
517 | * | |
518 | * FUNCTION: acpi_get_gpe_status | |
519 | * | |
520 | * PARAMETERS: gpe_device - Parent GPE Device | |
521 | * gpe_number - GPE level within the GPE block | |
522 | * Flags - Called from an ISR or not | |
44f6c012 | 523 | * event_status - Where the current status of the event will |
1da177e4 LT |
524 | * be returned |
525 | * | |
526 | * RETURN: Status | |
527 | * | |
528 | * DESCRIPTION: Get status of an event (general purpose) | |
529 | * | |
530 | ******************************************************************************/ | |
1da177e4 | 531 | acpi_status |
4be44fcd LB |
532 | acpi_get_gpe_status(acpi_handle gpe_device, |
533 | u32 gpe_number, u32 flags, acpi_event_status * event_status) | |
1da177e4 | 534 | { |
4be44fcd LB |
535 | acpi_status status = AE_OK; |
536 | struct acpi_gpe_event_info *gpe_event_info; | |
1da177e4 | 537 | |
b229cf92 | 538 | ACPI_FUNCTION_TRACE(acpi_get_gpe_status); |
1da177e4 LT |
539 | |
540 | /* Use semaphore lock if not executing at interrupt level */ | |
541 | ||
542 | if (flags & ACPI_NOT_ISR) { | |
4be44fcd LB |
543 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); |
544 | if (ACPI_FAILURE(status)) { | |
545 | return_ACPI_STATUS(status); | |
1da177e4 LT |
546 | } |
547 | } | |
548 | ||
549 | /* Ensure that we have a valid GPE number */ | |
550 | ||
4be44fcd | 551 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); |
1da177e4 LT |
552 | if (!gpe_event_info) { |
553 | status = AE_BAD_PARAMETER; | |
554 | goto unlock_and_exit; | |
555 | } | |
556 | ||
557 | /* Obtain status on the requested GPE number */ | |
558 | ||
4be44fcd | 559 | status = acpi_hw_get_gpe_status(gpe_event_info, event_status); |
1da177e4 | 560 | |
4be44fcd | 561 | unlock_and_exit: |
1da177e4 | 562 | if (flags & ACPI_NOT_ISR) { |
4be44fcd | 563 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); |
1da177e4 | 564 | } |
4be44fcd | 565 | return_ACPI_STATUS(status); |
1da177e4 | 566 | } |
8313524a BM |
567 | |
568 | ACPI_EXPORT_SYMBOL(acpi_get_gpe_status) | |
4be44fcd | 569 | #endif /* ACPI_FUTURE_USAGE */ |
1da177e4 LT |
570 | /******************************************************************************* |
571 | * | |
572 | * FUNCTION: acpi_install_gpe_block | |
573 | * | |
574 | * PARAMETERS: gpe_device - Handle to the parent GPE Block Device | |
575 | * gpe_block_address - Address and space_iD | |
576 | * register_count - Number of GPE register pairs in the block | |
6f42ccf2 | 577 | * interrupt_number - H/W interrupt for the block |
1da177e4 LT |
578 | * |
579 | * RETURN: Status | |
580 | * | |
581 | * DESCRIPTION: Create and Install a block of GPE registers | |
582 | * | |
583 | ******************************************************************************/ | |
1da177e4 | 584 | acpi_status |
4be44fcd LB |
585 | acpi_install_gpe_block(acpi_handle gpe_device, |
586 | struct acpi_generic_address *gpe_block_address, | |
587 | u32 register_count, u32 interrupt_number) | |
1da177e4 | 588 | { |
4be44fcd LB |
589 | acpi_status status; |
590 | union acpi_operand_object *obj_desc; | |
591 | struct acpi_namespace_node *node; | |
592 | struct acpi_gpe_block_info *gpe_block; | |
1da177e4 | 593 | |
b229cf92 | 594 | ACPI_FUNCTION_TRACE(acpi_install_gpe_block); |
1da177e4 | 595 | |
4be44fcd LB |
596 | if ((!gpe_device) || (!gpe_block_address) || (!register_count)) { |
597 | return_ACPI_STATUS(AE_BAD_PARAMETER); | |
1da177e4 LT |
598 | } |
599 | ||
4be44fcd LB |
600 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); |
601 | if (ACPI_FAILURE(status)) { | |
1da177e4 LT |
602 | return (status); |
603 | } | |
604 | ||
4be44fcd | 605 | node = acpi_ns_map_handle_to_node(gpe_device); |
1da177e4 LT |
606 | if (!node) { |
607 | status = AE_BAD_PARAMETER; | |
608 | goto unlock_and_exit; | |
609 | } | |
610 | ||
611 | /* | |
612 | * For user-installed GPE Block Devices, the gpe_block_base_number | |
613 | * is always zero | |
614 | */ | |
4be44fcd LB |
615 | status = |
616 | acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0, | |
617 | interrupt_number, &gpe_block); | |
618 | if (ACPI_FAILURE(status)) { | |
1da177e4 LT |
619 | goto unlock_and_exit; |
620 | } | |
621 | ||
96db255c BM |
622 | /* Run the _PRW methods and enable the GPEs */ |
623 | ||
624 | status = acpi_ev_initialize_gpe_block(node, gpe_block); | |
625 | if (ACPI_FAILURE(status)) { | |
626 | goto unlock_and_exit; | |
627 | } | |
628 | ||
1da177e4 LT |
629 | /* Get the device_object attached to the node */ |
630 | ||
4be44fcd | 631 | obj_desc = acpi_ns_get_attached_object(node); |
1da177e4 | 632 | if (!obj_desc) { |
52fc0b02 | 633 | |
1da177e4 LT |
634 | /* No object, create a new one */ |
635 | ||
4be44fcd | 636 | obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE); |
1da177e4 LT |
637 | if (!obj_desc) { |
638 | status = AE_NO_MEMORY; | |
639 | goto unlock_and_exit; | |
640 | } | |
641 | ||
4be44fcd LB |
642 | status = |
643 | acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE); | |
1da177e4 LT |
644 | |
645 | /* Remove local reference to the object */ | |
646 | ||
4be44fcd | 647 | acpi_ut_remove_reference(obj_desc); |
1da177e4 | 648 | |
4be44fcd | 649 | if (ACPI_FAILURE(status)) { |
1da177e4 LT |
650 | goto unlock_and_exit; |
651 | } | |
652 | } | |
653 | ||
654 | /* Install the GPE block in the device_object */ | |
655 | ||
656 | obj_desc->device.gpe_block = gpe_block; | |
657 | ||
4be44fcd LB |
658 | unlock_and_exit: |
659 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | |
660 | return_ACPI_STATUS(status); | |
1da177e4 | 661 | } |
1da177e4 | 662 | |
8313524a | 663 | ACPI_EXPORT_SYMBOL(acpi_install_gpe_block) |
1da177e4 LT |
664 | |
665 | /******************************************************************************* | |
666 | * | |
667 | * FUNCTION: acpi_remove_gpe_block | |
668 | * | |
669 | * PARAMETERS: gpe_device - Handle to the parent GPE Block Device | |
670 | * | |
671 | * RETURN: Status | |
672 | * | |
673 | * DESCRIPTION: Remove a previously installed block of GPE registers | |
674 | * | |
675 | ******************************************************************************/ | |
4be44fcd | 676 | acpi_status acpi_remove_gpe_block(acpi_handle gpe_device) |
1da177e4 | 677 | { |
4be44fcd LB |
678 | union acpi_operand_object *obj_desc; |
679 | acpi_status status; | |
680 | struct acpi_namespace_node *node; | |
1da177e4 | 681 | |
b229cf92 | 682 | ACPI_FUNCTION_TRACE(acpi_remove_gpe_block); |
1da177e4 LT |
683 | |
684 | if (!gpe_device) { | |
4be44fcd | 685 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
1da177e4 LT |
686 | } |
687 | ||
4be44fcd LB |
688 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); |
689 | if (ACPI_FAILURE(status)) { | |
1da177e4 LT |
690 | return (status); |
691 | } | |
692 | ||
4be44fcd | 693 | node = acpi_ns_map_handle_to_node(gpe_device); |
1da177e4 LT |
694 | if (!node) { |
695 | status = AE_BAD_PARAMETER; | |
696 | goto unlock_and_exit; | |
697 | } | |
698 | ||
699 | /* Get the device_object attached to the node */ | |
700 | ||
4be44fcd LB |
701 | obj_desc = acpi_ns_get_attached_object(node); |
702 | if (!obj_desc || !obj_desc->device.gpe_block) { | |
703 | return_ACPI_STATUS(AE_NULL_OBJECT); | |
1da177e4 LT |
704 | } |
705 | ||
706 | /* Delete the GPE block (but not the device_object) */ | |
707 | ||
4be44fcd LB |
708 | status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block); |
709 | if (ACPI_SUCCESS(status)) { | |
1da177e4 LT |
710 | obj_desc->device.gpe_block = NULL; |
711 | } | |
712 | ||
4be44fcd LB |
713 | unlock_and_exit: |
714 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | |
715 | return_ACPI_STATUS(status); | |
1da177e4 | 716 | } |
44f6c012 | 717 | |
8313524a | 718 | ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block) |