ACPICA: Lindent
[linux-block.git] / drivers / acpi / events / evmisc.c
CommitLineData
1da177e4
LT
1/******************************************************************************
2 *
3 * Module Name: evmisc - Miscellaneous event manager support functions
4 *
5 *****************************************************************************/
6
7/*
6c9deb72 8 * Copyright (C) 2000 - 2007, R. Byron Moore
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
44#include <acpi/acpi.h>
45#include <acpi/acevents.h>
46#include <acpi/acnamesp.h>
47#include <acpi/acinterp.h>
48
49#define _COMPONENT ACPI_EVENTS
4be44fcd 50ACPI_MODULE_NAME("evmisc")
1da177e4 51
4119532c 52/* Names for Notify() values, used for debug output */
44f6c012 53#ifdef ACPI_DEBUG_OUTPUT
4be44fcd 54static const char *acpi_notify_value_names[] = {
44f6c012
RM
55 "Bus Check",
56 "Device Check",
57 "Device Wake",
4119532c 58 "Eject Request",
44f6c012
RM
59 "Device Check Light",
60 "Frequency Mismatch",
61 "Bus Mode Mismatch",
62 "Power Fault"
63};
64#endif
65
f3d2e786
BM
66/* Pointer to FACS needed for the Global Lock */
67
68static struct acpi_table_facs *facs = NULL;
69
44f6c012
RM
70/* Local prototypes */
71
4be44fcd 72static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context);
44f6c012 73
4be44fcd 74static u32 acpi_ev_global_lock_handler(void *context);
44f6c012 75
8876016b
BM
76static acpi_status acpi_ev_remove_global_lock_handler(void);
77
1da177e4
LT
78/*******************************************************************************
79 *
80 * FUNCTION: acpi_ev_is_notify_object
81 *
82 * PARAMETERS: Node - Node to check
83 *
84 * RETURN: TRUE if notifies allowed on this object
85 *
86 * DESCRIPTION: Check type of node for a object that supports notifies.
87 *
88 * TBD: This could be replaced by a flag bit in the node.
89 *
90 ******************************************************************************/
91
4be44fcd 92u8 acpi_ev_is_notify_object(struct acpi_namespace_node *node)
1da177e4
LT
93{
94 switch (node->type) {
95 case ACPI_TYPE_DEVICE:
96 case ACPI_TYPE_PROCESSOR:
97 case ACPI_TYPE_POWER:
98 case ACPI_TYPE_THERMAL:
99 /*
100 * These are the ONLY objects that can receive ACPI notifications
101 */
102 return (TRUE);
103
104 default:
105 return (FALSE);
106 }
107}
108
1da177e4
LT
109/*******************************************************************************
110 *
111 * FUNCTION: acpi_ev_queue_notify_request
112 *
113 * PARAMETERS: Node - NS node for the notified object
114 * notify_value - Value from the Notify() request
115 *
116 * RETURN: Status
117 *
118 * DESCRIPTION: Dispatch a device notification event to a previously
119 * installed handler.
120 *
121 ******************************************************************************/
122
1da177e4 123acpi_status
4be44fcd
LB
124acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
125 u32 notify_value)
1da177e4 126{
4be44fcd
LB
127 union acpi_operand_object *obj_desc;
128 union acpi_operand_object *handler_obj = NULL;
129 union acpi_generic_state *notify_info;
130 acpi_status status = AE_OK;
1da177e4 131
b229cf92 132 ACPI_FUNCTION_NAME(ev_queue_notify_request);
1da177e4
LT
133
134 /*
135 * For value 3 (Ejection Request), some device method may need to be run.
44f6c012
RM
136 * For value 2 (Device Wake) if _PRW exists, the _PS0 method may need
137 * to be run.
1da177e4 138 * For value 0x80 (Status Change) on the power button or sleep button,
44f6c012 139 * initiate soft-off or sleep operation?
1da177e4 140 */
4be44fcd
LB
141 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
142 "Dispatching Notify(%X) on node %p\n", notify_value,
143 node));
1da177e4
LT
144
145 if (notify_value <= 7) {
4be44fcd
LB
146 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Notify value: %s\n",
147 acpi_notify_value_names[notify_value]));
148 } else {
149 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
150 "Notify value: 0x%2.2X **Device Specific**\n",
151 notify_value));
1da177e4
LT
152 }
153
154 /* Get the notify object attached to the NS Node */
155
4be44fcd 156 obj_desc = acpi_ns_get_attached_object(node);
1da177e4 157 if (obj_desc) {
52fc0b02 158
1da177e4
LT
159 /* We have the notify object, Get the right handler */
160
161 switch (node->type) {
162 case ACPI_TYPE_DEVICE:
163 case ACPI_TYPE_THERMAL:
164 case ACPI_TYPE_PROCESSOR:
165 case ACPI_TYPE_POWER:
166
167 if (notify_value <= ACPI_MAX_SYS_NOTIFY) {
4be44fcd
LB
168 handler_obj =
169 obj_desc->common_notify.system_notify;
170 } else {
171 handler_obj =
172 obj_desc->common_notify.device_notify;
1da177e4
LT
173 }
174 break;
175
176 default:
177 /* All other types are not supported */
178 return (AE_TYPE);
179 }
180 }
181
182 /* If there is any handler to run, schedule the dispatcher */
183
4be44fcd
LB
184 if ((acpi_gbl_system_notify.handler
185 && (notify_value <= ACPI_MAX_SYS_NOTIFY))
186 || (acpi_gbl_device_notify.handler
187 && (notify_value > ACPI_MAX_SYS_NOTIFY)) || handler_obj) {
188 notify_info = acpi_ut_create_generic_state();
1da177e4
LT
189 if (!notify_info) {
190 return (AE_NO_MEMORY);
191 }
192
61686124
BM
193 notify_info->common.descriptor_type =
194 ACPI_DESC_TYPE_STATE_NOTIFY;
4be44fcd
LB
195 notify_info->notify.node = node;
196 notify_info->notify.value = (u16) notify_value;
1da177e4
LT
197 notify_info->notify.handler_obj = handler_obj;
198
40d07080
LB
199 status =
200 acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_notify_dispatch,
201 notify_info);
202 if (ACPI_FAILURE(status)) {
203 acpi_ut_delete_generic_state(notify_info);
204 }
1da177e4
LT
205 }
206
207 if (!handler_obj) {
208 /*
209 * There is no per-device notify handler for this device.
210 * This may or may not be a problem.
211 */
4be44fcd
LB
212 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
213 "No notify handler for Notify(%4.4s, %X) node %p\n",
214 acpi_ut_get_node_name(node), notify_value,
215 node));
1da177e4
LT
216 }
217
218 return (status);
219}
220
1da177e4
LT
221/*******************************************************************************
222 *
223 * FUNCTION: acpi_ev_notify_dispatch
224 *
44f6c012 225 * PARAMETERS: Context - To be passed to the notify handler
1da177e4
LT
226 *
227 * RETURN: None.
228 *
229 * DESCRIPTION: Dispatch a device notification event to a previously
230 * installed handler.
231 *
232 ******************************************************************************/
233
4be44fcd 234static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context)
1da177e4 235{
4be44fcd
LB
236 union acpi_generic_state *notify_info =
237 (union acpi_generic_state *)context;
238 acpi_notify_handler global_handler = NULL;
239 void *global_context = NULL;
240 union acpi_operand_object *handler_obj;
1da177e4 241
4be44fcd 242 ACPI_FUNCTION_ENTRY();
1da177e4
LT
243
244 /*
245 * We will invoke a global notify handler if installed.
44f6c012
RM
246 * This is done _before_ we invoke the per-device handler attached
247 * to the device.
1da177e4
LT
248 */
249 if (notify_info->notify.value <= ACPI_MAX_SYS_NOTIFY) {
52fc0b02 250
1da177e4
LT
251 /* Global system notification handler */
252
253 if (acpi_gbl_system_notify.handler) {
254 global_handler = acpi_gbl_system_notify.handler;
255 global_context = acpi_gbl_system_notify.context;
256 }
4be44fcd 257 } else {
1da177e4
LT
258 /* Global driver notification handler */
259
260 if (acpi_gbl_device_notify.handler) {
261 global_handler = acpi_gbl_device_notify.handler;
262 global_context = acpi_gbl_device_notify.context;
263 }
264 }
265
266 /* Invoke the system handler first, if present */
267
268 if (global_handler) {
4be44fcd
LB
269 global_handler(notify_info->notify.node,
270 notify_info->notify.value, global_context);
1da177e4
LT
271 }
272
273 /* Now invoke the per-device handler, if present */
274
275 handler_obj = notify_info->notify.handler_obj;
276 if (handler_obj) {
4be44fcd
LB
277 handler_obj->notify.handler(notify_info->notify.node,
278 notify_info->notify.value,
279 handler_obj->notify.context);
1da177e4
LT
280 }
281
282 /* All done with the info object */
283
4be44fcd 284 acpi_ut_delete_generic_state(notify_info);
1da177e4
LT
285}
286
1da177e4
LT
287/*******************************************************************************
288 *
289 * FUNCTION: acpi_ev_global_lock_handler
290 *
291 * PARAMETERS: Context - From thread interface, not used
292 *
a72d4756 293 * RETURN: ACPI_INTERRUPT_HANDLED
1da177e4
LT
294 *
295 * DESCRIPTION: Invoked directly from the SCI handler when a global lock
a72d4756
BM
296 * release interrupt occurs. Attempt to acquire the global lock,
297 * if successful, signal the thread waiting for the lock.
298 *
299 * NOTE: Assumes that the semaphore can be signaled from interrupt level. If
300 * this is not possible for some reason, a separate thread will have to be
301 * scheduled to do this.
1da177e4
LT
302 *
303 ******************************************************************************/
304
4be44fcd 305static u32 acpi_ev_global_lock_handler(void *context)
1da177e4 306{
4be44fcd 307 u8 acquired = FALSE;
1da177e4
LT
308
309 /*
c81da666
BM
310 * Attempt to get the lock.
311 *
1da177e4
LT
312 * If we don't get it now, it will be marked pending and we will
313 * take another interrupt when it becomes free.
314 */
f3d2e786 315 ACPI_ACQUIRE_GLOBAL_LOCK(facs, acquired);
1da177e4 316 if (acquired) {
52fc0b02 317
1da177e4 318 /* Got the lock, now wake all threads waiting for it */
c81da666 319
1da177e4 320 acpi_gbl_global_lock_acquired = TRUE;
a72d4756
BM
321 /* Send a unit to the semaphore */
322
fd350943
LB
323 if (ACPI_FAILURE
324 (acpi_os_signal_semaphore
325 (acpi_gbl_global_lock_semaphore, 1))) {
a72d4756
BM
326 ACPI_ERROR((AE_INFO,
327 "Could not signal Global Lock semaphore"));
328 }
1da177e4
LT
329 }
330
331 return (ACPI_INTERRUPT_HANDLED);
332}
333
1da177e4
LT
334/*******************************************************************************
335 *
336 * FUNCTION: acpi_ev_init_global_lock_handler
337 *
338 * PARAMETERS: None
339 *
340 * RETURN: Status
341 *
342 * DESCRIPTION: Install a handler for the global lock release event
343 *
344 ******************************************************************************/
345
4be44fcd 346acpi_status acpi_ev_init_global_lock_handler(void)
1da177e4 347{
4be44fcd 348 acpi_status status;
1da177e4 349
b229cf92 350 ACPI_FUNCTION_TRACE(ev_init_global_lock_handler);
1da177e4 351
f3d2e786 352 status =
310a7f7f
BM
353 acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS,
354 (struct acpi_table_header **)&facs);
f3d2e786
BM
355 if (ACPI_FAILURE(status)) {
356 return_ACPI_STATUS(status);
357 }
358
1da177e4 359 acpi_gbl_global_lock_present = TRUE;
4be44fcd
LB
360 status = acpi_install_fixed_event_handler(ACPI_EVENT_GLOBAL,
361 acpi_ev_global_lock_handler,
362 NULL);
1da177e4
LT
363
364 /*
365 * If the global lock does not exist on this platform, the attempt
366 * to enable GBL_STATUS will fail (the GBL_ENABLE bit will not stick)
367 * Map to AE_OK, but mark global lock as not present.
368 * Any attempt to actually use the global lock will be flagged
369 * with an error.
370 */
371 if (status == AE_NO_HARDWARE_RESPONSE) {
b8e4d893
BM
372 ACPI_ERROR((AE_INFO,
373 "No response from Global Lock hardware, disabling lock"));
0c9938cc 374
1da177e4
LT
375 acpi_gbl_global_lock_present = FALSE;
376 status = AE_OK;
377 }
378
4be44fcd 379 return_ACPI_STATUS(status);
1da177e4
LT
380}
381
8876016b
BM
382/*******************************************************************************
383 *
384 * FUNCTION: acpi_ev_remove_global_lock_handler
385 *
386 * PARAMETERS: None
387 *
388 * RETURN: Status
389 *
390 * DESCRIPTION: Remove the handler for the Global Lock
391 *
392 ******************************************************************************/
393
394static acpi_status acpi_ev_remove_global_lock_handler(void)
395{
396 acpi_status status;
397
398 ACPI_FUNCTION_TRACE(ev_remove_global_lock_handler);
399
400 acpi_gbl_global_lock_present = FALSE;
401 status = acpi_remove_fixed_event_handler(ACPI_EVENT_GLOBAL,
402 acpi_ev_global_lock_handler);
403
404 return_ACPI_STATUS(status);
405}
406
1da177e4
LT
407/******************************************************************************
408 *
409 * FUNCTION: acpi_ev_acquire_global_lock
410 *
411 * PARAMETERS: Timeout - Max time to wait for the lock, in millisec.
412 *
413 * RETURN: Status
414 *
415 * DESCRIPTION: Attempt to gain ownership of the Global Lock.
416 *
c81da666
BM
417 * MUTEX: Interpreter must be locked
418 *
419 * Note: The original implementation allowed multiple threads to "acquire" the
420 * Global Lock, and the OS would hold the lock until the last thread had
421 * released it. However, this could potentially starve the BIOS out of the
422 * lock, especially in the case where there is a tight handshake between the
423 * Embedded Controller driver and the BIOS. Therefore, this implementation
424 * allows only one thread to acquire the HW Global Lock at a time, and makes
425 * the global lock appear as a standard mutex on the OS side.
426 *
1da177e4 427 *****************************************************************************/
610a3d06
AS
428static acpi_thread_id acpi_ev_global_lock_thread_id;
429static int acpi_ev_global_lock_acquired;
1da177e4 430
4be44fcd 431acpi_status acpi_ev_acquire_global_lock(u16 timeout)
1da177e4 432{
4be44fcd
LB
433 acpi_status status = AE_OK;
434 u8 acquired = FALSE;
1da177e4 435
b229cf92 436 ACPI_FUNCTION_TRACE(ev_acquire_global_lock);
1da177e4 437
c81da666
BM
438 /*
439 * Only one thread can acquire the GL at a time, the global_lock_mutex
440 * enforces this. This interface releases the interpreter if we must wait.
441 */
610a3d06
AS
442 status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, 0);
443 if (status == AE_TIME) {
444 if (acpi_ev_global_lock_thread_id == acpi_os_get_thread_id()) {
445 acpi_ev_global_lock_acquired++;
446 return AE_OK;
447 }
448 }
449
450 if (ACPI_FAILURE(status)) {
fd350943
LB
451 status =
452 acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex,
453 timeout);
610a3d06 454 }
c81da666
BM
455 if (ACPI_FAILURE(status)) {
456 return_ACPI_STATUS(status);
1da177e4 457 }
1da177e4 458
610a3d06
AS
459 acpi_ev_global_lock_thread_id = acpi_os_get_thread_id();
460 acpi_ev_global_lock_acquired++;
461
44f6c012 462 /*
c81da666
BM
463 * Make sure that a global lock actually exists. If not, just treat
464 * the lock as a standard mutex.
44f6c012 465 */
c81da666
BM
466 if (!acpi_gbl_global_lock_present) {
467 acpi_gbl_global_lock_acquired = TRUE;
4be44fcd 468 return_ACPI_STATUS(AE_OK);
1da177e4
LT
469 }
470
c81da666 471 /* Attempt to acquire the actual hardware lock */
1da177e4 472
f3d2e786 473 ACPI_ACQUIRE_GLOBAL_LOCK(facs, acquired);
1da177e4 474 if (acquired) {
52fc0b02 475
4be44fcd 476 /* We got the lock */
1da177e4 477
4be44fcd 478 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
c81da666 479 "Acquired hardware Global Lock\n"));
1da177e4
LT
480
481 acpi_gbl_global_lock_acquired = TRUE;
4be44fcd 482 return_ACPI_STATUS(AE_OK);
1da177e4
LT
483 }
484
485 /*
c81da666 486 * Did not get the lock. The pending bit was set above, and we must now
1da177e4
LT
487 * wait until we get the global lock released interrupt.
488 */
c81da666 489 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for hardware Global Lock\n"));
1da177e4
LT
490
491 /*
c81da666
BM
492 * Wait for handshake with the global lock interrupt handler.
493 * This interface releases the interpreter if we must wait.
1da177e4 494 */
c81da666
BM
495 status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore,
496 ACPI_WAIT_FOREVER);
f3d2e786 497
4be44fcd 498 return_ACPI_STATUS(status);
1da177e4
LT
499}
500
1da177e4
LT
501/*******************************************************************************
502 *
503 * FUNCTION: acpi_ev_release_global_lock
504 *
505 * PARAMETERS: None
506 *
507 * RETURN: Status
508 *
509 * DESCRIPTION: Releases ownership of the Global Lock.
510 *
511 ******************************************************************************/
512
4be44fcd 513acpi_status acpi_ev_release_global_lock(void)
1da177e4 514{
4be44fcd
LB
515 u8 pending = FALSE;
516 acpi_status status = AE_OK;
1da177e4 517
b229cf92 518 ACPI_FUNCTION_TRACE(ev_release_global_lock);
1da177e4 519
a72d4756 520 /* Lock must be already acquired */
c81da666
BM
521
522 if (!acpi_gbl_global_lock_acquired) {
b8e4d893 523 ACPI_WARNING((AE_INFO,
c81da666 524 "Cannot release the ACPI Global Lock, it has not been acquired"));
4be44fcd 525 return_ACPI_STATUS(AE_NOT_ACQUIRED);
1da177e4
LT
526 }
527
610a3d06
AS
528 acpi_ev_global_lock_acquired--;
529 if (acpi_ev_global_lock_acquired > 0) {
530 return AE_OK;
531 }
532
c81da666 533 if (acpi_gbl_global_lock_present) {
1da177e4 534
c81da666 535 /* Allow any thread to release the lock */
52fc0b02 536
f3d2e786 537 ACPI_RELEASE_GLOBAL_LOCK(facs, pending);
1da177e4 538
c81da666
BM
539 /*
540 * If the pending bit was set, we must write GBL_RLS to the control
541 * register
542 */
543 if (pending) {
544 status =
545 acpi_set_register(ACPI_BITREG_GLOBAL_LOCK_RELEASE,
d8c71b6d 546 1);
c81da666
BM
547 }
548
549 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
550 "Released hardware Global Lock\n"));
1da177e4
LT
551 }
552
1da177e4
LT
553 acpi_gbl_global_lock_acquired = FALSE;
554
c81da666 555 /* Release the local GL mutex */
89952d13 556 acpi_ev_global_lock_thread_id = NULL;
610a3d06 557 acpi_ev_global_lock_acquired = 0;
c81da666 558 acpi_os_release_mutex(acpi_gbl_global_lock_mutex);
4be44fcd 559 return_ACPI_STATUS(status);
1da177e4
LT
560}
561
1da177e4
LT
562/******************************************************************************
563 *
564 * FUNCTION: acpi_ev_terminate
565 *
566 * PARAMETERS: none
567 *
568 * RETURN: none
569 *
570 * DESCRIPTION: Disable events and free memory allocated for table storage.
571 *
572 ******************************************************************************/
573
4be44fcd 574void acpi_ev_terminate(void)
1da177e4 575{
4be44fcd
LB
576 acpi_native_uint i;
577 acpi_status status;
1da177e4 578
b229cf92 579 ACPI_FUNCTION_TRACE(ev_terminate);
1da177e4
LT
580
581 if (acpi_gbl_events_initialized) {
582 /*
583 * Disable all event-related functionality.
584 * In all cases, on error, print a message but obviously we don't abort.
585 */
586
587 /* Disable all fixed events */
588
589 for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
4be44fcd
LB
590 status = acpi_disable_event((u32) i, 0);
591 if (ACPI_FAILURE(status)) {
b8e4d893
BM
592 ACPI_ERROR((AE_INFO,
593 "Could not disable fixed event %d",
594 (u32) i));
1da177e4
LT
595 }
596 }
597
598 /* Disable all GPEs in all GPE blocks */
599
4be44fcd 600 status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block);
1da177e4
LT
601
602 /* Remove SCI handler */
603
4be44fcd 604 status = acpi_ev_remove_sci_handler();
1da177e4 605 if (ACPI_FAILURE(status)) {
b8e4d893 606 ACPI_ERROR((AE_INFO, "Could not remove SCI handler"));
1da177e4 607 }
8876016b
BM
608
609 status = acpi_ev_remove_global_lock_handler();
610 if (ACPI_FAILURE(status)) {
611 ACPI_ERROR((AE_INFO,
612 "Could not remove Global Lock handler"));
613 }
1da177e4
LT
614 }
615
616 /* Deallocate all handler objects installed within GPE info structs */
617
4be44fcd 618 status = acpi_ev_walk_gpe_list(acpi_ev_delete_gpe_handlers);
1da177e4
LT
619
620 /* Return to original mode if necessary */
621
622 if (acpi_gbl_original_mode == ACPI_SYS_MODE_LEGACY) {
4be44fcd
LB
623 status = acpi_disable();
624 if (ACPI_FAILURE(status)) {
b229cf92 625 ACPI_WARNING((AE_INFO, "AcpiDisable failed"));
1da177e4
LT
626 }
627 }
628 return_VOID;
629}