1 /****************************************************************************** 2 * 3 * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs) 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2014, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 45 #define __EVXFGPE_C__ 46 #define EXPORT_ACPI_INTERFACES 47 48 #include "acpi.h" 49 #include "accommon.h" 50 #include "acevents.h" 51 #include "acnamesp.h" 52 53 #define _COMPONENT ACPI_EVENTS 54 ACPI_MODULE_NAME ("evxfgpe") 55 56 57 #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ 58 /******************************************************************************* 59 * 60 * FUNCTION: AcpiUpdateAllGpes 61 * 62 * PARAMETERS: None 63 * 64 * RETURN: Status 65 * 66 * DESCRIPTION: Complete GPE initialization and enable all GPEs that have 67 * associated _Lxx or _Exx methods and are not pointed to by any 68 * device _PRW methods (this indicates that these GPEs are 69 * generally intended for system or device wakeup. Such GPEs 70 * have to be enabled directly when the devices whose _PRW 71 * methods point to them are set up for wakeup signaling.) 72 * 73 * NOTE: Should be called after any GPEs are added to the system. Primarily, 74 * after the system _PRW methods have been run, but also after a GPE Block 75 * Device has been added or if any new GPE methods have been added via a 76 * dynamic table load. 77 * 78 ******************************************************************************/ 79 80 ACPI_STATUS 81 AcpiUpdateAllGpes ( 82 void) 83 { 84 ACPI_STATUS Status; 85 86 87 ACPI_FUNCTION_TRACE (AcpiUpdateAllGpes); 88 89 90 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 91 if (ACPI_FAILURE (Status)) 92 { 93 return_ACPI_STATUS (Status); 94 } 95 96 if (AcpiGbl_AllGpesInitialized) 97 { 98 goto UnlockAndExit; 99 } 100 101 Status = AcpiEvWalkGpeList (AcpiEvInitializeGpeBlock, NULL); 102 if (ACPI_SUCCESS (Status)) 103 { 104 AcpiGbl_AllGpesInitialized = TRUE; 105 } 106 107 UnlockAndExit: 108 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 109 return_ACPI_STATUS (Status); 110 } 111 112 ACPI_EXPORT_SYMBOL (AcpiUpdateAllGpes) 113 114 115 /******************************************************************************* 116 * 117 * FUNCTION: AcpiEnableGpe 118 * 119 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 120 * GpeNumber - GPE level within the GPE block 121 * 122 * RETURN: Status 123 * 124 * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is 125 * hardware-enabled. 126 * 127 ******************************************************************************/ 128 129 ACPI_STATUS 130 AcpiEnableGpe ( 131 ACPI_HANDLE GpeDevice, 132 UINT32 GpeNumber) 133 { 134 ACPI_STATUS Status = AE_BAD_PARAMETER; 135 ACPI_GPE_EVENT_INFO *GpeEventInfo; 136 ACPI_CPU_FLAGS Flags; 137 138 139 ACPI_FUNCTION_TRACE (AcpiEnableGpe); 140 141 142 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 143 144 /* Ensure that we have a valid GPE number */ 145 146 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 147 if (GpeEventInfo) 148 { 149 Status = AcpiEvAddGpeReference (GpeEventInfo); 150 } 151 152 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 153 return_ACPI_STATUS (Status); 154 } 155 156 ACPI_EXPORT_SYMBOL (AcpiEnableGpe) 157 158 159 /******************************************************************************* 160 * 161 * FUNCTION: AcpiDisableGpe 162 * 163 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 164 * GpeNumber - GPE level within the GPE block 165 * 166 * RETURN: Status 167 * 168 * DESCRIPTION: Remove a reference to a GPE. When the last reference is 169 * removed, only then is the GPE disabled (for runtime GPEs), or 170 * the GPE mask bit disabled (for wake GPEs) 171 * 172 ******************************************************************************/ 173 174 ACPI_STATUS 175 AcpiDisableGpe ( 176 ACPI_HANDLE GpeDevice, 177 UINT32 GpeNumber) 178 { 179 ACPI_STATUS Status = AE_BAD_PARAMETER; 180 ACPI_GPE_EVENT_INFO *GpeEventInfo; 181 ACPI_CPU_FLAGS Flags; 182 183 184 ACPI_FUNCTION_TRACE (AcpiDisableGpe); 185 186 187 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 188 189 /* Ensure that we have a valid GPE number */ 190 191 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 192 if (GpeEventInfo) 193 { 194 Status = AcpiEvRemoveGpeReference (GpeEventInfo); 195 } 196 197 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 198 return_ACPI_STATUS (Status); 199 } 200 201 ACPI_EXPORT_SYMBOL (AcpiDisableGpe) 202 203 204 /******************************************************************************* 205 * 206 * FUNCTION: AcpiSetGpe 207 * 208 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 209 * GpeNumber - GPE level within the GPE block 210 * Action - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE 211 * 212 * RETURN: Status 213 * 214 * DESCRIPTION: Enable or disable an individual GPE. This function bypasses 215 * the reference count mechanism used in the AcpiEnableGpe and 216 * AcpiDisableGpe interfaces -- and should be used with care. 217 * 218 * Note: Typically used to disable a runtime GPE for short period of time, 219 * then re-enable it, without disturbing the existing reference counts. This 220 * is useful, for example, in the Embedded Controller (EC) driver. 221 * 222 ******************************************************************************/ 223 224 ACPI_STATUS 225 AcpiSetGpe ( 226 ACPI_HANDLE GpeDevice, 227 UINT32 GpeNumber, 228 UINT8 Action) 229 { 230 ACPI_GPE_EVENT_INFO *GpeEventInfo; 231 ACPI_STATUS Status; 232 ACPI_CPU_FLAGS Flags; 233 234 235 ACPI_FUNCTION_TRACE (AcpiSetGpe); 236 237 238 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 239 240 /* Ensure that we have a valid GPE number */ 241 242 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 243 if (!GpeEventInfo) 244 { 245 Status = AE_BAD_PARAMETER; 246 goto UnlockAndExit; 247 } 248 249 /* Perform the action */ 250 251 switch (Action) 252 { 253 case ACPI_GPE_ENABLE: 254 255 Status = AcpiEvEnableGpe (GpeEventInfo); 256 break; 257 258 case ACPI_GPE_DISABLE: 259 260 Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE); 261 break; 262 263 default: 264 265 Status = AE_BAD_PARAMETER; 266 break; 267 } 268 269 UnlockAndExit: 270 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 271 return_ACPI_STATUS (Status); 272 } 273 274 ACPI_EXPORT_SYMBOL (AcpiSetGpe) 275 276 277 /******************************************************************************* 278 * 279 * FUNCTION: AcpiSetupGpeForWake 280 * 281 * PARAMETERS: WakeDevice - Device associated with the GPE (via _PRW) 282 * GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 283 * GpeNumber - GPE level within the GPE block 284 * 285 * RETURN: Status 286 * 287 * DESCRIPTION: Mark a GPE as having the ability to wake the system. This 288 * interface is intended to be used as the host executes the 289 * _PRW methods (Power Resources for Wake) in the system tables. 290 * Each _PRW appears under a Device Object (The WakeDevice), and 291 * contains the info for the wake GPE associated with the 292 * WakeDevice. 293 * 294 ******************************************************************************/ 295 296 ACPI_STATUS 297 AcpiSetupGpeForWake ( 298 ACPI_HANDLE WakeDevice, 299 ACPI_HANDLE GpeDevice, 300 UINT32 GpeNumber) 301 { 302 ACPI_STATUS Status; 303 ACPI_GPE_EVENT_INFO *GpeEventInfo; 304 ACPI_NAMESPACE_NODE *DeviceNode; 305 ACPI_GPE_NOTIFY_INFO *Notify; 306 ACPI_GPE_NOTIFY_INFO *NewNotify; 307 ACPI_CPU_FLAGS Flags; 308 309 310 ACPI_FUNCTION_TRACE (AcpiSetupGpeForWake); 311 312 313 /* Parameter Validation */ 314 315 if (!WakeDevice) 316 { 317 /* 318 * By forcing WakeDevice to be valid, we automatically enable the 319 * implicit notify feature on all hosts. 320 */ 321 return_ACPI_STATUS (AE_BAD_PARAMETER); 322 } 323 324 /* Handle root object case */ 325 326 if (WakeDevice == ACPI_ROOT_OBJECT) 327 { 328 DeviceNode = AcpiGbl_RootNode; 329 } 330 else 331 { 332 DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, WakeDevice); 333 } 334 335 /* Validate WakeDevice is of type Device */ 336 337 if (DeviceNode->Type != ACPI_TYPE_DEVICE) 338 { 339 return_ACPI_STATUS (AE_BAD_PARAMETER); 340 } 341 342 /* 343 * Allocate a new notify object up front, in case it is needed. 344 * Memory allocation while holding a spinlock is a big no-no 345 * on some hosts. 346 */ 347 NewNotify = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_NOTIFY_INFO)); 348 if (!NewNotify) 349 { 350 return_ACPI_STATUS (AE_NO_MEMORY); 351 } 352 353 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 354 355 /* Ensure that we have a valid GPE number */ 356 357 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 358 if (!GpeEventInfo) 359 { 360 Status = AE_BAD_PARAMETER; 361 goto UnlockAndExit; 362 } 363 364 /* 365 * If there is no method or handler for this GPE, then the 366 * WakeDevice will be notified whenever this GPE fires. This is 367 * known as an "implicit notify". Note: The GPE is assumed to be 368 * level-triggered (for windows compatibility). 369 */ 370 if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == 371 ACPI_GPE_DISPATCH_NONE) 372 { 373 /* 374 * This is the first device for implicit notify on this GPE. 375 * Just set the flags here, and enter the NOTIFY block below. 376 */ 377 GpeEventInfo->Flags = 378 (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED); 379 } 380 381 /* 382 * If we already have an implicit notify on this GPE, add 383 * this device to the notify list. 384 */ 385 if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == 386 ACPI_GPE_DISPATCH_NOTIFY) 387 { 388 /* Ensure that the device is not already in the list */ 389 390 Notify = GpeEventInfo->Dispatch.NotifyList; 391 while (Notify) 392 { 393 if (Notify->DeviceNode == DeviceNode) 394 { 395 Status = AE_ALREADY_EXISTS; 396 goto UnlockAndExit; 397 } 398 Notify = Notify->Next; 399 } 400 401 /* Add this device to the notify list for this GPE */ 402 403 NewNotify->DeviceNode = DeviceNode; 404 NewNotify->Next = GpeEventInfo->Dispatch.NotifyList; 405 GpeEventInfo->Dispatch.NotifyList = NewNotify; 406 NewNotify = NULL; 407 } 408 409 /* Mark the GPE as a possible wake event */ 410 411 GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE; 412 Status = AE_OK; 413 414 415 UnlockAndExit: 416 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 417 418 /* Delete the notify object if it was not used above */ 419 420 if (NewNotify) 421 { 422 ACPI_FREE (NewNotify); 423 } 424 return_ACPI_STATUS (Status); 425 } 426 427 ACPI_EXPORT_SYMBOL (AcpiSetupGpeForWake) 428 429 430 /******************************************************************************* 431 * 432 * FUNCTION: AcpiSetGpeWakeMask 433 * 434 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 435 * GpeNumber - GPE level within the GPE block 436 * Action - Enable or Disable 437 * 438 * RETURN: Status 439 * 440 * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must 441 * already be marked as a WAKE GPE. 442 * 443 ******************************************************************************/ 444 445 ACPI_STATUS 446 AcpiSetGpeWakeMask ( 447 ACPI_HANDLE GpeDevice, 448 UINT32 GpeNumber, 449 UINT8 Action) 450 { 451 ACPI_STATUS Status = AE_OK; 452 ACPI_GPE_EVENT_INFO *GpeEventInfo; 453 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo; 454 ACPI_CPU_FLAGS Flags; 455 UINT32 RegisterBit; 456 457 458 ACPI_FUNCTION_TRACE (AcpiSetGpeWakeMask); 459 460 461 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 462 463 /* 464 * Ensure that we have a valid GPE number and that this GPE is in 465 * fact a wake GPE 466 */ 467 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 468 if (!GpeEventInfo) 469 { 470 Status = AE_BAD_PARAMETER; 471 goto UnlockAndExit; 472 } 473 474 if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE)) 475 { 476 Status = AE_TYPE; 477 goto UnlockAndExit; 478 } 479 480 GpeRegisterInfo = GpeEventInfo->RegisterInfo; 481 if (!GpeRegisterInfo) 482 { 483 Status = AE_NOT_EXIST; 484 goto UnlockAndExit; 485 } 486 487 RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo); 488 489 /* Perform the action */ 490 491 switch (Action) 492 { 493 case ACPI_GPE_ENABLE: 494 495 ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit); 496 break; 497 498 case ACPI_GPE_DISABLE: 499 500 ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit); 501 break; 502 503 default: 504 505 ACPI_ERROR ((AE_INFO, "%u, Invalid action", Action)); 506 Status = AE_BAD_PARAMETER; 507 break; 508 } 509 510 UnlockAndExit: 511 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 512 return_ACPI_STATUS (Status); 513 } 514 515 ACPI_EXPORT_SYMBOL (AcpiSetGpeWakeMask) 516 517 518 /******************************************************************************* 519 * 520 * FUNCTION: AcpiClearGpe 521 * 522 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 523 * GpeNumber - GPE level within the GPE block 524 * 525 * RETURN: Status 526 * 527 * DESCRIPTION: Clear an ACPI event (general purpose) 528 * 529 ******************************************************************************/ 530 531 ACPI_STATUS 532 AcpiClearGpe ( 533 ACPI_HANDLE GpeDevice, 534 UINT32 GpeNumber) 535 { 536 ACPI_STATUS Status = AE_OK; 537 ACPI_GPE_EVENT_INFO *GpeEventInfo; 538 ACPI_CPU_FLAGS Flags; 539 540 541 ACPI_FUNCTION_TRACE (AcpiClearGpe); 542 543 544 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 545 546 /* Ensure that we have a valid GPE number */ 547 548 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 549 if (!GpeEventInfo) 550 { 551 Status = AE_BAD_PARAMETER; 552 goto UnlockAndExit; 553 } 554 555 Status = AcpiHwClearGpe (GpeEventInfo); 556 557 UnlockAndExit: 558 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 559 return_ACPI_STATUS (Status); 560 } 561 562 ACPI_EXPORT_SYMBOL (AcpiClearGpe) 563 564 565 /******************************************************************************* 566 * 567 * FUNCTION: AcpiGetGpeStatus 568 * 569 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 570 * GpeNumber - GPE level within the GPE block 571 * EventStatus - Where the current status of the event 572 * will be returned 573 * 574 * RETURN: Status 575 * 576 * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled) 577 * 578 ******************************************************************************/ 579 580 ACPI_STATUS 581 AcpiGetGpeStatus ( 582 ACPI_HANDLE GpeDevice, 583 UINT32 GpeNumber, 584 ACPI_EVENT_STATUS *EventStatus) 585 { 586 ACPI_STATUS Status = AE_OK; 587 ACPI_GPE_EVENT_INFO *GpeEventInfo; 588 ACPI_CPU_FLAGS Flags; 589 590 591 ACPI_FUNCTION_TRACE (AcpiGetGpeStatus); 592 593 594 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 595 596 /* Ensure that we have a valid GPE number */ 597 598 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 599 if (!GpeEventInfo) 600 { 601 Status = AE_BAD_PARAMETER; 602 goto UnlockAndExit; 603 } 604 605 /* Obtain status on the requested GPE number */ 606 607 Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus); 608 609 UnlockAndExit: 610 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 611 return_ACPI_STATUS (Status); 612 } 613 614 ACPI_EXPORT_SYMBOL (AcpiGetGpeStatus) 615 616 617 /******************************************************************************* 618 * 619 * FUNCTION: AcpiFinishGpe 620 * 621 * PARAMETERS: GpeDevice - Namespace node for the GPE Block 622 * (NULL for FADT defined GPEs) 623 * GpeNumber - GPE level within the GPE block 624 * 625 * RETURN: Status 626 * 627 * DESCRIPTION: Clear and conditionally reenable a GPE. This completes the GPE 628 * processing. Intended for use by asynchronous host-installed 629 * GPE handlers. The GPE is only reenabled if the EnableForRun bit 630 * is set in the GPE info. 631 * 632 ******************************************************************************/ 633 634 ACPI_STATUS 635 AcpiFinishGpe ( 636 ACPI_HANDLE GpeDevice, 637 UINT32 GpeNumber) 638 { 639 ACPI_GPE_EVENT_INFO *GpeEventInfo; 640 ACPI_STATUS Status; 641 ACPI_CPU_FLAGS Flags; 642 643 644 ACPI_FUNCTION_TRACE (AcpiFinishGpe); 645 646 647 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 648 649 /* Ensure that we have a valid GPE number */ 650 651 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 652 if (!GpeEventInfo) 653 { 654 Status = AE_BAD_PARAMETER; 655 goto UnlockAndExit; 656 } 657 658 Status = AcpiEvFinishGpe (GpeEventInfo); 659 660 UnlockAndExit: 661 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 662 return_ACPI_STATUS (Status); 663 } 664 665 ACPI_EXPORT_SYMBOL (AcpiFinishGpe) 666 667 668 /****************************************************************************** 669 * 670 * FUNCTION: AcpiDisableAllGpes 671 * 672 * PARAMETERS: None 673 * 674 * RETURN: Status 675 * 676 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks 677 * 678 ******************************************************************************/ 679 680 ACPI_STATUS 681 AcpiDisableAllGpes ( 682 void) 683 { 684 ACPI_STATUS Status; 685 686 687 ACPI_FUNCTION_TRACE (AcpiDisableAllGpes); 688 689 690 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 691 if (ACPI_FAILURE (Status)) 692 { 693 return_ACPI_STATUS (Status); 694 } 695 696 Status = AcpiHwDisableAllGpes (); 697 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 698 699 return_ACPI_STATUS (Status); 700 } 701 702 ACPI_EXPORT_SYMBOL (AcpiDisableAllGpes) 703 704 705 /****************************************************************************** 706 * 707 * FUNCTION: AcpiEnableAllRuntimeGpes 708 * 709 * PARAMETERS: None 710 * 711 * RETURN: Status 712 * 713 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks 714 * 715 ******************************************************************************/ 716 717 ACPI_STATUS 718 AcpiEnableAllRuntimeGpes ( 719 void) 720 { 721 ACPI_STATUS Status; 722 723 724 ACPI_FUNCTION_TRACE (AcpiEnableAllRuntimeGpes); 725 726 727 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 728 if (ACPI_FAILURE (Status)) 729 { 730 return_ACPI_STATUS (Status); 731 } 732 733 Status = AcpiHwEnableAllRuntimeGpes (); 734 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 735 736 return_ACPI_STATUS (Status); 737 } 738 739 ACPI_EXPORT_SYMBOL (AcpiEnableAllRuntimeGpes) 740 741 742 /******************************************************************************* 743 * 744 * FUNCTION: AcpiInstallGpeBlock 745 * 746 * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device 747 * GpeBlockAddress - Address and SpaceID 748 * RegisterCount - Number of GPE register pairs in the block 749 * InterruptNumber - H/W interrupt for the block 750 * 751 * RETURN: Status 752 * 753 * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not 754 * enabled here. 755 * 756 ******************************************************************************/ 757 758 ACPI_STATUS 759 AcpiInstallGpeBlock ( 760 ACPI_HANDLE GpeDevice, 761 ACPI_GENERIC_ADDRESS *GpeBlockAddress, 762 UINT32 RegisterCount, 763 UINT32 InterruptNumber) 764 { 765 ACPI_STATUS Status; 766 ACPI_OPERAND_OBJECT *ObjDesc; 767 ACPI_NAMESPACE_NODE *Node; 768 ACPI_GPE_BLOCK_INFO *GpeBlock; 769 770 771 ACPI_FUNCTION_TRACE (AcpiInstallGpeBlock); 772 773 774 if ((!GpeDevice) || 775 (!GpeBlockAddress) || 776 (!RegisterCount)) 777 { 778 return_ACPI_STATUS (AE_BAD_PARAMETER); 779 } 780 781 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 782 if (ACPI_FAILURE (Status)) 783 { 784 return_ACPI_STATUS (Status); 785 } 786 787 Node = AcpiNsValidateHandle (GpeDevice); 788 if (!Node) 789 { 790 Status = AE_BAD_PARAMETER; 791 goto UnlockAndExit; 792 } 793 794 /* Validate the parent device */ 795 796 if (Node->Type != ACPI_TYPE_DEVICE) 797 { 798 Status = AE_TYPE; 799 goto UnlockAndExit; 800 } 801 802 if (Node->Object) 803 { 804 Status = AE_ALREADY_EXISTS; 805 goto UnlockAndExit; 806 } 807 808 /* 809 * For user-installed GPE Block Devices, the GpeBlockBaseNumber 810 * is always zero 811 */ 812 Status = AcpiEvCreateGpeBlock (Node, GpeBlockAddress, RegisterCount, 813 0, InterruptNumber, &GpeBlock); 814 if (ACPI_FAILURE (Status)) 815 { 816 goto UnlockAndExit; 817 } 818 819 /* Install block in the DeviceObject attached to the node */ 820 821 ObjDesc = AcpiNsGetAttachedObject (Node); 822 if (!ObjDesc) 823 { 824 /* 825 * No object, create a new one (Device nodes do not always have 826 * an attached object) 827 */ 828 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_DEVICE); 829 if (!ObjDesc) 830 { 831 Status = AE_NO_MEMORY; 832 goto UnlockAndExit; 833 } 834 835 Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_DEVICE); 836 837 /* Remove local reference to the object */ 838 839 AcpiUtRemoveReference (ObjDesc); 840 if (ACPI_FAILURE (Status)) 841 { 842 goto UnlockAndExit; 843 } 844 } 845 846 /* Now install the GPE block in the DeviceObject */ 847 848 ObjDesc->Device.GpeBlock = GpeBlock; 849 850 851 UnlockAndExit: 852 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 853 return_ACPI_STATUS (Status); 854 } 855 856 ACPI_EXPORT_SYMBOL (AcpiInstallGpeBlock) 857 858 859 /******************************************************************************* 860 * 861 * FUNCTION: AcpiRemoveGpeBlock 862 * 863 * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device 864 * 865 * RETURN: Status 866 * 867 * DESCRIPTION: Remove a previously installed block of GPE registers 868 * 869 ******************************************************************************/ 870 871 ACPI_STATUS 872 AcpiRemoveGpeBlock ( 873 ACPI_HANDLE GpeDevice) 874 { 875 ACPI_OPERAND_OBJECT *ObjDesc; 876 ACPI_STATUS Status; 877 ACPI_NAMESPACE_NODE *Node; 878 879 880 ACPI_FUNCTION_TRACE (AcpiRemoveGpeBlock); 881 882 883 if (!GpeDevice) 884 { 885 return_ACPI_STATUS (AE_BAD_PARAMETER); 886 } 887 888 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 889 if (ACPI_FAILURE (Status)) 890 { 891 return_ACPI_STATUS (Status); 892 } 893 894 Node = AcpiNsValidateHandle (GpeDevice); 895 if (!Node) 896 { 897 Status = AE_BAD_PARAMETER; 898 goto UnlockAndExit; 899 } 900 901 /* Validate the parent device */ 902 903 if (Node->Type != ACPI_TYPE_DEVICE) 904 { 905 Status = AE_TYPE; 906 goto UnlockAndExit; 907 } 908 909 /* Get the DeviceObject attached to the node */ 910 911 ObjDesc = AcpiNsGetAttachedObject (Node); 912 if (!ObjDesc || 913 !ObjDesc->Device.GpeBlock) 914 { 915 return_ACPI_STATUS (AE_NULL_OBJECT); 916 } 917 918 /* Delete the GPE block (but not the DeviceObject) */ 919 920 Status = AcpiEvDeleteGpeBlock (ObjDesc->Device.GpeBlock); 921 if (ACPI_SUCCESS (Status)) 922 { 923 ObjDesc->Device.GpeBlock = NULL; 924 } 925 926 UnlockAndExit: 927 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 928 return_ACPI_STATUS (Status); 929 } 930 931 ACPI_EXPORT_SYMBOL (AcpiRemoveGpeBlock) 932 933 934 /******************************************************************************* 935 * 936 * FUNCTION: AcpiGetGpeDevice 937 * 938 * PARAMETERS: Index - System GPE index (0-CurrentGpeCount) 939 * GpeDevice - Where the parent GPE Device is returned 940 * 941 * RETURN: Status 942 * 943 * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL 944 * gpe device indicates that the gpe number is contained in one of 945 * the FADT-defined gpe blocks. Otherwise, the GPE block device. 946 * 947 ******************************************************************************/ 948 949 ACPI_STATUS 950 AcpiGetGpeDevice ( 951 UINT32 Index, 952 ACPI_HANDLE *GpeDevice) 953 { 954 ACPI_GPE_DEVICE_INFO Info; 955 ACPI_STATUS Status; 956 957 958 ACPI_FUNCTION_TRACE (AcpiGetGpeDevice); 959 960 961 if (!GpeDevice) 962 { 963 return_ACPI_STATUS (AE_BAD_PARAMETER); 964 } 965 966 if (Index >= AcpiCurrentGpeCount) 967 { 968 return_ACPI_STATUS (AE_NOT_EXIST); 969 } 970 971 /* Setup and walk the GPE list */ 972 973 Info.Index = Index; 974 Info.Status = AE_NOT_EXIST; 975 Info.GpeDevice = NULL; 976 Info.NextBlockBaseIndex = 0; 977 978 Status = AcpiEvWalkGpeList (AcpiEvGetGpeDevice, &Info); 979 if (ACPI_FAILURE (Status)) 980 { 981 return_ACPI_STATUS (Status); 982 } 983 984 *GpeDevice = ACPI_CAST_PTR (ACPI_HANDLE, Info.GpeDevice); 985 return_ACPI_STATUS (Info.Status); 986 } 987 988 ACPI_EXPORT_SYMBOL (AcpiGetGpeDevice) 989 990 #endif /* !ACPI_REDUCED_HARDWARE */