]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /****************************************************************************** |
2 | * | |
3 | * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable | |
4 | * | |
5 | *****************************************************************************/ | |
6 | ||
7 | /* | |
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | |
9 | * All rights reserved. | |
10 | * | |
11 | * Redistribution and use in source and binary forms, with or without | |
12 | * modification, are permitted provided that the following conditions | |
13 | * are met: | |
14 | * 1. Redistributions of source code must retain the above copyright | |
15 | * notice, this list of conditions, and the following disclaimer, | |
16 | * without modification. | |
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | |
18 | * substantially similar to the "NO WARRANTY" disclaimer below | |
19 | * ("Disclaimer") and any redistribution must be conditioned upon | |
20 | * including a substantially similar Disclaimer requirement for further | |
21 | * binary redistribution. | |
22 | * 3. Neither the names of the above-listed copyright holders nor the names | |
23 | * of any contributors may be used to endorse or promote products derived | |
24 | * from this software without specific prior written permission. | |
25 | * | |
26 | * Alternatively, this software may be distributed under the terms of the | |
27 | * GNU General Public License ("GPL") version 2 as published by the Free | |
28 | * Software Foundation. | |
29 | * | |
30 | * NO WARRANTY | |
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | |
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
41 | * POSSIBILITY OF SUCH DAMAGES. | |
42 | */ | |
43 | ||
44 | #include <linux/module.h> | |
45 | ||
46 | #include <acpi/acpi.h> | |
47 | #include <acpi/acevents.h> | |
48 | #include <acpi/acnamesp.h> | |
49 | ||
50 | #define _COMPONENT ACPI_EVENTS | |
51 | ACPI_MODULE_NAME ("evxfevnt") | |
52 | ||
53 | ||
54 | /******************************************************************************* | |
55 | * | |
56 | * FUNCTION: acpi_enable | |
57 | * | |
58 | * PARAMETERS: None | |
59 | * | |
60 | * RETURN: Status | |
61 | * | |
62 | * DESCRIPTION: Transfers the system into ACPI mode. | |
63 | * | |
64 | ******************************************************************************/ | |
65 | ||
66 | acpi_status | |
44f6c012 RM |
67 | acpi_enable ( |
68 | void) | |
1da177e4 LT |
69 | { |
70 | acpi_status status = AE_OK; | |
71 | ||
72 | ||
73 | ACPI_FUNCTION_TRACE ("acpi_enable"); | |
74 | ||
75 | ||
76 | /* Make sure we have the FADT*/ | |
77 | ||
78 | if (!acpi_gbl_FADT) { | |
79 | ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "No FADT information present!\n")); | |
80 | return_ACPI_STATUS (AE_NO_ACPI_TABLES); | |
81 | } | |
82 | ||
83 | if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) { | |
84 | ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "System is already in ACPI mode\n")); | |
85 | } | |
86 | else { | |
87 | /* Transition to ACPI mode */ | |
88 | ||
89 | status = acpi_hw_set_mode (ACPI_SYS_MODE_ACPI); | |
90 | if (ACPI_FAILURE (status)) { | |
91 | ACPI_REPORT_ERROR (("Could not transition to ACPI mode.\n")); | |
92 | return_ACPI_STATUS (status); | |
93 | } | |
94 | ||
44f6c012 RM |
95 | ACPI_DEBUG_PRINT ((ACPI_DB_INIT, |
96 | "Transition to ACPI mode successful\n")); | |
1da177e4 LT |
97 | } |
98 | ||
99 | return_ACPI_STATUS (status); | |
100 | } | |
101 | ||
102 | ||
103 | /******************************************************************************* | |
104 | * | |
105 | * FUNCTION: acpi_disable | |
106 | * | |
107 | * PARAMETERS: None | |
108 | * | |
109 | * RETURN: Status | |
110 | * | |
44f6c012 | 111 | * DESCRIPTION: Transfers the system into LEGACY (non-ACPI) mode. |
1da177e4 LT |
112 | * |
113 | ******************************************************************************/ | |
114 | ||
115 | acpi_status | |
44f6c012 RM |
116 | acpi_disable ( |
117 | void) | |
1da177e4 LT |
118 | { |
119 | acpi_status status = AE_OK; | |
120 | ||
121 | ||
122 | ACPI_FUNCTION_TRACE ("acpi_disable"); | |
123 | ||
124 | ||
125 | if (!acpi_gbl_FADT) { | |
126 | ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "No FADT information present!\n")); | |
127 | return_ACPI_STATUS (AE_NO_ACPI_TABLES); | |
128 | } | |
129 | ||
130 | if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) { | |
44f6c012 RM |
131 | ACPI_DEBUG_PRINT ((ACPI_DB_INIT, |
132 | "System is already in legacy (non-ACPI) mode\n")); | |
1da177e4 LT |
133 | } |
134 | else { | |
135 | /* Transition to LEGACY mode */ | |
136 | ||
137 | status = acpi_hw_set_mode (ACPI_SYS_MODE_LEGACY); | |
138 | ||
139 | if (ACPI_FAILURE (status)) { | |
44f6c012 RM |
140 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, |
141 | "Could not exit ACPI mode to legacy mode")); | |
1da177e4 LT |
142 | return_ACPI_STATUS (status); |
143 | } | |
144 | ||
145 | ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "ACPI mode disabled\n")); | |
146 | } | |
147 | ||
148 | return_ACPI_STATUS (status); | |
149 | } | |
150 | ||
151 | ||
152 | /******************************************************************************* | |
153 | * | |
154 | * FUNCTION: acpi_enable_event | |
155 | * | |
156 | * PARAMETERS: Event - The fixed eventto be enabled | |
157 | * Flags - Reserved | |
158 | * | |
159 | * RETURN: Status | |
160 | * | |
161 | * DESCRIPTION: Enable an ACPI event (fixed) | |
162 | * | |
163 | ******************************************************************************/ | |
164 | ||
165 | acpi_status | |
166 | acpi_enable_event ( | |
167 | u32 event, | |
168 | u32 flags) | |
169 | { | |
170 | acpi_status status = AE_OK; | |
171 | u32 value; | |
172 | ||
173 | ||
174 | ACPI_FUNCTION_TRACE ("acpi_enable_event"); | |
175 | ||
176 | ||
177 | /* Decode the Fixed Event */ | |
178 | ||
179 | if (event > ACPI_EVENT_MAX) { | |
180 | return_ACPI_STATUS (AE_BAD_PARAMETER); | |
181 | } | |
182 | ||
183 | /* | |
184 | * Enable the requested fixed event (by writing a one to the | |
185 | * enable register bit) | |
186 | */ | |
187 | status = acpi_set_register (acpi_gbl_fixed_event_info[event].enable_register_id, | |
188 | 1, ACPI_MTX_LOCK); | |
189 | if (ACPI_FAILURE (status)) { | |
190 | return_ACPI_STATUS (status); | |
191 | } | |
192 | ||
193 | /* Make sure that the hardware responded */ | |
194 | ||
195 | status = acpi_get_register (acpi_gbl_fixed_event_info[event].enable_register_id, | |
196 | &value, ACPI_MTX_LOCK); | |
197 | if (ACPI_FAILURE (status)) { | |
198 | return_ACPI_STATUS (status); | |
199 | } | |
200 | ||
201 | if (value != 1) { | |
202 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | |
203 | "Could not enable %s event\n", acpi_ut_get_event_name (event))); | |
204 | return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE); | |
205 | } | |
206 | ||
207 | return_ACPI_STATUS (status); | |
208 | } | |
209 | EXPORT_SYMBOL(acpi_enable_event); | |
210 | ||
211 | ||
212 | /******************************************************************************* | |
213 | * | |
214 | * FUNCTION: acpi_set_gpe_type | |
215 | * | |
216 | * PARAMETERS: gpe_device - Parent GPE Device | |
217 | * gpe_number - GPE level within the GPE block | |
218 | * Type - New GPE type | |
219 | * | |
220 | * RETURN: Status | |
221 | * | |
44f6c012 | 222 | * DESCRIPTION: Set the type of an individual GPE |
1da177e4 LT |
223 | * |
224 | ******************************************************************************/ | |
225 | ||
226 | acpi_status | |
227 | acpi_set_gpe_type ( | |
228 | acpi_handle gpe_device, | |
229 | u32 gpe_number, | |
230 | u8 type) | |
231 | { | |
232 | acpi_status status = AE_OK; | |
233 | struct acpi_gpe_event_info *gpe_event_info; | |
234 | ||
235 | ||
236 | ACPI_FUNCTION_TRACE ("acpi_set_gpe_type"); | |
237 | ||
238 | ||
239 | /* Ensure that we have a valid GPE number */ | |
240 | ||
241 | gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number); | |
242 | if (!gpe_event_info) { | |
243 | status = AE_BAD_PARAMETER; | |
244 | goto unlock_and_exit; | |
245 | } | |
246 | ||
247 | if ((gpe_event_info->flags & ACPI_GPE_TYPE_MASK) == type) { | |
248 | return_ACPI_STATUS (AE_OK); | |
249 | } | |
250 | ||
251 | /* Set the new type (will disable GPE if currently enabled) */ | |
252 | ||
253 | status = acpi_ev_set_gpe_type (gpe_event_info, type); | |
254 | ||
255 | unlock_and_exit: | |
256 | return_ACPI_STATUS (status); | |
257 | } | |
258 | EXPORT_SYMBOL(acpi_set_gpe_type); | |
259 | ||
260 | ||
261 | /******************************************************************************* | |
262 | * | |
263 | * FUNCTION: acpi_enable_gpe | |
264 | * | |
265 | * PARAMETERS: gpe_device - Parent GPE Device | |
266 | * gpe_number - GPE level within the GPE block | |
267 | * Flags - Just enable, or also wake enable? | |
268 | * Called from ISR or not | |
269 | * | |
270 | * RETURN: Status | |
271 | * | |
272 | * DESCRIPTION: Enable an ACPI event (general purpose) | |
273 | * | |
274 | ******************************************************************************/ | |
275 | ||
276 | acpi_status | |
277 | acpi_enable_gpe ( | |
278 | acpi_handle gpe_device, | |
279 | u32 gpe_number, | |
280 | u32 flags) | |
281 | { | |
282 | acpi_status status = AE_OK; | |
283 | struct acpi_gpe_event_info *gpe_event_info; | |
284 | ||
285 | ||
286 | ACPI_FUNCTION_TRACE ("acpi_enable_gpe"); | |
287 | ||
288 | ||
289 | /* Use semaphore lock if not executing at interrupt level */ | |
290 | ||
291 | if (flags & ACPI_NOT_ISR) { | |
292 | status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS); | |
293 | if (ACPI_FAILURE (status)) { | |
294 | return_ACPI_STATUS (status); | |
295 | } | |
296 | } | |
297 | ||
298 | /* Ensure that we have a valid GPE number */ | |
299 | ||
300 | gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number); | |
301 | if (!gpe_event_info) { | |
302 | status = AE_BAD_PARAMETER; | |
303 | goto unlock_and_exit; | |
304 | } | |
305 | ||
306 | /* Perform the enable */ | |
307 | ||
308 | status = acpi_ev_enable_gpe (gpe_event_info, TRUE); | |
309 | ||
310 | unlock_and_exit: | |
311 | if (flags & ACPI_NOT_ISR) { | |
312 | (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS); | |
313 | } | |
314 | return_ACPI_STATUS (status); | |
315 | } | |
316 | EXPORT_SYMBOL(acpi_enable_gpe); | |
317 | ||
318 | ||
319 | /******************************************************************************* | |
320 | * | |
321 | * FUNCTION: acpi_disable_gpe | |
322 | * | |
323 | * PARAMETERS: gpe_device - Parent GPE Device | |
324 | * gpe_number - GPE level within the GPE block | |
325 | * Flags - Just disable, or also wake disable? | |
326 | * Called from ISR or not | |
327 | * | |
328 | * RETURN: Status | |
329 | * | |
330 | * DESCRIPTION: Disable an ACPI event (general purpose) | |
331 | * | |
332 | ******************************************************************************/ | |
333 | ||
334 | acpi_status | |
335 | acpi_disable_gpe ( | |
336 | acpi_handle gpe_device, | |
337 | u32 gpe_number, | |
338 | u32 flags) | |
339 | { | |
340 | acpi_status status = AE_OK; | |
341 | struct acpi_gpe_event_info *gpe_event_info; | |
342 | ||
343 | ||
344 | ACPI_FUNCTION_TRACE ("acpi_disable_gpe"); | |
345 | ||
346 | ||
347 | /* Use semaphore lock if not executing at interrupt level */ | |
348 | ||
349 | if (flags & ACPI_NOT_ISR) { | |
350 | status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS); | |
351 | if (ACPI_FAILURE (status)) { | |
352 | return_ACPI_STATUS (status); | |
353 | } | |
354 | } | |
355 | ||
356 | /* Ensure that we have a valid GPE number */ | |
357 | ||
358 | gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number); | |
359 | if (!gpe_event_info) { | |
360 | status = AE_BAD_PARAMETER; | |
361 | goto unlock_and_exit; | |
362 | } | |
363 | ||
364 | status = acpi_ev_disable_gpe (gpe_event_info); | |
365 | ||
366 | unlock_and_exit: | |
367 | if (flags & ACPI_NOT_ISR) { | |
368 | (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS); | |
369 | } | |
370 | return_ACPI_STATUS (status); | |
371 | } | |
372 | ||
373 | ||
374 | /******************************************************************************* | |
375 | * | |
376 | * FUNCTION: acpi_disable_event | |
377 | * | |
378 | * PARAMETERS: Event - The fixed eventto be enabled | |
379 | * Flags - Reserved | |
380 | * | |
381 | * RETURN: Status | |
382 | * | |
383 | * DESCRIPTION: Disable an ACPI event (fixed) | |
384 | * | |
385 | ******************************************************************************/ | |
386 | ||
387 | acpi_status | |
388 | acpi_disable_event ( | |
389 | u32 event, | |
390 | u32 flags) | |
391 | { | |
392 | acpi_status status = AE_OK; | |
393 | u32 value; | |
394 | ||
395 | ||
396 | ACPI_FUNCTION_TRACE ("acpi_disable_event"); | |
397 | ||
398 | ||
399 | /* Decode the Fixed Event */ | |
400 | ||
401 | if (event > ACPI_EVENT_MAX) { | |
402 | return_ACPI_STATUS (AE_BAD_PARAMETER); | |
403 | } | |
404 | ||
405 | /* | |
406 | * Disable the requested fixed event (by writing a zero to the | |
407 | * enable register bit) | |
408 | */ | |
409 | status = acpi_set_register (acpi_gbl_fixed_event_info[event].enable_register_id, | |
410 | 0, ACPI_MTX_LOCK); | |
411 | if (ACPI_FAILURE (status)) { | |
412 | return_ACPI_STATUS (status); | |
413 | } | |
414 | ||
415 | status = acpi_get_register (acpi_gbl_fixed_event_info[event].enable_register_id, | |
416 | &value, ACPI_MTX_LOCK); | |
417 | if (ACPI_FAILURE (status)) { | |
418 | return_ACPI_STATUS (status); | |
419 | } | |
420 | ||
421 | if (value != 0) { | |
422 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | |
423 | "Could not disable %s events\n", acpi_ut_get_event_name (event))); | |
424 | return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE); | |
425 | } | |
426 | ||
427 | return_ACPI_STATUS (status); | |
428 | } | |
429 | EXPORT_SYMBOL(acpi_disable_event); | |
430 | ||
431 | ||
432 | /******************************************************************************* | |
433 | * | |
434 | * FUNCTION: acpi_clear_event | |
435 | * | |
436 | * PARAMETERS: Event - The fixed event to be cleared | |
437 | * | |
438 | * RETURN: Status | |
439 | * | |
440 | * DESCRIPTION: Clear an ACPI event (fixed) | |
441 | * | |
442 | ******************************************************************************/ | |
443 | ||
444 | acpi_status | |
445 | acpi_clear_event ( | |
446 | u32 event) | |
447 | { | |
448 | acpi_status status = AE_OK; | |
449 | ||
450 | ||
451 | ACPI_FUNCTION_TRACE ("acpi_clear_event"); | |
452 | ||
453 | ||
454 | /* Decode the Fixed Event */ | |
455 | ||
456 | if (event > ACPI_EVENT_MAX) { | |
457 | return_ACPI_STATUS (AE_BAD_PARAMETER); | |
458 | } | |
459 | ||
460 | /* | |
461 | * Clear the requested fixed event (By writing a one to the | |
462 | * status register bit) | |
463 | */ | |
464 | status = acpi_set_register (acpi_gbl_fixed_event_info[event].status_register_id, | |
465 | 1, ACPI_MTX_LOCK); | |
466 | ||
467 | return_ACPI_STATUS (status); | |
468 | } | |
469 | EXPORT_SYMBOL(acpi_clear_event); | |
470 | ||
471 | ||
472 | /******************************************************************************* | |
473 | * | |
474 | * FUNCTION: acpi_clear_gpe | |
475 | * | |
476 | * PARAMETERS: gpe_device - Parent GPE Device | |
477 | * gpe_number - GPE level within the GPE block | |
478 | * Flags - Called from an ISR or not | |
479 | * | |
480 | * RETURN: Status | |
481 | * | |
482 | * DESCRIPTION: Clear an ACPI event (general purpose) | |
483 | * | |
484 | ******************************************************************************/ | |
485 | ||
486 | acpi_status | |
487 | acpi_clear_gpe ( | |
488 | acpi_handle gpe_device, | |
489 | u32 gpe_number, | |
490 | u32 flags) | |
491 | { | |
492 | acpi_status status = AE_OK; | |
493 | struct acpi_gpe_event_info *gpe_event_info; | |
494 | ||
495 | ||
496 | ACPI_FUNCTION_TRACE ("acpi_clear_gpe"); | |
497 | ||
498 | ||
499 | /* Use semaphore lock if not executing at interrupt level */ | |
500 | ||
501 | if (flags & ACPI_NOT_ISR) { | |
502 | status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS); | |
503 | if (ACPI_FAILURE (status)) { | |
504 | return_ACPI_STATUS (status); | |
505 | } | |
506 | } | |
507 | ||
508 | /* Ensure that we have a valid GPE number */ | |
509 | ||
510 | gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number); | |
511 | if (!gpe_event_info) { | |
512 | status = AE_BAD_PARAMETER; | |
513 | goto unlock_and_exit; | |
514 | } | |
515 | ||
516 | status = acpi_hw_clear_gpe (gpe_event_info); | |
517 | ||
518 | unlock_and_exit: | |
519 | if (flags & ACPI_NOT_ISR) { | |
520 | (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS); | |
521 | } | |
522 | return_ACPI_STATUS (status); | |
523 | } | |
524 | ||
525 | ||
526 | #ifdef ACPI_FUTURE_USAGE | |
1da177e4 LT |
527 | /******************************************************************************* |
528 | * | |
529 | * FUNCTION: acpi_get_event_status | |
530 | * | |
531 | * PARAMETERS: Event - The fixed event | |
44f6c012 | 532 | * event_status - Where the current status of the event will |
1da177e4 LT |
533 | * be returned |
534 | * | |
535 | * RETURN: Status | |
536 | * | |
537 | * DESCRIPTION: Obtains and returns the current status of the event | |
538 | * | |
539 | ******************************************************************************/ | |
540 | ||
541 | acpi_status | |
542 | acpi_get_event_status ( | |
543 | u32 event, | |
544 | acpi_event_status *event_status) | |
545 | { | |
546 | acpi_status status = AE_OK; | |
547 | ||
548 | ||
549 | ACPI_FUNCTION_TRACE ("acpi_get_event_status"); | |
550 | ||
551 | ||
552 | if (!event_status) { | |
553 | return_ACPI_STATUS (AE_BAD_PARAMETER); | |
554 | } | |
555 | ||
556 | /* Decode the Fixed Event */ | |
557 | ||
558 | if (event > ACPI_EVENT_MAX) { | |
559 | return_ACPI_STATUS (AE_BAD_PARAMETER); | |
560 | } | |
561 | ||
562 | /* Get the status of the requested fixed event */ | |
563 | ||
564 | status = acpi_get_register (acpi_gbl_fixed_event_info[event].status_register_id, | |
565 | event_status, ACPI_MTX_LOCK); | |
566 | ||
567 | return_ACPI_STATUS (status); | |
568 | } | |
569 | ||
570 | ||
571 | /******************************************************************************* | |
572 | * | |
573 | * FUNCTION: acpi_get_gpe_status | |
574 | * | |
575 | * PARAMETERS: gpe_device - Parent GPE Device | |
576 | * gpe_number - GPE level within the GPE block | |
577 | * Flags - Called from an ISR or not | |
44f6c012 | 578 | * event_status - Where the current status of the event will |
1da177e4 LT |
579 | * be returned |
580 | * | |
581 | * RETURN: Status | |
582 | * | |
583 | * DESCRIPTION: Get status of an event (general purpose) | |
584 | * | |
585 | ******************************************************************************/ | |
586 | ||
587 | acpi_status | |
588 | acpi_get_gpe_status ( | |
589 | acpi_handle gpe_device, | |
590 | u32 gpe_number, | |
591 | u32 flags, | |
592 | acpi_event_status *event_status) | |
593 | { | |
594 | acpi_status status = AE_OK; | |
595 | struct acpi_gpe_event_info *gpe_event_info; | |
596 | ||
597 | ||
598 | ACPI_FUNCTION_TRACE ("acpi_get_gpe_status"); | |
599 | ||
600 | ||
601 | /* Use semaphore lock if not executing at interrupt level */ | |
602 | ||
603 | if (flags & ACPI_NOT_ISR) { | |
604 | status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS); | |
605 | if (ACPI_FAILURE (status)) { | |
606 | return_ACPI_STATUS (status); | |
607 | } | |
608 | } | |
609 | ||
610 | /* Ensure that we have a valid GPE number */ | |
611 | ||
612 | gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number); | |
613 | if (!gpe_event_info) { | |
614 | status = AE_BAD_PARAMETER; | |
615 | goto unlock_and_exit; | |
616 | } | |
617 | ||
618 | /* Obtain status on the requested GPE number */ | |
619 | ||
620 | status = acpi_hw_get_gpe_status (gpe_event_info, event_status); | |
621 | ||
622 | unlock_and_exit: | |
623 | if (flags & ACPI_NOT_ISR) { | |
624 | (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS); | |
625 | } | |
626 | return_ACPI_STATUS (status); | |
627 | } | |
628 | #endif /* ACPI_FUTURE_USAGE */ | |
629 | ||
630 | ||
631 | /******************************************************************************* | |
632 | * | |
633 | * FUNCTION: acpi_install_gpe_block | |
634 | * | |
635 | * PARAMETERS: gpe_device - Handle to the parent GPE Block Device | |
636 | * gpe_block_address - Address and space_iD | |
637 | * register_count - Number of GPE register pairs in the block | |
6f42ccf2 | 638 | * interrupt_number - H/W interrupt for the block |
1da177e4 LT |
639 | * |
640 | * RETURN: Status | |
641 | * | |
642 | * DESCRIPTION: Create and Install a block of GPE registers | |
643 | * | |
644 | ******************************************************************************/ | |
645 | ||
646 | acpi_status | |
647 | acpi_install_gpe_block ( | |
648 | acpi_handle gpe_device, | |
649 | struct acpi_generic_address *gpe_block_address, | |
650 | u32 register_count, | |
6f42ccf2 | 651 | u32 interrupt_number) |
1da177e4 LT |
652 | { |
653 | acpi_status status; | |
654 | union acpi_operand_object *obj_desc; | |
655 | struct acpi_namespace_node *node; | |
656 | struct acpi_gpe_block_info *gpe_block; | |
657 | ||
658 | ||
659 | ACPI_FUNCTION_TRACE ("acpi_install_gpe_block"); | |
660 | ||
661 | ||
662 | if ((!gpe_device) || | |
663 | (!gpe_block_address) || | |
664 | (!register_count)) { | |
665 | return_ACPI_STATUS (AE_BAD_PARAMETER); | |
666 | } | |
667 | ||
668 | status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); | |
669 | if (ACPI_FAILURE (status)) { | |
670 | return (status); | |
671 | } | |
672 | ||
673 | node = acpi_ns_map_handle_to_node (gpe_device); | |
674 | if (!node) { | |
675 | status = AE_BAD_PARAMETER; | |
676 | goto unlock_and_exit; | |
677 | } | |
678 | ||
679 | /* | |
680 | * For user-installed GPE Block Devices, the gpe_block_base_number | |
681 | * is always zero | |
682 | */ | |
683 | status = acpi_ev_create_gpe_block (node, gpe_block_address, register_count, | |
6f42ccf2 | 684 | 0, interrupt_number, &gpe_block); |
1da177e4 LT |
685 | if (ACPI_FAILURE (status)) { |
686 | goto unlock_and_exit; | |
687 | } | |
688 | ||
689 | /* Get the device_object attached to the node */ | |
690 | ||
691 | obj_desc = acpi_ns_get_attached_object (node); | |
692 | if (!obj_desc) { | |
693 | /* No object, create a new one */ | |
694 | ||
695 | obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_DEVICE); | |
696 | if (!obj_desc) { | |
697 | status = AE_NO_MEMORY; | |
698 | goto unlock_and_exit; | |
699 | } | |
700 | ||
701 | status = acpi_ns_attach_object (node, obj_desc, ACPI_TYPE_DEVICE); | |
702 | ||
703 | /* Remove local reference to the object */ | |
704 | ||
705 | acpi_ut_remove_reference (obj_desc); | |
706 | ||
707 | if (ACPI_FAILURE (status)) { | |
708 | goto unlock_and_exit; | |
709 | } | |
710 | } | |
711 | ||
712 | /* Install the GPE block in the device_object */ | |
713 | ||
714 | obj_desc->device.gpe_block = gpe_block; | |
715 | ||
716 | ||
717 | unlock_and_exit: | |
718 | (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); | |
719 | return_ACPI_STATUS (status); | |
720 | } | |
721 | EXPORT_SYMBOL(acpi_install_gpe_block); | |
722 | ||
723 | ||
724 | /******************************************************************************* | |
725 | * | |
726 | * FUNCTION: acpi_remove_gpe_block | |
727 | * | |
728 | * PARAMETERS: gpe_device - Handle to the parent GPE Block Device | |
729 | * | |
730 | * RETURN: Status | |
731 | * | |
732 | * DESCRIPTION: Remove a previously installed block of GPE registers | |
733 | * | |
734 | ******************************************************************************/ | |
735 | ||
736 | acpi_status | |
737 | acpi_remove_gpe_block ( | |
738 | acpi_handle gpe_device) | |
739 | { | |
740 | union acpi_operand_object *obj_desc; | |
741 | acpi_status status; | |
742 | struct acpi_namespace_node *node; | |
743 | ||
744 | ||
745 | ACPI_FUNCTION_TRACE ("acpi_remove_gpe_block"); | |
746 | ||
747 | ||
748 | if (!gpe_device) { | |
749 | return_ACPI_STATUS (AE_BAD_PARAMETER); | |
750 | } | |
751 | ||
752 | status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); | |
753 | if (ACPI_FAILURE (status)) { | |
754 | return (status); | |
755 | } | |
756 | ||
757 | node = acpi_ns_map_handle_to_node (gpe_device); | |
758 | if (!node) { | |
759 | status = AE_BAD_PARAMETER; | |
760 | goto unlock_and_exit; | |
761 | } | |
762 | ||
763 | /* Get the device_object attached to the node */ | |
764 | ||
765 | obj_desc = acpi_ns_get_attached_object (node); | |
766 | if (!obj_desc || | |
767 | !obj_desc->device.gpe_block) { | |
768 | return_ACPI_STATUS (AE_NULL_OBJECT); | |
769 | } | |
770 | ||
771 | /* Delete the GPE block (but not the device_object) */ | |
772 | ||
773 | status = acpi_ev_delete_gpe_block (obj_desc->device.gpe_block); | |
774 | if (ACPI_SUCCESS (status)) { | |
775 | obj_desc->device.gpe_block = NULL; | |
776 | } | |
777 | ||
778 | unlock_and_exit: | |
779 | (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); | |
780 | return_ACPI_STATUS (status); | |
781 | } | |
44f6c012 | 782 | |
1da177e4 | 783 | EXPORT_SYMBOL(acpi_remove_gpe_block); |