1 /******************************************************************************
 
   3  * Module Name: evxface - External interfaces for ACPI events
 
   5  *****************************************************************************/
 
   8  * Copyright (C) 2000 - 2008, Intel Corp.
 
  11  * Redistribution and use in source and binary forms, with or without
 
  12  * modification, are permitted provided that the following conditions
 
  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.
 
  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.
 
  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.
 
  44 #include <acpi/acpi.h>
 
  45 #include <acpi/acnamesp.h>
 
  46 #include <acpi/acevents.h>
 
  47 #include <acpi/acinterp.h>
 
  49 #define _COMPONENT          ACPI_EVENTS
 
  50 ACPI_MODULE_NAME("evxface")
 
  52 /*******************************************************************************
 
  54  * FUNCTION:    acpi_install_exception_handler
 
  56  * PARAMETERS:  Handler         - Pointer to the handler function for the
 
  61  * DESCRIPTION: Saves the pointer to the handler function
 
  63  ******************************************************************************/
 
  64 #ifdef ACPI_FUTURE_USAGE
 
  65 acpi_status acpi_install_exception_handler(acpi_exception_handler handler)
 
  69         ACPI_FUNCTION_TRACE(acpi_install_exception_handler);
 
  71         status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
 
  72         if (ACPI_FAILURE(status)) {
 
  73                 return_ACPI_STATUS(status);
 
  76         /* Don't allow two handlers. */
 
  78         if (acpi_gbl_exception_handler) {
 
  79                 status = AE_ALREADY_EXISTS;
 
  83         /* Install the handler */
 
  85         acpi_gbl_exception_handler = handler;
 
  88         (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
 
  89         return_ACPI_STATUS(status);
 
  92 ACPI_EXPORT_SYMBOL(acpi_install_exception_handler)
 
  93 #endif                          /*  ACPI_FUTURE_USAGE  */
 
  94 /*******************************************************************************
 
  96  * FUNCTION:    acpi_install_fixed_event_handler
 
  98  * PARAMETERS:  Event           - Event type to enable.
 
  99  *              Handler         - Pointer to the handler function for the
 
 101  *              Context         - Value passed to the handler on each GPE
 
 105  * DESCRIPTION: Saves the pointer to the handler function and then enables the
 
 108  ******************************************************************************/
 
 110 acpi_install_fixed_event_handler(u32 event,
 
 111                                  acpi_event_handler handler, void *context)
 
 115         ACPI_FUNCTION_TRACE(acpi_install_fixed_event_handler);
 
 117         /* Parameter validation */
 
 119         if (event > ACPI_EVENT_MAX) {
 
 120                 return_ACPI_STATUS(AE_BAD_PARAMETER);
 
 123         status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
 
 124         if (ACPI_FAILURE(status)) {
 
 125                 return_ACPI_STATUS(status);
 
 128         /* Don't allow two handlers. */
 
 130         if (NULL != acpi_gbl_fixed_event_handlers[event].handler) {
 
 131                 status = AE_ALREADY_EXISTS;
 
 135         /* Install the handler before enabling the event */
 
 137         acpi_gbl_fixed_event_handlers[event].handler = handler;
 
 138         acpi_gbl_fixed_event_handlers[event].context = context;
 
 140         status = acpi_clear_event(event);
 
 141         if (ACPI_SUCCESS(status))
 
 142                 status = acpi_enable_event(event, 0);
 
 143         if (ACPI_FAILURE(status)) {
 
 144                 ACPI_WARNING((AE_INFO, "Could not enable fixed event %X",
 
 147                 /* Remove the handler */
 
 149                 acpi_gbl_fixed_event_handlers[event].handler = NULL;
 
 150                 acpi_gbl_fixed_event_handlers[event].context = NULL;
 
 152                 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 
 153                                   "Enabled fixed event %X, Handler=%p\n", event,
 
 158         (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
 
 159         return_ACPI_STATUS(status);
 
 162 ACPI_EXPORT_SYMBOL(acpi_install_fixed_event_handler)
 
 164 /*******************************************************************************
 
 166  * FUNCTION:    acpi_remove_fixed_event_handler
 
 168  * PARAMETERS:  Event           - Event type to disable.
 
 169  *              Handler         - Address of the handler
 
 173  * DESCRIPTION: Disables the event and unregisters the event handler.
 
 175  ******************************************************************************/
 
 177 acpi_remove_fixed_event_handler(u32 event, acpi_event_handler handler)
 
 179         acpi_status status = AE_OK;
 
 181         ACPI_FUNCTION_TRACE(acpi_remove_fixed_event_handler);
 
 183         /* Parameter validation */
 
 185         if (event > ACPI_EVENT_MAX) {
 
 186                 return_ACPI_STATUS(AE_BAD_PARAMETER);
 
 189         status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
 
 190         if (ACPI_FAILURE(status)) {
 
 191                 return_ACPI_STATUS(status);
 
 194         /* Disable the event before removing the handler */
 
 196         status = acpi_disable_event(event, 0);
 
 198         /* Always Remove the handler */
 
 200         acpi_gbl_fixed_event_handlers[event].handler = NULL;
 
 201         acpi_gbl_fixed_event_handlers[event].context = NULL;
 
 203         if (ACPI_FAILURE(status)) {
 
 204                 ACPI_WARNING((AE_INFO,
 
 205                               "Could not write to fixed event enable register %X",
 
 208                 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Disabled fixed event %X\n",
 
 212         (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
 
 213         return_ACPI_STATUS(status);
 
 216 ACPI_EXPORT_SYMBOL(acpi_remove_fixed_event_handler)
 
 218 /*******************************************************************************
 
 220  * FUNCTION:    acpi_install_notify_handler
 
 222  * PARAMETERS:  Device          - The device for which notifies will be handled
 
 223  *              handler_type    - The type of handler:
 
 224  *                                  ACPI_SYSTEM_NOTIFY: system_handler (00-7f)
 
 225  *                                  ACPI_DEVICE_NOTIFY: driver_handler (80-ff)
 
 226  *                                  ACPI_ALL_NOTIFY:  both system and device
 
 227  *              Handler         - Address of the handler
 
 228  *              Context         - Value passed to the handler on each GPE
 
 232  * DESCRIPTION: Install a handler for notifies on an ACPI device
 
 234  ******************************************************************************/
 
 236 acpi_install_notify_handler(acpi_handle device,
 
 238                             acpi_notify_handler handler, void *context)
 
 240         union acpi_operand_object *obj_desc;
 
 241         union acpi_operand_object *notify_obj;
 
 242         struct acpi_namespace_node *node;
 
 245         ACPI_FUNCTION_TRACE(acpi_install_notify_handler);
 
 247         /* Parameter validation */
 
 250             (!handler) || (handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
 
 251                 return_ACPI_STATUS(AE_BAD_PARAMETER);
 
 254         status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
 
 255         if (ACPI_FAILURE(status)) {
 
 256                 return_ACPI_STATUS(status);
 
 259         /* Convert and validate the device handle */
 
 261         node = acpi_ns_map_handle_to_node(device);
 
 263                 status = AE_BAD_PARAMETER;
 
 264                 goto unlock_and_exit;
 
 269          * Registering a notify handler on the root object indicates that the
 
 270          * caller wishes to receive notifications for all objects.  Note that
 
 271          * only one <external> global handler can be regsitered (per notify type).
 
 273         if (device == ACPI_ROOT_OBJECT) {
 
 275                 /* Make sure the handler is not already installed */
 
 277                 if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
 
 278                      acpi_gbl_system_notify.handler) ||
 
 279                     ((handler_type & ACPI_DEVICE_NOTIFY) &&
 
 280                      acpi_gbl_device_notify.handler)) {
 
 281                         status = AE_ALREADY_EXISTS;
 
 282                         goto unlock_and_exit;
 
 285                 if (handler_type & ACPI_SYSTEM_NOTIFY) {
 
 286                         acpi_gbl_system_notify.node = node;
 
 287                         acpi_gbl_system_notify.handler = handler;
 
 288                         acpi_gbl_system_notify.context = context;
 
 291                 if (handler_type & ACPI_DEVICE_NOTIFY) {
 
 292                         acpi_gbl_device_notify.node = node;
 
 293                         acpi_gbl_device_notify.handler = handler;
 
 294                         acpi_gbl_device_notify.context = context;
 
 297                 /* Global notify handler installed */
 
 302          * Caller will only receive notifications specific to the target object.
 
 303          * Note that only certain object types can receive notifications.
 
 306                 /* Notifies allowed on this object? */
 
 308                 if (!acpi_ev_is_notify_object(node)) {
 
 310                         goto unlock_and_exit;
 
 313                 /* Check for an existing internal object */
 
 315                 obj_desc = acpi_ns_get_attached_object(node);
 
 318                         /* Object exists - make sure there's no handler */
 
 320                         if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
 
 321                              obj_desc->common_notify.system_notify) ||
 
 322                             ((handler_type & ACPI_DEVICE_NOTIFY) &&
 
 323                              obj_desc->common_notify.device_notify)) {
 
 324                                 status = AE_ALREADY_EXISTS;
 
 325                                 goto unlock_and_exit;
 
 328                         /* Create a new object */
 
 330                         obj_desc = acpi_ut_create_internal_object(node->type);
 
 332                                 status = AE_NO_MEMORY;
 
 333                                 goto unlock_and_exit;
 
 336                         /* Attach new object to the Node */
 
 339                             acpi_ns_attach_object(device, obj_desc, node->type);
 
 341                         /* Remove local reference to the object */
 
 343                         acpi_ut_remove_reference(obj_desc);
 
 344                         if (ACPI_FAILURE(status)) {
 
 345                                 goto unlock_and_exit;
 
 349                 /* Install the handler */
 
 352                     acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_NOTIFY);
 
 354                         status = AE_NO_MEMORY;
 
 355                         goto unlock_and_exit;
 
 358                 notify_obj->notify.node = node;
 
 359                 notify_obj->notify.handler = handler;
 
 360                 notify_obj->notify.context = context;
 
 362                 if (handler_type & ACPI_SYSTEM_NOTIFY) {
 
 363                         obj_desc->common_notify.system_notify = notify_obj;
 
 366                 if (handler_type & ACPI_DEVICE_NOTIFY) {
 
 367                         obj_desc->common_notify.device_notify = notify_obj;
 
 370                 if (handler_type == ACPI_ALL_NOTIFY) {
 
 372                         /* Extra ref if installed in both */
 
 374                         acpi_ut_add_reference(notify_obj);
 
 379         (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 
 380         return_ACPI_STATUS(status);
 
 383 ACPI_EXPORT_SYMBOL(acpi_install_notify_handler)
 
 385 /*******************************************************************************
 
 387  * FUNCTION:    acpi_remove_notify_handler
 
 389  * PARAMETERS:  Device          - The device for which notifies will be handled
 
 390  *              handler_type    - The type of handler:
 
 391  *                                  ACPI_SYSTEM_NOTIFY: system_handler (00-7f)
 
 392  *                                  ACPI_DEVICE_NOTIFY: driver_handler (80-ff)
 
 393  *                                  ACPI_ALL_NOTIFY:  both system and device
 
 394  *              Handler         - Address of the handler
 
 398  * DESCRIPTION: Remove a handler for notifies on an ACPI device
 
 400  ******************************************************************************/
 
 402 acpi_remove_notify_handler(acpi_handle device,
 
 403                            u32 handler_type, acpi_notify_handler handler)
 
 405         union acpi_operand_object *notify_obj;
 
 406         union acpi_operand_object *obj_desc;
 
 407         struct acpi_namespace_node *node;
 
 410         ACPI_FUNCTION_TRACE(acpi_remove_notify_handler);
 
 412         /* Parameter validation */
 
 415             (!handler) || (handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
 
 416                 status = AE_BAD_PARAMETER;
 
 420         status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
 
 421         if (ACPI_FAILURE(status)) {
 
 425         /* Convert and validate the device handle */
 
 427         node = acpi_ns_map_handle_to_node(device);
 
 429                 status = AE_BAD_PARAMETER;
 
 430                 goto unlock_and_exit;
 
 435         if (device == ACPI_ROOT_OBJECT) {
 
 436                 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 
 437                                   "Removing notify handler for namespace root object\n"));
 
 439                 if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
 
 440                      !acpi_gbl_system_notify.handler) ||
 
 441                     ((handler_type & ACPI_DEVICE_NOTIFY) &&
 
 442                      !acpi_gbl_device_notify.handler)) {
 
 443                         status = AE_NOT_EXIST;
 
 444                         goto unlock_and_exit;
 
 447                 /* Make sure all deferred tasks are completed */
 
 449                 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 
 450                 acpi_os_wait_events_complete(NULL);
 
 451                 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
 
 452                 if (ACPI_FAILURE(status)) {
 
 456                 if (handler_type & ACPI_SYSTEM_NOTIFY) {
 
 457                         acpi_gbl_system_notify.node = NULL;
 
 458                         acpi_gbl_system_notify.handler = NULL;
 
 459                         acpi_gbl_system_notify.context = NULL;
 
 462                 if (handler_type & ACPI_DEVICE_NOTIFY) {
 
 463                         acpi_gbl_device_notify.node = NULL;
 
 464                         acpi_gbl_device_notify.handler = NULL;
 
 465                         acpi_gbl_device_notify.context = NULL;
 
 469         /* All Other Objects */
 
 472                 /* Notifies allowed on this object? */
 
 474                 if (!acpi_ev_is_notify_object(node)) {
 
 476                         goto unlock_and_exit;
 
 479                 /* Check for an existing internal object */
 
 481                 obj_desc = acpi_ns_get_attached_object(node);
 
 483                         status = AE_NOT_EXIST;
 
 484                         goto unlock_and_exit;
 
 487                 /* Object exists - make sure there's an existing handler */
 
 489                 if (handler_type & ACPI_SYSTEM_NOTIFY) {
 
 490                         notify_obj = obj_desc->common_notify.system_notify;
 
 492                                 status = AE_NOT_EXIST;
 
 493                                 goto unlock_and_exit;
 
 496                         if (notify_obj->notify.handler != handler) {
 
 497                                 status = AE_BAD_PARAMETER;
 
 498                                 goto unlock_and_exit;
 
 500                         /* Make sure all deferred tasks are completed */
 
 502                         (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 
 503                         acpi_os_wait_events_complete(NULL);
 
 504                         status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
 
 505                         if (ACPI_FAILURE(status)) {
 
 509                         /* Remove the handler */
 
 510                         obj_desc->common_notify.system_notify = NULL;
 
 511                         acpi_ut_remove_reference(notify_obj);
 
 514                 if (handler_type & ACPI_DEVICE_NOTIFY) {
 
 515                         notify_obj = obj_desc->common_notify.device_notify;
 
 517                                 status = AE_NOT_EXIST;
 
 518                                 goto unlock_and_exit;
 
 521                         if (notify_obj->notify.handler != handler) {
 
 522                                 status = AE_BAD_PARAMETER;
 
 523                                 goto unlock_and_exit;
 
 525                         /* Make sure all deferred tasks are completed */
 
 527                         (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 
 528                         acpi_os_wait_events_complete(NULL);
 
 529                         status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
 
 530                         if (ACPI_FAILURE(status)) {
 
 534                         /* Remove the handler */
 
 535                         obj_desc->common_notify.device_notify = NULL;
 
 536                         acpi_ut_remove_reference(notify_obj);
 
 541         (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 
 543         if (ACPI_FAILURE(status))
 
 544                 ACPI_EXCEPTION((AE_INFO, status, "Removing notify handler"));
 
 545         return_ACPI_STATUS(status);
 
 548 ACPI_EXPORT_SYMBOL(acpi_remove_notify_handler)
 
 550 /*******************************************************************************
 
 552  * FUNCTION:    acpi_install_gpe_handler
 
 554  * PARAMETERS:  gpe_device      - Namespace node for the GPE (NULL for FADT
 
 556  *              gpe_number      - The GPE number within the GPE block
 
 557  *              Type            - Whether this GPE should be treated as an
 
 558  *                                edge- or level-triggered interrupt.
 
 559  *              Address         - Address of the handler
 
 560  *              Context         - Value passed to the handler on each GPE
 
 564  * DESCRIPTION: Install a handler for a General Purpose Event.
 
 566  ******************************************************************************/
 
 568 acpi_install_gpe_handler(acpi_handle gpe_device,
 
 570                          u32 type, acpi_event_handler address, void *context)
 
 572         struct acpi_gpe_event_info *gpe_event_info;
 
 573         struct acpi_handler_info *handler;
 
 575         acpi_cpu_flags flags;
 
 577         ACPI_FUNCTION_TRACE(acpi_install_gpe_handler);
 
 579         /* Parameter validation */
 
 581         if ((!address) || (type > ACPI_GPE_XRUPT_TYPE_MASK)) {
 
 582                 status = AE_BAD_PARAMETER;
 
 586         status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
 
 587         if (ACPI_FAILURE(status)) {
 
 591         /* Ensure that we have a valid GPE number */
 
 593         gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
 
 594         if (!gpe_event_info) {
 
 595                 status = AE_BAD_PARAMETER;
 
 596                 goto unlock_and_exit;
 
 599         /* Make sure that there isn't a handler there already */
 
 601         if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
 
 602             ACPI_GPE_DISPATCH_HANDLER) {
 
 603                 status = AE_ALREADY_EXISTS;
 
 604                 goto unlock_and_exit;
 
 607         /* Allocate and init handler object */
 
 609         handler = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_handler_info));
 
 611                 status = AE_NO_MEMORY;
 
 612                 goto unlock_and_exit;
 
 615         handler->address = address;
 
 616         handler->context = context;
 
 617         handler->method_node = gpe_event_info->dispatch.method_node;
 
 619         /* Disable the GPE before installing the handler */
 
 621         status = acpi_ev_disable_gpe(gpe_event_info);
 
 622         if (ACPI_FAILURE(status)) {
 
 623                 goto unlock_and_exit;
 
 626         /* Install the handler */
 
 628         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
 
 629         gpe_event_info->dispatch.handler = handler;
 
 631         /* Setup up dispatch flags to indicate handler (vs. method) */
 
 633         gpe_event_info->flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);  /* Clear bits */
 
 634         gpe_event_info->flags |= (u8) (type | ACPI_GPE_DISPATCH_HANDLER);
 
 636         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
 
 639         (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
 
 641         if (ACPI_FAILURE(status))
 
 642                 ACPI_EXCEPTION((AE_INFO, status,
 
 643                                 "Installing notify handler failed"));
 
 644         return_ACPI_STATUS(status);
 
 647 ACPI_EXPORT_SYMBOL(acpi_install_gpe_handler)
 
 649 /*******************************************************************************
 
 651  * FUNCTION:    acpi_remove_gpe_handler
 
 653  * PARAMETERS:  gpe_device      - Namespace node for the GPE (NULL for FADT
 
 655  *              gpe_number      - The event to remove a handler
 
 656  *              Address         - Address of the handler
 
 660  * DESCRIPTION: Remove a handler for a General Purpose acpi_event.
 
 662  ******************************************************************************/
 
 664 acpi_remove_gpe_handler(acpi_handle gpe_device,
 
 665                         u32 gpe_number, acpi_event_handler address)
 
 667         struct acpi_gpe_event_info *gpe_event_info;
 
 668         struct acpi_handler_info *handler;
 
 670         acpi_cpu_flags flags;
 
 672         ACPI_FUNCTION_TRACE(acpi_remove_gpe_handler);
 
 674         /* Parameter validation */
 
 677                 return_ACPI_STATUS(AE_BAD_PARAMETER);
 
 680         status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
 
 681         if (ACPI_FAILURE(status)) {
 
 682                 return_ACPI_STATUS(status);
 
 685         /* Ensure that we have a valid GPE number */
 
 687         gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
 
 688         if (!gpe_event_info) {
 
 689                 status = AE_BAD_PARAMETER;
 
 690                 goto unlock_and_exit;
 
 693         /* Make sure that a handler is indeed installed */
 
 695         if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) !=
 
 696             ACPI_GPE_DISPATCH_HANDLER) {
 
 697                 status = AE_NOT_EXIST;
 
 698                 goto unlock_and_exit;
 
 701         /* Make sure that the installed handler is the same */
 
 703         if (gpe_event_info->dispatch.handler->address != address) {
 
 704                 status = AE_BAD_PARAMETER;
 
 705                 goto unlock_and_exit;
 
 708         /* Disable the GPE before removing the handler */
 
 710         status = acpi_ev_disable_gpe(gpe_event_info);
 
 711         if (ACPI_FAILURE(status)) {
 
 712                 goto unlock_and_exit;
 
 715         /* Make sure all deferred tasks are completed */
 
 717         (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
 
 718         acpi_os_wait_events_complete(NULL);
 
 719         status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
 
 720         if (ACPI_FAILURE(status)) {
 
 721                 return_ACPI_STATUS(status);
 
 724         /* Remove the handler */
 
 726         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
 
 727         handler = gpe_event_info->dispatch.handler;
 
 729         /* Restore Method node (if any), set dispatch flags */
 
 731         gpe_event_info->dispatch.method_node = handler->method_node;
 
 732         gpe_event_info->flags &= ~ACPI_GPE_DISPATCH_MASK;       /* Clear bits */
 
 733         if (handler->method_node) {
 
 734                 gpe_event_info->flags |= ACPI_GPE_DISPATCH_METHOD;
 
 736         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
 
 738         /* Now we can free the handler object */
 
 743         (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
 
 744         return_ACPI_STATUS(status);
 
 747 ACPI_EXPORT_SYMBOL(acpi_remove_gpe_handler)
 
 749 /*******************************************************************************
 
 751  * FUNCTION:    acpi_acquire_global_lock
 
 753  * PARAMETERS:  Timeout         - How long the caller is willing to wait
 
 754  *              Handle          - Where the handle to the lock is returned
 
 759  * DESCRIPTION: Acquire the ACPI Global Lock
 
 761  * Note: Allows callers with the same thread ID to acquire the global lock
 
 762  * multiple times. In other words, externally, the behavior of the global lock
 
 763  * is identical to an AML mutex. On the first acquire, a new handle is
 
 764  * returned. On any subsequent calls to acquire by the same thread, the same
 
 765  * handle is returned.
 
 767  ******************************************************************************/
 
 768 acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle)
 
 773                 return (AE_BAD_PARAMETER);
 
 776         /* Must lock interpreter to prevent race conditions */
 
 778         acpi_ex_enter_interpreter();
 
 780         status = acpi_ex_acquire_mutex_object(timeout,
 
 781                                               acpi_gbl_global_lock_mutex,
 
 782                                               acpi_os_get_thread_id());
 
 784         if (ACPI_SUCCESS(status)) {
 
 786                 /* Return the global lock handle (updated in acpi_ev_acquire_global_lock) */
 
 788                 *handle = acpi_gbl_global_lock_handle;
 
 791         acpi_ex_exit_interpreter();
 
 795 ACPI_EXPORT_SYMBOL(acpi_acquire_global_lock)
 
 797 /*******************************************************************************
 
 799  * FUNCTION:    acpi_release_global_lock
 
 801  * PARAMETERS:  Handle      - Returned from acpi_acquire_global_lock
 
 805  * DESCRIPTION: Release the ACPI Global Lock. The handle must be valid.
 
 807  ******************************************************************************/
 
 808 acpi_status acpi_release_global_lock(u32 handle)
 
 812         if (!handle || (handle != acpi_gbl_global_lock_handle)) {
 
 813                 return (AE_NOT_ACQUIRED);
 
 816         status = acpi_ex_release_mutex_object(acpi_gbl_global_lock_mutex);
 
 820 ACPI_EXPORT_SYMBOL(acpi_release_global_lock)