1 /****************************************************************************** 2 * 3 * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs) 4 * 5 *****************************************************************************/ 6 7 /****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2016, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 *****************************************************************************/ 115 116 #define EXPORT_ACPI_INTERFACES 117 118 #include "acpi.h" 119 #include "accommon.h" 120 #include "acevents.h" 121 #include "acnamesp.h" 122 123 #define _COMPONENT ACPI_EVENTS 124 ACPI_MODULE_NAME ("evxfgpe") 125 126 127 #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ 128 /******************************************************************************* 129 * 130 * FUNCTION: AcpiUpdateAllGpes 131 * 132 * PARAMETERS: None 133 * 134 * RETURN: Status 135 * 136 * DESCRIPTION: Complete GPE initialization and enable all GPEs that have 137 * associated _Lxx or _Exx methods and are not pointed to by any 138 * device _PRW methods (this indicates that these GPEs are 139 * generally intended for system or device wakeup. Such GPEs 140 * have to be enabled directly when the devices whose _PRW 141 * methods point to them are set up for wakeup signaling.) 142 * 143 * NOTE: Should be called after any GPEs are added to the system. Primarily, 144 * after the system _PRW methods have been run, but also after a GPE Block 145 * Device has been added or if any new GPE methods have been added via a 146 * dynamic table load. 147 * 148 ******************************************************************************/ 149 150 ACPI_STATUS 151 AcpiUpdateAllGpes ( 152 void) 153 { 154 ACPI_STATUS Status; 155 156 157 ACPI_FUNCTION_TRACE (AcpiUpdateAllGpes); 158 159 160 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 161 if (ACPI_FAILURE (Status)) 162 { 163 return_ACPI_STATUS (Status); 164 } 165 166 if (AcpiGbl_AllGpesInitialized) 167 { 168 goto UnlockAndExit; 169 } 170 171 Status = AcpiEvWalkGpeList (AcpiEvInitializeGpeBlock, NULL); 172 if (ACPI_SUCCESS (Status)) 173 { 174 AcpiGbl_AllGpesInitialized = TRUE; 175 } 176 177 UnlockAndExit: 178 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 179 return_ACPI_STATUS (Status); 180 } 181 182 ACPI_EXPORT_SYMBOL (AcpiUpdateAllGpes) 183 184 185 /******************************************************************************* 186 * 187 * FUNCTION: AcpiEnableGpe 188 * 189 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 190 * GpeNumber - GPE level within the GPE block 191 * 192 * RETURN: Status 193 * 194 * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is 195 * hardware-enabled. 196 * 197 ******************************************************************************/ 198 199 ACPI_STATUS 200 AcpiEnableGpe ( 201 ACPI_HANDLE GpeDevice, 202 UINT32 GpeNumber) 203 { 204 ACPI_STATUS Status = AE_BAD_PARAMETER; 205 ACPI_GPE_EVENT_INFO *GpeEventInfo; 206 ACPI_CPU_FLAGS Flags; 207 208 209 ACPI_FUNCTION_TRACE (AcpiEnableGpe); 210 211 212 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 213 214 /* 215 * Ensure that we have a valid GPE number and that there is some way 216 * of handling the GPE (handler or a GPE method). In other words, we 217 * won't allow a valid GPE to be enabled if there is no way to handle it. 218 */ 219 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 220 if (GpeEventInfo) 221 { 222 if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) != 223 ACPI_GPE_DISPATCH_NONE) 224 { 225 Status = AcpiEvAddGpeReference (GpeEventInfo); 226 } 227 else 228 { 229 Status = AE_NO_HANDLER; 230 } 231 } 232 233 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 234 return_ACPI_STATUS (Status); 235 } 236 237 ACPI_EXPORT_SYMBOL (AcpiEnableGpe) 238 239 240 /******************************************************************************* 241 * 242 * FUNCTION: AcpiDisableGpe 243 * 244 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 245 * GpeNumber - GPE level within the GPE block 246 * 247 * RETURN: Status 248 * 249 * DESCRIPTION: Remove a reference to a GPE. When the last reference is 250 * removed, only then is the GPE disabled (for runtime GPEs), or 251 * the GPE mask bit disabled (for wake GPEs) 252 * 253 ******************************************************************************/ 254 255 ACPI_STATUS 256 AcpiDisableGpe ( 257 ACPI_HANDLE GpeDevice, 258 UINT32 GpeNumber) 259 { 260 ACPI_STATUS Status = AE_BAD_PARAMETER; 261 ACPI_GPE_EVENT_INFO *GpeEventInfo; 262 ACPI_CPU_FLAGS Flags; 263 264 265 ACPI_FUNCTION_TRACE (AcpiDisableGpe); 266 267 268 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 269 270 /* Ensure that we have a valid GPE number */ 271 272 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 273 if (GpeEventInfo) 274 { 275 Status = AcpiEvRemoveGpeReference (GpeEventInfo); 276 } 277 278 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 279 return_ACPI_STATUS (Status); 280 } 281 282 ACPI_EXPORT_SYMBOL (AcpiDisableGpe) 283 284 285 /******************************************************************************* 286 * 287 * FUNCTION: AcpiSetGpe 288 * 289 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 290 * GpeNumber - GPE level within the GPE block 291 * Action - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE 292 * 293 * RETURN: Status 294 * 295 * DESCRIPTION: Enable or disable an individual GPE. This function bypasses 296 * the reference count mechanism used in the AcpiEnableGpe(), 297 * AcpiDisableGpe() interfaces. 298 * This API is typically used by the GPE raw handler mode driver 299 * to switch between the polling mode and the interrupt mode after 300 * the driver has enabled the GPE. 301 * The APIs should be invoked in this order: 302 * AcpiEnableGpe() <- Ensure the reference count > 0 303 * AcpiSetGpe(ACPI_GPE_DISABLE) <- Enter polling mode 304 * AcpiSetGpe(ACPI_GPE_ENABLE) <- Leave polling mode 305 * AcpiDisableGpe() <- Decrease the reference count 306 * 307 * Note: If a GPE is shared by 2 silicon components, then both the drivers 308 * should support GPE polling mode or disabling the GPE for long period 309 * for one driver may break the other. So use it with care since all 310 * firmware _Lxx/_Exx handlers currently rely on the GPE interrupt mode. 311 * 312 ******************************************************************************/ 313 314 ACPI_STATUS 315 AcpiSetGpe ( 316 ACPI_HANDLE GpeDevice, 317 UINT32 GpeNumber, 318 UINT8 Action) 319 { 320 ACPI_GPE_EVENT_INFO *GpeEventInfo; 321 ACPI_STATUS Status; 322 ACPI_CPU_FLAGS Flags; 323 324 325 ACPI_FUNCTION_TRACE (AcpiSetGpe); 326 327 328 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 329 330 /* Ensure that we have a valid GPE number */ 331 332 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 333 if (!GpeEventInfo) 334 { 335 Status = AE_BAD_PARAMETER; 336 goto UnlockAndExit; 337 } 338 339 /* Perform the action */ 340 341 switch (Action) 342 { 343 case ACPI_GPE_ENABLE: 344 345 Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE); 346 break; 347 348 case ACPI_GPE_DISABLE: 349 350 Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE); 351 break; 352 353 default: 354 355 Status = AE_BAD_PARAMETER; 356 break; 357 } 358 359 UnlockAndExit: 360 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 361 return_ACPI_STATUS (Status); 362 } 363 364 ACPI_EXPORT_SYMBOL (AcpiSetGpe) 365 366 367 /******************************************************************************* 368 * 369 * FUNCTION: AcpiMarkGpeForWake 370 * 371 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 372 * GpeNumber - GPE level within the GPE block 373 * 374 * RETURN: Status 375 * 376 * DESCRIPTION: Mark a GPE as having the ability to wake the system. Simply 377 * sets the ACPI_GPE_CAN_WAKE flag. 378 * 379 * Some potential callers of AcpiSetupGpeForWake may know in advance that 380 * there won't be any notify handlers installed for device wake notifications 381 * from the given GPE (one example is a button GPE in Linux). For these cases, 382 * AcpiMarkGpeForWake should be used instead of AcpiSetupGpeForWake. 383 * This will set the ACPI_GPE_CAN_WAKE flag for the GPE without trying to 384 * setup implicit wake notification for it (since there's no handler method). 385 * 386 ******************************************************************************/ 387 388 ACPI_STATUS 389 AcpiMarkGpeForWake ( 390 ACPI_HANDLE GpeDevice, 391 UINT32 GpeNumber) 392 { 393 ACPI_GPE_EVENT_INFO *GpeEventInfo; 394 ACPI_STATUS Status = AE_BAD_PARAMETER; 395 ACPI_CPU_FLAGS Flags; 396 397 398 ACPI_FUNCTION_TRACE (AcpiMarkGpeForWake); 399 400 401 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 402 403 /* Ensure that we have a valid GPE number */ 404 405 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 406 if (GpeEventInfo) 407 { 408 /* Mark the GPE as a possible wake event */ 409 410 GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE; 411 Status = AE_OK; 412 } 413 414 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 415 return_ACPI_STATUS (Status); 416 } 417 418 ACPI_EXPORT_SYMBOL (AcpiMarkGpeForWake) 419 420 421 /******************************************************************************* 422 * 423 * FUNCTION: AcpiSetupGpeForWake 424 * 425 * PARAMETERS: WakeDevice - Device associated with the GPE (via _PRW) 426 * GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 427 * GpeNumber - GPE level within the GPE block 428 * 429 * RETURN: Status 430 * 431 * DESCRIPTION: Mark a GPE as having the ability to wake the system. This 432 * interface is intended to be used as the host executes the 433 * _PRW methods (Power Resources for Wake) in the system tables. 434 * Each _PRW appears under a Device Object (The WakeDevice), and 435 * contains the info for the wake GPE associated with the 436 * WakeDevice. 437 * 438 ******************************************************************************/ 439 440 ACPI_STATUS 441 AcpiSetupGpeForWake ( 442 ACPI_HANDLE WakeDevice, 443 ACPI_HANDLE GpeDevice, 444 UINT32 GpeNumber) 445 { 446 ACPI_STATUS Status; 447 ACPI_GPE_EVENT_INFO *GpeEventInfo; 448 ACPI_NAMESPACE_NODE *DeviceNode; 449 ACPI_GPE_NOTIFY_INFO *Notify; 450 ACPI_GPE_NOTIFY_INFO *NewNotify; 451 ACPI_CPU_FLAGS Flags; 452 453 454 ACPI_FUNCTION_TRACE (AcpiSetupGpeForWake); 455 456 457 /* Parameter Validation */ 458 459 if (!WakeDevice) 460 { 461 /* 462 * By forcing WakeDevice to be valid, we automatically enable the 463 * implicit notify feature on all hosts. 464 */ 465 return_ACPI_STATUS (AE_BAD_PARAMETER); 466 } 467 468 /* Handle root object case */ 469 470 if (WakeDevice == ACPI_ROOT_OBJECT) 471 { 472 DeviceNode = AcpiGbl_RootNode; 473 } 474 else 475 { 476 DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, WakeDevice); 477 } 478 479 /* Validate WakeDevice is of type Device */ 480 481 if (DeviceNode->Type != ACPI_TYPE_DEVICE) 482 { 483 return_ACPI_STATUS (AE_BAD_PARAMETER); 484 } 485 486 /* 487 * Allocate a new notify object up front, in case it is needed. 488 * Memory allocation while holding a spinlock is a big no-no 489 * on some hosts. 490 */ 491 NewNotify = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_NOTIFY_INFO)); 492 if (!NewNotify) 493 { 494 return_ACPI_STATUS (AE_NO_MEMORY); 495 } 496 497 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 498 499 /* Ensure that we have a valid GPE number */ 500 501 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 502 if (!GpeEventInfo) 503 { 504 Status = AE_BAD_PARAMETER; 505 goto UnlockAndExit; 506 } 507 508 /* 509 * If there is no method or handler for this GPE, then the 510 * WakeDevice will be notified whenever this GPE fires. This is 511 * known as an "implicit notify". Note: The GPE is assumed to be 512 * level-triggered (for windows compatibility). 513 */ 514 if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == 515 ACPI_GPE_DISPATCH_NONE) 516 { 517 /* 518 * This is the first device for implicit notify on this GPE. 519 * Just set the flags here, and enter the NOTIFY block below. 520 */ 521 GpeEventInfo->Flags = 522 (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED); 523 } 524 525 /* 526 * If we already have an implicit notify on this GPE, add 527 * this device to the notify list. 528 */ 529 if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == 530 ACPI_GPE_DISPATCH_NOTIFY) 531 { 532 /* Ensure that the device is not already in the list */ 533 534 Notify = GpeEventInfo->Dispatch.NotifyList; 535 while (Notify) 536 { 537 if (Notify->DeviceNode == DeviceNode) 538 { 539 Status = AE_ALREADY_EXISTS; 540 goto UnlockAndExit; 541 } 542 Notify = Notify->Next; 543 } 544 545 /* Add this device to the notify list for this GPE */ 546 547 NewNotify->DeviceNode = DeviceNode; 548 NewNotify->Next = GpeEventInfo->Dispatch.NotifyList; 549 GpeEventInfo->Dispatch.NotifyList = NewNotify; 550 NewNotify = NULL; 551 } 552 553 /* Mark the GPE as a possible wake event */ 554 555 GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE; 556 Status = AE_OK; 557 558 559 UnlockAndExit: 560 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 561 562 /* Delete the notify object if it was not used above */ 563 564 if (NewNotify) 565 { 566 ACPI_FREE (NewNotify); 567 } 568 return_ACPI_STATUS (Status); 569 } 570 571 ACPI_EXPORT_SYMBOL (AcpiSetupGpeForWake) 572 573 574 /******************************************************************************* 575 * 576 * FUNCTION: AcpiSetGpeWakeMask 577 * 578 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 579 * GpeNumber - GPE level within the GPE block 580 * Action - Enable or Disable 581 * 582 * RETURN: Status 583 * 584 * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must 585 * already be marked as a WAKE GPE. 586 * 587 ******************************************************************************/ 588 589 ACPI_STATUS 590 AcpiSetGpeWakeMask ( 591 ACPI_HANDLE GpeDevice, 592 UINT32 GpeNumber, 593 UINT8 Action) 594 { 595 ACPI_STATUS Status = AE_OK; 596 ACPI_GPE_EVENT_INFO *GpeEventInfo; 597 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo; 598 ACPI_CPU_FLAGS Flags; 599 UINT32 RegisterBit; 600 601 602 ACPI_FUNCTION_TRACE (AcpiSetGpeWakeMask); 603 604 605 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 606 607 /* 608 * Ensure that we have a valid GPE number and that this GPE is in 609 * fact a wake GPE 610 */ 611 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 612 if (!GpeEventInfo) 613 { 614 Status = AE_BAD_PARAMETER; 615 goto UnlockAndExit; 616 } 617 618 if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE)) 619 { 620 Status = AE_TYPE; 621 goto UnlockAndExit; 622 } 623 624 GpeRegisterInfo = GpeEventInfo->RegisterInfo; 625 if (!GpeRegisterInfo) 626 { 627 Status = AE_NOT_EXIST; 628 goto UnlockAndExit; 629 } 630 631 RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo); 632 633 /* Perform the action */ 634 635 switch (Action) 636 { 637 case ACPI_GPE_ENABLE: 638 639 ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit); 640 break; 641 642 case ACPI_GPE_DISABLE: 643 644 ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit); 645 break; 646 647 default: 648 649 ACPI_ERROR ((AE_INFO, "%u, Invalid action", Action)); 650 Status = AE_BAD_PARAMETER; 651 break; 652 } 653 654 UnlockAndExit: 655 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 656 return_ACPI_STATUS (Status); 657 } 658 659 ACPI_EXPORT_SYMBOL (AcpiSetGpeWakeMask) 660 661 662 /******************************************************************************* 663 * 664 * FUNCTION: AcpiClearGpe 665 * 666 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 667 * GpeNumber - GPE level within the GPE block 668 * 669 * RETURN: Status 670 * 671 * DESCRIPTION: Clear an ACPI event (general purpose) 672 * 673 ******************************************************************************/ 674 675 ACPI_STATUS 676 AcpiClearGpe ( 677 ACPI_HANDLE GpeDevice, 678 UINT32 GpeNumber) 679 { 680 ACPI_STATUS Status = AE_OK; 681 ACPI_GPE_EVENT_INFO *GpeEventInfo; 682 ACPI_CPU_FLAGS Flags; 683 684 685 ACPI_FUNCTION_TRACE (AcpiClearGpe); 686 687 688 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 689 690 /* Ensure that we have a valid GPE number */ 691 692 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 693 if (!GpeEventInfo) 694 { 695 Status = AE_BAD_PARAMETER; 696 goto UnlockAndExit; 697 } 698 699 Status = AcpiHwClearGpe (GpeEventInfo); 700 701 UnlockAndExit: 702 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 703 return_ACPI_STATUS (Status); 704 } 705 706 ACPI_EXPORT_SYMBOL (AcpiClearGpe) 707 708 709 /******************************************************************************* 710 * 711 * FUNCTION: AcpiGetGpeStatus 712 * 713 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 714 * GpeNumber - GPE level within the GPE block 715 * EventStatus - Where the current status of the event 716 * will be returned 717 * 718 * RETURN: Status 719 * 720 * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled) 721 * 722 ******************************************************************************/ 723 724 ACPI_STATUS 725 AcpiGetGpeStatus ( 726 ACPI_HANDLE GpeDevice, 727 UINT32 GpeNumber, 728 ACPI_EVENT_STATUS *EventStatus) 729 { 730 ACPI_STATUS Status = AE_OK; 731 ACPI_GPE_EVENT_INFO *GpeEventInfo; 732 ACPI_CPU_FLAGS Flags; 733 734 735 ACPI_FUNCTION_TRACE (AcpiGetGpeStatus); 736 737 738 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 739 740 /* Ensure that we have a valid GPE number */ 741 742 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 743 if (!GpeEventInfo) 744 { 745 Status = AE_BAD_PARAMETER; 746 goto UnlockAndExit; 747 } 748 749 /* Obtain status on the requested GPE number */ 750 751 Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus); 752 753 UnlockAndExit: 754 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 755 return_ACPI_STATUS (Status); 756 } 757 758 ACPI_EXPORT_SYMBOL (AcpiGetGpeStatus) 759 760 761 /******************************************************************************* 762 * 763 * FUNCTION: AcpiFinishGpe 764 * 765 * PARAMETERS: GpeDevice - Namespace node for the GPE Block 766 * (NULL for FADT defined GPEs) 767 * GpeNumber - GPE level within the GPE block 768 * 769 * RETURN: Status 770 * 771 * DESCRIPTION: Clear and conditionally reenable a GPE. This completes the GPE 772 * processing. Intended for use by asynchronous host-installed 773 * GPE handlers. The GPE is only reenabled if the EnableForRun bit 774 * is set in the GPE info. 775 * 776 ******************************************************************************/ 777 778 ACPI_STATUS 779 AcpiFinishGpe ( 780 ACPI_HANDLE GpeDevice, 781 UINT32 GpeNumber) 782 { 783 ACPI_GPE_EVENT_INFO *GpeEventInfo; 784 ACPI_STATUS Status; 785 ACPI_CPU_FLAGS Flags; 786 787 788 ACPI_FUNCTION_TRACE (AcpiFinishGpe); 789 790 791 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 792 793 /* Ensure that we have a valid GPE number */ 794 795 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 796 if (!GpeEventInfo) 797 { 798 Status = AE_BAD_PARAMETER; 799 goto UnlockAndExit; 800 } 801 802 Status = AcpiEvFinishGpe (GpeEventInfo); 803 804 UnlockAndExit: 805 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 806 return_ACPI_STATUS (Status); 807 } 808 809 ACPI_EXPORT_SYMBOL (AcpiFinishGpe) 810 811 812 /****************************************************************************** 813 * 814 * FUNCTION: AcpiDisableAllGpes 815 * 816 * PARAMETERS: None 817 * 818 * RETURN: Status 819 * 820 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks 821 * 822 ******************************************************************************/ 823 824 ACPI_STATUS 825 AcpiDisableAllGpes ( 826 void) 827 { 828 ACPI_STATUS Status; 829 830 831 ACPI_FUNCTION_TRACE (AcpiDisableAllGpes); 832 833 834 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 835 if (ACPI_FAILURE (Status)) 836 { 837 return_ACPI_STATUS (Status); 838 } 839 840 Status = AcpiHwDisableAllGpes (); 841 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 842 843 return_ACPI_STATUS (Status); 844 } 845 846 ACPI_EXPORT_SYMBOL (AcpiDisableAllGpes) 847 848 849 /****************************************************************************** 850 * 851 * FUNCTION: AcpiEnableAllRuntimeGpes 852 * 853 * PARAMETERS: None 854 * 855 * RETURN: Status 856 * 857 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks 858 * 859 ******************************************************************************/ 860 861 ACPI_STATUS 862 AcpiEnableAllRuntimeGpes ( 863 void) 864 { 865 ACPI_STATUS Status; 866 867 868 ACPI_FUNCTION_TRACE (AcpiEnableAllRuntimeGpes); 869 870 871 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 872 if (ACPI_FAILURE (Status)) 873 { 874 return_ACPI_STATUS (Status); 875 } 876 877 Status = AcpiHwEnableAllRuntimeGpes (); 878 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 879 880 return_ACPI_STATUS (Status); 881 } 882 883 ACPI_EXPORT_SYMBOL (AcpiEnableAllRuntimeGpes) 884 885 886 /****************************************************************************** 887 * 888 * FUNCTION: AcpiEnableAllWakeupGpes 889 * 890 * PARAMETERS: None 891 * 892 * RETURN: Status 893 * 894 * DESCRIPTION: Enable all "wakeup" GPEs and disable all of the other GPEs, in 895 * all GPE blocks. 896 * 897 ******************************************************************************/ 898 899 ACPI_STATUS 900 AcpiEnableAllWakeupGpes ( 901 void) 902 { 903 ACPI_STATUS Status; 904 905 906 ACPI_FUNCTION_TRACE (AcpiEnableAllWakeupGpes); 907 908 909 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 910 if (ACPI_FAILURE (Status)) 911 { 912 return_ACPI_STATUS (Status); 913 } 914 915 Status = AcpiHwEnableAllWakeupGpes (); 916 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 917 918 return_ACPI_STATUS (Status); 919 } 920 921 ACPI_EXPORT_SYMBOL (AcpiEnableAllWakeupGpes) 922 923 924 /******************************************************************************* 925 * 926 * FUNCTION: AcpiInstallGpeBlock 927 * 928 * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device 929 * GpeBlockAddress - Address and SpaceID 930 * RegisterCount - Number of GPE register pairs in the block 931 * InterruptNumber - H/W interrupt for the block 932 * 933 * RETURN: Status 934 * 935 * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not 936 * enabled here. 937 * 938 ******************************************************************************/ 939 940 ACPI_STATUS 941 AcpiInstallGpeBlock ( 942 ACPI_HANDLE GpeDevice, 943 ACPI_GENERIC_ADDRESS *GpeBlockAddress, 944 UINT32 RegisterCount, 945 UINT32 InterruptNumber) 946 { 947 ACPI_STATUS Status; 948 ACPI_OPERAND_OBJECT *ObjDesc; 949 ACPI_NAMESPACE_NODE *Node; 950 ACPI_GPE_BLOCK_INFO *GpeBlock; 951 952 953 ACPI_FUNCTION_TRACE (AcpiInstallGpeBlock); 954 955 956 if ((!GpeDevice) || 957 (!GpeBlockAddress) || 958 (!RegisterCount)) 959 { 960 return_ACPI_STATUS (AE_BAD_PARAMETER); 961 } 962 963 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 964 if (ACPI_FAILURE (Status)) 965 { 966 return_ACPI_STATUS (Status); 967 } 968 969 Node = AcpiNsValidateHandle (GpeDevice); 970 if (!Node) 971 { 972 Status = AE_BAD_PARAMETER; 973 goto UnlockAndExit; 974 } 975 976 /* Validate the parent device */ 977 978 if (Node->Type != ACPI_TYPE_DEVICE) 979 { 980 Status = AE_TYPE; 981 goto UnlockAndExit; 982 } 983 984 if (Node->Object) 985 { 986 Status = AE_ALREADY_EXISTS; 987 goto UnlockAndExit; 988 } 989 990 /* 991 * For user-installed GPE Block Devices, the GpeBlockBaseNumber 992 * is always zero 993 */ 994 Status = AcpiEvCreateGpeBlock (Node, GpeBlockAddress->Address, 995 GpeBlockAddress->SpaceId, RegisterCount, 996 0, InterruptNumber, &GpeBlock); 997 if (ACPI_FAILURE (Status)) 998 { 999 goto UnlockAndExit; 1000 } 1001 1002 /* Install block in the DeviceObject attached to the node */ 1003 1004 ObjDesc = AcpiNsGetAttachedObject (Node); 1005 if (!ObjDesc) 1006 { 1007 /* 1008 * No object, create a new one (Device nodes do not always have 1009 * an attached object) 1010 */ 1011 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_DEVICE); 1012 if (!ObjDesc) 1013 { 1014 Status = AE_NO_MEMORY; 1015 goto UnlockAndExit; 1016 } 1017 1018 Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_DEVICE); 1019 1020 /* Remove local reference to the object */ 1021 1022 AcpiUtRemoveReference (ObjDesc); 1023 if (ACPI_FAILURE (Status)) 1024 { 1025 goto UnlockAndExit; 1026 } 1027 } 1028 1029 /* Now install the GPE block in the DeviceObject */ 1030 1031 ObjDesc->Device.GpeBlock = GpeBlock; 1032 1033 1034 UnlockAndExit: 1035 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 1036 return_ACPI_STATUS (Status); 1037 } 1038 1039 ACPI_EXPORT_SYMBOL (AcpiInstallGpeBlock) 1040 1041 1042 /******************************************************************************* 1043 * 1044 * FUNCTION: AcpiRemoveGpeBlock 1045 * 1046 * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device 1047 * 1048 * RETURN: Status 1049 * 1050 * DESCRIPTION: Remove a previously installed block of GPE registers 1051 * 1052 ******************************************************************************/ 1053 1054 ACPI_STATUS 1055 AcpiRemoveGpeBlock ( 1056 ACPI_HANDLE GpeDevice) 1057 { 1058 ACPI_OPERAND_OBJECT *ObjDesc; 1059 ACPI_STATUS Status; 1060 ACPI_NAMESPACE_NODE *Node; 1061 1062 1063 ACPI_FUNCTION_TRACE (AcpiRemoveGpeBlock); 1064 1065 1066 if (!GpeDevice) 1067 { 1068 return_ACPI_STATUS (AE_BAD_PARAMETER); 1069 } 1070 1071 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 1072 if (ACPI_FAILURE (Status)) 1073 { 1074 return_ACPI_STATUS (Status); 1075 } 1076 1077 Node = AcpiNsValidateHandle (GpeDevice); 1078 if (!Node) 1079 { 1080 Status = AE_BAD_PARAMETER; 1081 goto UnlockAndExit; 1082 } 1083 1084 /* Validate the parent device */ 1085 1086 if (Node->Type != ACPI_TYPE_DEVICE) 1087 { 1088 Status = AE_TYPE; 1089 goto UnlockAndExit; 1090 } 1091 1092 /* Get the DeviceObject attached to the node */ 1093 1094 ObjDesc = AcpiNsGetAttachedObject (Node); 1095 if (!ObjDesc || 1096 !ObjDesc->Device.GpeBlock) 1097 { 1098 return_ACPI_STATUS (AE_NULL_OBJECT); 1099 } 1100 1101 /* Delete the GPE block (but not the DeviceObject) */ 1102 1103 Status = AcpiEvDeleteGpeBlock (ObjDesc->Device.GpeBlock); 1104 if (ACPI_SUCCESS (Status)) 1105 { 1106 ObjDesc->Device.GpeBlock = NULL; 1107 } 1108 1109 UnlockAndExit: 1110 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 1111 return_ACPI_STATUS (Status); 1112 } 1113 1114 ACPI_EXPORT_SYMBOL (AcpiRemoveGpeBlock) 1115 1116 1117 /******************************************************************************* 1118 * 1119 * FUNCTION: AcpiGetGpeDevice 1120 * 1121 * PARAMETERS: Index - System GPE index (0-CurrentGpeCount) 1122 * GpeDevice - Where the parent GPE Device is returned 1123 * 1124 * RETURN: Status 1125 * 1126 * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL 1127 * gpe device indicates that the gpe number is contained in one of 1128 * the FADT-defined gpe blocks. Otherwise, the GPE block device. 1129 * 1130 ******************************************************************************/ 1131 1132 ACPI_STATUS 1133 AcpiGetGpeDevice ( 1134 UINT32 Index, 1135 ACPI_HANDLE *GpeDevice) 1136 { 1137 ACPI_GPE_DEVICE_INFO Info; 1138 ACPI_STATUS Status; 1139 1140 1141 ACPI_FUNCTION_TRACE (AcpiGetGpeDevice); 1142 1143 1144 if (!GpeDevice) 1145 { 1146 return_ACPI_STATUS (AE_BAD_PARAMETER); 1147 } 1148 1149 if (Index >= AcpiCurrentGpeCount) 1150 { 1151 return_ACPI_STATUS (AE_NOT_EXIST); 1152 } 1153 1154 /* Setup and walk the GPE list */ 1155 1156 Info.Index = Index; 1157 Info.Status = AE_NOT_EXIST; 1158 Info.GpeDevice = NULL; 1159 Info.NextBlockBaseIndex = 0; 1160 1161 Status = AcpiEvWalkGpeList (AcpiEvGetGpeDevice, &Info); 1162 if (ACPI_FAILURE (Status)) 1163 { 1164 return_ACPI_STATUS (Status); 1165 } 1166 1167 *GpeDevice = ACPI_CAST_PTR (ACPI_HANDLE, Info.GpeDevice); 1168 return_ACPI_STATUS (Info.Status); 1169 } 1170 1171 ACPI_EXPORT_SYMBOL (AcpiGetGpeDevice) 1172 1173 #endif /* !ACPI_REDUCED_HARDWARE */ 1174