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