diff options
author | Louis Yung-Chieh Lo <yjlou@chromium.org> | 2014-05-06 17:12:52 -0700 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-05-09 04:45:19 +0000 |
commit | 2cff588c1aaf05db05d07a4325881dffe24db761 (patch) | |
tree | 745ebbf5a1a2d303d249e22438040e5014fbe2eb /power | |
parent | 6803674335d88f7ce1b3f61b2b19b88f55464116 (diff) | |
download | chrome-ec-2cff588c1aaf05db05d07a4325881dffe24db761.tar.gz |
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: I51afed7201d16ebcd889ad12a7af90026591cc2d
Signed-off-by: Louis Yung-Chieh Lo <yjlou@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/198587
Reviewed-by: David Hendricks <dhendrix@chromium.org>
Diffstat (limited to 'power')
-rw-r--r-- | power/tegra.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/power/tegra.c b/power/tegra.c index fe549f41db..91d10790bd 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( |