1 /****************************************************************************** 2 * 3 * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs) 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2017, 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 (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) != 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 * FUNCTION: acpi_set_gpe 189 * 190 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 191 * gpe_number - GPE level within the GPE block 192 * action - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE 193 * 194 * RETURN: Status 195 * 196 * DESCRIPTION: Enable or disable an individual GPE. This function bypasses 197 * the reference count mechanism used in the acpi_enable_gpe(), 198 * acpi_disable_gpe() interfaces. 199 * This API is typically used by the GPE raw handler mode driver 200 * to switch between the polling mode and the interrupt mode after 201 * the driver has enabled the GPE. 202 * The APIs should be invoked in this order: 203 * acpi_enable_gpe() <- Ensure the reference count > 0 204 * acpi_set_gpe(ACPI_GPE_DISABLE) <- Enter polling mode 205 * acpi_set_gpe(ACPI_GPE_ENABLE) <- Leave polling mode 206 * acpi_disable_gpe() <- Decrease the reference count 207 * 208 * Note: If a GPE is shared by 2 silicon components, then both the drivers 209 * should support GPE polling mode or disabling the GPE for long period 210 * for one driver may break the other. So use it with care since all 211 * firmware _Lxx/_Exx handlers currently rely on the GPE interrupt mode. 212 * 213 ******************************************************************************/ 214 acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action) 215 { 216 struct acpi_gpe_event_info *gpe_event_info; 217 acpi_status status; 218 acpi_cpu_flags flags; 219 220 ACPI_FUNCTION_TRACE(acpi_set_gpe); 221 222 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 223 224 /* Ensure that we have a valid GPE number */ 225 226 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 227 if (!gpe_event_info) { 228 status = AE_BAD_PARAMETER; 229 goto unlock_and_exit; 230 } 231 232 /* Perform the action */ 233 234 switch (action) { 235 case ACPI_GPE_ENABLE: 236 237 status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE); 238 gpe_event_info->disable_for_dispatch = FALSE; 239 break; 240 241 case ACPI_GPE_DISABLE: 242 243 status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); 244 gpe_event_info->disable_for_dispatch = TRUE; 245 break; 246 247 default: 248 249 status = AE_BAD_PARAMETER; 250 break; 251 } 252 253 unlock_and_exit: 254 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 255 return_ACPI_STATUS(status); 256 } 257 258 ACPI_EXPORT_SYMBOL(acpi_set_gpe) 259 260 /******************************************************************************* 261 * 262 * FUNCTION: acpi_mask_gpe 263 * 264 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 265 * gpe_number - GPE level within the GPE block 266 * is_masked - Whether the GPE is masked or not 267 * 268 * RETURN: Status 269 * 270 * DESCRIPTION: Unconditionally mask/unmask the an individual GPE, ex., to 271 * prevent a GPE flooding. 272 * 273 ******************************************************************************/ 274 acpi_status acpi_mask_gpe(acpi_handle gpe_device, u32 gpe_number, u8 is_masked) 275 { 276 struct acpi_gpe_event_info *gpe_event_info; 277 acpi_status status; 278 acpi_cpu_flags flags; 279 280 ACPI_FUNCTION_TRACE(acpi_mask_gpe); 281 282 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 283 284 /* Ensure that we have a valid GPE number */ 285 286 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 287 if (!gpe_event_info) { 288 status = AE_BAD_PARAMETER; 289 goto unlock_and_exit; 290 } 291 292 status = acpi_ev_mask_gpe(gpe_event_info, is_masked); 293 294 unlock_and_exit: 295 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 296 return_ACPI_STATUS(status); 297 } 298 299 ACPI_EXPORT_SYMBOL(acpi_mask_gpe) 300 301 /******************************************************************************* 302 * 303 * FUNCTION: acpi_mark_gpe_for_wake 304 * 305 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 306 * gpe_number - GPE level within the GPE block 307 * 308 * RETURN: Status 309 * 310 * DESCRIPTION: Mark a GPE as having the ability to wake the system. Simply 311 * sets the ACPI_GPE_CAN_WAKE flag. 312 * 313 * Some potential callers of acpi_setup_gpe_for_wake may know in advance that 314 * there won't be any notify handlers installed for device wake notifications 315 * from the given GPE (one example is a button GPE in Linux). For these cases, 316 * acpi_mark_gpe_for_wake should be used instead of acpi_setup_gpe_for_wake. 317 * This will set the ACPI_GPE_CAN_WAKE flag for the GPE without trying to 318 * setup implicit wake notification for it (since there's no handler method). 319 * 320 ******************************************************************************/ 321 acpi_status acpi_mark_gpe_for_wake(acpi_handle gpe_device, u32 gpe_number) 322 { 323 struct acpi_gpe_event_info *gpe_event_info; 324 acpi_status status = AE_BAD_PARAMETER; 325 acpi_cpu_flags flags; 326 327 ACPI_FUNCTION_TRACE(acpi_mark_gpe_for_wake); 328 329 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 330 331 /* Ensure that we have a valid GPE number */ 332 333 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 334 if (gpe_event_info) { 335 336 /* Mark the GPE as a possible wake event */ 337 338 gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; 339 status = AE_OK; 340 } 341 342 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 343 return_ACPI_STATUS(status); 344 } 345 346 ACPI_EXPORT_SYMBOL(acpi_mark_gpe_for_wake) 347 348 /******************************************************************************* 349 * 350 * FUNCTION: acpi_setup_gpe_for_wake 351 * 352 * PARAMETERS: wake_device - Device associated with the GPE (via _PRW) 353 * gpe_device - Parent GPE Device. NULL for GPE0/GPE1 354 * gpe_number - GPE level within the GPE block 355 * 356 * RETURN: Status 357 * 358 * DESCRIPTION: Mark a GPE as having the ability to wake the system. This 359 * interface is intended to be used as the host executes the 360 * _PRW methods (Power Resources for Wake) in the system tables. 361 * Each _PRW appears under a Device Object (The wake_device), and 362 * contains the info for the wake GPE associated with the 363 * wake_device. 364 * 365 ******************************************************************************/ 366 acpi_status 367 acpi_setup_gpe_for_wake(acpi_handle wake_device, 368 acpi_handle gpe_device, u32 gpe_number) 369 { 370 acpi_status status; 371 struct acpi_gpe_event_info *gpe_event_info; 372 struct acpi_namespace_node *device_node; 373 struct acpi_gpe_notify_info *notify; 374 struct acpi_gpe_notify_info *new_notify; 375 acpi_cpu_flags flags; 376 377 ACPI_FUNCTION_TRACE(acpi_setup_gpe_for_wake); 378 379 /* Parameter Validation */ 380 381 if (!wake_device) { 382 /* 383 * By forcing wake_device to be valid, we automatically enable the 384 * implicit notify feature on all hosts. 385 */ 386 return_ACPI_STATUS(AE_BAD_PARAMETER); 387 } 388 389 /* Handle root object case */ 390 391 if (wake_device == ACPI_ROOT_OBJECT) { 392 device_node = acpi_gbl_root_node; 393 } else { 394 device_node = 395 ACPI_CAST_PTR(struct acpi_namespace_node, wake_device); 396 } 397 398 /* Validate wake_device is of type Device */ 399 400 if (device_node->type != ACPI_TYPE_DEVICE) { 401 return_ACPI_STATUS (AE_BAD_PARAMETER); 402 } 403 404 /* 405 * Allocate a new notify object up front, in case it is needed. 406 * Memory allocation while holding a spinlock is a big no-no 407 * on some hosts. 408 */ 409 new_notify = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_notify_info)); 410 if (!new_notify) { 411 return_ACPI_STATUS(AE_NO_MEMORY); 412 } 413 414 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 415 416 /* Ensure that we have a valid GPE number */ 417 418 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 419 if (!gpe_event_info) { 420 status = AE_BAD_PARAMETER; 421 goto unlock_and_exit; 422 } 423 424 /* 425 * If there is no method or handler for this GPE, then the 426 * wake_device will be notified whenever this GPE fires. This is 427 * known as an "implicit notify". Note: The GPE is assumed to be 428 * level-triggered (for windows compatibility). 429 */ 430 if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) == 431 ACPI_GPE_DISPATCH_NONE) { 432 /* 433 * This is the first device for implicit notify on this GPE. 434 * Just set the flags here, and enter the NOTIFY block below. 435 */ 436 gpe_event_info->flags = 437 (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED); 438 } 439 440 /* 441 * If we already have an implicit notify on this GPE, add 442 * this device to the notify list. 443 */ 444 if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) == 445 ACPI_GPE_DISPATCH_NOTIFY) { 446 447 /* Ensure that the device is not already in the list */ 448 449 notify = gpe_event_info->dispatch.notify_list; 450 while (notify) { 451 if (notify->device_node == device_node) { 452 status = AE_ALREADY_EXISTS; 453 goto unlock_and_exit; 454 } 455 notify = notify->next; 456 } 457 458 /* Add this device to the notify list for this GPE */ 459 460 new_notify->device_node = device_node; 461 new_notify->next = gpe_event_info->dispatch.notify_list; 462 gpe_event_info->dispatch.notify_list = new_notify; 463 new_notify = NULL; 464 } 465 466 /* Mark the GPE as a possible wake event */ 467 468 gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; 469 status = AE_OK; 470 471 unlock_and_exit: 472 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 473 474 /* Delete the notify object if it was not used above */ 475 476 if (new_notify) { 477 ACPI_FREE(new_notify); 478 } 479 return_ACPI_STATUS(status); 480 } 481 ACPI_EXPORT_SYMBOL(acpi_setup_gpe_for_wake) 482 483 /******************************************************************************* 484 * 485 * FUNCTION: acpi_set_gpe_wake_mask 486 * 487 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 488 * gpe_number - GPE level within the GPE block 489 * action - Enable or Disable 490 * 491 * RETURN: Status 492 * 493 * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must 494 * already be marked as a WAKE GPE. 495 * 496 ******************************************************************************/ 497 498 acpi_status 499 acpi_set_gpe_wake_mask(acpi_handle gpe_device, u32 gpe_number, u8 action) 500 { 501 acpi_status status = AE_OK; 502 struct acpi_gpe_event_info *gpe_event_info; 503 struct acpi_gpe_register_info *gpe_register_info; 504 acpi_cpu_flags flags; 505 u32 register_bit; 506 507 ACPI_FUNCTION_TRACE(acpi_set_gpe_wake_mask); 508 509 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 510 511 /* 512 * Ensure that we have a valid GPE number and that this GPE is in 513 * fact a wake GPE 514 */ 515 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 516 if (!gpe_event_info) { 517 status = AE_BAD_PARAMETER; 518 goto unlock_and_exit; 519 } 520 521 if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { 522 status = AE_TYPE; 523 goto unlock_and_exit; 524 } 525 526 gpe_register_info = gpe_event_info->register_info; 527 if (!gpe_register_info) { 528 status = AE_NOT_EXIST; 529 goto unlock_and_exit; 530 } 531 532 register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info); 533 534 /* Perform the action */ 535 536 switch (action) { 537 case ACPI_GPE_ENABLE: 538 539 ACPI_SET_BIT(gpe_register_info->enable_for_wake, 540 (u8)register_bit); 541 break; 542 543 case ACPI_GPE_DISABLE: 544 545 ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake, 546 (u8)register_bit); 547 break; 548 549 default: 550 551 ACPI_ERROR((AE_INFO, "%u, Invalid action", action)); 552 status = AE_BAD_PARAMETER; 553 break; 554 } 555 556 unlock_and_exit: 557 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 558 return_ACPI_STATUS(status); 559 } 560 561 ACPI_EXPORT_SYMBOL(acpi_set_gpe_wake_mask) 562 563 /******************************************************************************* 564 * 565 * FUNCTION: acpi_clear_gpe 566 * 567 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 568 * gpe_number - GPE level within the GPE block 569 * 570 * RETURN: Status 571 * 572 * DESCRIPTION: Clear an ACPI event (general purpose) 573 * 574 ******************************************************************************/ 575 acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number) 576 { 577 acpi_status status = AE_OK; 578 struct acpi_gpe_event_info *gpe_event_info; 579 acpi_cpu_flags flags; 580 581 ACPI_FUNCTION_TRACE(acpi_clear_gpe); 582 583 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 584 585 /* Ensure that we have a valid GPE number */ 586 587 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 588 if (!gpe_event_info) { 589 status = AE_BAD_PARAMETER; 590 goto unlock_and_exit; 591 } 592 593 status = acpi_hw_clear_gpe(gpe_event_info); 594 595 unlock_and_exit: 596 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 597 return_ACPI_STATUS(status); 598 } 599 600 ACPI_EXPORT_SYMBOL(acpi_clear_gpe) 601 602 /******************************************************************************* 603 * 604 * FUNCTION: acpi_get_gpe_status 605 * 606 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 607 * gpe_number - GPE level within the GPE block 608 * event_status - Where the current status of the event 609 * will be returned 610 * 611 * RETURN: Status 612 * 613 * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled) 614 * 615 ******************************************************************************/ 616 acpi_status 617 acpi_get_gpe_status(acpi_handle gpe_device, 618 u32 gpe_number, acpi_event_status *event_status) 619 { 620 acpi_status status = AE_OK; 621 struct acpi_gpe_event_info *gpe_event_info; 622 acpi_cpu_flags flags; 623 624 ACPI_FUNCTION_TRACE(acpi_get_gpe_status); 625 626 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 627 628 /* Ensure that we have a valid GPE number */ 629 630 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 631 if (!gpe_event_info) { 632 status = AE_BAD_PARAMETER; 633 goto unlock_and_exit; 634 } 635 636 /* Obtain status on the requested GPE number */ 637 638 status = acpi_hw_get_gpe_status(gpe_event_info, event_status); 639 640 unlock_and_exit: 641 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 642 return_ACPI_STATUS(status); 643 } 644 645 ACPI_EXPORT_SYMBOL(acpi_get_gpe_status) 646 647 /******************************************************************************* 648 * 649 * FUNCTION: acpi_finish_gpe 650 * 651 * PARAMETERS: gpe_device - Namespace node for the GPE Block 652 * (NULL for FADT defined GPEs) 653 * gpe_number - GPE level within the GPE block 654 * 655 * RETURN: Status 656 * 657 * DESCRIPTION: Clear and conditionally reenable a GPE. This completes the GPE 658 * processing. Intended for use by asynchronous host-installed 659 * GPE handlers. The GPE is only reenabled if the enable_for_run bit 660 * is set in the GPE info. 661 * 662 ******************************************************************************/ 663 acpi_status acpi_finish_gpe(acpi_handle gpe_device, u32 gpe_number) 664 { 665 struct acpi_gpe_event_info *gpe_event_info; 666 acpi_status status; 667 acpi_cpu_flags flags; 668 669 ACPI_FUNCTION_TRACE(acpi_finish_gpe); 670 671 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 672 673 /* Ensure that we have a valid GPE number */ 674 675 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 676 if (!gpe_event_info) { 677 status = AE_BAD_PARAMETER; 678 goto unlock_and_exit; 679 } 680 681 status = acpi_ev_finish_gpe(gpe_event_info); 682 683 unlock_and_exit: 684 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 685 return_ACPI_STATUS(status); 686 } 687 688 ACPI_EXPORT_SYMBOL(acpi_finish_gpe) 689 690 /****************************************************************************** 691 * 692 * FUNCTION: acpi_disable_all_gpes 693 * 694 * PARAMETERS: None 695 * 696 * RETURN: Status 697 * 698 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks 699 * 700 ******************************************************************************/ 701 702 acpi_status acpi_disable_all_gpes(void) 703 { 704 acpi_status status; 705 706 ACPI_FUNCTION_TRACE(acpi_disable_all_gpes); 707 708 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); 709 if (ACPI_FAILURE(status)) { 710 return_ACPI_STATUS(status); 711 } 712 713 status = acpi_hw_disable_all_gpes(); 714 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); 715 716 return_ACPI_STATUS(status); 717 } 718 719 ACPI_EXPORT_SYMBOL(acpi_disable_all_gpes) 720 721 /****************************************************************************** 722 * 723 * FUNCTION: acpi_enable_all_runtime_gpes 724 * 725 * PARAMETERS: None 726 * 727 * RETURN: Status 728 * 729 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks 730 * 731 ******************************************************************************/ 732 733 acpi_status acpi_enable_all_runtime_gpes(void) 734 { 735 acpi_status status; 736 737 ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes); 738 739 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); 740 if (ACPI_FAILURE(status)) { 741 return_ACPI_STATUS(status); 742 } 743 744 status = acpi_hw_enable_all_runtime_gpes(); 745 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); 746 747 return_ACPI_STATUS(status); 748 } 749 750 ACPI_EXPORT_SYMBOL(acpi_enable_all_runtime_gpes) 751 752 /****************************************************************************** 753 * 754 * FUNCTION: acpi_enable_all_wakeup_gpes 755 * 756 * PARAMETERS: None 757 * 758 * RETURN: Status 759 * 760 * DESCRIPTION: Enable all "wakeup" GPEs and disable all of the other GPEs, in 761 * all GPE blocks. 762 * 763 ******************************************************************************/ 764 acpi_status acpi_enable_all_wakeup_gpes(void) 765 { 766 acpi_status status; 767 768 ACPI_FUNCTION_TRACE(acpi_enable_all_wakeup_gpes); 769 770 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); 771 if (ACPI_FAILURE(status)) { 772 return_ACPI_STATUS(status); 773 } 774 775 status = acpi_hw_enable_all_wakeup_gpes(); 776 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); 777 778 return_ACPI_STATUS(status); 779 } 780 781 ACPI_EXPORT_SYMBOL(acpi_enable_all_wakeup_gpes) 782 783 /******************************************************************************* 784 * 785 * FUNCTION: acpi_install_gpe_block 786 * 787 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device 788 * gpe_block_address - Address and space_ID 789 * register_count - Number of GPE register pairs in the block 790 * interrupt_number - H/W interrupt for the block 791 * 792 * RETURN: Status 793 * 794 * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not 795 * enabled here. 796 * 797 ******************************************************************************/ 798 acpi_status 799 acpi_install_gpe_block(acpi_handle gpe_device, 800 struct acpi_generic_address *gpe_block_address, 801 u32 register_count, u32 interrupt_number) 802 { 803 acpi_status status; 804 union acpi_operand_object *obj_desc; 805 struct acpi_namespace_node *node; 806 struct acpi_gpe_block_info *gpe_block; 807 808 ACPI_FUNCTION_TRACE(acpi_install_gpe_block); 809 810 if ((!gpe_device) || (!gpe_block_address) || (!register_count)) { 811 return_ACPI_STATUS(AE_BAD_PARAMETER); 812 } 813 814 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 815 if (ACPI_FAILURE(status)) { 816 return_ACPI_STATUS(status); 817 } 818 819 node = acpi_ns_validate_handle(gpe_device); 820 if (!node) { 821 status = AE_BAD_PARAMETER; 822 goto unlock_and_exit; 823 } 824 825 /* Validate the parent device */ 826 827 if (node->type != ACPI_TYPE_DEVICE) { 828 status = AE_TYPE; 829 goto unlock_and_exit; 830 } 831 832 if (node->object) { 833 status = AE_ALREADY_EXISTS; 834 goto unlock_and_exit; 835 } 836 837 /* 838 * For user-installed GPE Block Devices, the gpe_block_base_number 839 * is always zero 840 */ 841 status = acpi_ev_create_gpe_block(node, gpe_block_address->address, 842 gpe_block_address->space_id, 843 register_count, 0, interrupt_number, 844 &gpe_block); 845 if (ACPI_FAILURE(status)) { 846 goto unlock_and_exit; 847 } 848 849 /* Install block in the device_object attached to the node */ 850 851 obj_desc = acpi_ns_get_attached_object(node); 852 if (!obj_desc) { 853 854 /* 855 * No object, create a new one (Device nodes do not always have 856 * an attached object) 857 */ 858 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE); 859 if (!obj_desc) { 860 status = AE_NO_MEMORY; 861 goto unlock_and_exit; 862 } 863 864 status = 865 acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE); 866 867 /* Remove local reference to the object */ 868 869 acpi_ut_remove_reference(obj_desc); 870 871 if (ACPI_FAILURE(status)) { 872 goto unlock_and_exit; 873 } 874 } 875 876 /* Now install the GPE block in the device_object */ 877 878 obj_desc->device.gpe_block = gpe_block; 879 880 unlock_and_exit: 881 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 882 return_ACPI_STATUS(status); 883 } 884 885 ACPI_EXPORT_SYMBOL(acpi_install_gpe_block) 886 887 /******************************************************************************* 888 * 889 * FUNCTION: acpi_remove_gpe_block 890 * 891 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device 892 * 893 * RETURN: Status 894 * 895 * DESCRIPTION: Remove a previously installed block of GPE registers 896 * 897 ******************************************************************************/ 898 acpi_status acpi_remove_gpe_block(acpi_handle gpe_device) 899 { 900 union acpi_operand_object *obj_desc; 901 acpi_status status; 902 struct acpi_namespace_node *node; 903 904 ACPI_FUNCTION_TRACE(acpi_remove_gpe_block); 905 906 if (!gpe_device) { 907 return_ACPI_STATUS(AE_BAD_PARAMETER); 908 } 909 910 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 911 if (ACPI_FAILURE(status)) { 912 return_ACPI_STATUS(status); 913 } 914 915 node = acpi_ns_validate_handle(gpe_device); 916 if (!node) { 917 status = AE_BAD_PARAMETER; 918 goto unlock_and_exit; 919 } 920 921 /* Validate the parent device */ 922 923 if (node->type != ACPI_TYPE_DEVICE) { 924 status = AE_TYPE; 925 goto unlock_and_exit; 926 } 927 928 /* Get the device_object attached to the node */ 929 930 obj_desc = acpi_ns_get_attached_object(node); 931 if (!obj_desc || !obj_desc->device.gpe_block) { 932 return_ACPI_STATUS(AE_NULL_OBJECT); 933 } 934 935 /* Delete the GPE block (but not the device_object) */ 936 937 status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block); 938 if (ACPI_SUCCESS(status)) { 939 obj_desc->device.gpe_block = NULL; 940 } 941 942 unlock_and_exit: 943 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 944 return_ACPI_STATUS(status); 945 } 946 947 ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block) 948 949 /******************************************************************************* 950 * 951 * FUNCTION: acpi_get_gpe_device 952 * 953 * PARAMETERS: index - System GPE index (0-current_gpe_count) 954 * gpe_device - Where the parent GPE Device is returned 955 * 956 * RETURN: Status 957 * 958 * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL 959 * gpe device indicates that the gpe number is contained in one of 960 * the FADT-defined gpe blocks. Otherwise, the GPE block device. 961 * 962 ******************************************************************************/ 963 acpi_status acpi_get_gpe_device(u32 index, acpi_handle *gpe_device) 964 { 965 struct acpi_gpe_device_info info; 966 acpi_status status; 967 968 ACPI_FUNCTION_TRACE(acpi_get_gpe_device); 969 970 if (!gpe_device) { 971 return_ACPI_STATUS(AE_BAD_PARAMETER); 972 } 973 974 if (index >= acpi_current_gpe_count) { 975 return_ACPI_STATUS(AE_NOT_EXIST); 976 } 977 978 /* Setup and walk the GPE list */ 979 980 info.index = index; 981 info.status = AE_NOT_EXIST; 982 info.gpe_device = NULL; 983 info.next_block_base_index = 0; 984 985 status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info); 986 if (ACPI_FAILURE(status)) { 987 return_ACPI_STATUS(status); 988 } 989 990 *gpe_device = ACPI_CAST_PTR(acpi_handle, info.gpe_device); 991 return_ACPI_STATUS(info.status); 992 } 993 994 ACPI_EXPORT_SYMBOL(acpi_get_gpe_device) 995 #endif /* !ACPI_REDUCED_HARDWARE */ 996