ACPI_STATUS AcpiEnterSleepStatePrep ( UINT8 SleepState) { ACPI_STATUS Status; ACPI_OBJECT_LIST ArgList; ACPI_OBJECT Arg; UINT32 SstValue; ACPI_FUNCTION_TRACE (AcpiEnterSleepStatePrep); Status = AcpiGetSleepTypeData (SleepState, &AcpiGbl_SleepTypeA, &AcpiGbl_SleepTypeB); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* Execute the _PTS method (Prepare To Sleep) */ ArgList.Count = 1; ArgList.Pointer = &Arg; Arg.Type = ACPI_TYPE_INTEGER; Arg.Integer.Value = SleepState; Status = AcpiEvaluateObject (NULL, METHOD_PATHNAME__PTS, &ArgList, NULL); if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND) { return_ACPI_STATUS (Status); } /* Setup the argument to the _SST method (System STatus) */ switch (SleepState) { case ACPI_STATE_S0: SstValue = ACPI_SST_WORKING; break; case ACPI_STATE_S1: case ACPI_STATE_S2: case ACPI_STATE_S3: SstValue = ACPI_SST_SLEEPING; break; case ACPI_STATE_S4: SstValue = ACPI_SST_SLEEP_CONTEXT; break; default: SstValue = ACPI_SST_INDICATOR_OFF; /* Default is off */ break; } /* * Set the system indicators to show the desired sleep state. * _SST is an optional method (return no error if not found) */ AcpiHwExecuteSleepMethod (METHOD_PATHNAME__SST, SstValue); return_ACPI_STATUS (AE_OK); }
ACPI_STATUS AcpiHwLegacyWake ( UINT8 SleepState) { ACPI_STATUS Status; ACPI_FUNCTION_TRACE (HwLegacyWake); /* Ensure EnterSleepStatePrep -> EnterSleepState ordering */ AcpiGbl_SleepTypeA = ACPI_SLEEP_TYPE_INVALID; AcpiHwExecuteSleepMethod (METHOD_PATHNAME__SST, ACPI_SST_WAKING); /* * GPEs must be enabled before _WAK is called as GPEs * might get fired there * * Restore the GPEs: * 1) Disable/Clear all GPEs * 2) Enable all runtime GPEs */ Status = AcpiHwDisableAllGpes (); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } Status = AcpiHwEnableAllRuntimeGpes (); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* * Now we can execute _WAK, etc. Some machines require that the GPEs * are enabled before the wake methods are executed. */ AcpiHwExecuteSleepMethod (METHOD_PATHNAME__WAK, SleepState); /* * Some BIOS code assumes that WAK_STS will be cleared on resume * and use it to determine whether the system is rebooting or * resuming. Clear WAK_STS for compatibility. */ (void) AcpiWriteBitRegister (ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS); AcpiGbl_SystemAwakeAndRunning = TRUE; /* Enable power button */ (void) AcpiWriteBitRegister( AcpiGbl_FixedEventInfo[ACPI_EVENT_POWER_BUTTON].EnableRegisterId, ACPI_ENABLE_EVENT); (void) AcpiWriteBitRegister( AcpiGbl_FixedEventInfo[ACPI_EVENT_POWER_BUTTON].StatusRegisterId, ACPI_CLEAR_STATUS); AcpiHwExecuteSleepMethod (METHOD_PATHNAME__SST, ACPI_SST_WORKING); return_ACPI_STATUS (Status); }
ACPI_STATUS AcpiHwExtendedSleep ( UINT8 SleepState, UINT8 Flags) { ACPI_STATUS Status; UINT8 SleepTypeValue; UINT64 SleepStatus; ACPI_FUNCTION_TRACE (HwExtendedSleep); /* Extended sleep registers must be valid */ if (!AcpiGbl_FADT.SleepControl.Address || !AcpiGbl_FADT.SleepStatus.Address) { return_ACPI_STATUS (AE_NOT_EXIST); } /* Clear wake status (WAK_STS) */ Status = AcpiWrite (ACPI_X_WAKE_STATUS, &AcpiGbl_FADT.SleepStatus); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } AcpiGbl_SystemAwakeAndRunning = FALSE; /* Optionally execute _GTS (Going To Sleep) */ if (Flags & ACPI_EXECUTE_GTS) { AcpiHwExecuteSleepMethod (METHOD_PATHNAME__GTS, SleepState); } /* Flush caches, as per ACPI specification */ ACPI_FLUSH_CPU_CACHE (); /* * Set the SLP_TYP and SLP_EN bits. * * Note: We only use the first value returned by the \_Sx method * (AcpiGbl_SleepTypeA) - As per ACPI specification. */ ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "Entering sleep state [S%u]\n", SleepState)); SleepTypeValue = ((AcpiGbl_SleepTypeA << ACPI_X_SLEEP_TYPE_POSITION) & ACPI_X_SLEEP_TYPE_MASK); Status = AcpiWrite ((SleepTypeValue | ACPI_X_SLEEP_ENABLE), &AcpiGbl_FADT.SleepControl); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* Wait for transition back to Working State */ do { Status = AcpiRead (&SleepStatus, &AcpiGbl_FADT.SleepStatus); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } } while (!(((UINT8) SleepStatus) & ACPI_X_WAKE_STATUS)); return_ACPI_STATUS (AE_OK); }