Home | History | Annotate | Line # | Download | only in hardware
hwgpe.c revision 1.1
      1 
      2 /******************************************************************************
      3  *
      4  * Module Name: hwgpe - Low level GPE enable/disable/clear functions
      5  *
      6  *****************************************************************************/
      7 
      8 /******************************************************************************
      9  *
     10  * 1. Copyright Notice
     11  *
     12  * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
     13  * All rights reserved.
     14  *
     15  * 2. License
     16  *
     17  * 2.1. This is your license from Intel Corp. under its intellectual property
     18  * rights.  You may have additional license terms from the party that provided
     19  * you this software, covering your right to use that party's intellectual
     20  * property rights.
     21  *
     22  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
     23  * copy of the source code appearing in this file ("Covered Code") an
     24  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
     25  * base code distributed originally by Intel ("Original Intel Code") to copy,
     26  * make derivatives, distribute, use and display any portion of the Covered
     27  * Code in any form, with the right to sublicense such rights; and
     28  *
     29  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
     30  * license (with the right to sublicense), under only those claims of Intel
     31  * patents that are infringed by the Original Intel Code, to make, use, sell,
     32  * offer to sell, and import the Covered Code and derivative works thereof
     33  * solely to the minimum extent necessary to exercise the above copyright
     34  * license, and in no event shall the patent license extend to any additions
     35  * to or modifications of the Original Intel Code.  No other license or right
     36  * is granted directly or by implication, estoppel or otherwise;
     37  *
     38  * The above copyright and patent license is granted only if the following
     39  * conditions are met:
     40  *
     41  * 3. Conditions
     42  *
     43  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
     44  * Redistribution of source code of any substantial portion of the Covered
     45  * Code or modification with rights to further distribute source must include
     46  * the above Copyright Notice, the above License, this list of Conditions,
     47  * and the following Disclaimer and Export Compliance provision.  In addition,
     48  * Licensee must cause all Covered Code to which Licensee contributes to
     49  * contain a file documenting the changes Licensee made to create that Covered
     50  * Code and the date of any change.  Licensee must include in that file the
     51  * documentation of any changes made by any predecessor Licensee.  Licensee
     52  * must include a prominent statement that the modification is derived,
     53  * directly or indirectly, from Original Intel Code.
     54  *
     55  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
     56  * Redistribution of source code of any substantial portion of the Covered
     57  * Code or modification without rights to further distribute source must
     58  * include the following Disclaimer and Export Compliance provision in the
     59  * documentation and/or other materials provided with distribution.  In
     60  * addition, Licensee may not authorize further sublicense of source of any
     61  * portion of the Covered Code, and must include terms to the effect that the
     62  * license from Licensee to its licensee is limited to the intellectual
     63  * property embodied in the software Licensee provides to its licensee, and
     64  * not to intellectual property embodied in modifications its licensee may
     65  * make.
     66  *
     67  * 3.3. Redistribution of Executable. Redistribution in executable form of any
     68  * substantial portion of the Covered Code or modification must reproduce the
     69  * above Copyright Notice, and the following Disclaimer and Export Compliance
     70  * provision in the documentation and/or other materials provided with the
     71  * distribution.
     72  *
     73  * 3.4. Intel retains all right, title, and interest in and to the Original
     74  * Intel Code.
     75  *
     76  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
     77  * Intel shall be used in advertising or otherwise to promote the sale, use or
     78  * other dealings in products derived from or relating to the Covered Code
     79  * without prior written authorization from Intel.
     80  *
     81  * 4. Disclaimer and Export Compliance
     82  *
     83  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
     84  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
     85  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
     86  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
     87  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
     88  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
     89  * PARTICULAR PURPOSE.
     90  *
     91  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
     92  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
     93  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
     94  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
     95  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
     96  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
     97  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
     98  * LIMITED REMEDY.
     99  *
    100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
    101  * software or system incorporating such software without first obtaining any
    102  * required license or other approval from the U. S. Department of Commerce or
    103  * any other agency or department of the United States Government.  In the
    104  * event Licensee exports any such software from the United States or
    105  * re-exports any such software from a foreign destination, Licensee shall
    106  * ensure that the distribution and export/re-export of the software is in
    107  * compliance with all laws, regulations, orders, or other restrictions of the
    108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
    109  * any of its subsidiaries will export/re-export any technical data, process,
    110  * software, or service, directly or indirectly, to any country for which the
    111  * United States government or any agency thereof requires an export license,
    112  * other governmental approval, or letter of assurance, without first obtaining
    113  * such license, approval or letter.
    114  *
    115  *****************************************************************************/
    116 
    117 #include "acpi.h"
    118 #include "accommon.h"
    119 #include "acevents.h"
    120 
    121 #define _COMPONENT          ACPI_HARDWARE
    122         ACPI_MODULE_NAME    ("hwgpe")
    123 
    124 /* Local prototypes */
    125 
    126 static ACPI_STATUS
    127 AcpiHwEnableWakeupGpeBlock (
    128     ACPI_GPE_XRUPT_INFO     *GpeXruptInfo,
    129     ACPI_GPE_BLOCK_INFO     *GpeBlock,
    130     void                    *Context);
    131 
    132 
    133 /******************************************************************************
    134  *
    135  * FUNCTION:    AcpiHwLowDisableGpe
    136  *
    137  * PARAMETERS:  GpeEventInfo        - Info block for the GPE to be disabled
    138  *
    139  * RETURN:      Status
    140  *
    141  * DESCRIPTION: Disable a single GPE in the enable register.
    142  *
    143  ******************************************************************************/
    144 
    145 ACPI_STATUS
    146 AcpiHwLowDisableGpe (
    147     ACPI_GPE_EVENT_INFO     *GpeEventInfo)
    148 {
    149     ACPI_GPE_REGISTER_INFO  *GpeRegisterInfo;
    150     ACPI_STATUS             Status;
    151     UINT32                  EnableMask;
    152 
    153 
    154     /* Get the info block for the entire GPE register */
    155 
    156     GpeRegisterInfo = GpeEventInfo->RegisterInfo;
    157     if (!GpeRegisterInfo)
    158     {
    159         return (AE_NOT_EXIST);
    160     }
    161 
    162     /* Get current value of the enable register that contains this GPE */
    163 
    164     Status = AcpiHwRead (&EnableMask, &GpeRegisterInfo->EnableAddress);
    165     if (ACPI_FAILURE (Status))
    166     {
    167         return (Status);
    168     }
    169 
    170     /* Clear just the bit that corresponds to this GPE */
    171 
    172     ACPI_CLEAR_BIT (EnableMask, ((UINT32) 1 <<
    173         (GpeEventInfo->GpeNumber - GpeRegisterInfo->BaseGpeNumber)));
    174 
    175 
    176     /* Write the updated enable mask */
    177 
    178     Status = AcpiHwWrite (EnableMask, &GpeRegisterInfo->EnableAddress);
    179     return (Status);
    180 }
    181 
    182 
    183 /******************************************************************************
    184  *
    185  * FUNCTION:    AcpiHwWriteGpeEnableReg
    186  *
    187  * PARAMETERS:  GpeEventInfo        - Info block for the GPE to be enabled
    188  *
    189  * RETURN:      Status
    190  *
    191  * DESCRIPTION: Write a GPE enable register.  Note: The bit for this GPE must
    192  *              already be cleared or set in the parent register
    193  *              EnableForRun mask.
    194  *
    195  ******************************************************************************/
    196 
    197 ACPI_STATUS
    198 AcpiHwWriteGpeEnableReg (
    199     ACPI_GPE_EVENT_INFO     *GpeEventInfo)
    200 {
    201     ACPI_GPE_REGISTER_INFO  *GpeRegisterInfo;
    202     ACPI_STATUS             Status;
    203 
    204 
    205     ACPI_FUNCTION_ENTRY ();
    206 
    207 
    208     /* Get the info block for the entire GPE register */
    209 
    210     GpeRegisterInfo = GpeEventInfo->RegisterInfo;
    211     if (!GpeRegisterInfo)
    212     {
    213         return (AE_NOT_EXIST);
    214     }
    215 
    216     /* Write the entire GPE (runtime) enable register */
    217 
    218     Status = AcpiHwWrite (GpeRegisterInfo->EnableForRun,
    219                     &GpeRegisterInfo->EnableAddress);
    220 
    221     return (Status);
    222 }
    223 
    224 
    225 /******************************************************************************
    226  *
    227  * FUNCTION:    AcpiHwClearGpe
    228  *
    229  * PARAMETERS:  GpeEventInfo        - Info block for the GPE to be cleared
    230  *
    231  * RETURN:      Status
    232  *
    233  * DESCRIPTION: Clear the status bit for a single GPE.
    234  *
    235  ******************************************************************************/
    236 
    237 ACPI_STATUS
    238 AcpiHwClearGpe (
    239     ACPI_GPE_EVENT_INFO     *GpeEventInfo)
    240 {
    241     ACPI_STATUS             Status;
    242     UINT8                   RegisterBit;
    243 
    244 
    245     ACPI_FUNCTION_ENTRY ();
    246 
    247 
    248     RegisterBit = (UINT8) (1 <<
    249         (GpeEventInfo->GpeNumber - GpeEventInfo->RegisterInfo->BaseGpeNumber));
    250 
    251     /*
    252      * Write a one to the appropriate bit in the status register to
    253      * clear this GPE.
    254      */
    255     Status = AcpiHwWrite (RegisterBit,
    256                     &GpeEventInfo->RegisterInfo->StatusAddress);
    257 
    258     return (Status);
    259 }
    260 
    261 
    262 /******************************************************************************
    263  *
    264  * FUNCTION:    AcpiHwGetGpeStatus
    265  *
    266  * PARAMETERS:  GpeEventInfo        - Info block for the GPE to queried
    267  *              EventStatus         - Where the GPE status is returned
    268  *
    269  * RETURN:      Status
    270  *
    271  * DESCRIPTION: Return the status of a single GPE.
    272  *
    273  ******************************************************************************/
    274 
    275 ACPI_STATUS
    276 AcpiHwGetGpeStatus (
    277     ACPI_GPE_EVENT_INFO     *GpeEventInfo,
    278     ACPI_EVENT_STATUS       *EventStatus)
    279 {
    280     UINT32                  InByte;
    281     UINT8                   RegisterBit;
    282     ACPI_GPE_REGISTER_INFO  *GpeRegisterInfo;
    283     ACPI_STATUS             Status;
    284     ACPI_EVENT_STATUS       LocalEventStatus = 0;
    285 
    286 
    287     ACPI_FUNCTION_ENTRY ();
    288 
    289 
    290     if (!EventStatus)
    291     {
    292         return (AE_BAD_PARAMETER);
    293     }
    294 
    295     /* Get the info block for the entire GPE register */
    296 
    297     GpeRegisterInfo = GpeEventInfo->RegisterInfo;
    298 
    299     /* Get the register bitmask for this GPE */
    300 
    301     RegisterBit = (UINT8) (1 <<
    302         (GpeEventInfo->GpeNumber - GpeEventInfo->RegisterInfo->BaseGpeNumber));
    303 
    304     /* GPE currently enabled? (enabled for runtime?) */
    305 
    306     if (RegisterBit & GpeRegisterInfo->EnableForRun)
    307     {
    308         LocalEventStatus |= ACPI_EVENT_FLAG_ENABLED;
    309     }
    310 
    311     /* GPE enabled for wake? */
    312 
    313     if (RegisterBit & GpeRegisterInfo->EnableForWake)
    314     {
    315         LocalEventStatus |= ACPI_EVENT_FLAG_WAKE_ENABLED;
    316     }
    317 
    318     /* GPE currently active (status bit == 1)? */
    319 
    320     Status = AcpiHwRead (&InByte, &GpeRegisterInfo->StatusAddress);
    321     if (ACPI_FAILURE (Status))
    322     {
    323         return (Status);
    324     }
    325 
    326     if (RegisterBit & InByte)
    327     {
    328         LocalEventStatus |= ACPI_EVENT_FLAG_SET;
    329     }
    330 
    331     /* Set return value */
    332 
    333     (*EventStatus) = LocalEventStatus;
    334     return (AE_OK);
    335 }
    336 
    337 
    338 /******************************************************************************
    339  *
    340  * FUNCTION:    AcpiHwDisableGpeBlock
    341  *
    342  * PARAMETERS:  GpeXruptInfo        - GPE Interrupt info
    343  *              GpeBlock            - Gpe Block info
    344  *
    345  * RETURN:      Status
    346  *
    347  * DESCRIPTION: Disable all GPEs within a single GPE block
    348  *
    349  ******************************************************************************/
    350 
    351 ACPI_STATUS
    352 AcpiHwDisableGpeBlock (
    353     ACPI_GPE_XRUPT_INFO     *GpeXruptInfo,
    354     ACPI_GPE_BLOCK_INFO     *GpeBlock,
    355     void                    *Context)
    356 {
    357     UINT32                  i;
    358     ACPI_STATUS             Status;
    359 
    360 
    361     /* Examine each GPE Register within the block */
    362 
    363     for (i = 0; i < GpeBlock->RegisterCount; i++)
    364     {
    365         /* Disable all GPEs in this register */
    366 
    367         Status = AcpiHwWrite (0x00, &GpeBlock->RegisterInfo[i].EnableAddress);
    368         if (ACPI_FAILURE (Status))
    369         {
    370             return (Status);
    371         }
    372     }
    373 
    374     return (AE_OK);
    375 }
    376 
    377 
    378 /******************************************************************************
    379  *
    380  * FUNCTION:    AcpiHwClearGpeBlock
    381  *
    382  * PARAMETERS:  GpeXruptInfo        - GPE Interrupt info
    383  *              GpeBlock            - Gpe Block info
    384  *
    385  * RETURN:      Status
    386  *
    387  * DESCRIPTION: Clear status bits for all GPEs within a single GPE block
    388  *
    389  ******************************************************************************/
    390 
    391 ACPI_STATUS
    392 AcpiHwClearGpeBlock (
    393     ACPI_GPE_XRUPT_INFO     *GpeXruptInfo,
    394     ACPI_GPE_BLOCK_INFO     *GpeBlock,
    395     void                    *Context)
    396 {
    397     UINT32                  i;
    398     ACPI_STATUS             Status;
    399 
    400 
    401     /* Examine each GPE Register within the block */
    402 
    403     for (i = 0; i < GpeBlock->RegisterCount; i++)
    404     {
    405         /* Clear status on all GPEs in this register */
    406 
    407         Status = AcpiHwWrite (0xFF, &GpeBlock->RegisterInfo[i].StatusAddress);
    408         if (ACPI_FAILURE (Status))
    409         {
    410             return (Status);
    411         }
    412     }
    413 
    414     return (AE_OK);
    415 }
    416 
    417 
    418 /******************************************************************************
    419  *
    420  * FUNCTION:    AcpiHwEnableRuntimeGpeBlock
    421  *
    422  * PARAMETERS:  GpeXruptInfo        - GPE Interrupt info
    423  *              GpeBlock            - Gpe Block info
    424  *
    425  * RETURN:      Status
    426  *
    427  * DESCRIPTION: Enable all "runtime" GPEs within a single GPE block. Includes
    428  *              combination wake/run GPEs.
    429  *
    430  ******************************************************************************/
    431 
    432 ACPI_STATUS
    433 AcpiHwEnableRuntimeGpeBlock (
    434     ACPI_GPE_XRUPT_INFO     *GpeXruptInfo,
    435     ACPI_GPE_BLOCK_INFO     *GpeBlock,
    436     void                    *Context)
    437 {
    438     UINT32                  i;
    439     ACPI_STATUS             Status;
    440 
    441 
    442     /* NOTE: assumes that all GPEs are currently disabled */
    443 
    444     /* Examine each GPE Register within the block */
    445 
    446     for (i = 0; i < GpeBlock->RegisterCount; i++)
    447     {
    448         if (!GpeBlock->RegisterInfo[i].EnableForRun)
    449         {
    450             continue;
    451         }
    452 
    453         /* Enable all "runtime" GPEs in this register */
    454 
    455         Status = AcpiHwWrite (GpeBlock->RegisterInfo[i].EnableForRun,
    456                     &GpeBlock->RegisterInfo[i].EnableAddress);
    457         if (ACPI_FAILURE (Status))
    458         {
    459             return (Status);
    460         }
    461     }
    462 
    463     return (AE_OK);
    464 }
    465 
    466 
    467 /******************************************************************************
    468  *
    469  * FUNCTION:    AcpiHwEnableWakeupGpeBlock
    470  *
    471  * PARAMETERS:  GpeXruptInfo        - GPE Interrupt info
    472  *              GpeBlock            - Gpe Block info
    473  *
    474  * RETURN:      Status
    475  *
    476  * DESCRIPTION: Enable all "wake" GPEs within a single GPE block. Includes
    477  *              combination wake/run GPEs.
    478  *
    479  ******************************************************************************/
    480 
    481 static ACPI_STATUS
    482 AcpiHwEnableWakeupGpeBlock (
    483     ACPI_GPE_XRUPT_INFO     *GpeXruptInfo,
    484     ACPI_GPE_BLOCK_INFO     *GpeBlock,
    485     void                    *Context)
    486 {
    487     UINT32                  i;
    488     ACPI_STATUS             Status;
    489 
    490 
    491     /* Examine each GPE Register within the block */
    492 
    493     for (i = 0; i < GpeBlock->RegisterCount; i++)
    494     {
    495         if (!GpeBlock->RegisterInfo[i].EnableForWake)
    496         {
    497             continue;
    498         }
    499 
    500         /* Enable all "wake" GPEs in this register */
    501 
    502         Status = AcpiHwWrite (GpeBlock->RegisterInfo[i].EnableForWake,
    503                     &GpeBlock->RegisterInfo[i].EnableAddress);
    504         if (ACPI_FAILURE (Status))
    505         {
    506             return (Status);
    507         }
    508     }
    509 
    510     return (AE_OK);
    511 }
    512 
    513 
    514 /******************************************************************************
    515  *
    516  * FUNCTION:    AcpiHwDisableAllGpes
    517  *
    518  * PARAMETERS:  None
    519  *
    520  * RETURN:      Status
    521  *
    522  * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
    523  *
    524  ******************************************************************************/
    525 
    526 ACPI_STATUS
    527 AcpiHwDisableAllGpes (
    528     void)
    529 {
    530     ACPI_STATUS             Status;
    531 
    532 
    533     ACPI_FUNCTION_TRACE (HwDisableAllGpes);
    534 
    535 
    536     Status = AcpiEvWalkGpeList (AcpiHwDisableGpeBlock, NULL);
    537     Status = AcpiEvWalkGpeList (AcpiHwClearGpeBlock, NULL);
    538     return_ACPI_STATUS (Status);
    539 }
    540 
    541 
    542 /******************************************************************************
    543  *
    544  * FUNCTION:    AcpiHwEnableAllRuntimeGpes
    545  *
    546  * PARAMETERS:  None
    547  *
    548  * RETURN:      Status
    549  *
    550  * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
    551  *
    552  ******************************************************************************/
    553 
    554 ACPI_STATUS
    555 AcpiHwEnableAllRuntimeGpes (
    556     void)
    557 {
    558     ACPI_STATUS             Status;
    559 
    560 
    561     ACPI_FUNCTION_TRACE (HwEnableAllRuntimeGpes);
    562 
    563 
    564     Status = AcpiEvWalkGpeList (AcpiHwEnableRuntimeGpeBlock, NULL);
    565     return_ACPI_STATUS (Status);
    566 }
    567 
    568 
    569 /******************************************************************************
    570  *
    571  * FUNCTION:    AcpiHwEnableAllWakeupGpes
    572  *
    573  * PARAMETERS:  None
    574  *
    575  * RETURN:      Status
    576  *
    577  * DESCRIPTION: Enable all "wakeup" GPEs, in all GPE blocks
    578  *
    579  ******************************************************************************/
    580 
    581 ACPI_STATUS
    582 AcpiHwEnableAllWakeupGpes (
    583     void)
    584 {
    585     ACPI_STATUS             Status;
    586 
    587 
    588     ACPI_FUNCTION_TRACE (HwEnableAllWakeupGpes);
    589 
    590 
    591     Status = AcpiEvWalkGpeList (AcpiHwEnableWakeupGpeBlock, NULL);
    592     return_ACPI_STATUS (Status);
    593 }
    594 
    595