xref: /linux/drivers/acpi/acpica/evxface.c (revision b43ab901d671e3e3cad425ea5e9a3c74e266dcdd)
1 /******************************************************************************
2  *
3  * Module Name: evxface - External interfaces for ACPI events
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2012, Intel Corp.
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/export.h>
45 #include <acpi/acpi.h>
46 #include "accommon.h"
47 #include "acnamesp.h"
48 #include "acevents.h"
49 #include "acinterp.h"
50 
51 #define _COMPONENT          ACPI_EVENTS
52 ACPI_MODULE_NAME("evxface")
53 
54 /*******************************************************************************
55  *
56  * FUNCTION:    acpi_install_exception_handler
57  *
58  * PARAMETERS:  Handler         - Pointer to the handler function for the
59  *                                event
60  *
61  * RETURN:      Status
62  *
63  * DESCRIPTION: Saves the pointer to the handler function
64  *
65  ******************************************************************************/
66 #ifdef ACPI_FUTURE_USAGE
67 acpi_status acpi_install_exception_handler(acpi_exception_handler handler)
68 {
69 	acpi_status status;
70 
71 	ACPI_FUNCTION_TRACE(acpi_install_exception_handler);
72 
73 	status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
74 	if (ACPI_FAILURE(status)) {
75 		return_ACPI_STATUS(status);
76 	}
77 
78 	/* Don't allow two handlers. */
79 
80 	if (acpi_gbl_exception_handler) {
81 		status = AE_ALREADY_EXISTS;
82 		goto cleanup;
83 	}
84 
85 	/* Install the handler */
86 
87 	acpi_gbl_exception_handler = handler;
88 
89       cleanup:
90 	(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
91 	return_ACPI_STATUS(status);
92 }
93 
94 ACPI_EXPORT_SYMBOL(acpi_install_exception_handler)
95 #endif				/*  ACPI_FUTURE_USAGE  */
96 
97 /*******************************************************************************
98  *
99  * FUNCTION:    acpi_install_global_event_handler
100  *
101  * PARAMETERS:  Handler         - Pointer to the global event handler function
102  *              Context         - Value passed to the handler on each event
103  *
104  * RETURN:      Status
105  *
106  * DESCRIPTION: Saves the pointer to the handler function. The global handler
107  *              is invoked upon each incoming GPE and Fixed Event. It is
108  *              invoked at interrupt level at the time of the event dispatch.
109  *              Can be used to update event counters, etc.
110  *
111  ******************************************************************************/
112 acpi_status
113 acpi_install_global_event_handler(ACPI_GBL_EVENT_HANDLER handler, void *context)
114 {
115 	acpi_status status;
116 
117 	ACPI_FUNCTION_TRACE(acpi_install_global_event_handler);
118 
119 	/* Parameter validation */
120 
121 	if (!handler) {
122 		return_ACPI_STATUS(AE_BAD_PARAMETER);
123 	}
124 
125 	status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
126 	if (ACPI_FAILURE(status)) {
127 		return_ACPI_STATUS(status);
128 	}
129 
130 	/* Don't allow two handlers. */
131 
132 	if (acpi_gbl_global_event_handler) {
133 		status = AE_ALREADY_EXISTS;
134 		goto cleanup;
135 	}
136 
137 	acpi_gbl_global_event_handler = handler;
138 	acpi_gbl_global_event_handler_context = context;
139 
140       cleanup:
141 	(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
142 	return_ACPI_STATUS(status);
143 }
144 
145 ACPI_EXPORT_SYMBOL(acpi_install_global_event_handler)
146 
147 /*******************************************************************************
148  *
149  * FUNCTION:    acpi_install_fixed_event_handler
150  *
151  * PARAMETERS:  Event           - Event type to enable.
152  *              Handler         - Pointer to the handler function for the
153  *                                event
154  *              Context         - Value passed to the handler on each GPE
155  *
156  * RETURN:      Status
157  *
158  * DESCRIPTION: Saves the pointer to the handler function and then enables the
159  *              event.
160  *
161  ******************************************************************************/
162 acpi_status
163 acpi_install_fixed_event_handler(u32 event,
164 				 acpi_event_handler handler, void *context)
165 {
166 	acpi_status status;
167 
168 	ACPI_FUNCTION_TRACE(acpi_install_fixed_event_handler);
169 
170 	/* Parameter validation */
171 
172 	if (event > ACPI_EVENT_MAX) {
173 		return_ACPI_STATUS(AE_BAD_PARAMETER);
174 	}
175 
176 	status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
177 	if (ACPI_FAILURE(status)) {
178 		return_ACPI_STATUS(status);
179 	}
180 
181 	/* Don't allow two handlers. */
182 
183 	if (NULL != acpi_gbl_fixed_event_handlers[event].handler) {
184 		status = AE_ALREADY_EXISTS;
185 		goto cleanup;
186 	}
187 
188 	/* Install the handler before enabling the event */
189 
190 	acpi_gbl_fixed_event_handlers[event].handler = handler;
191 	acpi_gbl_fixed_event_handlers[event].context = context;
192 
193 	status = acpi_clear_event(event);
194 	if (ACPI_SUCCESS(status))
195 		status = acpi_enable_event(event, 0);
196 	if (ACPI_FAILURE(status)) {
197 		ACPI_WARNING((AE_INFO, "Could not enable fixed event 0x%X",
198 			      event));
199 
200 		/* Remove the handler */
201 
202 		acpi_gbl_fixed_event_handlers[event].handler = NULL;
203 		acpi_gbl_fixed_event_handlers[event].context = NULL;
204 	} else {
205 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
206 				  "Enabled fixed event %X, Handler=%p\n", event,
207 				  handler));
208 	}
209 
210       cleanup:
211 	(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
212 	return_ACPI_STATUS(status);
213 }
214 
215 ACPI_EXPORT_SYMBOL(acpi_install_fixed_event_handler)
216 
217 /*******************************************************************************
218  *
219  * FUNCTION:    acpi_remove_fixed_event_handler
220  *
221  * PARAMETERS:  Event           - Event type to disable.
222  *              Handler         - Address of the handler
223  *
224  * RETURN:      Status
225  *
226  * DESCRIPTION: Disables the event and unregisters the event handler.
227  *
228  ******************************************************************************/
229 acpi_status
230 acpi_remove_fixed_event_handler(u32 event, acpi_event_handler handler)
231 {
232 	acpi_status status = AE_OK;
233 
234 	ACPI_FUNCTION_TRACE(acpi_remove_fixed_event_handler);
235 
236 	/* Parameter validation */
237 
238 	if (event > ACPI_EVENT_MAX) {
239 		return_ACPI_STATUS(AE_BAD_PARAMETER);
240 	}
241 
242 	status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
243 	if (ACPI_FAILURE(status)) {
244 		return_ACPI_STATUS(status);
245 	}
246 
247 	/* Disable the event before removing the handler */
248 
249 	status = acpi_disable_event(event, 0);
250 
251 	/* Always Remove the handler */
252 
253 	acpi_gbl_fixed_event_handlers[event].handler = NULL;
254 	acpi_gbl_fixed_event_handlers[event].context = NULL;
255 
256 	if (ACPI_FAILURE(status)) {
257 		ACPI_WARNING((AE_INFO,
258 			      "Could not write to fixed event enable register 0x%X",
259 			      event));
260 	} else {
261 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Disabled fixed event %X\n",
262 				  event));
263 	}
264 
265 	(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
266 	return_ACPI_STATUS(status);
267 }
268 
269 ACPI_EXPORT_SYMBOL(acpi_remove_fixed_event_handler)
270 
271 /*******************************************************************************
272  *
273  * FUNCTION:    acpi_populate_handler_object
274  *
275  * PARAMETERS:  handler_obj        - Handler object to populate
276  *              handler_type       - The type of handler:
277  *                                  ACPI_SYSTEM_NOTIFY: system_handler (00-7f)
278  *                                  ACPI_DEVICE_NOTIFY: driver_handler (80-ff)
279  *                                  ACPI_ALL_NOTIFY:  both system and device
280  *              handler            - Address of the handler
281  *              context            - Value passed to the handler on each GPE
282  *              next               - Address of a handler object to link to
283  *
284  * RETURN:      None
285  *
286  * DESCRIPTION: Populate a handler object.
287  *
288  ******************************************************************************/
289 static void
290 acpi_populate_handler_object(struct acpi_object_notify_handler *handler_obj,
291 			     u32 handler_type,
292 			     acpi_notify_handler handler, void *context,
293 			     struct acpi_object_notify_handler *next)
294 {
295 	handler_obj->handler_type = handler_type;
296 	handler_obj->handler = handler;
297 	handler_obj->context = context;
298 	handler_obj->next = next;
299 }
300 
301 /*******************************************************************************
302  *
303  * FUNCTION:    acpi_add_handler_object
304  *
305  * PARAMETERS:  parent_obj         - Parent of the new object
306  *              handler            - Address of the handler
307  *              context            - Value passed to the handler on each GPE
308  *
309  * RETURN:      Status
310  *
311  * DESCRIPTION: Create a new handler object and populate it.
312  *
313  ******************************************************************************/
314 static acpi_status
315 acpi_add_handler_object(struct acpi_object_notify_handler *parent_obj,
316 			acpi_notify_handler handler, void *context)
317 {
318 	struct acpi_object_notify_handler *handler_obj;
319 
320 	/* The parent must not be a defice notify handler object. */
321 	if (parent_obj->handler_type & ACPI_DEVICE_NOTIFY)
322 		return AE_BAD_PARAMETER;
323 
324 	handler_obj = ACPI_ALLOCATE_ZEROED(sizeof(*handler_obj));
325 	if (!handler_obj)
326 		return AE_NO_MEMORY;
327 
328 	acpi_populate_handler_object(handler_obj,
329 					ACPI_SYSTEM_NOTIFY,
330 					handler, context,
331 					parent_obj->next);
332 	parent_obj->next = handler_obj;
333 
334 	return AE_OK;
335 }
336 
337 /*******************************************************************************
338  *
339  * FUNCTION:    acpi_install_notify_handler
340  *
341  * PARAMETERS:  Device          - The device for which notifies will be handled
342  *              handler_type    - The type of handler:
343  *                                  ACPI_SYSTEM_NOTIFY: system_handler (00-7f)
344  *                                  ACPI_DEVICE_NOTIFY: driver_handler (80-ff)
345  *                                  ACPI_ALL_NOTIFY:  both system and device
346  *              Handler         - Address of the handler
347  *              Context         - Value passed to the handler on each GPE
348  *
349  * RETURN:      Status
350  *
351  * DESCRIPTION: Install a handler for notifies on an ACPI device
352  *
353  ******************************************************************************/
354 acpi_status
355 acpi_install_notify_handler(acpi_handle device,
356 			    u32 handler_type,
357 			    acpi_notify_handler handler, void *context)
358 {
359 	union acpi_operand_object *obj_desc;
360 	union acpi_operand_object *notify_obj;
361 	struct acpi_namespace_node *node;
362 	acpi_status status;
363 
364 	ACPI_FUNCTION_TRACE(acpi_install_notify_handler);
365 
366 	/* Parameter validation */
367 
368 	if ((!device) ||
369 	    (!handler) || (handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
370 		return_ACPI_STATUS(AE_BAD_PARAMETER);
371 	}
372 
373 	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
374 	if (ACPI_FAILURE(status)) {
375 		return_ACPI_STATUS(status);
376 	}
377 
378 	/* Convert and validate the device handle */
379 
380 	node = acpi_ns_validate_handle(device);
381 	if (!node) {
382 		status = AE_BAD_PARAMETER;
383 		goto unlock_and_exit;
384 	}
385 
386 	/*
387 	 * Root Object:
388 	 * Registering a notify handler on the root object indicates that the
389 	 * caller wishes to receive notifications for all objects. Note that
390 	 * only one <external> global handler can be regsitered (per notify type).
391 	 */
392 	if (device == ACPI_ROOT_OBJECT) {
393 
394 		/* Make sure the handler is not already installed */
395 
396 		if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
397 		     acpi_gbl_system_notify.handler) ||
398 		    ((handler_type & ACPI_DEVICE_NOTIFY) &&
399 		     acpi_gbl_device_notify.handler)) {
400 			status = AE_ALREADY_EXISTS;
401 			goto unlock_and_exit;
402 		}
403 
404 		if (handler_type & ACPI_SYSTEM_NOTIFY) {
405 			acpi_gbl_system_notify.node = node;
406 			acpi_gbl_system_notify.handler = handler;
407 			acpi_gbl_system_notify.context = context;
408 		}
409 
410 		if (handler_type & ACPI_DEVICE_NOTIFY) {
411 			acpi_gbl_device_notify.node = node;
412 			acpi_gbl_device_notify.handler = handler;
413 			acpi_gbl_device_notify.context = context;
414 		}
415 
416 		/* Global notify handler installed */
417 	}
418 
419 	/*
420 	 * All Other Objects:
421 	 * Caller will only receive notifications specific to the target object.
422 	 * Note that only certain object types can receive notifications.
423 	 */
424 	else {
425 		/* Notifies allowed on this object? */
426 
427 		if (!acpi_ev_is_notify_object(node)) {
428 			status = AE_TYPE;
429 			goto unlock_and_exit;
430 		}
431 
432 		/* Check for an existing internal object */
433 
434 		obj_desc = acpi_ns_get_attached_object(node);
435 		if (obj_desc) {
436 
437 			/* Object exists. */
438 
439 			/* For a device notify, make sure there's no handler. */
440 			if ((handler_type & ACPI_DEVICE_NOTIFY) &&
441 			     obj_desc->common_notify.device_notify) {
442 				status = AE_ALREADY_EXISTS;
443 				goto unlock_and_exit;
444 			}
445 
446 			/* System notifies may have more handlers installed. */
447 			notify_obj = obj_desc->common_notify.system_notify;
448 
449 			if ((handler_type & ACPI_SYSTEM_NOTIFY) && notify_obj) {
450 				struct acpi_object_notify_handler *parent_obj;
451 
452 				if (handler_type & ACPI_DEVICE_NOTIFY) {
453 					status = AE_ALREADY_EXISTS;
454 					goto unlock_and_exit;
455 				}
456 
457 				parent_obj = &notify_obj->notify;
458 				status = acpi_add_handler_object(parent_obj,
459 								 handler,
460 								 context);
461 				goto unlock_and_exit;
462 			}
463 		} else {
464 			/* Create a new object */
465 
466 			obj_desc = acpi_ut_create_internal_object(node->type);
467 			if (!obj_desc) {
468 				status = AE_NO_MEMORY;
469 				goto unlock_and_exit;
470 			}
471 
472 			/* Attach new object to the Node */
473 
474 			status =
475 			    acpi_ns_attach_object(device, obj_desc, node->type);
476 
477 			/* Remove local reference to the object */
478 
479 			acpi_ut_remove_reference(obj_desc);
480 			if (ACPI_FAILURE(status)) {
481 				goto unlock_and_exit;
482 			}
483 		}
484 
485 		/* Install the handler */
486 
487 		notify_obj =
488 		    acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_NOTIFY);
489 		if (!notify_obj) {
490 			status = AE_NO_MEMORY;
491 			goto unlock_and_exit;
492 		}
493 
494 		acpi_populate_handler_object(&notify_obj->notify,
495 						handler_type,
496 						handler, context,
497 						NULL);
498 
499 		if (handler_type & ACPI_SYSTEM_NOTIFY) {
500 			obj_desc->common_notify.system_notify = notify_obj;
501 		}
502 
503 		if (handler_type & ACPI_DEVICE_NOTIFY) {
504 			obj_desc->common_notify.device_notify = notify_obj;
505 		}
506 
507 		if (handler_type == ACPI_ALL_NOTIFY) {
508 
509 			/* Extra ref if installed in both */
510 
511 			acpi_ut_add_reference(notify_obj);
512 		}
513 	}
514 
515       unlock_and_exit:
516 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
517 	return_ACPI_STATUS(status);
518 }
519 
520 ACPI_EXPORT_SYMBOL(acpi_install_notify_handler)
521 
522 /*******************************************************************************
523  *
524  * FUNCTION:    acpi_remove_notify_handler
525  *
526  * PARAMETERS:  Device          - The device for which notifies will be handled
527  *              handler_type    - The type of handler:
528  *                                  ACPI_SYSTEM_NOTIFY: system_handler (00-7f)
529  *                                  ACPI_DEVICE_NOTIFY: driver_handler (80-ff)
530  *                                  ACPI_ALL_NOTIFY:  both system and device
531  *              Handler         - Address of the handler
532  *
533  * RETURN:      Status
534  *
535  * DESCRIPTION: Remove a handler for notifies on an ACPI device
536  *
537  ******************************************************************************/
538 acpi_status
539 acpi_remove_notify_handler(acpi_handle device,
540 			   u32 handler_type, acpi_notify_handler handler)
541 {
542 	union acpi_operand_object *notify_obj;
543 	union acpi_operand_object *obj_desc;
544 	struct acpi_namespace_node *node;
545 	acpi_status status;
546 
547 	ACPI_FUNCTION_TRACE(acpi_remove_notify_handler);
548 
549 	/* Parameter validation */
550 
551 	if ((!device) ||
552 	    (!handler) || (handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
553 		status = AE_BAD_PARAMETER;
554 		goto exit;
555 	}
556 
557 
558 	/* Make sure all deferred tasks are completed */
559 	acpi_os_wait_events_complete(NULL);
560 
561 	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
562 	if (ACPI_FAILURE(status)) {
563 		goto exit;
564 	}
565 
566 	/* Convert and validate the device handle */
567 
568 	node = acpi_ns_validate_handle(device);
569 	if (!node) {
570 		status = AE_BAD_PARAMETER;
571 		goto unlock_and_exit;
572 	}
573 
574 	/* Root Object */
575 
576 	if (device == ACPI_ROOT_OBJECT) {
577 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
578 				  "Removing notify handler for namespace root object\n"));
579 
580 		if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
581 		     !acpi_gbl_system_notify.handler) ||
582 		    ((handler_type & ACPI_DEVICE_NOTIFY) &&
583 		     !acpi_gbl_device_notify.handler)) {
584 			status = AE_NOT_EXIST;
585 			goto unlock_and_exit;
586 		}
587 
588 		if (handler_type & ACPI_SYSTEM_NOTIFY) {
589 			acpi_gbl_system_notify.node = NULL;
590 			acpi_gbl_system_notify.handler = NULL;
591 			acpi_gbl_system_notify.context = NULL;
592 		}
593 
594 		if (handler_type & ACPI_DEVICE_NOTIFY) {
595 			acpi_gbl_device_notify.node = NULL;
596 			acpi_gbl_device_notify.handler = NULL;
597 			acpi_gbl_device_notify.context = NULL;
598 		}
599 	}
600 
601 	/* All Other Objects */
602 
603 	else {
604 		/* Notifies allowed on this object? */
605 
606 		if (!acpi_ev_is_notify_object(node)) {
607 			status = AE_TYPE;
608 			goto unlock_and_exit;
609 		}
610 
611 		/* Check for an existing internal object */
612 
613 		obj_desc = acpi_ns_get_attached_object(node);
614 		if (!obj_desc) {
615 			status = AE_NOT_EXIST;
616 			goto unlock_and_exit;
617 		}
618 
619 		/* Object exists - make sure there's an existing handler */
620 
621 		if (handler_type & ACPI_SYSTEM_NOTIFY) {
622 			struct acpi_object_notify_handler *handler_obj;
623 			struct acpi_object_notify_handler *parent_obj;
624 
625 			notify_obj = obj_desc->common_notify.system_notify;
626 			if (!notify_obj) {
627 				status = AE_NOT_EXIST;
628 				goto unlock_and_exit;
629 			}
630 
631 			handler_obj = &notify_obj->notify;
632 			parent_obj = NULL;
633 			while (handler_obj->handler != handler) {
634 				if (handler_obj->next) {
635 					parent_obj = handler_obj;
636 					handler_obj = handler_obj->next;
637 				} else {
638 					break;
639 				}
640 			}
641 
642 			if (handler_obj->handler != handler) {
643 				status = AE_BAD_PARAMETER;
644 				goto unlock_and_exit;
645 			}
646 
647 			/*
648 			 * Remove the handler.  There are three possible cases.
649 			 * First, we may need to remove a non-embedded object.
650 			 * Second, we may need to remove the embedded object's
651 			 * handler data, while non-embedded objects exist.
652 			 * Finally, we may need to remove the embedded object
653 			 * entirely along with its container.
654 			 */
655 			if (parent_obj) {
656 				/* Non-embedded object is being removed. */
657 				parent_obj->next = handler_obj->next;
658 				ACPI_FREE(handler_obj);
659 			} else if (notify_obj->notify.next) {
660 				/*
661 				 * The handler matches the embedded object, but
662 				 * there are more handler objects in the list.
663 				 * Replace the embedded object's data with the
664 				 * first next object's data and remove that
665 				 * object.
666 				 */
667 				parent_obj = &notify_obj->notify;
668 				handler_obj = notify_obj->notify.next;
669 				*parent_obj = *handler_obj;
670 				ACPI_FREE(handler_obj);
671 			} else {
672 				/* No more handler objects in the list. */
673 				obj_desc->common_notify.system_notify = NULL;
674 				acpi_ut_remove_reference(notify_obj);
675 			}
676 		}
677 
678 		if (handler_type & ACPI_DEVICE_NOTIFY) {
679 			notify_obj = obj_desc->common_notify.device_notify;
680 			if (!notify_obj) {
681 				status = AE_NOT_EXIST;
682 				goto unlock_and_exit;
683 			}
684 
685 			if (notify_obj->notify.handler != handler) {
686 				status = AE_BAD_PARAMETER;
687 				goto unlock_and_exit;
688 			}
689 
690 			/* Remove the handler */
691 			obj_desc->common_notify.device_notify = NULL;
692 			acpi_ut_remove_reference(notify_obj);
693 		}
694 	}
695 
696       unlock_and_exit:
697 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
698       exit:
699 	if (ACPI_FAILURE(status))
700 		ACPI_EXCEPTION((AE_INFO, status, "Removing notify handler"));
701 	return_ACPI_STATUS(status);
702 }
703 
704 ACPI_EXPORT_SYMBOL(acpi_remove_notify_handler)
705 
706 /*******************************************************************************
707  *
708  * FUNCTION:    acpi_install_gpe_handler
709  *
710  * PARAMETERS:  gpe_device      - Namespace node for the GPE (NULL for FADT
711  *                                defined GPEs)
712  *              gpe_number      - The GPE number within the GPE block
713  *              Type            - Whether this GPE should be treated as an
714  *                                edge- or level-triggered interrupt.
715  *              Address         - Address of the handler
716  *              Context         - Value passed to the handler on each GPE
717  *
718  * RETURN:      Status
719  *
720  * DESCRIPTION: Install a handler for a General Purpose Event.
721  *
722  ******************************************************************************/
723 acpi_status
724 acpi_install_gpe_handler(acpi_handle gpe_device,
725 			 u32 gpe_number,
726 			 u32 type, acpi_gpe_handler address, void *context)
727 {
728 	struct acpi_gpe_event_info *gpe_event_info;
729 	struct acpi_gpe_handler_info *handler;
730 	acpi_status status;
731 	acpi_cpu_flags flags;
732 
733 	ACPI_FUNCTION_TRACE(acpi_install_gpe_handler);
734 
735 	/* Parameter validation */
736 
737 	if ((!address) || (type & ~ACPI_GPE_XRUPT_TYPE_MASK)) {
738 		return_ACPI_STATUS(AE_BAD_PARAMETER);
739 	}
740 
741 	status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
742 	if (ACPI_FAILURE(status)) {
743 		return_ACPI_STATUS(status);
744 	}
745 
746 	/* Allocate memory for the handler object */
747 
748 	handler = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_handler_info));
749 	if (!handler) {
750 		status = AE_NO_MEMORY;
751 		goto unlock_and_exit;
752 	}
753 
754 	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
755 
756 	/* Ensure that we have a valid GPE number */
757 
758 	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
759 	if (!gpe_event_info) {
760 		status = AE_BAD_PARAMETER;
761 		goto free_and_exit;
762 	}
763 
764 	/* Make sure that there isn't a handler there already */
765 
766 	if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
767 	    ACPI_GPE_DISPATCH_HANDLER) {
768 		status = AE_ALREADY_EXISTS;
769 		goto free_and_exit;
770 	}
771 
772 	/* Allocate and init handler object */
773 
774 	handler->address = address;
775 	handler->context = context;
776 	handler->method_node = gpe_event_info->dispatch.method_node;
777 	handler->original_flags = gpe_event_info->flags &
778 			(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
779 
780 	/*
781 	 * If the GPE is associated with a method, it might have been enabled
782 	 * automatically during initialization, in which case it has to be
783 	 * disabled now to avoid spurious execution of the handler.
784 	 */
785 
786 	if ((handler->original_flags & ACPI_GPE_DISPATCH_METHOD)
787 	    && gpe_event_info->runtime_count) {
788 		handler->originally_enabled = 1;
789 		(void)acpi_ev_remove_gpe_reference(gpe_event_info);
790 	}
791 
792 	/* Install the handler */
793 
794 	gpe_event_info->dispatch.handler = handler;
795 
796 	/* Setup up dispatch flags to indicate handler (vs. method) */
797 
798 	gpe_event_info->flags &=
799 	    ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
800 	gpe_event_info->flags |= (u8) (type | ACPI_GPE_DISPATCH_HANDLER);
801 
802 	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
803 
804 unlock_and_exit:
805 	(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
806 	return_ACPI_STATUS(status);
807 
808 free_and_exit:
809 	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
810 	ACPI_FREE(handler);
811 	goto unlock_and_exit;
812 }
813 
814 ACPI_EXPORT_SYMBOL(acpi_install_gpe_handler)
815 
816 /*******************************************************************************
817  *
818  * FUNCTION:    acpi_remove_gpe_handler
819  *
820  * PARAMETERS:  gpe_device      - Namespace node for the GPE (NULL for FADT
821  *                                defined GPEs)
822  *              gpe_number      - The event to remove a handler
823  *              Address         - Address of the handler
824  *
825  * RETURN:      Status
826  *
827  * DESCRIPTION: Remove a handler for a General Purpose acpi_event.
828  *
829  ******************************************************************************/
830 acpi_status
831 acpi_remove_gpe_handler(acpi_handle gpe_device,
832 			u32 gpe_number, acpi_gpe_handler address)
833 {
834 	struct acpi_gpe_event_info *gpe_event_info;
835 	struct acpi_gpe_handler_info *handler;
836 	acpi_status status;
837 	acpi_cpu_flags flags;
838 
839 	ACPI_FUNCTION_TRACE(acpi_remove_gpe_handler);
840 
841 	/* Parameter validation */
842 
843 	if (!address) {
844 		return_ACPI_STATUS(AE_BAD_PARAMETER);
845 	}
846 
847 	/* Make sure all deferred tasks are completed */
848 
849 	acpi_os_wait_events_complete(NULL);
850 
851 	status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
852 	if (ACPI_FAILURE(status)) {
853 		return_ACPI_STATUS(status);
854 	}
855 
856 	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
857 
858 	/* Ensure that we have a valid GPE number */
859 
860 	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
861 	if (!gpe_event_info) {
862 		status = AE_BAD_PARAMETER;
863 		goto unlock_and_exit;
864 	}
865 
866 	/* Make sure that a handler is indeed installed */
867 
868 	if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) !=
869 	    ACPI_GPE_DISPATCH_HANDLER) {
870 		status = AE_NOT_EXIST;
871 		goto unlock_and_exit;
872 	}
873 
874 	/* Make sure that the installed handler is the same */
875 
876 	if (gpe_event_info->dispatch.handler->address != address) {
877 		status = AE_BAD_PARAMETER;
878 		goto unlock_and_exit;
879 	}
880 
881 	/* Remove the handler */
882 
883 	handler = gpe_event_info->dispatch.handler;
884 
885 	/* Restore Method node (if any), set dispatch flags */
886 
887 	gpe_event_info->dispatch.method_node = handler->method_node;
888 	gpe_event_info->flags &=
889 		~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
890 	gpe_event_info->flags |= handler->original_flags;
891 
892 	/*
893 	 * If the GPE was previously associated with a method and it was
894 	 * enabled, it should be enabled at this point to restore the
895 	 * post-initialization configuration.
896 	 */
897 
898 	if ((handler->original_flags & ACPI_GPE_DISPATCH_METHOD)
899 	    && handler->originally_enabled)
900 		(void)acpi_ev_add_gpe_reference(gpe_event_info);
901 
902 	/* Now we can free the handler object */
903 
904 	ACPI_FREE(handler);
905 
906 unlock_and_exit:
907 	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
908 
909 	(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
910 	return_ACPI_STATUS(status);
911 }
912 
913 ACPI_EXPORT_SYMBOL(acpi_remove_gpe_handler)
914 
915 /*******************************************************************************
916  *
917  * FUNCTION:    acpi_acquire_global_lock
918  *
919  * PARAMETERS:  Timeout         - How long the caller is willing to wait
920  *              Handle          - Where the handle to the lock is returned
921  *                                (if acquired)
922  *
923  * RETURN:      Status
924  *
925  * DESCRIPTION: Acquire the ACPI Global Lock
926  *
927  * Note: Allows callers with the same thread ID to acquire the global lock
928  * multiple times. In other words, externally, the behavior of the global lock
929  * is identical to an AML mutex. On the first acquire, a new handle is
930  * returned. On any subsequent calls to acquire by the same thread, the same
931  * handle is returned.
932  *
933  ******************************************************************************/
934 acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle)
935 {
936 	acpi_status status;
937 
938 	if (!handle) {
939 		return (AE_BAD_PARAMETER);
940 	}
941 
942 	/* Must lock interpreter to prevent race conditions */
943 
944 	acpi_ex_enter_interpreter();
945 
946 	status = acpi_ex_acquire_mutex_object(timeout,
947 					      acpi_gbl_global_lock_mutex,
948 					      acpi_os_get_thread_id());
949 
950 	if (ACPI_SUCCESS(status)) {
951 
952 		/* Return the global lock handle (updated in acpi_ev_acquire_global_lock) */
953 
954 		*handle = acpi_gbl_global_lock_handle;
955 	}
956 
957 	acpi_ex_exit_interpreter();
958 	return (status);
959 }
960 
961 ACPI_EXPORT_SYMBOL(acpi_acquire_global_lock)
962 
963 /*******************************************************************************
964  *
965  * FUNCTION:    acpi_release_global_lock
966  *
967  * PARAMETERS:  Handle      - Returned from acpi_acquire_global_lock
968  *
969  * RETURN:      Status
970  *
971  * DESCRIPTION: Release the ACPI Global Lock. The handle must be valid.
972  *
973  ******************************************************************************/
974 acpi_status acpi_release_global_lock(u32 handle)
975 {
976 	acpi_status status;
977 
978 	if (!handle || (handle != acpi_gbl_global_lock_handle)) {
979 		return (AE_NOT_ACQUIRED);
980 	}
981 
982 	status = acpi_ex_release_mutex_object(acpi_gbl_global_lock_mutex);
983 	return (status);
984 }
985 
986 ACPI_EXPORT_SYMBOL(acpi_release_global_lock)
987