acpi_status acpi_hw_legacy_wake(u8 sleep_state) { acpi_status status; ACPI_FUNCTION_TRACE(hw_legacy_wake); /* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */ acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID; acpi_hw_execute_sleep_method(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 = 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; /* Enable power button */ (void) acpi_write_bit_register(acpi_gbl_fixed_event_info [ACPI_EVENT_POWER_BUTTON]. enable_register_id, ACPI_ENABLE_EVENT); (void) acpi_write_bit_register(acpi_gbl_fixed_event_info [ACPI_EVENT_POWER_BUTTON]. status_register_id, ACPI_CLEAR_STATUS); acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, ACPI_SST_WORKING); return_ACPI_STATUS(status); }
acpi_status acpi_enable_all_runtime_gpes(void) { acpi_status status; ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes); status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } status = acpi_hw_enable_all_runtime_gpes(); (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); return_ACPI_STATUS(status); }
acpi_status acpi_hw_legacy_wake(u8 sleep_state, u8 flags) { acpi_status status; ACPI_FUNCTION_TRACE(hw_legacy_wake); acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID; acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, ACPI_SST_WAKING); 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); } acpi_hw_execute_sleep_method(METHOD_PATHNAME__WAK, sleep_state); acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, 1); acpi_gbl_system_awake_and_running = TRUE; (void) acpi_write_bit_register(acpi_gbl_fixed_event_info [ACPI_EVENT_POWER_BUTTON]. enable_register_id, ACPI_ENABLE_EVENT); (void) acpi_write_bit_register(acpi_gbl_fixed_event_info [ACPI_EVENT_POWER_BUTTON]. status_register_id, ACPI_CLEAR_STATUS); status = acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0); if (ACPI_FAILURE(status) && (status != AE_BAD_ADDRESS)) { return_ACPI_STATUS(status); } acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, ACPI_SST_WORKING); return_ACPI_STATUS(status); }
static void acpi_pm_enable_gpes(void) { acpi_hw_enable_all_runtime_gpes(); }
/******************************************************************************* * * FUNCTION: acpi_leave_sleep_state * * PARAMETERS: sleep_state - Which sleep state we just exited * * RETURN: Status * * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep * Called with interrupts ENABLED. * ******************************************************************************/ acpi_status acpi_leave_sleep_state(u8 sleep_state) { struct acpi_object_list arg_list; union acpi_object arg; acpi_status status; struct acpi_bit_register_info *sleep_type_reg_info; struct acpi_bit_register_info *sleep_enable_reg_info; u32 PM1Acontrol; u32 PM1Bcontrol; ACPI_FUNCTION_TRACE(acpi_leave_sleep_state); /* * Set SLP_TYPE and SLP_EN to state S0. * This is unclear from the ACPI Spec, but it is required * by some machines. */ status = acpi_get_sleep_type_data(ACPI_STATE_S0, &acpi_gbl_sleep_type_a, &acpi_gbl_sleep_type_b); if (ACPI_SUCCESS(status)) { sleep_type_reg_info = acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE_A); 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_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol); if (ACPI_SUCCESS(status)) { /* Clear SLP_EN and SLP_TYP fields */ PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask | sleep_enable_reg_info-> access_bit_mask); PM1Bcontrol = PM1Acontrol; /* Insert SLP_TYP bits */ PM1Acontrol |= (acpi_gbl_sleep_type_a << sleep_type_reg_info-> bit_position); PM1Bcontrol |= (acpi_gbl_sleep_type_b << sleep_type_reg_info-> bit_position); /* Just ignore any errors */ (void)acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol); (void)acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol); } } /* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */ acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID; /* Setup parameter object */ arg_list.count = 1; arg_list.pointer = &arg; arg.type = ACPI_TYPE_INTEGER; /* Ignore any errors from these methods */ arg.integer.value = ACPI_SST_WAKING; status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { ACPI_EXCEPTION((AE_INFO, status, "During Method _SST")); } arg.integer.value = sleep_state; status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL); if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS")); } status = acpi_evaluate_object(NULL, METHOD_NAME__WAK, &arg_list, 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 = acpi_hw_disable_all_gpes(); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } acpi_gbl_system_awake_and_running = TRUE; status = acpi_hw_enable_all_runtime_gpes(); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* Enable power button */ (void) acpi_set_register(acpi_gbl_fixed_event_info [ACPI_EVENT_POWER_BUTTON].enable_register_id, 1, ACPI_MTX_DO_NOT_LOCK); (void) acpi_set_register(acpi_gbl_fixed_event_info [ACPI_EVENT_POWER_BUTTON].status_register_id, 1, ACPI_MTX_DO_NOT_LOCK); arg.integer.value = ACPI_SST_WORKING; status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { ACPI_EXCEPTION((AE_INFO, status, "During Method _SST")); } return_ACPI_STATUS(status); }
/******************************************************************************* * * FUNCTION: acpi_leave_sleep_state * * PARAMETERS: sleep_state - Which sleep state we just exited * * RETURN: Status * * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep * Called with interrupts ENABLED. * ******************************************************************************/ acpi_status acpi_leave_sleep_state(u8 sleep_state) { struct acpi_object_list arg_list; union acpi_object arg; acpi_status status; ACPI_FUNCTION_TRACE(acpi_leave_sleep_state); /* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */ acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID; /* Setup parameter object */ arg_list.count = 1; arg_list.pointer = &arg; arg.type = ACPI_TYPE_INTEGER; /* Ignore any errors from these methods */ arg.integer.value = ACPI_SST_WAKING; status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { ACPI_EXCEPTION((AE_INFO, status, "During Method _SST")); } /* * 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 = 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); } arg.integer.value = sleep_state; status = acpi_evaluate_object(NULL, METHOD_NAME__WAK, &arg_list, 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? */ /* * Some BIOSes assume that WAK_STS will be cleared on resume and use * it to determine whether the system is rebooting or resuming. Clear * it for compatibility. */ acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, 1); acpi_gbl_system_awake_and_running = TRUE; /* Enable power button */ (void) acpi_write_bit_register(acpi_gbl_fixed_event_info [ACPI_EVENT_POWER_BUTTON]. enable_register_id, ACPI_ENABLE_EVENT); (void) acpi_write_bit_register(acpi_gbl_fixed_event_info [ACPI_EVENT_POWER_BUTTON]. status_register_id, ACPI_CLEAR_STATUS); arg.integer.value = ACPI_SST_WORKING; status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { ACPI_EXCEPTION((AE_INFO, status, "During Method _SST")); } return_ACPI_STATUS(status); }
static void acpi_hibernation_restore_cleanup(void) { acpi_hw_enable_all_runtime_gpes(); }