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