From bf406dec4b17378efc3d825c1bc084308d195a50 Mon Sep 17 00:00:00 2001 From: Louis Yung-Chieh Lo Date: Tue, 6 May 2014 17:12:52 -0700 Subject: tegra: fixed a corner case that AP_OFF flag is not cleared. If we follow the TEST steps below, the power state machine in AP and EC were out of sync -- due to the un-clear bit and wrong initial power state. BUG=chrome-os-partner:24835 BRANCH=tot,nyan TEST=on big. > reboot > power off // De-assert XPSHOLD > reboot ap-off > sysinfo // This reset flags does NOT contain "ap-off". > power on % ectool reboot_ec RW // The following message is NOT observed. // "system is on, but RESET_FLAG_AP_OFF is on". > power // This should show the AP is "on". // ensure everything still works. > reboot ap-off // AP keeps off. > reboot // AP is on. Change-Id: Ic7aba45922bf1dac65aab2225cad03ee09df530f Original-Change-Id: I51afed7201d16ebcd889ad12a7af90026591cc2d Signed-off-by: Louis Yung-Chieh Lo Reviewed-on: https://chromium-review.googlesource.com/199000 Reviewed-by: Gabe Black Commit-Queue: Gabe Black Tested-by: Gabe Black --- power/tegra.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/power/tegra.c b/power/tegra.c index 124f712d66..cbf6f13ff0 100644 --- a/power/tegra.c +++ b/power/tegra.c @@ -231,6 +231,8 @@ DECLARE_HOOK(HOOK_LID_CHANGE, tegra_lid_event, HOOK_PRIO_DEFAULT); enum power_state power_chipset_init(void) { + int init_power_state; + /* * Force the AP shutdown unless we are doing SYSJUMP. Otherwise, * the AP could stay in strange state. @@ -244,6 +246,14 @@ enum power_state power_chipset_init(void) * flash SPI from USB). */ chipset_reset(0); + + init_power_state = POWER_G3; + } else { + /* In the SYSJUMP case, we check if the AP is on */ + if (power_get_signals() & IN_XPSHOLD) + init_power_state = POWER_S0; + else + init_power_state = POWER_G3; } /* Leave power off only if requested by reset flags */ @@ -253,7 +263,7 @@ enum power_state power_chipset_init(void) auto_power_on = 1; } - return POWER_G3; + return init_power_state; } /*****************************************************************************/ @@ -293,13 +303,16 @@ void chipset_force_shutdown(void) */ static int check_for_power_on_event(void) { + int ap_off_flag; + + ap_off_flag = system_get_reset_flags() & RESET_FLAG_AP_OFF; + system_clear_reset_flags(RESET_FLAG_AP_OFF); /* check if system is already ON */ if (power_get_signals() & IN_XPSHOLD) { - if (system_get_reset_flags() & RESET_FLAG_AP_OFF) { + if (ap_off_flag) { CPRINTF( "[%T system is on, but " "RESET_FLAG_AP_OFF is on]\n"); - system_clear_reset_flags(RESET_FLAG_AP_OFF); return 0; } else { CPRINTF( -- cgit v1.2.1