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