1 /****************************************************************************** 2 * 3 * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs) 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2012, 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 Status = AcpiEvEnableGpe (GpeEventInfo); 254 break; 255 256 case ACPI_GPE_DISABLE: 257 Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE); 258 break; 259 260 default: 261 Status = AE_BAD_PARAMETER; 262 break; 263 } 264 265 UnlockAndExit: 266 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 267 return_ACPI_STATUS (Status); 268 } 269 270 ACPI_EXPORT_SYMBOL (AcpiSetGpe) 271 272 273 /******************************************************************************* 274 * 275 * FUNCTION: AcpiSetupGpeForWake 276 * 277 * PARAMETERS: WakeDevice - Device associated with the GPE (via _PRW) 278 * GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 279 * GpeNumber - GPE level within the GPE block 280 * 281 * RETURN: Status 282 * 283 * DESCRIPTION: Mark a GPE as having the ability to wake the system. This 284 * interface is intended to be used as the host executes the 285 * _PRW methods (Power Resources for Wake) in the system tables. 286 * Each _PRW appears under a Device Object (The WakeDevice), and 287 * contains the info for the wake GPE associated with the 288 * WakeDevice. 289 * 290 ******************************************************************************/ 291 292 ACPI_STATUS 293 AcpiSetupGpeForWake ( 294 ACPI_HANDLE WakeDevice, 295 ACPI_HANDLE GpeDevice, 296 UINT32 GpeNumber) 297 { 298 ACPI_STATUS Status; 299 ACPI_GPE_EVENT_INFO *GpeEventInfo; 300 ACPI_NAMESPACE_NODE *DeviceNode; 301 ACPI_GPE_NOTIFY_INFO *Notify; 302 ACPI_GPE_NOTIFY_INFO *NewNotify; 303 ACPI_CPU_FLAGS Flags; 304 305 306 ACPI_FUNCTION_TRACE (AcpiSetupGpeForWake); 307 308 309 /* Parameter Validation */ 310 311 if (!WakeDevice) 312 { 313 /* 314 * By forcing WakeDevice to be valid, we automatically enable the 315 * implicit notify feature on all hosts. 316 */ 317 return_ACPI_STATUS (AE_BAD_PARAMETER); 318 } 319 320 /* Handle root object case */ 321 322 if (WakeDevice == ACPI_ROOT_OBJECT) 323 { 324 DeviceNode = AcpiGbl_RootNode; 325 } 326 else 327 { 328 DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, WakeDevice); 329 } 330 331 /* Validate WakeDevice is of type Device */ 332 333 if (DeviceNode->Type != ACPI_TYPE_DEVICE) 334 { 335 return_ACPI_STATUS (AE_BAD_PARAMETER); 336 } 337 338 /* 339 * Allocate a new notify object up front, in case it is needed. 340 * Memory allocation while holding a spinlock is a big no-no 341 * on some hosts. 342 */ 343 NewNotify = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_NOTIFY_INFO)); 344 if (!NewNotify) 345 { 346 return_ACPI_STATUS (AE_NO_MEMORY); 347 } 348 349 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 350 351 /* Ensure that we have a valid GPE number */ 352 353 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 354 if (!GpeEventInfo) 355 { 356 Status = AE_BAD_PARAMETER; 357 goto UnlockAndExit; 358 } 359 360 /* 361 * If there is no method or handler for this GPE, then the 362 * WakeDevice will be notified whenever this GPE fires. This is 363 * known as an "implicit notify". Note: The GPE is assumed to be 364 * level-triggered (for windows compatibility). 365 */ 366 if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == 367 ACPI_GPE_DISPATCH_NONE) 368 { 369 /* 370 * This is the first device for implicit notify on this GPE. 371 * Just set the flags here, and enter the NOTIFY block below. 372 */ 373 GpeEventInfo->Flags = 374 (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED); 375 } 376 377 /* 378 * If we already have an implicit notify on this GPE, add 379 * this device to the notify list. 380 */ 381 if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == 382 ACPI_GPE_DISPATCH_NOTIFY) 383 { 384 /* Ensure that the device is not already in the list */ 385 386 Notify = GpeEventInfo->Dispatch.NotifyList; 387 while (Notify) 388 { 389 if (Notify->DeviceNode == DeviceNode) 390 { 391 Status = AE_ALREADY_EXISTS; 392 goto UnlockAndExit; 393 } 394 Notify = Notify->Next; 395 } 396 397 /* Add this device to the notify list for this GPE */ 398 399 NewNotify->DeviceNode = DeviceNode; 400 NewNotify->Next = GpeEventInfo->Dispatch.NotifyList; 401 GpeEventInfo->Dispatch.NotifyList = NewNotify; 402 NewNotify = NULL; 403 } 404 405 /* Mark the GPE as a possible wake event */ 406 407 GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE; 408 Status = AE_OK; 409 410 411 UnlockAndExit: 412 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 413 414 /* Delete the notify object if it was not used above */ 415 416 if (NewNotify) 417 { 418 ACPI_FREE (NewNotify); 419 } 420 return_ACPI_STATUS (Status); 421 } 422 423 ACPI_EXPORT_SYMBOL (AcpiSetupGpeForWake) 424 425 426 /******************************************************************************* 427 * 428 * FUNCTION: AcpiSetGpeWakeMask 429 * 430 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 431 * GpeNumber - GPE level within the GPE block 432 * Action - Enable or Disable 433 * 434 * RETURN: Status 435 * 436 * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must 437 * already be marked as a WAKE GPE. 438 * 439 ******************************************************************************/ 440 441 ACPI_STATUS 442 AcpiSetGpeWakeMask ( 443 ACPI_HANDLE GpeDevice, 444 UINT32 GpeNumber, 445 UINT8 Action) 446 { 447 ACPI_STATUS Status = AE_OK; 448 ACPI_GPE_EVENT_INFO *GpeEventInfo; 449 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo; 450 ACPI_CPU_FLAGS Flags; 451 UINT32 RegisterBit; 452 453 454 ACPI_FUNCTION_TRACE (AcpiSetGpeWakeMask); 455 456 457 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 458 459 /* 460 * Ensure that we have a valid GPE number and that this GPE is in 461 * fact a wake GPE 462 */ 463 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 464 if (!GpeEventInfo) 465 { 466 Status = AE_BAD_PARAMETER; 467 goto UnlockAndExit; 468 } 469 470 if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE)) 471 { 472 Status = AE_TYPE; 473 goto UnlockAndExit; 474 } 475 476 GpeRegisterInfo = GpeEventInfo->RegisterInfo; 477 if (!GpeRegisterInfo) 478 { 479 Status = AE_NOT_EXIST; 480 goto UnlockAndExit; 481 } 482 483 RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo); 484 485 /* Perform the action */ 486 487 switch (Action) 488 { 489 case ACPI_GPE_ENABLE: 490 ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit); 491 break; 492 493 case ACPI_GPE_DISABLE: 494 ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit); 495 break; 496 497 default: 498 ACPI_ERROR ((AE_INFO, "%u, Invalid action", Action)); 499 Status = AE_BAD_PARAMETER; 500 break; 501 } 502 503 UnlockAndExit: 504 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 505 return_ACPI_STATUS (Status); 506 } 507 508 ACPI_EXPORT_SYMBOL (AcpiSetGpeWakeMask) 509 510 511 /******************************************************************************* 512 * 513 * FUNCTION: AcpiClearGpe 514 * 515 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 516 * GpeNumber - GPE level within the GPE block 517 * 518 * RETURN: Status 519 * 520 * DESCRIPTION: Clear an ACPI event (general purpose) 521 * 522 ******************************************************************************/ 523 524 ACPI_STATUS 525 AcpiClearGpe ( 526 ACPI_HANDLE GpeDevice, 527 UINT32 GpeNumber) 528 { 529 ACPI_STATUS Status = AE_OK; 530 ACPI_GPE_EVENT_INFO *GpeEventInfo; 531 ACPI_CPU_FLAGS Flags; 532 533 534 ACPI_FUNCTION_TRACE (AcpiClearGpe); 535 536 537 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 538 539 /* Ensure that we have a valid GPE number */ 540 541 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 542 if (!GpeEventInfo) 543 { 544 Status = AE_BAD_PARAMETER; 545 goto UnlockAndExit; 546 } 547 548 Status = AcpiHwClearGpe (GpeEventInfo); 549 550 UnlockAndExit: 551 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 552 return_ACPI_STATUS (Status); 553 } 554 555 ACPI_EXPORT_SYMBOL (AcpiClearGpe) 556 557 558 /******************************************************************************* 559 * 560 * FUNCTION: AcpiGetGpeStatus 561 * 562 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 563 * GpeNumber - GPE level within the GPE block 564 * EventStatus - Where the current status of the event 565 * will be returned 566 * 567 * RETURN: Status 568 * 569 * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled) 570 * 571 ******************************************************************************/ 572 573 ACPI_STATUS 574 AcpiGetGpeStatus ( 575 ACPI_HANDLE GpeDevice, 576 UINT32 GpeNumber, 577 ACPI_EVENT_STATUS *EventStatus) 578 { 579 ACPI_STATUS Status = AE_OK; 580 ACPI_GPE_EVENT_INFO *GpeEventInfo; 581 ACPI_CPU_FLAGS Flags; 582 583 584 ACPI_FUNCTION_TRACE (AcpiGetGpeStatus); 585 586 587 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 588 589 /* Ensure that we have a valid GPE number */ 590 591 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 592 if (!GpeEventInfo) 593 { 594 Status = AE_BAD_PARAMETER; 595 goto UnlockAndExit; 596 } 597 598 /* Obtain status on the requested GPE number */ 599 600 Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus); 601 602 UnlockAndExit: 603 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 604 return_ACPI_STATUS (Status); 605 } 606 607 ACPI_EXPORT_SYMBOL (AcpiGetGpeStatus) 608 609 610 /******************************************************************************* 611 * 612 * FUNCTION: AcpiFinishGpe 613 * 614 * PARAMETERS: GpeDevice - Namespace node for the GPE Block 615 * (NULL for FADT defined GPEs) 616 * GpeNumber - GPE level within the GPE block 617 * 618 * RETURN: Status 619 * 620 * DESCRIPTION: Clear and conditionally reenable a GPE. This completes the GPE 621 * processing. Intended for use by asynchronous host-installed 622 * GPE handlers. The GPE is only reenabled if the EnableForRun bit 623 * is set in the GPE info. 624 * 625 ******************************************************************************/ 626 627 ACPI_STATUS 628 AcpiFinishGpe ( 629 ACPI_HANDLE GpeDevice, 630 UINT32 GpeNumber) 631 { 632 ACPI_GPE_EVENT_INFO *GpeEventInfo; 633 ACPI_STATUS Status; 634 ACPI_CPU_FLAGS Flags; 635 636 637 ACPI_FUNCTION_TRACE (AcpiFinishGpe); 638 639 640 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 641 642 /* Ensure that we have a valid GPE number */ 643 644 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 645 if (!GpeEventInfo) 646 { 647 Status = AE_BAD_PARAMETER; 648 goto UnlockAndExit; 649 } 650 651 Status = AcpiEvFinishGpe (GpeEventInfo); 652 653 UnlockAndExit: 654 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 655 return_ACPI_STATUS (Status); 656 } 657 658 ACPI_EXPORT_SYMBOL (AcpiFinishGpe) 659 660 661 /****************************************************************************** 662 * 663 * FUNCTION: AcpiDisableAllGpes 664 * 665 * PARAMETERS: None 666 * 667 * RETURN: Status 668 * 669 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks 670 * 671 ******************************************************************************/ 672 673 ACPI_STATUS 674 AcpiDisableAllGpes ( 675 void) 676 { 677 ACPI_STATUS Status; 678 679 680 ACPI_FUNCTION_TRACE (AcpiDisableAllGpes); 681 682 683 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 684 if (ACPI_FAILURE (Status)) 685 { 686 return_ACPI_STATUS (Status); 687 } 688 689 Status = AcpiHwDisableAllGpes (); 690 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 691 692 return_ACPI_STATUS (Status); 693 } 694 695 ACPI_EXPORT_SYMBOL (AcpiDisableAllGpes) 696 697 698 /****************************************************************************** 699 * 700 * FUNCTION: AcpiEnableAllRuntimeGpes 701 * 702 * PARAMETERS: None 703 * 704 * RETURN: Status 705 * 706 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks 707 * 708 ******************************************************************************/ 709 710 ACPI_STATUS 711 AcpiEnableAllRuntimeGpes ( 712 void) 713 { 714 ACPI_STATUS Status; 715 716 717 ACPI_FUNCTION_TRACE (AcpiEnableAllRuntimeGpes); 718 719 720 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 721 if (ACPI_FAILURE (Status)) 722 { 723 return_ACPI_STATUS (Status); 724 } 725 726 Status = AcpiHwEnableAllRuntimeGpes (); 727 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 728 729 return_ACPI_STATUS (Status); 730 } 731 732 ACPI_EXPORT_SYMBOL (AcpiEnableAllRuntimeGpes) 733 734 735 /******************************************************************************* 736 * 737 * FUNCTION: AcpiInstallGpeBlock 738 * 739 * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device 740 * GpeBlockAddress - Address and SpaceID 741 * RegisterCount - Number of GPE register pairs in the block 742 * InterruptNumber - H/W interrupt for the block 743 * 744 * RETURN: Status 745 * 746 * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not 747 * enabled here. 748 * 749 ******************************************************************************/ 750 751 ACPI_STATUS 752 AcpiInstallGpeBlock ( 753 ACPI_HANDLE GpeDevice, 754 ACPI_GENERIC_ADDRESS *GpeBlockAddress, 755 UINT32 RegisterCount, 756 UINT32 InterruptNumber) 757 { 758 ACPI_STATUS Status; 759 ACPI_OPERAND_OBJECT *ObjDesc; 760 ACPI_NAMESPACE_NODE *Node; 761 ACPI_GPE_BLOCK_INFO *GpeBlock; 762 763 764 ACPI_FUNCTION_TRACE (AcpiInstallGpeBlock); 765 766 767 if ((!GpeDevice) || 768 (!GpeBlockAddress) || 769 (!RegisterCount)) 770 { 771 return_ACPI_STATUS (AE_BAD_PARAMETER); 772 } 773 774 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 775 if (ACPI_FAILURE (Status)) 776 { 777 return_ACPI_STATUS (Status); 778 } 779 780 Node = AcpiNsValidateHandle (GpeDevice); 781 if (!Node) 782 { 783 Status = AE_BAD_PARAMETER; 784 goto UnlockAndExit; 785 } 786 787 /* 788 * For user-installed GPE Block Devices, the GpeBlockBaseNumber 789 * is always zero 790 */ 791 Status = AcpiEvCreateGpeBlock (Node, GpeBlockAddress, RegisterCount, 792 0, InterruptNumber, &GpeBlock); 793 if (ACPI_FAILURE (Status)) 794 { 795 goto UnlockAndExit; 796 } 797 798 /* Install block in the DeviceObject attached to the node */ 799 800 ObjDesc = AcpiNsGetAttachedObject (Node); 801 if (!ObjDesc) 802 { 803 /* 804 * No object, create a new one (Device nodes do not always have 805 * an attached object) 806 */ 807 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_DEVICE); 808 if (!ObjDesc) 809 { 810 Status = AE_NO_MEMORY; 811 goto UnlockAndExit; 812 } 813 814 Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_DEVICE); 815 816 /* Remove local reference to the object */ 817 818 AcpiUtRemoveReference (ObjDesc); 819 if (ACPI_FAILURE (Status)) 820 { 821 goto UnlockAndExit; 822 } 823 } 824 825 /* Now install the GPE block in the DeviceObject */ 826 827 ObjDesc->Device.GpeBlock = GpeBlock; 828 829 830 UnlockAndExit: 831 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 832 return_ACPI_STATUS (Status); 833 } 834 835 ACPI_EXPORT_SYMBOL (AcpiInstallGpeBlock) 836 837 838 /******************************************************************************* 839 * 840 * FUNCTION: AcpiRemoveGpeBlock 841 * 842 * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device 843 * 844 * RETURN: Status 845 * 846 * DESCRIPTION: Remove a previously installed block of GPE registers 847 * 848 ******************************************************************************/ 849 850 ACPI_STATUS 851 AcpiRemoveGpeBlock ( 852 ACPI_HANDLE GpeDevice) 853 { 854 ACPI_OPERAND_OBJECT *ObjDesc; 855 ACPI_STATUS Status; 856 ACPI_NAMESPACE_NODE *Node; 857 858 859 ACPI_FUNCTION_TRACE (AcpiRemoveGpeBlock); 860 861 862 if (!GpeDevice) 863 { 864 return_ACPI_STATUS (AE_BAD_PARAMETER); 865 } 866 867 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 868 if (ACPI_FAILURE (Status)) 869 { 870 return_ACPI_STATUS (Status); 871 } 872 873 Node = AcpiNsValidateHandle (GpeDevice); 874 if (!Node) 875 { 876 Status = AE_BAD_PARAMETER; 877 goto UnlockAndExit; 878 } 879 880 /* Get the DeviceObject attached to the node */ 881 882 ObjDesc = AcpiNsGetAttachedObject (Node); 883 if (!ObjDesc || 884 !ObjDesc->Device.GpeBlock) 885 { 886 return_ACPI_STATUS (AE_NULL_OBJECT); 887 } 888 889 /* Delete the GPE block (but not the DeviceObject) */ 890 891 Status = AcpiEvDeleteGpeBlock (ObjDesc->Device.GpeBlock); 892 if (ACPI_SUCCESS (Status)) 893 { 894 ObjDesc->Device.GpeBlock = NULL; 895 } 896 897 UnlockAndExit: 898 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 899 return_ACPI_STATUS (Status); 900 } 901 902 ACPI_EXPORT_SYMBOL (AcpiRemoveGpeBlock) 903 904 905 /******************************************************************************* 906 * 907 * FUNCTION: AcpiGetGpeDevice 908 * 909 * PARAMETERS: Index - System GPE index (0-CurrentGpeCount) 910 * GpeDevice - Where the parent GPE Device is returned 911 * 912 * RETURN: Status 913 * 914 * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL 915 * gpe device indicates that the gpe number is contained in one of 916 * the FADT-defined gpe blocks. Otherwise, the GPE block device. 917 * 918 ******************************************************************************/ 919 920 ACPI_STATUS 921 AcpiGetGpeDevice ( 922 UINT32 Index, 923 ACPI_HANDLE *GpeDevice) 924 { 925 ACPI_GPE_DEVICE_INFO Info; 926 ACPI_STATUS Status; 927 928 929 ACPI_FUNCTION_TRACE (AcpiGetGpeDevice); 930 931 932 if (!GpeDevice) 933 { 934 return_ACPI_STATUS (AE_BAD_PARAMETER); 935 } 936 937 if (Index >= AcpiCurrentGpeCount) 938 { 939 return_ACPI_STATUS (AE_NOT_EXIST); 940 } 941 942 /* Setup and walk the GPE list */ 943 944 Info.Index = Index; 945 Info.Status = AE_NOT_EXIST; 946 Info.GpeDevice = NULL; 947 Info.NextBlockBaseIndex = 0; 948 949 Status = AcpiEvWalkGpeList (AcpiEvGetGpeDevice, &Info); 950 if (ACPI_FAILURE (Status)) 951 { 952 return_ACPI_STATUS (Status); 953 } 954 955 *GpeDevice = ACPI_CAST_PTR (ACPI_HANDLE, Info.GpeDevice); 956 return_ACPI_STATUS (Info.Status); 957 } 958 959 ACPI_EXPORT_SYMBOL (AcpiGetGpeDevice) 960 961 #endif /* !ACPI_REDUCED_HARDWARE */ 962