1 /****************************************************************************** 2 * 3 * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs) 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2018, 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 } else if (gpe_event_info->flags & ACPI_GPE_AUTO_ENABLED) { 439 /* 440 * A reference to this GPE has been added during the GPE block 441 * initialization, so drop it now to prevent the GPE from being 442 * permanently enabled and clear its ACPI_GPE_AUTO_ENABLED flag. 443 */ 444 (void)acpi_ev_remove_gpe_reference(gpe_event_info); 445 gpe_event_info->flags &= ~ACPI_GPE_AUTO_ENABLED; 446 } 447 448 /* 449 * If we already have an implicit notify on this GPE, add 450 * this device to the notify list. 451 */ 452 if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) == 453 ACPI_GPE_DISPATCH_NOTIFY) { 454 455 /* Ensure that the device is not already in the list */ 456 457 notify = gpe_event_info->dispatch.notify_list; 458 while (notify) { 459 if (notify->device_node == device_node) { 460 status = AE_ALREADY_EXISTS; 461 goto unlock_and_exit; 462 } 463 notify = notify->next; 464 } 465 466 /* Add this device to the notify list for this GPE */ 467 468 new_notify->device_node = device_node; 469 new_notify->next = gpe_event_info->dispatch.notify_list; 470 gpe_event_info->dispatch.notify_list = new_notify; 471 new_notify = NULL; 472 } 473 474 /* Mark the GPE as a possible wake event */ 475 476 gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; 477 status = AE_OK; 478 479 unlock_and_exit: 480 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 481 482 /* Delete the notify object if it was not used above */ 483 484 if (new_notify) { 485 ACPI_FREE(new_notify); 486 } 487 return_ACPI_STATUS(status); 488 } 489 ACPI_EXPORT_SYMBOL(acpi_setup_gpe_for_wake) 490 491 /******************************************************************************* 492 * 493 * FUNCTION: acpi_set_gpe_wake_mask 494 * 495 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 496 * gpe_number - GPE level within the GPE block 497 * action - Enable or Disable 498 * 499 * RETURN: Status 500 * 501 * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must 502 * already be marked as a WAKE GPE. 503 * 504 ******************************************************************************/ 505 506 acpi_status 507 acpi_set_gpe_wake_mask(acpi_handle gpe_device, u32 gpe_number, u8 action) 508 { 509 acpi_status status = AE_OK; 510 struct acpi_gpe_event_info *gpe_event_info; 511 struct acpi_gpe_register_info *gpe_register_info; 512 acpi_cpu_flags flags; 513 u32 register_bit; 514 515 ACPI_FUNCTION_TRACE(acpi_set_gpe_wake_mask); 516 517 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 518 519 /* 520 * Ensure that we have a valid GPE number and that this GPE is in 521 * fact a wake GPE 522 */ 523 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 524 if (!gpe_event_info) { 525 status = AE_BAD_PARAMETER; 526 goto unlock_and_exit; 527 } 528 529 if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { 530 status = AE_TYPE; 531 goto unlock_and_exit; 532 } 533 534 gpe_register_info = gpe_event_info->register_info; 535 if (!gpe_register_info) { 536 status = AE_NOT_EXIST; 537 goto unlock_and_exit; 538 } 539 540 register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info); 541 542 /* Perform the action */ 543 544 switch (action) { 545 case ACPI_GPE_ENABLE: 546 547 ACPI_SET_BIT(gpe_register_info->enable_for_wake, 548 (u8)register_bit); 549 break; 550 551 case ACPI_GPE_DISABLE: 552 553 ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake, 554 (u8)register_bit); 555 break; 556 557 default: 558 559 ACPI_ERROR((AE_INFO, "%u, Invalid action", action)); 560 status = AE_BAD_PARAMETER; 561 break; 562 } 563 564 unlock_and_exit: 565 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 566 return_ACPI_STATUS(status); 567 } 568 569 ACPI_EXPORT_SYMBOL(acpi_set_gpe_wake_mask) 570 571 /******************************************************************************* 572 * 573 * FUNCTION: acpi_clear_gpe 574 * 575 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 576 * gpe_number - GPE level within the GPE block 577 * 578 * RETURN: Status 579 * 580 * DESCRIPTION: Clear an ACPI event (general purpose) 581 * 582 ******************************************************************************/ 583 acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number) 584 { 585 acpi_status status = AE_OK; 586 struct acpi_gpe_event_info *gpe_event_info; 587 acpi_cpu_flags flags; 588 589 ACPI_FUNCTION_TRACE(acpi_clear_gpe); 590 591 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 592 593 /* Ensure that we have a valid GPE number */ 594 595 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 596 if (!gpe_event_info) { 597 status = AE_BAD_PARAMETER; 598 goto unlock_and_exit; 599 } 600 601 status = acpi_hw_clear_gpe(gpe_event_info); 602 603 unlock_and_exit: 604 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 605 return_ACPI_STATUS(status); 606 } 607 608 ACPI_EXPORT_SYMBOL(acpi_clear_gpe) 609 610 /******************************************************************************* 611 * 612 * FUNCTION: acpi_get_gpe_status 613 * 614 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 615 * gpe_number - GPE level within the GPE block 616 * event_status - Where the current status of the event 617 * will be returned 618 * 619 * RETURN: Status 620 * 621 * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled) 622 * 623 ******************************************************************************/ 624 acpi_status 625 acpi_get_gpe_status(acpi_handle gpe_device, 626 u32 gpe_number, acpi_event_status *event_status) 627 { 628 acpi_status status = AE_OK; 629 struct acpi_gpe_event_info *gpe_event_info; 630 acpi_cpu_flags flags; 631 632 ACPI_FUNCTION_TRACE(acpi_get_gpe_status); 633 634 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 635 636 /* Ensure that we have a valid GPE number */ 637 638 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 639 if (!gpe_event_info) { 640 status = AE_BAD_PARAMETER; 641 goto unlock_and_exit; 642 } 643 644 /* Obtain status on the requested GPE number */ 645 646 status = acpi_hw_get_gpe_status(gpe_event_info, event_status); 647 648 unlock_and_exit: 649 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 650 return_ACPI_STATUS(status); 651 } 652 653 ACPI_EXPORT_SYMBOL(acpi_get_gpe_status) 654 655 /******************************************************************************* 656 * 657 * FUNCTION: acpi_finish_gpe 658 * 659 * PARAMETERS: gpe_device - Namespace node for the GPE Block 660 * (NULL for FADT defined GPEs) 661 * gpe_number - GPE level within the GPE block 662 * 663 * RETURN: Status 664 * 665 * DESCRIPTION: Clear and conditionally reenable a GPE. This completes the GPE 666 * processing. Intended for use by asynchronous host-installed 667 * GPE handlers. The GPE is only reenabled if the enable_for_run bit 668 * is set in the GPE info. 669 * 670 ******************************************************************************/ 671 acpi_status acpi_finish_gpe(acpi_handle gpe_device, u32 gpe_number) 672 { 673 struct acpi_gpe_event_info *gpe_event_info; 674 acpi_status status; 675 acpi_cpu_flags flags; 676 677 ACPI_FUNCTION_TRACE(acpi_finish_gpe); 678 679 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 680 681 /* Ensure that we have a valid GPE number */ 682 683 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); 684 if (!gpe_event_info) { 685 status = AE_BAD_PARAMETER; 686 goto unlock_and_exit; 687 } 688 689 status = acpi_ev_finish_gpe(gpe_event_info); 690 691 unlock_and_exit: 692 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 693 return_ACPI_STATUS(status); 694 } 695 696 ACPI_EXPORT_SYMBOL(acpi_finish_gpe) 697 698 /****************************************************************************** 699 * 700 * FUNCTION: acpi_disable_all_gpes 701 * 702 * PARAMETERS: None 703 * 704 * RETURN: Status 705 * 706 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks 707 * 708 ******************************************************************************/ 709 710 acpi_status acpi_disable_all_gpes(void) 711 { 712 acpi_status status; 713 714 ACPI_FUNCTION_TRACE(acpi_disable_all_gpes); 715 716 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); 717 if (ACPI_FAILURE(status)) { 718 return_ACPI_STATUS(status); 719 } 720 721 status = acpi_hw_disable_all_gpes(); 722 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); 723 724 return_ACPI_STATUS(status); 725 } 726 727 ACPI_EXPORT_SYMBOL(acpi_disable_all_gpes) 728 729 /****************************************************************************** 730 * 731 * FUNCTION: acpi_enable_all_runtime_gpes 732 * 733 * PARAMETERS: None 734 * 735 * RETURN: Status 736 * 737 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks 738 * 739 ******************************************************************************/ 740 741 acpi_status acpi_enable_all_runtime_gpes(void) 742 { 743 acpi_status status; 744 745 ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes); 746 747 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); 748 if (ACPI_FAILURE(status)) { 749 return_ACPI_STATUS(status); 750 } 751 752 status = acpi_hw_enable_all_runtime_gpes(); 753 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); 754 755 return_ACPI_STATUS(status); 756 } 757 758 ACPI_EXPORT_SYMBOL(acpi_enable_all_runtime_gpes) 759 760 /****************************************************************************** 761 * 762 * FUNCTION: acpi_enable_all_wakeup_gpes 763 * 764 * PARAMETERS: None 765 * 766 * RETURN: Status 767 * 768 * DESCRIPTION: Enable all "wakeup" GPEs and disable all of the other GPEs, in 769 * all GPE blocks. 770 * 771 ******************************************************************************/ 772 acpi_status acpi_enable_all_wakeup_gpes(void) 773 { 774 acpi_status status; 775 776 ACPI_FUNCTION_TRACE(acpi_enable_all_wakeup_gpes); 777 778 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); 779 if (ACPI_FAILURE(status)) { 780 return_ACPI_STATUS(status); 781 } 782 783 status = acpi_hw_enable_all_wakeup_gpes(); 784 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); 785 786 return_ACPI_STATUS(status); 787 } 788 789 ACPI_EXPORT_SYMBOL(acpi_enable_all_wakeup_gpes) 790 791 /******************************************************************************* 792 * 793 * FUNCTION: acpi_install_gpe_block 794 * 795 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device 796 * gpe_block_address - Address and space_ID 797 * register_count - Number of GPE register pairs in the block 798 * interrupt_number - H/W interrupt for the block 799 * 800 * RETURN: Status 801 * 802 * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not 803 * enabled here. 804 * 805 ******************************************************************************/ 806 acpi_status 807 acpi_install_gpe_block(acpi_handle gpe_device, 808 struct acpi_generic_address *gpe_block_address, 809 u32 register_count, u32 interrupt_number) 810 { 811 acpi_status status; 812 union acpi_operand_object *obj_desc; 813 struct acpi_namespace_node *node; 814 struct acpi_gpe_block_info *gpe_block; 815 816 ACPI_FUNCTION_TRACE(acpi_install_gpe_block); 817 818 if ((!gpe_device) || (!gpe_block_address) || (!register_count)) { 819 return_ACPI_STATUS(AE_BAD_PARAMETER); 820 } 821 822 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 823 if (ACPI_FAILURE(status)) { 824 return_ACPI_STATUS(status); 825 } 826 827 node = acpi_ns_validate_handle(gpe_device); 828 if (!node) { 829 status = AE_BAD_PARAMETER; 830 goto unlock_and_exit; 831 } 832 833 /* Validate the parent device */ 834 835 if (node->type != ACPI_TYPE_DEVICE) { 836 status = AE_TYPE; 837 goto unlock_and_exit; 838 } 839 840 if (node->object) { 841 status = AE_ALREADY_EXISTS; 842 goto unlock_and_exit; 843 } 844 845 /* 846 * For user-installed GPE Block Devices, the gpe_block_base_number 847 * is always zero 848 */ 849 status = acpi_ev_create_gpe_block(node, gpe_block_address->address, 850 gpe_block_address->space_id, 851 register_count, 0, interrupt_number, 852 &gpe_block); 853 if (ACPI_FAILURE(status)) { 854 goto unlock_and_exit; 855 } 856 857 /* Install block in the device_object attached to the node */ 858 859 obj_desc = acpi_ns_get_attached_object(node); 860 if (!obj_desc) { 861 862 /* 863 * No object, create a new one (Device nodes do not always have 864 * an attached object) 865 */ 866 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE); 867 if (!obj_desc) { 868 status = AE_NO_MEMORY; 869 goto unlock_and_exit; 870 } 871 872 status = 873 acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE); 874 875 /* Remove local reference to the object */ 876 877 acpi_ut_remove_reference(obj_desc); 878 879 if (ACPI_FAILURE(status)) { 880 goto unlock_and_exit; 881 } 882 } 883 884 /* Now install the GPE block in the device_object */ 885 886 obj_desc->device.gpe_block = gpe_block; 887 888 unlock_and_exit: 889 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 890 return_ACPI_STATUS(status); 891 } 892 893 ACPI_EXPORT_SYMBOL(acpi_install_gpe_block) 894 895 /******************************************************************************* 896 * 897 * FUNCTION: acpi_remove_gpe_block 898 * 899 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device 900 * 901 * RETURN: Status 902 * 903 * DESCRIPTION: Remove a previously installed block of GPE registers 904 * 905 ******************************************************************************/ 906 acpi_status acpi_remove_gpe_block(acpi_handle gpe_device) 907 { 908 union acpi_operand_object *obj_desc; 909 acpi_status status; 910 struct acpi_namespace_node *node; 911 912 ACPI_FUNCTION_TRACE(acpi_remove_gpe_block); 913 914 if (!gpe_device) { 915 return_ACPI_STATUS(AE_BAD_PARAMETER); 916 } 917 918 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 919 if (ACPI_FAILURE(status)) { 920 return_ACPI_STATUS(status); 921 } 922 923 node = acpi_ns_validate_handle(gpe_device); 924 if (!node) { 925 status = AE_BAD_PARAMETER; 926 goto unlock_and_exit; 927 } 928 929 /* Validate the parent device */ 930 931 if (node->type != ACPI_TYPE_DEVICE) { 932 status = AE_TYPE; 933 goto unlock_and_exit; 934 } 935 936 /* Get the device_object attached to the node */ 937 938 obj_desc = acpi_ns_get_attached_object(node); 939 if (!obj_desc || !obj_desc->device.gpe_block) { 940 return_ACPI_STATUS(AE_NULL_OBJECT); 941 } 942 943 /* Delete the GPE block (but not the device_object) */ 944 945 status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block); 946 if (ACPI_SUCCESS(status)) { 947 obj_desc->device.gpe_block = NULL; 948 } 949 950 unlock_and_exit: 951 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 952 return_ACPI_STATUS(status); 953 } 954 955 ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block) 956 957 /******************************************************************************* 958 * 959 * FUNCTION: acpi_get_gpe_device 960 * 961 * PARAMETERS: index - System GPE index (0-current_gpe_count) 962 * gpe_device - Where the parent GPE Device is returned 963 * 964 * RETURN: Status 965 * 966 * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL 967 * gpe device indicates that the gpe number is contained in one of 968 * the FADT-defined gpe blocks. Otherwise, the GPE block device. 969 * 970 ******************************************************************************/ 971 acpi_status acpi_get_gpe_device(u32 index, acpi_handle *gpe_device) 972 { 973 struct acpi_gpe_device_info info; 974 acpi_status status; 975 976 ACPI_FUNCTION_TRACE(acpi_get_gpe_device); 977 978 if (!gpe_device) { 979 return_ACPI_STATUS(AE_BAD_PARAMETER); 980 } 981 982 if (index >= acpi_current_gpe_count) { 983 return_ACPI_STATUS(AE_NOT_EXIST); 984 } 985 986 /* Setup and walk the GPE list */ 987 988 info.index = index; 989 info.status = AE_NOT_EXIST; 990 info.gpe_device = NULL; 991 info.next_block_base_index = 0; 992 993 status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info); 994 if (ACPI_FAILURE(status)) { 995 return_ACPI_STATUS(status); 996 } 997 998 *gpe_device = ACPI_CAST_PTR(acpi_handle, info.gpe_device); 999 return_ACPI_STATUS(info.status); 1000 } 1001 1002 ACPI_EXPORT_SYMBOL(acpi_get_gpe_device) 1003 #endif /* !ACPI_REDUCED_HARDWARE */ 1004