pandora: defconfig: update
[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 <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)