#if (!ACPI_REDUCED_HARDWARE) /* Entire module */ /******************************************************************************* * * FUNCTION: acpi_hw_legacy_sleep * * PARAMETERS: sleep_state - Which sleep state to enter * * RETURN: Status * * DESCRIPTION: Enter a system sleep state via the legacy FADT PM registers * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED *
******************************************************************************/
acpi_status acpi_hw_legacy_sleep(u8 sleep_state)
{ struct acpi_bit_register_info *sleep_type_reg_info; struct acpi_bit_register_info *sleep_enable_reg_info;
u32 pm1a_control;
u32 pm1b_control;
u32 in_value;
acpi_status status;
status = acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS,
ACPI_CLEAR_STATUS); if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
/* Disable all GPEs */
status = acpi_hw_disable_all_gpes(); if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
status = acpi_hw_clear_acpi_status(); if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
acpi_gbl_system_awake_and_running = FALSE;
/* Enable all wakeup GPEs */
status = acpi_hw_enable_all_wakeup_gpes(); if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
/* Get current value of PM1A control */
status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
&pm1a_control); if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
ACPI_DEBUG_PRINT((ACPI_DB_INIT, "Entering sleep state [S%u]\n", sleep_state));
if (sleep_state < ACPI_STATE_S4) {
ACPI_FLUSH_CPU_CACHE();
}
status = acpi_os_enter_sleep(sleep_state, pm1a_control, pm1b_control); if (status == AE_CTRL_TERMINATE) {
return_ACPI_STATUS(AE_OK);
} if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
/* Write #2: Write both SLP_TYP + SLP_EN */
status = acpi_hw_write_pm1_control(pm1a_control, pm1b_control); if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
if (sleep_state > 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.
*/
acpi_os_stall(10 * ACPI_USEC_PER_SEC);
status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL,
sleep_enable_reg_info->
access_bit_mask); if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
}
/* Wait for transition back to Working State */
do {
status =
acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS, &in_value); if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
} while (!in_value);
return_ACPI_STATUS(AE_OK);
}
/******************************************************************************* * * FUNCTION: acpi_hw_legacy_wake_prep * * PARAMETERS: sleep_state - Which sleep state we just exited * * RETURN: Status * * DESCRIPTION: Perform the first state of OS-independent ACPI cleanup after a * sleep. * Called with interrupts ENABLED. *
******************************************************************************/
/* * Set SLP_TYPE and SLP_EN to state S0. * This is unclear from the ACPI Spec, but it is required * by some machines.
*/ if (acpi_gbl_sleep_type_a_s0 != ACPI_SLEEP_TYPE_INVALID) {
sleep_type_reg_info =
acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE);
sleep_enable_reg_info =
acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE);
/* Get current value of PM1A control */
status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
&pm1a_control); if (ACPI_SUCCESS(status)) {
/******************************************************************************* * * FUNCTION: acpi_hw_legacy_wake * * PARAMETERS: sleep_state - Which sleep state we just exited * * RETURN: Status * * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep * Called with interrupts ENABLED. *
******************************************************************************/
/* * GPEs must be enabled before _WAK is called as GPEs * might get fired there * * Restore the GPEs: * 1) Disable all GPEs * 2) Enable all runtime GPEs
*/
status = acpi_hw_disable_all_gpes(); if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
status = acpi_hw_enable_all_runtime_gpes(); 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.
*/
acpi_hw_execute_sleep_method(METHOD_PATHNAME__WAK, sleep_state);
/* * 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)acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS,
ACPI_CLEAR_STATUS);
acpi_gbl_system_awake_and_running = TRUE;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.