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