1 /****************************************************************************** 2 * 3 * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs) 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 "acevents.h" 49 #include "acnamesp.h" 50 51 #define _COMPONENT ACPI_EVENTS 52 ACPI_MODULE_NAME("evxfgpe") 53 54 #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ 55 /******************************************************************************* 56 * 57 * FUNCTION: acpi_update_all_gpes 58 * 59 * PARAMETERS: None 60 * 61 * RETURN: Status 62 * 63 * DESCRIPTION: Complete GPE initialization and enable all GPEs that have 64 * associated _Lxx or _Exx methods and are not pointed to by any 65 * device _PRW methods (this indicates that these GPEs are 66 * generally intended for system or device wakeup. Such GPEs 67 * have to be enabled directly when the devices whose _PRW 68 * methods point to them are set up for wakeup signaling.) 69 * 70 * NOTE: Should be called after any GPEs are added to the system. Primarily, 71 * after the system _PRW methods have been run, but also after a GPE Block 72 * Device has been added or if any new GPE methods have been added via a 73 * dynamic table load. 74 * 75 ******************************************************************************/ 76 77 acpi_status acpi_update_all_gpes(void) 78 { 79 acpi_status status; 80 81 ACPI_FUNCTION_TRACE(acpi_update_all_gpes); 82 83 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); 84 if (ACPI_FAILURE(status)) { 85 return_ACPI_STATUS(status); 86 } 87 88 if (acpi_gbl_all_gpes_initialized) { 89 goto unlock_and_exit; 90 } 91 92 status = acpi_ev_walk_gpe_list(acpi_ev_initialize_gpe_block, NULL); 93 if (ACPI_SUCCESS(status)) { 94 acpi_gbl_all_gpes_initialized = TRUE; 95 } 96 97 unlock_and_exit: 98 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); 99 100 return_ACPI_STATUS(status); 101 } 102 103 ACPI_EXPORT_SYMBOL(acpi_update_all_gpes) 104 105 /******************************************************************************* 106 * 107 * FUNCTION: acpi_enable_gpe 108 * 109 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 110 * gpe_number - GPE level within the GPE block 111 * 112 * RETURN: Status 113 * 114 * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is 115 * hardware-enabled. 116 * 117 ******************************************************************************/ 118 119 acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) 120 { 121 acpi_status status = AE_BAD_PARAMETER; 122 struct acpi_gpe_event_info *gpe_event_info; 123 acpi_cpu_flags flags; 124 125 ACPI_FUNCTION_TRACE(acpi_enable_gpe); 126 127 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 128 129 /* 130 * Ensure that we have a valid GPE number and that there is some way 131 * of handling the GPE (handler or a GPE method). In other words, we 132 * won't allow a valid GPE to be enabled if there is no way to handle it. 133 */ 134 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 135 if (gpe_event_info) { 136 if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) != 137 ACPI_GPE_DISPATCH_NONE) { 138 status = acpi_ev_add_gpe_reference(gpe_event_info); 139 } else { 140 status = AE_NO_HANDLER; 141 } 142 } 143 144 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 145 return_ACPI_STATUS(status); 146 } 147 ACPI_EXPORT_SYMBOL(acpi_enable_gpe) 148 149 /******************************************************************************* 150 * 151 * FUNCTION: acpi_disable_gpe 152 * 153 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 154 * gpe_number - GPE level within the GPE block 155 * 156 * RETURN: Status 157 * 158 * DESCRIPTION: Remove a reference to a GPE. When the last reference is 159 * removed, only then is the GPE disabled (for runtime GPEs), or 160 * the GPE mask bit disabled (for wake GPEs) 161 * 162 ******************************************************************************/ 163 164 acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number) 165 { 166 acpi_status status = AE_BAD_PARAMETER; 167 struct acpi_gpe_event_info *gpe_event_info; 168 acpi_cpu_flags flags; 169 170 ACPI_FUNCTION_TRACE(acpi_disable_gpe); 171 172 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 173 174 /* Ensure that we have a valid GPE number */ 175 176 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 177 if (gpe_event_info) { 178 status = acpi_ev_remove_gpe_reference(gpe_event_info) ; 179 } 180 181 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 182 return_ACPI_STATUS(status); 183 } 184 185 ACPI_EXPORT_SYMBOL(acpi_disable_gpe) 186 187 188 /******************************************************************************* 189 * 190 * FUNCTION: acpi_mark_gpe_for_wake 191 * 192 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 193 * gpe_number - GPE level within the GPE block 194 * 195 * RETURN: Status 196 * 197 * DESCRIPTION: Mark a GPE as having the ability to wake the system. Simply 198 * sets the ACPI_GPE_CAN_WAKE flag. 199 * 200 * Some potential callers of acpi_setup_gpe_for_wake may know in advance that 201 * there won't be any notify handlers installed for device wake notifications 202 * from the given GPE (one example is a button GPE in Linux). For these cases, 203 * acpi_mark_gpe_for_wake should be used instead of acpi_setup_gpe_for_wake. 204 * This will set the ACPI_GPE_CAN_WAKE flag for the GPE without trying to 205 * setup implicit wake notification for it (since there's no handler method). 206 * 207 ******************************************************************************/ 208 acpi_status acpi_mark_gpe_for_wake(acpi_handle gpe_device, u32 gpe_number) 209 { 210 struct acpi_gpe_event_info *gpe_event_info; 211 acpi_status status = AE_BAD_PARAMETER; 212 acpi_cpu_flags flags; 213 214 ACPI_FUNCTION_TRACE(acpi_mark_gpe_for_wake); 215 216 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 217 218 /* Ensure that we have a valid GPE number */ 219 220 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 221 if (gpe_event_info) { 222 223 /* Mark the GPE as a possible wake event */ 224 225 gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; 226 status = AE_OK; 227 } 228 229 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 230 return_ACPI_STATUS(status); 231 } 232 233 ACPI_EXPORT_SYMBOL(acpi_mark_gpe_for_wake) 234 235 /******************************************************************************* 236 * 237 * FUNCTION: acpi_setup_gpe_for_wake 238 * 239 * PARAMETERS: wake_device - Device associated with the GPE (via _PRW) 240 * gpe_device - Parent GPE Device. NULL for GPE0/GPE1 241 * gpe_number - GPE level within the GPE block 242 * 243 * RETURN: Status 244 * 245 * DESCRIPTION: Mark a GPE as having the ability to wake the system. This 246 * interface is intended to be used as the host executes the 247 * _PRW methods (Power Resources for Wake) in the system tables. 248 * Each _PRW appears under a Device Object (The wake_device), and 249 * contains the info for the wake GPE associated with the 250 * wake_device. 251 * 252 ******************************************************************************/ 253 acpi_status 254 acpi_setup_gpe_for_wake(acpi_handle wake_device, 255 acpi_handle gpe_device, u32 gpe_number) 256 { 257 acpi_status status; 258 struct acpi_gpe_event_info *gpe_event_info; 259 struct acpi_namespace_node *device_node; 260 struct acpi_gpe_notify_info *notify; 261 struct acpi_gpe_notify_info *new_notify; 262 acpi_cpu_flags flags; 263 264 ACPI_FUNCTION_TRACE(acpi_setup_gpe_for_wake); 265 266 /* Parameter Validation */ 267 268 if (!wake_device) { 269 /* 270 * By forcing wake_device to be valid, we automatically enable the 271 * implicit notify feature on all hosts. 272 */ 273 return_ACPI_STATUS(AE_BAD_PARAMETER); 274 } 275 276 /* Handle root object case */ 277 278 if (wake_device == ACPI_ROOT_OBJECT) { 279 device_node = acpi_gbl_root_node; 280 } else { 281 device_node = 282 ACPI_CAST_PTR(struct acpi_namespace_node, wake_device); 283 } 284 285 /* Validate wake_device is of type Device */ 286 287 if (device_node->type != ACPI_TYPE_DEVICE) { 288 return_ACPI_STATUS (AE_BAD_PARAMETER); 289 } 290 291 /* 292 * Allocate a new notify object up front, in case it is needed. 293 * Memory allocation while holding a spinlock is a big no-no 294 * on some hosts. 295 */ 296 new_notify = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_notify_info)); 297 if (!new_notify) { 298 return_ACPI_STATUS(AE_NO_MEMORY); 299 } 300 301 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 302 303 /* Ensure that we have a valid GPE number */ 304 305 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 306 if (!gpe_event_info) { 307 status = AE_BAD_PARAMETER; 308 goto unlock_and_exit; 309 } 310 311 /* 312 * If there is no method or handler for this GPE, then the 313 * wake_device will be notified whenever this GPE fires. This is 314 * known as an "implicit notify". Note: The GPE is assumed to be 315 * level-triggered (for windows compatibility). 316 */ 317 if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == 318 ACPI_GPE_DISPATCH_NONE) { 319 /* 320 * This is the first device for implicit notify on this GPE. 321 * Just set the flags here, and enter the NOTIFY block below. 322 */ 323 gpe_event_info->flags = 324 (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED); 325 } 326 327 /* 328 * If we already have an implicit notify on this GPE, add 329 * this device to the notify list. 330 */ 331 if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == 332 ACPI_GPE_DISPATCH_NOTIFY) { 333 334 /* Ensure that the device is not already in the list */ 335 336 notify = gpe_event_info->dispatch.notify_list; 337 while (notify) { 338 if (notify->device_node == device_node) { 339 status = AE_ALREADY_EXISTS; 340 goto unlock_and_exit; 341 } 342 notify = notify->next; 343 } 344 345 /* Add this device to the notify list for this GPE */ 346 347 new_notify->device_node = device_node; 348 new_notify->next = gpe_event_info->dispatch.notify_list; 349 gpe_event_info->dispatch.notify_list = new_notify; 350 new_notify = NULL; 351 } 352 353 /* Mark the GPE as a possible wake event */ 354 355 gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; 356 status = AE_OK; 357 358 unlock_and_exit: 359 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 360 361 /* Delete the notify object if it was not used above */ 362 363 if (new_notify) { 364 ACPI_FREE(new_notify); 365 } 366 return_ACPI_STATUS(status); 367 } 368 ACPI_EXPORT_SYMBOL(acpi_setup_gpe_for_wake) 369 370 /******************************************************************************* 371 * 372 * FUNCTION: acpi_set_gpe_wake_mask 373 * 374 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 375 * gpe_number - GPE level within the GPE block 376 * action - Enable or Disable 377 * 378 * RETURN: Status 379 * 380 * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must 381 * already be marked as a WAKE GPE. 382 * 383 ******************************************************************************/ 384 385 acpi_status 386 acpi_set_gpe_wake_mask(acpi_handle gpe_device, u32 gpe_number, u8 action) 387 { 388 acpi_status status = AE_OK; 389 struct acpi_gpe_event_info *gpe_event_info; 390 struct acpi_gpe_register_info *gpe_register_info; 391 acpi_cpu_flags flags; 392 u32 register_bit; 393 394 ACPI_FUNCTION_TRACE(acpi_set_gpe_wake_mask); 395 396 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 397 398 /* 399 * Ensure that we have a valid GPE number and that this GPE is in 400 * fact a wake GPE 401 */ 402 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 403 if (!gpe_event_info) { 404 status = AE_BAD_PARAMETER; 405 goto unlock_and_exit; 406 } 407 408 if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { 409 status = AE_TYPE; 410 goto unlock_and_exit; 411 } 412 413 gpe_register_info = gpe_event_info->register_info; 414 if (!gpe_register_info) { 415 status = AE_NOT_EXIST; 416 goto unlock_and_exit; 417 } 418 419 register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info); 420 421 /* Perform the action */ 422 423 switch (action) { 424 case ACPI_GPE_ENABLE: 425 426 ACPI_SET_BIT(gpe_register_info->enable_for_wake, 427 (u8)register_bit); 428 break; 429 430 case ACPI_GPE_DISABLE: 431 432 ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake, 433 (u8)register_bit); 434 break; 435 436 default: 437 438 ACPI_ERROR((AE_INFO, "%u, Invalid action", action)); 439 status = AE_BAD_PARAMETER; 440 break; 441 } 442 443 unlock_and_exit: 444 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 445 return_ACPI_STATUS(status); 446 } 447 448 ACPI_EXPORT_SYMBOL(acpi_set_gpe_wake_mask) 449 450 /******************************************************************************* 451 * 452 * FUNCTION: acpi_clear_gpe 453 * 454 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 455 * gpe_number - GPE level within the GPE block 456 * 457 * RETURN: Status 458 * 459 * DESCRIPTION: Clear an ACPI event (general purpose) 460 * 461 ******************************************************************************/ 462 acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number) 463 { 464 acpi_status status = AE_OK; 465 struct acpi_gpe_event_info *gpe_event_info; 466 acpi_cpu_flags flags; 467 468 ACPI_FUNCTION_TRACE(acpi_clear_gpe); 469 470 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 471 472 /* Ensure that we have a valid GPE number */ 473 474 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 475 if (!gpe_event_info) { 476 status = AE_BAD_PARAMETER; 477 goto unlock_and_exit; 478 } 479 480 status = acpi_hw_clear_gpe(gpe_event_info); 481 482 unlock_and_exit: 483 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 484 return_ACPI_STATUS(status); 485 } 486 487 ACPI_EXPORT_SYMBOL(acpi_clear_gpe) 488 489 /******************************************************************************* 490 * 491 * FUNCTION: acpi_get_gpe_status 492 * 493 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 494 * gpe_number - GPE level within the GPE block 495 * event_status - Where the current status of the event 496 * will be returned 497 * 498 * RETURN: Status 499 * 500 * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled) 501 * 502 ******************************************************************************/ 503 acpi_status 504 acpi_get_gpe_status(acpi_handle gpe_device, 505 u32 gpe_number, acpi_event_status *event_status) 506 { 507 acpi_status status = AE_OK; 508 struct acpi_gpe_event_info *gpe_event_info; 509 acpi_cpu_flags flags; 510 511 ACPI_FUNCTION_TRACE(acpi_get_gpe_status); 512 513 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 514 515 /* Ensure that we have a valid GPE number */ 516 517 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 518 if (!gpe_event_info) { 519 status = AE_BAD_PARAMETER; 520 goto unlock_and_exit; 521 } 522 523 /* Obtain status on the requested GPE number */ 524 525 status = acpi_hw_get_gpe_status(gpe_event_info, event_status); 526 527 if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) 528 *event_status |= ACPI_EVENT_FLAG_HANDLE; 529 530 unlock_and_exit: 531 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 532 return_ACPI_STATUS(status); 533 } 534 535 ACPI_EXPORT_SYMBOL(acpi_get_gpe_status) 536 537 /****************************************************************************** 538 * 539 * FUNCTION: acpi_disable_all_gpes 540 * 541 * PARAMETERS: None 542 * 543 * RETURN: Status 544 * 545 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks 546 * 547 ******************************************************************************/ 548 549 acpi_status acpi_disable_all_gpes(void) 550 { 551 acpi_status status; 552 553 ACPI_FUNCTION_TRACE(acpi_disable_all_gpes); 554 555 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); 556 if (ACPI_FAILURE(status)) { 557 return_ACPI_STATUS(status); 558 } 559 560 status = acpi_hw_disable_all_gpes(); 561 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); 562 563 return_ACPI_STATUS(status); 564 } 565 566 ACPI_EXPORT_SYMBOL(acpi_disable_all_gpes) 567 568 /****************************************************************************** 569 * 570 * FUNCTION: acpi_enable_all_runtime_gpes 571 * 572 * PARAMETERS: None 573 * 574 * RETURN: Status 575 * 576 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks 577 * 578 ******************************************************************************/ 579 580 acpi_status acpi_enable_all_runtime_gpes(void) 581 { 582 acpi_status status; 583 584 ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes); 585 586 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); 587 if (ACPI_FAILURE(status)) { 588 return_ACPI_STATUS(status); 589 } 590 591 status = acpi_hw_enable_all_runtime_gpes(); 592 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); 593 594 return_ACPI_STATUS(status); 595 } 596 597 ACPI_EXPORT_SYMBOL(acpi_enable_all_runtime_gpes) 598 599 /******************************************************************************* 600 * 601 * FUNCTION: acpi_install_gpe_block 602 * 603 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device 604 * gpe_block_address - Address and space_ID 605 * register_count - Number of GPE register pairs in the block 606 * interrupt_number - H/W interrupt for the block 607 * 608 * RETURN: Status 609 * 610 * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not 611 * enabled here. 612 * 613 ******************************************************************************/ 614 acpi_status 615 acpi_install_gpe_block(acpi_handle gpe_device, 616 struct acpi_generic_address *gpe_block_address, 617 u32 register_count, u32 interrupt_number) 618 { 619 acpi_status status; 620 union acpi_operand_object *obj_desc; 621 struct acpi_namespace_node *node; 622 struct acpi_gpe_block_info *gpe_block; 623 624 ACPI_FUNCTION_TRACE(acpi_install_gpe_block); 625 626 if ((!gpe_device) || (!gpe_block_address) || (!register_count)) { 627 return_ACPI_STATUS(AE_BAD_PARAMETER); 628 } 629 630 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 631 if (ACPI_FAILURE(status)) { 632 return_ACPI_STATUS(status); 633 } 634 635 node = acpi_ns_validate_handle(gpe_device); 636 if (!node) { 637 status = AE_BAD_PARAMETER; 638 goto unlock_and_exit; 639 } 640 641 /* Validate the parent device */ 642 643 if (node->type != ACPI_TYPE_DEVICE) { 644 status = AE_TYPE; 645 goto unlock_and_exit; 646 } 647 648 if (node->object) { 649 status = AE_ALREADY_EXISTS; 650 goto unlock_and_exit; 651 } 652 653 /* 654 * For user-installed GPE Block Devices, the gpe_block_base_number 655 * is always zero 656 */ 657 status = acpi_ev_create_gpe_block(node, gpe_block_address->address, 658 gpe_block_address->space_id, 659 register_count, 0, interrupt_number, 660 &gpe_block); 661 if (ACPI_FAILURE(status)) { 662 goto unlock_and_exit; 663 } 664 665 /* Install block in the device_object attached to the node */ 666 667 obj_desc = acpi_ns_get_attached_object(node); 668 if (!obj_desc) { 669 670 /* 671 * No object, create a new one (Device nodes do not always have 672 * an attached object) 673 */ 674 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE); 675 if (!obj_desc) { 676 status = AE_NO_MEMORY; 677 goto unlock_and_exit; 678 } 679 680 status = 681 acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE); 682 683 /* Remove local reference to the object */ 684 685 acpi_ut_remove_reference(obj_desc); 686 687 if (ACPI_FAILURE(status)) { 688 goto unlock_and_exit; 689 } 690 } 691 692 /* Now install the GPE block in the device_object */ 693 694 obj_desc->device.gpe_block = gpe_block; 695 696 unlock_and_exit: 697 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 698 return_ACPI_STATUS(status); 699 } 700 701 ACPI_EXPORT_SYMBOL(acpi_install_gpe_block) 702 703 /******************************************************************************* 704 * 705 * FUNCTION: acpi_remove_gpe_block 706 * 707 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device 708 * 709 * RETURN: Status 710 * 711 * DESCRIPTION: Remove a previously installed block of GPE registers 712 * 713 ******************************************************************************/ 714 acpi_status acpi_remove_gpe_block(acpi_handle gpe_device) 715 { 716 union acpi_operand_object *obj_desc; 717 acpi_status status; 718 struct acpi_namespace_node *node; 719 720 ACPI_FUNCTION_TRACE(acpi_remove_gpe_block); 721 722 if (!gpe_device) { 723 return_ACPI_STATUS(AE_BAD_PARAMETER); 724 } 725 726 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 727 if (ACPI_FAILURE(status)) { 728 return_ACPI_STATUS(status); 729 } 730 731 node = acpi_ns_validate_handle(gpe_device); 732 if (!node) { 733 status = AE_BAD_PARAMETER; 734 goto unlock_and_exit; 735 } 736 737 /* Validate the parent device */ 738 739 if (node->type != ACPI_TYPE_DEVICE) { 740 status = AE_TYPE; 741 goto unlock_and_exit; 742 } 743 744 /* Get the device_object attached to the node */ 745 746 obj_desc = acpi_ns_get_attached_object(node); 747 if (!obj_desc || !obj_desc->device.gpe_block) { 748 return_ACPI_STATUS(AE_NULL_OBJECT); 749 } 750 751 /* Delete the GPE block (but not the device_object) */ 752 753 status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block); 754 if (ACPI_SUCCESS(status)) { 755 obj_desc->device.gpe_block = NULL; 756 } 757 758 unlock_and_exit: 759 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 760 return_ACPI_STATUS(status); 761 } 762 763 ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block) 764 765 /******************************************************************************* 766 * 767 * FUNCTION: acpi_get_gpe_device 768 * 769 * PARAMETERS: index - System GPE index (0-current_gpe_count) 770 * gpe_device - Where the parent GPE Device is returned 771 * 772 * RETURN: Status 773 * 774 * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL 775 * gpe device indicates that the gpe number is contained in one of 776 * the FADT-defined gpe blocks. Otherwise, the GPE block device. 777 * 778 ******************************************************************************/ 779 acpi_status acpi_get_gpe_device(u32 index, acpi_handle * gpe_device) 780 { 781 struct acpi_gpe_device_info info; 782 acpi_status status; 783 784 ACPI_FUNCTION_TRACE(acpi_get_gpe_device); 785 786 if (!gpe_device) { 787 return_ACPI_STATUS(AE_BAD_PARAMETER); 788 } 789 790 if (index >= acpi_current_gpe_count) { 791 return_ACPI_STATUS(AE_NOT_EXIST); 792 } 793 794 /* Setup and walk the GPE list */ 795 796 info.index = index; 797 info.status = AE_NOT_EXIST; 798 info.gpe_device = NULL; 799 info.next_block_base_index = 0; 800 801 status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info); 802 if (ACPI_FAILURE(status)) { 803 return_ACPI_STATUS(status); 804 } 805 806 *gpe_device = ACPI_CAST_PTR(acpi_handle, info.gpe_device); 807 return_ACPI_STATUS(info.status); 808 } 809 810 ACPI_EXPORT_SYMBOL(acpi_get_gpe_device) 811 #endif /* !ACPI_REDUCED_HARDWARE */ 812