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