⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hwsleep.c

📁 acpi tools for linux include acpiexec and acpixtract
💻 C
📖 第 1 页 / 共 2 页
字号:
    SleepEnableRegInfo = AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_ENABLE);    /* Clear wake status */    Status = AcpiSetRegister (ACPI_BITREG_WAKE_STATUS, 1);    if (ACPI_FAILURE (Status))    {        return_ACPI_STATUS (Status);    }    /* Clear all fixed and general purpose status bits */    Status = AcpiHwClearAcpiStatus ();    if (ACPI_FAILURE (Status))    {        return_ACPI_STATUS (Status);    }    if (SleepState != ACPI_STATE_S5)    {        /* Disable BM arbitration */        Status = AcpiSetRegister (ACPI_BITREG_ARB_DISABLE, 1);        if (ACPI_FAILURE (Status))        {            return_ACPI_STATUS (Status);        }    }    /*     * 1) Disable/Clear all GPEs     * 2) Enable all wakeup GPEs     */    Status = AcpiHwDisableAllGpes ();    if (ACPI_FAILURE (Status))    {        return_ACPI_STATUS (Status);    }    AcpiGbl_SystemAwakeAndRunning = FALSE;    Status = AcpiHwEnableAllWakeupGpes ();    if (ACPI_FAILURE (Status))    {        return_ACPI_STATUS (Status);    }    /* Get current value of PM1A control */    Status = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK,                ACPI_REGISTER_PM1_CONTROL, &PM1AControl);    if (ACPI_FAILURE (Status))    {        return_ACPI_STATUS (Status);    }    ACPI_DEBUG_PRINT ((ACPI_DB_INIT,        "Entering sleep state [S%d]\n", SleepState));    /* Clear SLP_EN and SLP_TYP fields */    PM1AControl &= ~(SleepTypeRegInfo->AccessBitMask |                     SleepEnableRegInfo->AccessBitMask);    PM1BControl = PM1AControl;    /* Insert SLP_TYP bits */    PM1AControl |= (AcpiGbl_SleepTypeA << SleepTypeRegInfo->BitPosition);    PM1BControl |= (AcpiGbl_SleepTypeB << SleepTypeRegInfo->BitPosition);    /*     * We split the writes of SLP_TYP and SLP_EN to workaround     * poorly implemented hardware.     */    /* Write #1: fill in SLP_TYP data */    Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK,                ACPI_REGISTER_PM1A_CONTROL, PM1AControl);    if (ACPI_FAILURE (Status))    {        return_ACPI_STATUS (Status);    }    Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK,                ACPI_REGISTER_PM1B_CONTROL, PM1BControl);    if (ACPI_FAILURE (Status))    {        return_ACPI_STATUS (Status);    }    /* Insert SLP_ENABLE bit */    PM1AControl |= SleepEnableRegInfo->AccessBitMask;    PM1BControl |= SleepEnableRegInfo->AccessBitMask;    /* Write #2: SLP_TYP + SLP_EN */    ACPI_FLUSH_CPU_CACHE ();    Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK,                ACPI_REGISTER_PM1A_CONTROL, PM1AControl);    if (ACPI_FAILURE (Status))    {        return_ACPI_STATUS (Status);    }    Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK,                ACPI_REGISTER_PM1B_CONTROL, PM1BControl);    if (ACPI_FAILURE (Status))    {        return_ACPI_STATUS (Status);    }    if (SleepState > ACPI_STATE_S3)    {        /*         * We wanted to sleep > S3, but it didn't happen (by virtue of the         * fact that we are still executing!)         *         * Wait ten seconds, then try again. This is to get S4/S5 to work on         * all machines.         *         * We wait so long to allow chipsets that poll this reg very slowly to         * still read the right value. Ideally, this block would go         * away entirely.         */        AcpiOsStall (10000000);        Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK,                    ACPI_REGISTER_PM1_CONTROL,                    SleepEnableRegInfo->AccessBitMask);        if (ACPI_FAILURE (Status))        {            return_ACPI_STATUS (Status);        }    }    /* Wait until we enter sleep state */    do    {        Status = AcpiGetRegister (ACPI_BITREG_WAKE_STATUS, &InValue);        if (ACPI_FAILURE (Status))        {            return_ACPI_STATUS (Status);        }        /* Spin until we wake */    } while (!InValue);    return_ACPI_STATUS (AE_OK);}ACPI_EXPORT_SYMBOL (AcpiEnterSleepState)/******************************************************************************* * * FUNCTION:    AcpiEnterSleepStateS4bios * * PARAMETERS:  None * * RETURN:      Status * * DESCRIPTION: Perform a S4 bios request. *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED * ******************************************************************************/ACPI_STATUSAcpiEnterSleepStateS4bios (    void){    UINT32                  InValue;    ACPI_STATUS             Status;    ACPI_FUNCTION_TRACE (AcpiEnterSleepStateS4bios);    Status = AcpiSetRegister (ACPI_BITREG_WAKE_STATUS, 1);    if (ACPI_FAILURE (Status))    {        return_ACPI_STATUS (Status);    }    Status = AcpiHwClearAcpiStatus ();    if (ACPI_FAILURE (Status))    {        return_ACPI_STATUS (Status);    }    /*     * 1) Disable/Clear all GPEs     * 2) Enable all wakeup GPEs     */    Status = AcpiHwDisableAllGpes ();    if (ACPI_FAILURE (Status))    {        return_ACPI_STATUS (Status);    }    AcpiGbl_SystemAwakeAndRunning = FALSE;    Status = AcpiHwEnableAllWakeupGpes ();    if (ACPI_FAILURE (Status))    {        return_ACPI_STATUS (Status);    }    ACPI_FLUSH_CPU_CACHE ();    Status = AcpiOsWritePort (AcpiGbl_FADT.SmiCommand,                (UINT32) AcpiGbl_FADT.S4BiosRequest, 8);    do {        AcpiOsStall(1000);        Status = AcpiGetRegister (ACPI_BITREG_WAKE_STATUS, &InValue);        if (ACPI_FAILURE (Status))        {            return_ACPI_STATUS (Status);        }    } while (!InValue);    return_ACPI_STATUS (AE_OK);}ACPI_EXPORT_SYMBOL (AcpiEnterSleepStateS4bios)/******************************************************************************* * * FUNCTION:    AcpiLeaveSleepState * * PARAMETERS:  SleepState          - Which sleep state we just exited * * RETURN:      Status * * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep *              Called with interrupts ENABLED. * ******************************************************************************/ACPI_STATUSAcpiLeaveSleepState (    UINT8                   SleepState){    ACPI_OBJECT_LIST        ArgList;    ACPI_OBJECT             Arg;    ACPI_STATUS             Status;    ACPI_BIT_REGISTER_INFO  *SleepTypeRegInfo;    ACPI_BIT_REGISTER_INFO  *SleepEnableRegInfo;    UINT32                  PM1AControl;    UINT32                  PM1BControl;    ACPI_FUNCTION_TRACE (AcpiLeaveSleepState);    /*     * Set SLP_TYPE and SLP_EN to state S0.     * This is unclear from the ACPI Spec, but it is required     * by some machines.     */    Status = AcpiGetSleepTypeData (ACPI_STATE_S0,                    &AcpiGbl_SleepTypeA, &AcpiGbl_SleepTypeB);    if (ACPI_SUCCESS (Status))    {        SleepTypeRegInfo   = AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_TYPE_A);        SleepEnableRegInfo = AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_ENABLE);        /* Get current value of PM1A control */        Status = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK,                    ACPI_REGISTER_PM1_CONTROL, &PM1AControl);        if (ACPI_SUCCESS (Status))        {            /* Clear SLP_EN and SLP_TYP fields */            PM1AControl &= ~(SleepTypeRegInfo->AccessBitMask |                             SleepEnableRegInfo->AccessBitMask);            PM1BControl = PM1AControl;            /* Insert SLP_TYP bits */            PM1AControl |= (AcpiGbl_SleepTypeA << SleepTypeRegInfo->BitPosition);            PM1BControl |= (AcpiGbl_SleepTypeB << SleepTypeRegInfo->BitPosition);            /* Just ignore any errors */            (void) AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK,                            ACPI_REGISTER_PM1A_CONTROL, PM1AControl);            (void) AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK,                            ACPI_REGISTER_PM1B_CONTROL, PM1BControl);        }    }    /* Ensure EnterSleepStatePrep -> EnterSleepState ordering */    AcpiGbl_SleepTypeA = ACPI_SLEEP_TYPE_INVALID;    /* Setup parameter object */    ArgList.Count = 1;    ArgList.Pointer = &Arg;    Arg.Type = ACPI_TYPE_INTEGER;    /* Ignore any errors from these methods */    Arg.Integer.Value = ACPI_SST_WAKING;    Status = AcpiEvaluateObject (NULL, METHOD_NAME__SST, &ArgList, NULL);    if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND)    {        ACPI_EXCEPTION ((AE_INFO, Status, "During Method _SST"));    }    Arg.Integer.Value = SleepState;    Status = AcpiEvaluateObject (NULL, METHOD_NAME__BFS, &ArgList, NULL);    if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND)    {        ACPI_EXCEPTION ((AE_INFO, Status, "During Method _BFS"));    }    Status = AcpiEvaluateObject (NULL, METHOD_NAME__WAK, &ArgList, NULL);    if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND)    {        ACPI_EXCEPTION ((AE_INFO, Status, "During Method _WAK"));    }    /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */    /*     * Restore the GPEs:     * 1) Disable/Clear all GPEs     * 2) Enable all runtime GPEs     */    Status = AcpiHwDisableAllGpes ();    if (ACPI_FAILURE (Status))    {        return_ACPI_STATUS (Status);    }    AcpiGbl_SystemAwakeAndRunning = TRUE;    Status = AcpiHwEnableAllRuntimeGpes ();    if (ACPI_FAILURE (Status))    {        return_ACPI_STATUS (Status);    }    /* Enable power button */    (void) AcpiSetRegister(            AcpiGbl_FixedEventInfo[ACPI_EVENT_POWER_BUTTON].EnableRegisterId, 1);    (void) AcpiSetRegister(            AcpiGbl_FixedEventInfo[ACPI_EVENT_POWER_BUTTON].StatusRegisterId, 1);    /* Enable BM arbitration */    Status = AcpiSetRegister (ACPI_BITREG_ARB_DISABLE, 0);    if (ACPI_FAILURE (Status))    {        return_ACPI_STATUS (Status);    }    Arg.Integer.Value = ACPI_SST_WORKING;    Status = AcpiEvaluateObject (NULL, METHOD_NAME__SST, &ArgList, NULL);    if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND)    {        ACPI_EXCEPTION ((AE_INFO, Status, "During Method _SST"));    }    return_ACPI_STATUS (Status);}ACPI_EXPORT_SYMBOL (AcpiLeaveSleepState)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -