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