1 /****************************************************************************** 2 * 3 * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2008, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include <acpi/acpi.h> 45 #include "accommon.h" 46 #include "acevents.h" 47 #include "acnamesp.h" 48 #include "actables.h" 49 50 #define _COMPONENT ACPI_EVENTS 51 ACPI_MODULE_NAME("evxfevnt") 52 53 /* Local prototypes */ 54 acpi_status 55 acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, 56 struct acpi_gpe_block_info *gpe_block, void *context); 57 58 /******************************************************************************* 59 * 60 * FUNCTION: acpi_enable 61 * 62 * PARAMETERS: None 63 * 64 * RETURN: Status 65 * 66 * DESCRIPTION: Transfers the system into ACPI mode. 67 * 68 ******************************************************************************/ 69 70 acpi_status acpi_enable(void) 71 { 72 acpi_status status = AE_OK; 73 74 ACPI_FUNCTION_TRACE(acpi_enable); 75 76 /* ACPI tables must be present */ 77 78 if (!acpi_tb_tables_loaded()) { 79 return_ACPI_STATUS(AE_NO_ACPI_TABLES); 80 } 81 82 /* Check current mode */ 83 84 if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) { 85 ACPI_DEBUG_PRINT((ACPI_DB_INIT, 86 "System is already in ACPI mode\n")); 87 } else { 88 /* Transition to ACPI mode */ 89 90 status = acpi_hw_set_mode(ACPI_SYS_MODE_ACPI); 91 if (ACPI_FAILURE(status)) { 92 ACPI_ERROR((AE_INFO, 93 "Could not transition to ACPI mode")); 94 return_ACPI_STATUS(status); 95 } 96 97 ACPI_DEBUG_PRINT((ACPI_DB_INIT, 98 "Transition to ACPI mode successful\n")); 99 } 100 101 return_ACPI_STATUS(status); 102 } 103 104 ACPI_EXPORT_SYMBOL(acpi_enable) 105 106 /******************************************************************************* 107 * 108 * FUNCTION: acpi_disable 109 * 110 * PARAMETERS: None 111 * 112 * RETURN: Status 113 * 114 * DESCRIPTION: Transfers the system into LEGACY (non-ACPI) mode. 115 * 116 ******************************************************************************/ 117 acpi_status acpi_disable(void) 118 { 119 acpi_status status = AE_OK; 120 121 ACPI_FUNCTION_TRACE(acpi_disable); 122 123 if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) { 124 ACPI_DEBUG_PRINT((ACPI_DB_INIT, 125 "System is already in legacy (non-ACPI) mode\n")); 126 } else { 127 /* Transition to LEGACY mode */ 128 129 status = acpi_hw_set_mode(ACPI_SYS_MODE_LEGACY); 130 131 if (ACPI_FAILURE(status)) { 132 ACPI_ERROR((AE_INFO, 133 "Could not exit ACPI mode to legacy mode")); 134 return_ACPI_STATUS(status); 135 } 136 137 ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI mode disabled\n")); 138 } 139 140 return_ACPI_STATUS(status); 141 } 142 143 ACPI_EXPORT_SYMBOL(acpi_disable) 144 145 /******************************************************************************* 146 * 147 * FUNCTION: acpi_enable_event 148 * 149 * PARAMETERS: Event - The fixed eventto be enabled 150 * Flags - Reserved 151 * 152 * RETURN: Status 153 * 154 * DESCRIPTION: Enable an ACPI event (fixed) 155 * 156 ******************************************************************************/ 157 acpi_status acpi_enable_event(u32 event, u32 flags) 158 { 159 acpi_status status = AE_OK; 160 u32 value; 161 162 ACPI_FUNCTION_TRACE(acpi_enable_event); 163 164 /* Decode the Fixed Event */ 165 166 if (event > ACPI_EVENT_MAX) { 167 return_ACPI_STATUS(AE_BAD_PARAMETER); 168 } 169 170 /* 171 * Enable the requested fixed event (by writing a one to the enable 172 * register bit) 173 */ 174 status = 175 acpi_set_register(acpi_gbl_fixed_event_info[event]. 176 enable_register_id, 1); 177 if (ACPI_FAILURE(status)) { 178 return_ACPI_STATUS(status); 179 } 180 181 /* Make sure that the hardware responded */ 182 183 status = 184 acpi_get_register(acpi_gbl_fixed_event_info[event]. 185 enable_register_id, &value); 186 if (ACPI_FAILURE(status)) { 187 return_ACPI_STATUS(status); 188 } 189 190 if (value != 1) { 191 ACPI_ERROR((AE_INFO, 192 "Could not enable %s event", 193 acpi_ut_get_event_name(event))); 194 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); 195 } 196 197 return_ACPI_STATUS(status); 198 } 199 200 ACPI_EXPORT_SYMBOL(acpi_enable_event) 201 202 /******************************************************************************* 203 * 204 * FUNCTION: acpi_set_gpe_type 205 * 206 * PARAMETERS: gpe_device - Parent GPE Device 207 * gpe_number - GPE level within the GPE block 208 * Type - New GPE type 209 * 210 * RETURN: Status 211 * 212 * DESCRIPTION: Set the type of an individual GPE 213 * 214 ******************************************************************************/ 215 acpi_status acpi_set_gpe_type(acpi_handle gpe_device, u32 gpe_number, u8 type) 216 { 217 acpi_status status = AE_OK; 218 struct acpi_gpe_event_info *gpe_event_info; 219 220 ACPI_FUNCTION_TRACE(acpi_set_gpe_type); 221 222 /* Ensure that we have a valid GPE number */ 223 224 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 225 if (!gpe_event_info) { 226 status = AE_BAD_PARAMETER; 227 goto unlock_and_exit; 228 } 229 230 if ((gpe_event_info->flags & ACPI_GPE_TYPE_MASK) == type) { 231 return_ACPI_STATUS(AE_OK); 232 } 233 234 /* Set the new type (will disable GPE if currently enabled) */ 235 236 status = acpi_ev_set_gpe_type(gpe_event_info, type); 237 238 unlock_and_exit: 239 return_ACPI_STATUS(status); 240 } 241 242 ACPI_EXPORT_SYMBOL(acpi_set_gpe_type) 243 244 /******************************************************************************* 245 * 246 * FUNCTION: acpi_enable_gpe 247 * 248 * PARAMETERS: gpe_device - Parent GPE Device 249 * gpe_number - GPE level within the GPE block 250 * Flags - Just enable, or also wake enable? 251 * Called from ISR or not 252 * 253 * RETURN: Status 254 * 255 * DESCRIPTION: Enable an ACPI event (general purpose) 256 * 257 ******************************************************************************/ 258 acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) 259 { 260 acpi_status status = AE_OK; 261 acpi_cpu_flags flags; 262 struct acpi_gpe_event_info *gpe_event_info; 263 264 ACPI_FUNCTION_TRACE(acpi_enable_gpe); 265 266 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 267 268 /* Ensure that we have a valid GPE number */ 269 270 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 271 if (!gpe_event_info) { 272 status = AE_BAD_PARAMETER; 273 goto unlock_and_exit; 274 } 275 276 /* Perform the enable */ 277 278 status = acpi_ev_enable_gpe(gpe_event_info, TRUE); 279 280 unlock_and_exit: 281 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 282 return_ACPI_STATUS(status); 283 } 284 285 ACPI_EXPORT_SYMBOL(acpi_enable_gpe) 286 287 /******************************************************************************* 288 * 289 * FUNCTION: acpi_disable_gpe 290 * 291 * PARAMETERS: gpe_device - Parent GPE Device 292 * gpe_number - GPE level within the GPE block 293 * Flags - Just disable, or also wake disable? 294 * Called from ISR or not 295 * 296 * RETURN: Status 297 * 298 * DESCRIPTION: Disable an ACPI event (general purpose) 299 * 300 ******************************************************************************/ 301 acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number) 302 { 303 acpi_status status = AE_OK; 304 acpi_cpu_flags flags; 305 struct acpi_gpe_event_info *gpe_event_info; 306 307 ACPI_FUNCTION_TRACE(acpi_disable_gpe); 308 309 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 310 /* Ensure that we have a valid GPE number */ 311 312 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 313 if (!gpe_event_info) { 314 status = AE_BAD_PARAMETER; 315 goto unlock_and_exit; 316 } 317 318 status = acpi_ev_disable_gpe(gpe_event_info); 319 320 unlock_and_exit: 321 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 322 return_ACPI_STATUS(status); 323 } 324 325 ACPI_EXPORT_SYMBOL(acpi_disable_gpe) 326 327 /******************************************************************************* 328 * 329 * FUNCTION: acpi_disable_event 330 * 331 * PARAMETERS: Event - The fixed eventto be enabled 332 * Flags - Reserved 333 * 334 * RETURN: Status 335 * 336 * DESCRIPTION: Disable an ACPI event (fixed) 337 * 338 ******************************************************************************/ 339 acpi_status acpi_disable_event(u32 event, u32 flags) 340 { 341 acpi_status status = AE_OK; 342 u32 value; 343 344 ACPI_FUNCTION_TRACE(acpi_disable_event); 345 346 /* Decode the Fixed Event */ 347 348 if (event > ACPI_EVENT_MAX) { 349 return_ACPI_STATUS(AE_BAD_PARAMETER); 350 } 351 352 /* 353 * Disable the requested fixed event (by writing a zero to the enable 354 * register bit) 355 */ 356 status = 357 acpi_set_register(acpi_gbl_fixed_event_info[event]. 358 enable_register_id, 0); 359 if (ACPI_FAILURE(status)) { 360 return_ACPI_STATUS(status); 361 } 362 363 status = 364 acpi_get_register(acpi_gbl_fixed_event_info[event]. 365 enable_register_id, &value); 366 if (ACPI_FAILURE(status)) { 367 return_ACPI_STATUS(status); 368 } 369 370 if (value != 0) { 371 ACPI_ERROR((AE_INFO, 372 "Could not disable %s events", 373 acpi_ut_get_event_name(event))); 374 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); 375 } 376 377 return_ACPI_STATUS(status); 378 } 379 380 ACPI_EXPORT_SYMBOL(acpi_disable_event) 381 382 /******************************************************************************* 383 * 384 * FUNCTION: acpi_clear_event 385 * 386 * PARAMETERS: Event - The fixed event to be cleared 387 * 388 * RETURN: Status 389 * 390 * DESCRIPTION: Clear an ACPI event (fixed) 391 * 392 ******************************************************************************/ 393 acpi_status acpi_clear_event(u32 event) 394 { 395 acpi_status status = AE_OK; 396 397 ACPI_FUNCTION_TRACE(acpi_clear_event); 398 399 /* Decode the Fixed Event */ 400 401 if (event > ACPI_EVENT_MAX) { 402 return_ACPI_STATUS(AE_BAD_PARAMETER); 403 } 404 405 /* 406 * Clear the requested fixed event (By writing a one to the status 407 * register bit) 408 */ 409 status = 410 acpi_set_register(acpi_gbl_fixed_event_info[event]. 411 status_register_id, 1); 412 413 return_ACPI_STATUS(status); 414 } 415 416 ACPI_EXPORT_SYMBOL(acpi_clear_event) 417 418 /******************************************************************************* 419 * 420 * FUNCTION: acpi_clear_gpe 421 * 422 * PARAMETERS: gpe_device - Parent GPE Device 423 * gpe_number - GPE level within the GPE block 424 * Flags - Called from an ISR or not 425 * 426 * RETURN: Status 427 * 428 * DESCRIPTION: Clear an ACPI event (general purpose) 429 * 430 ******************************************************************************/ 431 acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags) 432 { 433 acpi_status status = AE_OK; 434 struct acpi_gpe_event_info *gpe_event_info; 435 436 ACPI_FUNCTION_TRACE(acpi_clear_gpe); 437 438 /* Use semaphore lock if not executing at interrupt level */ 439 440 if (flags & ACPI_NOT_ISR) { 441 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); 442 if (ACPI_FAILURE(status)) { 443 return_ACPI_STATUS(status); 444 } 445 } 446 447 /* Ensure that we have a valid GPE number */ 448 449 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 450 if (!gpe_event_info) { 451 status = AE_BAD_PARAMETER; 452 goto unlock_and_exit; 453 } 454 455 status = acpi_hw_clear_gpe(gpe_event_info); 456 457 unlock_and_exit: 458 if (flags & ACPI_NOT_ISR) { 459 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); 460 } 461 return_ACPI_STATUS(status); 462 } 463 464 ACPI_EXPORT_SYMBOL(acpi_clear_gpe) 465 /******************************************************************************* 466 * 467 * FUNCTION: acpi_get_event_status 468 * 469 * PARAMETERS: Event - The fixed event 470 * event_status - Where the current status of the event will 471 * be returned 472 * 473 * RETURN: Status 474 * 475 * DESCRIPTION: Obtains and returns the current status of the event 476 * 477 ******************************************************************************/ 478 acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status) 479 { 480 acpi_status status = AE_OK; 481 u32 value; 482 483 ACPI_FUNCTION_TRACE(acpi_get_event_status); 484 485 if (!event_status) { 486 return_ACPI_STATUS(AE_BAD_PARAMETER); 487 } 488 489 /* Decode the Fixed Event */ 490 491 if (event > ACPI_EVENT_MAX) { 492 return_ACPI_STATUS(AE_BAD_PARAMETER); 493 } 494 495 /* Get the status of the requested fixed event */ 496 497 status = 498 acpi_get_register(acpi_gbl_fixed_event_info[event]. 499 enable_register_id, &value); 500 if (ACPI_FAILURE(status)) 501 return_ACPI_STATUS(status); 502 503 *event_status = value; 504 505 status = 506 acpi_get_register(acpi_gbl_fixed_event_info[event]. 507 status_register_id, &value); 508 if (ACPI_FAILURE(status)) 509 return_ACPI_STATUS(status); 510 511 if (value) 512 *event_status |= ACPI_EVENT_FLAG_SET; 513 514 if (acpi_gbl_fixed_event_handlers[event].handler) 515 *event_status |= ACPI_EVENT_FLAG_HANDLE; 516 517 return_ACPI_STATUS(status); 518 } 519 520 ACPI_EXPORT_SYMBOL(acpi_get_event_status) 521 522 /******************************************************************************* 523 * 524 * FUNCTION: acpi_get_gpe_status 525 * 526 * PARAMETERS: gpe_device - Parent GPE Device 527 * gpe_number - GPE level within the GPE block 528 * Flags - Called from an ISR or not 529 * event_status - Where the current status of the event will 530 * be returned 531 * 532 * RETURN: Status 533 * 534 * DESCRIPTION: Get status of an event (general purpose) 535 * 536 ******************************************************************************/ 537 acpi_status 538 acpi_get_gpe_status(acpi_handle gpe_device, 539 u32 gpe_number, u32 flags, acpi_event_status * event_status) 540 { 541 acpi_status status = AE_OK; 542 struct acpi_gpe_event_info *gpe_event_info; 543 544 ACPI_FUNCTION_TRACE(acpi_get_gpe_status); 545 546 /* Use semaphore lock if not executing at interrupt level */ 547 548 if (flags & ACPI_NOT_ISR) { 549 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); 550 if (ACPI_FAILURE(status)) { 551 return_ACPI_STATUS(status); 552 } 553 } 554 555 /* Ensure that we have a valid GPE number */ 556 557 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 558 if (!gpe_event_info) { 559 status = AE_BAD_PARAMETER; 560 goto unlock_and_exit; 561 } 562 563 /* Obtain status on the requested GPE number */ 564 565 status = acpi_hw_get_gpe_status(gpe_event_info, event_status); 566 567 if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) 568 *event_status |= ACPI_EVENT_FLAG_HANDLE; 569 570 unlock_and_exit: 571 if (flags & ACPI_NOT_ISR) { 572 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); 573 } 574 return_ACPI_STATUS(status); 575 } 576 577 ACPI_EXPORT_SYMBOL(acpi_get_gpe_status) 578 /******************************************************************************* 579 * 580 * FUNCTION: acpi_install_gpe_block 581 * 582 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device 583 * gpe_block_address - Address and space_iD 584 * register_count - Number of GPE register pairs in the block 585 * interrupt_number - H/W interrupt for the block 586 * 587 * RETURN: Status 588 * 589 * DESCRIPTION: Create and Install a block of GPE registers 590 * 591 ******************************************************************************/ 592 acpi_status 593 acpi_install_gpe_block(acpi_handle gpe_device, 594 struct acpi_generic_address *gpe_block_address, 595 u32 register_count, u32 interrupt_number) 596 { 597 acpi_status status; 598 union acpi_operand_object *obj_desc; 599 struct acpi_namespace_node *node; 600 struct acpi_gpe_block_info *gpe_block; 601 602 ACPI_FUNCTION_TRACE(acpi_install_gpe_block); 603 604 if ((!gpe_device) || (!gpe_block_address) || (!register_count)) { 605 return_ACPI_STATUS(AE_BAD_PARAMETER); 606 } 607 608 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 609 if (ACPI_FAILURE(status)) { 610 return (status); 611 } 612 613 node = acpi_ns_map_handle_to_node(gpe_device); 614 if (!node) { 615 status = AE_BAD_PARAMETER; 616 goto unlock_and_exit; 617 } 618 619 /* 620 * For user-installed GPE Block Devices, the gpe_block_base_number 621 * is always zero 622 */ 623 status = 624 acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0, 625 interrupt_number, &gpe_block); 626 if (ACPI_FAILURE(status)) { 627 goto unlock_and_exit; 628 } 629 630 /* Run the _PRW methods and enable the GPEs */ 631 632 status = acpi_ev_initialize_gpe_block(node, gpe_block); 633 if (ACPI_FAILURE(status)) { 634 goto unlock_and_exit; 635 } 636 637 /* Get the device_object attached to the node */ 638 639 obj_desc = acpi_ns_get_attached_object(node); 640 if (!obj_desc) { 641 642 /* No object, create a new one */ 643 644 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE); 645 if (!obj_desc) { 646 status = AE_NO_MEMORY; 647 goto unlock_and_exit; 648 } 649 650 status = 651 acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE); 652 653 /* Remove local reference to the object */ 654 655 acpi_ut_remove_reference(obj_desc); 656 657 if (ACPI_FAILURE(status)) { 658 goto unlock_and_exit; 659 } 660 } 661 662 /* Install the GPE block in the device_object */ 663 664 obj_desc->device.gpe_block = gpe_block; 665 666 unlock_and_exit: 667 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 668 return_ACPI_STATUS(status); 669 } 670 671 ACPI_EXPORT_SYMBOL(acpi_install_gpe_block) 672 673 /******************************************************************************* 674 * 675 * FUNCTION: acpi_remove_gpe_block 676 * 677 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device 678 * 679 * RETURN: Status 680 * 681 * DESCRIPTION: Remove a previously installed block of GPE registers 682 * 683 ******************************************************************************/ 684 acpi_status acpi_remove_gpe_block(acpi_handle gpe_device) 685 { 686 union acpi_operand_object *obj_desc; 687 acpi_status status; 688 struct acpi_namespace_node *node; 689 690 ACPI_FUNCTION_TRACE(acpi_remove_gpe_block); 691 692 if (!gpe_device) { 693 return_ACPI_STATUS(AE_BAD_PARAMETER); 694 } 695 696 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 697 if (ACPI_FAILURE(status)) { 698 return (status); 699 } 700 701 node = acpi_ns_map_handle_to_node(gpe_device); 702 if (!node) { 703 status = AE_BAD_PARAMETER; 704 goto unlock_and_exit; 705 } 706 707 /* Get the device_object attached to the node */ 708 709 obj_desc = acpi_ns_get_attached_object(node); 710 if (!obj_desc || !obj_desc->device.gpe_block) { 711 return_ACPI_STATUS(AE_NULL_OBJECT); 712 } 713 714 /* Delete the GPE block (but not the device_object) */ 715 716 status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block); 717 if (ACPI_SUCCESS(status)) { 718 obj_desc->device.gpe_block = NULL; 719 } 720 721 unlock_and_exit: 722 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 723 return_ACPI_STATUS(status); 724 } 725 726 ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block) 727 728 /******************************************************************************* 729 * 730 * FUNCTION: acpi_get_gpe_device 731 * 732 * PARAMETERS: Index - System GPE index (0-current_gpe_count) 733 * gpe_device - Where the parent GPE Device is returned 734 * 735 * RETURN: Status 736 * 737 * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL 738 * gpe device indicates that the gpe number is contained in one of 739 * the FADT-defined gpe blocks. Otherwise, the GPE block device. 740 * 741 ******************************************************************************/ 742 acpi_status 743 acpi_get_gpe_device(u32 index, acpi_handle *gpe_device) 744 { 745 struct acpi_gpe_device_info info; 746 acpi_status status; 747 748 ACPI_FUNCTION_TRACE(acpi_get_gpe_device); 749 750 if (!gpe_device) { 751 return_ACPI_STATUS(AE_BAD_PARAMETER); 752 } 753 754 if (index >= acpi_current_gpe_count) { 755 return_ACPI_STATUS(AE_NOT_EXIST); 756 } 757 758 /* Setup and walk the GPE list */ 759 760 info.index = index; 761 info.status = AE_NOT_EXIST; 762 info.gpe_device = NULL; 763 info.next_block_base_index = 0; 764 765 status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info); 766 if (ACPI_FAILURE(status)) { 767 return_ACPI_STATUS(status); 768 } 769 770 *gpe_device = info.gpe_device; 771 return_ACPI_STATUS(info.status); 772 } 773 774 ACPI_EXPORT_SYMBOL(acpi_get_gpe_device) 775 776 /******************************************************************************* 777 * 778 * FUNCTION: acpi_ev_get_gpe_device 779 * 780 * PARAMETERS: GPE_WALK_CALLBACK 781 * 782 * RETURN: Status 783 * 784 * DESCRIPTION: Matches the input GPE index (0-current_gpe_count) with a GPE 785 * block device. NULL if the GPE is one of the FADT-defined GPEs. 786 * 787 ******************************************************************************/ 788 acpi_status 789 acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, 790 struct acpi_gpe_block_info *gpe_block, void *context) 791 { 792 struct acpi_gpe_device_info *info = context; 793 794 /* Increment Index by the number of GPEs in this block */ 795 796 info->next_block_base_index += 797 (gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH); 798 799 if (info->index < info->next_block_base_index) { 800 /* 801 * The GPE index is within this block, get the node. Leave the node 802 * NULL for the FADT-defined GPEs 803 */ 804 if ((gpe_block->node)->type == ACPI_TYPE_DEVICE) { 805 info->gpe_device = gpe_block->node; 806 } 807 808 info->status = AE_OK; 809 return (AE_CTRL_END); 810 } 811 812 return (AE_OK); 813 } 814 815 /****************************************************************************** 816 * 817 * FUNCTION: acpi_disable_all_gpes 818 * 819 * PARAMETERS: None 820 * 821 * RETURN: Status 822 * 823 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks 824 * 825 ******************************************************************************/ 826 827 acpi_status acpi_disable_all_gpes(void) 828 { 829 acpi_status status; 830 831 ACPI_FUNCTION_TRACE(acpi_disable_all_gpes); 832 833 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); 834 if (ACPI_FAILURE(status)) { 835 return_ACPI_STATUS(status); 836 } 837 838 status = acpi_hw_disable_all_gpes(); 839 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); 840 841 return_ACPI_STATUS(status); 842 } 843 844 /****************************************************************************** 845 * 846 * FUNCTION: acpi_enable_all_runtime_gpes 847 * 848 * PARAMETERS: None 849 * 850 * RETURN: Status 851 * 852 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks 853 * 854 ******************************************************************************/ 855 856 acpi_status acpi_enable_all_runtime_gpes(void) 857 { 858 acpi_status status; 859 860 ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes); 861 862 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); 863 if (ACPI_FAILURE(status)) { 864 return_ACPI_STATUS(status); 865 } 866 867 status = acpi_hw_enable_all_runtime_gpes(); 868 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); 869 870 return_ACPI_STATUS(status); 871 } 872