1 /****************************************************************************** 2 * 3 * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2010, 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 static 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; 73 int retry; 74 75 ACPI_FUNCTION_TRACE(acpi_enable); 76 77 /* ACPI tables must be present */ 78 79 if (!acpi_tb_tables_loaded()) { 80 return_ACPI_STATUS(AE_NO_ACPI_TABLES); 81 } 82 83 /* Check current mode */ 84 85 if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) { 86 ACPI_DEBUG_PRINT((ACPI_DB_INIT, 87 "System is already in ACPI mode\n")); 88 return_ACPI_STATUS(AE_OK); 89 } 90 91 /* Transition to ACPI mode */ 92 93 status = acpi_hw_set_mode(ACPI_SYS_MODE_ACPI); 94 if (ACPI_FAILURE(status)) { 95 ACPI_ERROR((AE_INFO, 96 "Could not transition to ACPI mode")); 97 return_ACPI_STATUS(status); 98 } 99 100 /* Sanity check that transition succeeded */ 101 102 for (retry = 0; retry < 30000; ++retry) { 103 if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) { 104 if (retry != 0) 105 ACPI_WARNING((AE_INFO, 106 "Platform took > %d00 usec to enter ACPI mode", retry)); 107 return_ACPI_STATUS(AE_OK); 108 } 109 acpi_os_stall(100); /* 100 usec */ 110 } 111 112 ACPI_ERROR((AE_INFO, "Hardware did not enter ACPI mode")); 113 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); 114 } 115 116 ACPI_EXPORT_SYMBOL(acpi_enable) 117 118 /******************************************************************************* 119 * 120 * FUNCTION: acpi_disable 121 * 122 * PARAMETERS: None 123 * 124 * RETURN: Status 125 * 126 * DESCRIPTION: Transfers the system into LEGACY (non-ACPI) mode. 127 * 128 ******************************************************************************/ 129 acpi_status acpi_disable(void) 130 { 131 acpi_status status = AE_OK; 132 133 ACPI_FUNCTION_TRACE(acpi_disable); 134 135 if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) { 136 ACPI_DEBUG_PRINT((ACPI_DB_INIT, 137 "System is already in legacy (non-ACPI) mode\n")); 138 } else { 139 /* Transition to LEGACY mode */ 140 141 status = acpi_hw_set_mode(ACPI_SYS_MODE_LEGACY); 142 143 if (ACPI_FAILURE(status)) { 144 ACPI_ERROR((AE_INFO, 145 "Could not exit ACPI mode to legacy mode")); 146 return_ACPI_STATUS(status); 147 } 148 149 ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI mode disabled\n")); 150 } 151 152 return_ACPI_STATUS(status); 153 } 154 155 ACPI_EXPORT_SYMBOL(acpi_disable) 156 157 /******************************************************************************* 158 * 159 * FUNCTION: acpi_enable_event 160 * 161 * PARAMETERS: Event - The fixed eventto be enabled 162 * Flags - Reserved 163 * 164 * RETURN: Status 165 * 166 * DESCRIPTION: Enable an ACPI event (fixed) 167 * 168 ******************************************************************************/ 169 acpi_status acpi_enable_event(u32 event, u32 flags) 170 { 171 acpi_status status = AE_OK; 172 u32 value; 173 174 ACPI_FUNCTION_TRACE(acpi_enable_event); 175 176 /* Decode the Fixed Event */ 177 178 if (event > ACPI_EVENT_MAX) { 179 return_ACPI_STATUS(AE_BAD_PARAMETER); 180 } 181 182 /* 183 * Enable the requested fixed event (by writing a one to the enable 184 * register bit) 185 */ 186 status = 187 acpi_write_bit_register(acpi_gbl_fixed_event_info[event]. 188 enable_register_id, ACPI_ENABLE_EVENT); 189 if (ACPI_FAILURE(status)) { 190 return_ACPI_STATUS(status); 191 } 192 193 /* Make sure that the hardware responded */ 194 195 status = 196 acpi_read_bit_register(acpi_gbl_fixed_event_info[event]. 197 enable_register_id, &value); 198 if (ACPI_FAILURE(status)) { 199 return_ACPI_STATUS(status); 200 } 201 202 if (value != 1) { 203 ACPI_ERROR((AE_INFO, 204 "Could not enable %s event", 205 acpi_ut_get_event_name(event))); 206 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); 207 } 208 209 return_ACPI_STATUS(status); 210 } 211 212 ACPI_EXPORT_SYMBOL(acpi_enable_event) 213 214 /******************************************************************************* 215 * 216 * FUNCTION: acpi_gpe_wakeup 217 * 218 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 219 * gpe_number - GPE level within the GPE block 220 * Action - Enable or Disable 221 * 222 * RETURN: Status 223 * 224 * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. 225 * 226 ******************************************************************************/ 227 acpi_status acpi_gpe_wakeup(acpi_handle gpe_device, u32 gpe_number, u8 action) 228 { 229 acpi_status status = AE_OK; 230 struct acpi_gpe_event_info *gpe_event_info; 231 struct acpi_gpe_register_info *gpe_register_info; 232 acpi_cpu_flags flags; 233 u32 register_bit; 234 235 ACPI_FUNCTION_TRACE(acpi_gpe_wakeup); 236 237 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 238 239 /* Ensure that we have a valid GPE number */ 240 241 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 242 if (!gpe_event_info || !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { 243 status = AE_BAD_PARAMETER; 244 goto unlock_and_exit; 245 } 246 247 gpe_register_info = gpe_event_info->register_info; 248 if (!gpe_register_info) { 249 status = AE_NOT_EXIST; 250 goto unlock_and_exit; 251 } 252 253 register_bit = 254 acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info); 255 256 /* Perform the action */ 257 258 switch (action) { 259 case ACPI_GPE_ENABLE: 260 ACPI_SET_BIT(gpe_register_info->enable_for_wake, 261 (u8)register_bit); 262 break; 263 264 case ACPI_GPE_DISABLE: 265 ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake, 266 (u8)register_bit); 267 break; 268 269 default: 270 ACPI_ERROR((AE_INFO, "%u, Invalid action", action)); 271 status = AE_BAD_PARAMETER; 272 break; 273 } 274 275 unlock_and_exit: 276 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 277 return_ACPI_STATUS(status); 278 } 279 280 ACPI_EXPORT_SYMBOL(acpi_gpe_wakeup) 281 282 /******************************************************************************* 283 * 284 * FUNCTION: acpi_enable_gpe 285 * 286 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 287 * gpe_number - GPE level within the GPE block 288 * 289 * RETURN: Status 290 * 291 * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is 292 * hardware-enabled. 293 * 294 ******************************************************************************/ 295 acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) 296 { 297 acpi_status status = AE_BAD_PARAMETER; 298 struct acpi_gpe_event_info *gpe_event_info; 299 acpi_cpu_flags flags; 300 301 ACPI_FUNCTION_TRACE(acpi_enable_gpe); 302 303 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 304 305 /* Ensure that we have a valid GPE number */ 306 307 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 308 if (gpe_event_info) { 309 status = acpi_raw_enable_gpe(gpe_event_info); 310 } 311 312 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 313 return_ACPI_STATUS(status); 314 } 315 ACPI_EXPORT_SYMBOL(acpi_enable_gpe) 316 317 /******************************************************************************* 318 * 319 * FUNCTION: acpi_disable_gpe 320 * 321 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 322 * gpe_number - GPE level within the GPE block 323 * 324 * RETURN: Status 325 * 326 * DESCRIPTION: Remove a reference to a GPE. When the last reference is 327 * removed, only then is the GPE disabled (for runtime GPEs), or 328 * the GPE mask bit disabled (for wake GPEs) 329 * 330 ******************************************************************************/ 331 acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number) 332 { 333 acpi_status status = AE_BAD_PARAMETER; 334 struct acpi_gpe_event_info *gpe_event_info; 335 acpi_cpu_flags flags; 336 337 ACPI_FUNCTION_TRACE(acpi_disable_gpe); 338 339 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 340 341 /* Ensure that we have a valid GPE number */ 342 343 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 344 if (gpe_event_info) { 345 status = acpi_raw_disable_gpe(gpe_event_info) ; 346 } 347 348 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 349 return_ACPI_STATUS(status); 350 } 351 ACPI_EXPORT_SYMBOL(acpi_disable_gpe) 352 353 /******************************************************************************* 354 * 355 * FUNCTION: acpi_gpe_can_wake 356 * 357 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 358 * gpe_number - GPE level within the GPE block 359 * 360 * RETURN: Status 361 * 362 * DESCRIPTION: Set the ACPI_GPE_CAN_WAKE flag for the given GPE. If the GPE 363 * has a corresponding method and is currently enabled, disable it 364 * (GPEs with corresponding methods are enabled unconditionally 365 * during initialization, but GPEs that can wake up are expected 366 * to be initially disabled). 367 * 368 ******************************************************************************/ 369 acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number) 370 { 371 acpi_status status = AE_OK; 372 struct acpi_gpe_event_info *gpe_event_info; 373 acpi_cpu_flags flags; 374 375 ACPI_FUNCTION_TRACE(acpi_gpe_can_wake); 376 377 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 378 379 /* Ensure that we have a valid GPE number */ 380 381 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 382 if (gpe_event_info) { 383 gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; 384 } else { 385 status = AE_BAD_PARAMETER; 386 } 387 388 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 389 return_ACPI_STATUS(status); 390 } 391 ACPI_EXPORT_SYMBOL(acpi_gpe_can_wake) 392 393 /******************************************************************************* 394 * 395 * FUNCTION: acpi_disable_event 396 * 397 * PARAMETERS: Event - The fixed eventto be enabled 398 * Flags - Reserved 399 * 400 * RETURN: Status 401 * 402 * DESCRIPTION: Disable an ACPI event (fixed) 403 * 404 ******************************************************************************/ 405 acpi_status acpi_disable_event(u32 event, u32 flags) 406 { 407 acpi_status status = AE_OK; 408 u32 value; 409 410 ACPI_FUNCTION_TRACE(acpi_disable_event); 411 412 /* Decode the Fixed Event */ 413 414 if (event > ACPI_EVENT_MAX) { 415 return_ACPI_STATUS(AE_BAD_PARAMETER); 416 } 417 418 /* 419 * Disable the requested fixed event (by writing a zero to the enable 420 * register bit) 421 */ 422 status = 423 acpi_write_bit_register(acpi_gbl_fixed_event_info[event]. 424 enable_register_id, ACPI_DISABLE_EVENT); 425 if (ACPI_FAILURE(status)) { 426 return_ACPI_STATUS(status); 427 } 428 429 status = 430 acpi_read_bit_register(acpi_gbl_fixed_event_info[event]. 431 enable_register_id, &value); 432 if (ACPI_FAILURE(status)) { 433 return_ACPI_STATUS(status); 434 } 435 436 if (value != 0) { 437 ACPI_ERROR((AE_INFO, 438 "Could not disable %s events", 439 acpi_ut_get_event_name(event))); 440 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); 441 } 442 443 return_ACPI_STATUS(status); 444 } 445 446 ACPI_EXPORT_SYMBOL(acpi_disable_event) 447 448 /******************************************************************************* 449 * 450 * FUNCTION: acpi_clear_event 451 * 452 * PARAMETERS: Event - The fixed event to be cleared 453 * 454 * RETURN: Status 455 * 456 * DESCRIPTION: Clear an ACPI event (fixed) 457 * 458 ******************************************************************************/ 459 acpi_status acpi_clear_event(u32 event) 460 { 461 acpi_status status = AE_OK; 462 463 ACPI_FUNCTION_TRACE(acpi_clear_event); 464 465 /* Decode the Fixed Event */ 466 467 if (event > ACPI_EVENT_MAX) { 468 return_ACPI_STATUS(AE_BAD_PARAMETER); 469 } 470 471 /* 472 * Clear the requested fixed event (By writing a one to the status 473 * register bit) 474 */ 475 status = 476 acpi_write_bit_register(acpi_gbl_fixed_event_info[event]. 477 status_register_id, ACPI_CLEAR_STATUS); 478 479 return_ACPI_STATUS(status); 480 } 481 482 ACPI_EXPORT_SYMBOL(acpi_clear_event) 483 484 /******************************************************************************* 485 * 486 * FUNCTION: acpi_clear_gpe 487 * 488 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 489 * gpe_number - GPE level within the GPE block 490 * 491 * RETURN: Status 492 * 493 * DESCRIPTION: Clear an ACPI event (general purpose) 494 * 495 ******************************************************************************/ 496 acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number) 497 { 498 acpi_status status = AE_OK; 499 struct acpi_gpe_event_info *gpe_event_info; 500 acpi_cpu_flags flags; 501 502 ACPI_FUNCTION_TRACE(acpi_clear_gpe); 503 504 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 505 506 /* Ensure that we have a valid GPE number */ 507 508 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 509 if (!gpe_event_info) { 510 status = AE_BAD_PARAMETER; 511 goto unlock_and_exit; 512 } 513 514 status = acpi_hw_clear_gpe(gpe_event_info); 515 516 unlock_and_exit: 517 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 518 return_ACPI_STATUS(status); 519 } 520 521 ACPI_EXPORT_SYMBOL(acpi_clear_gpe) 522 /******************************************************************************* 523 * 524 * FUNCTION: acpi_get_event_status 525 * 526 * PARAMETERS: Event - The fixed event 527 * event_status - Where the current status of the event will 528 * be returned 529 * 530 * RETURN: Status 531 * 532 * DESCRIPTION: Obtains and returns the current status of the event 533 * 534 ******************************************************************************/ 535 acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status) 536 { 537 acpi_status status = AE_OK; 538 u32 value; 539 540 ACPI_FUNCTION_TRACE(acpi_get_event_status); 541 542 if (!event_status) { 543 return_ACPI_STATUS(AE_BAD_PARAMETER); 544 } 545 546 /* Decode the Fixed Event */ 547 548 if (event > ACPI_EVENT_MAX) { 549 return_ACPI_STATUS(AE_BAD_PARAMETER); 550 } 551 552 /* Get the status of the requested fixed event */ 553 554 status = 555 acpi_read_bit_register(acpi_gbl_fixed_event_info[event]. 556 enable_register_id, &value); 557 if (ACPI_FAILURE(status)) 558 return_ACPI_STATUS(status); 559 560 *event_status = value; 561 562 status = 563 acpi_read_bit_register(acpi_gbl_fixed_event_info[event]. 564 status_register_id, &value); 565 if (ACPI_FAILURE(status)) 566 return_ACPI_STATUS(status); 567 568 if (value) 569 *event_status |= ACPI_EVENT_FLAG_SET; 570 571 if (acpi_gbl_fixed_event_handlers[event].handler) 572 *event_status |= ACPI_EVENT_FLAG_HANDLE; 573 574 return_ACPI_STATUS(status); 575 } 576 577 ACPI_EXPORT_SYMBOL(acpi_get_event_status) 578 579 /******************************************************************************* 580 * 581 * FUNCTION: acpi_get_gpe_status 582 * 583 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 584 * gpe_number - GPE level within the GPE block 585 * event_status - Where the current status of the event will 586 * be returned 587 * 588 * RETURN: Status 589 * 590 * DESCRIPTION: Get status of an event (general purpose) 591 * 592 ******************************************************************************/ 593 acpi_status 594 acpi_get_gpe_status(acpi_handle gpe_device, 595 u32 gpe_number, acpi_event_status *event_status) 596 { 597 acpi_status status = AE_OK; 598 struct acpi_gpe_event_info *gpe_event_info; 599 acpi_cpu_flags flags; 600 601 ACPI_FUNCTION_TRACE(acpi_get_gpe_status); 602 603 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 604 605 /* Ensure that we have a valid GPE number */ 606 607 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 608 if (!gpe_event_info) { 609 status = AE_BAD_PARAMETER; 610 goto unlock_and_exit; 611 } 612 613 /* Obtain status on the requested GPE number */ 614 615 status = acpi_hw_get_gpe_status(gpe_event_info, event_status); 616 617 if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) 618 *event_status |= ACPI_EVENT_FLAG_HANDLE; 619 620 unlock_and_exit: 621 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 622 return_ACPI_STATUS(status); 623 } 624 625 ACPI_EXPORT_SYMBOL(acpi_get_gpe_status) 626 /******************************************************************************* 627 * 628 * FUNCTION: acpi_install_gpe_block 629 * 630 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device 631 * gpe_block_address - Address and space_iD 632 * register_count - Number of GPE register pairs in the block 633 * interrupt_number - H/W interrupt for the block 634 * 635 * RETURN: Status 636 * 637 * DESCRIPTION: Create and Install a block of GPE registers 638 * 639 ******************************************************************************/ 640 acpi_status 641 acpi_install_gpe_block(acpi_handle gpe_device, 642 struct acpi_generic_address *gpe_block_address, 643 u32 register_count, u32 interrupt_number) 644 { 645 acpi_status status = AE_OK; 646 union acpi_operand_object *obj_desc; 647 struct acpi_namespace_node *node; 648 struct acpi_gpe_block_info *gpe_block; 649 650 ACPI_FUNCTION_TRACE(acpi_install_gpe_block); 651 652 if ((!gpe_device) || (!gpe_block_address) || (!register_count)) { 653 return_ACPI_STATUS(AE_BAD_PARAMETER); 654 } 655 656 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 657 if (ACPI_FAILURE(status)) { 658 return (status); 659 } 660 661 node = acpi_ns_validate_handle(gpe_device); 662 if (!node) { 663 status = AE_BAD_PARAMETER; 664 goto unlock_and_exit; 665 } 666 667 /* 668 * For user-installed GPE Block Devices, the gpe_block_base_number 669 * is always zero 670 */ 671 status = 672 acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0, 673 interrupt_number, &gpe_block); 674 if (ACPI_FAILURE(status)) { 675 goto unlock_and_exit; 676 } 677 678 /* Install block in the device_object attached to the node */ 679 680 obj_desc = acpi_ns_get_attached_object(node); 681 if (!obj_desc) { 682 683 /* 684 * No object, create a new one (Device nodes do not always have 685 * an attached object) 686 */ 687 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE); 688 if (!obj_desc) { 689 status = AE_NO_MEMORY; 690 goto unlock_and_exit; 691 } 692 693 status = 694 acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE); 695 696 /* Remove local reference to the object */ 697 698 acpi_ut_remove_reference(obj_desc); 699 700 if (ACPI_FAILURE(status)) { 701 goto unlock_and_exit; 702 } 703 } 704 705 /* Now install the GPE block in the device_object */ 706 707 obj_desc->device.gpe_block = gpe_block; 708 709 unlock_and_exit: 710 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 711 return_ACPI_STATUS(status); 712 } 713 714 ACPI_EXPORT_SYMBOL(acpi_install_gpe_block) 715 716 /******************************************************************************* 717 * 718 * FUNCTION: acpi_remove_gpe_block 719 * 720 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device 721 * 722 * RETURN: Status 723 * 724 * DESCRIPTION: Remove a previously installed block of GPE registers 725 * 726 ******************************************************************************/ 727 acpi_status acpi_remove_gpe_block(acpi_handle gpe_device) 728 { 729 union acpi_operand_object *obj_desc; 730 acpi_status status; 731 struct acpi_namespace_node *node; 732 733 ACPI_FUNCTION_TRACE(acpi_remove_gpe_block); 734 735 if (!gpe_device) { 736 return_ACPI_STATUS(AE_BAD_PARAMETER); 737 } 738 739 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 740 if (ACPI_FAILURE(status)) { 741 return (status); 742 } 743 744 node = acpi_ns_validate_handle(gpe_device); 745 if (!node) { 746 status = AE_BAD_PARAMETER; 747 goto unlock_and_exit; 748 } 749 750 /* Get the device_object attached to the node */ 751 752 obj_desc = acpi_ns_get_attached_object(node); 753 if (!obj_desc || !obj_desc->device.gpe_block) { 754 return_ACPI_STATUS(AE_NULL_OBJECT); 755 } 756 757 /* Delete the GPE block (but not the device_object) */ 758 759 status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block); 760 if (ACPI_SUCCESS(status)) { 761 obj_desc->device.gpe_block = NULL; 762 } 763 764 unlock_and_exit: 765 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 766 return_ACPI_STATUS(status); 767 } 768 769 ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block) 770 771 /******************************************************************************* 772 * 773 * FUNCTION: acpi_get_gpe_device 774 * 775 * PARAMETERS: Index - System GPE index (0-current_gpe_count) 776 * gpe_device - Where the parent GPE Device is returned 777 * 778 * RETURN: Status 779 * 780 * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL 781 * gpe device indicates that the gpe number is contained in one of 782 * the FADT-defined gpe blocks. Otherwise, the GPE block device. 783 * 784 ******************************************************************************/ 785 acpi_status 786 acpi_get_gpe_device(u32 index, acpi_handle *gpe_device) 787 { 788 struct acpi_gpe_device_info info; 789 acpi_status status; 790 791 ACPI_FUNCTION_TRACE(acpi_get_gpe_device); 792 793 if (!gpe_device) { 794 return_ACPI_STATUS(AE_BAD_PARAMETER); 795 } 796 797 if (index >= acpi_current_gpe_count) { 798 return_ACPI_STATUS(AE_NOT_EXIST); 799 } 800 801 /* Setup and walk the GPE list */ 802 803 info.index = index; 804 info.status = AE_NOT_EXIST; 805 info.gpe_device = NULL; 806 info.next_block_base_index = 0; 807 808 status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info); 809 if (ACPI_FAILURE(status)) { 810 return_ACPI_STATUS(status); 811 } 812 813 *gpe_device = info.gpe_device; 814 return_ACPI_STATUS(info.status); 815 } 816 817 ACPI_EXPORT_SYMBOL(acpi_get_gpe_device) 818 819 /******************************************************************************* 820 * 821 * FUNCTION: acpi_ev_get_gpe_device 822 * 823 * PARAMETERS: GPE_WALK_CALLBACK 824 * 825 * RETURN: Status 826 * 827 * DESCRIPTION: Matches the input GPE index (0-current_gpe_count) with a GPE 828 * block device. NULL if the GPE is one of the FADT-defined GPEs. 829 * 830 ******************************************************************************/ 831 static acpi_status 832 acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, 833 struct acpi_gpe_block_info *gpe_block, void *context) 834 { 835 struct acpi_gpe_device_info *info = context; 836 837 /* Increment Index by the number of GPEs in this block */ 838 839 info->next_block_base_index += gpe_block->gpe_count; 840 841 if (info->index < info->next_block_base_index) { 842 /* 843 * The GPE index is within this block, get the node. Leave the node 844 * NULL for the FADT-defined GPEs 845 */ 846 if ((gpe_block->node)->type == ACPI_TYPE_DEVICE) { 847 info->gpe_device = gpe_block->node; 848 } 849 850 info->status = AE_OK; 851 return (AE_CTRL_END); 852 } 853 854 return (AE_OK); 855 } 856 857 /****************************************************************************** 858 * 859 * FUNCTION: acpi_disable_all_gpes 860 * 861 * PARAMETERS: None 862 * 863 * RETURN: Status 864 * 865 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks 866 * 867 ******************************************************************************/ 868 869 acpi_status acpi_disable_all_gpes(void) 870 { 871 acpi_status status; 872 873 ACPI_FUNCTION_TRACE(acpi_disable_all_gpes); 874 875 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); 876 if (ACPI_FAILURE(status)) { 877 return_ACPI_STATUS(status); 878 } 879 880 status = acpi_hw_disable_all_gpes(); 881 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); 882 883 return_ACPI_STATUS(status); 884 } 885 886 /****************************************************************************** 887 * 888 * FUNCTION: acpi_enable_all_runtime_gpes 889 * 890 * PARAMETERS: None 891 * 892 * RETURN: Status 893 * 894 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks 895 * 896 ******************************************************************************/ 897 898 acpi_status acpi_enable_all_runtime_gpes(void) 899 { 900 acpi_status status; 901 902 ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes); 903 904 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); 905 if (ACPI_FAILURE(status)) { 906 return_ACPI_STATUS(status); 907 } 908 909 status = acpi_hw_enable_all_runtime_gpes(); 910 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); 911 912 return_ACPI_STATUS(status); 913 } 914 915 /****************************************************************************** 916 * 917 * FUNCTION: acpi_update_gpes 918 * 919 * PARAMETERS: None 920 * 921 * RETURN: None 922 * 923 * DESCRIPTION: Enable all GPEs that have associated _Lxx or _Exx methods and 924 * are not pointed to by any device _PRW methods indicating that 925 * these GPEs are generally intended for system or device wakeup 926 * (such GPEs have to be enabled directly when the devices whose 927 * _PRW methods point to them are set up for wakeup signaling). 928 * 929 ******************************************************************************/ 930 931 acpi_status acpi_update_gpes(void) 932 { 933 acpi_status status; 934 935 ACPI_FUNCTION_TRACE(acpi_update_gpes); 936 937 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); 938 if (ACPI_FAILURE(status)) { 939 return_ACPI_STATUS(status); 940 } else if (acpi_all_gpes_initialized) { 941 goto unlock; 942 } 943 944 status = acpi_ev_walk_gpe_list(acpi_ev_initialize_gpe_block, NULL); 945 if (ACPI_SUCCESS(status)) { 946 acpi_all_gpes_initialized = TRUE; 947 } 948 949 unlock: 950 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); 951 952 return_ACPI_STATUS(status); 953 } 954