diff options
author | Kaiyen Chang <kaiyen.chang@intel.com> | 2015-08-03 21:16:11 +0800 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2015-08-19 22:50:01 +0000 |
commit | bc788218ebab6bd83e7dea9b5160ca1bddfa1dc6 (patch) | |
tree | 7d39e4afd1cbd37a192fc2eb7f89d078cb099c31 | |
parent | d89f2a0eb1ca168ce69d4791af7f5457db76bf63 (diff) | |
download | chrome-ec-bc788218ebab6bd83e7dea9b5160ca1bddfa1dc6.tar.gz |
Fixed a failure of power button press while entering G3 state.
If the power button is pressed while S5 inactivity timer is about to
expire, EC need to give CPU a little time to start up before changing
the state from S5 to G3 (the hard off state); otherwise the system will
not start up. This issue can be reproduced on Rambi.
BUG=chrome-os-partner:42728, chrome-os-partner:42811
BRANCH=None
TEST=Implement an ec command to simulate power button press while S5
inactivity timer is about to expire, and then make sure that the
patch did solve the issue.
Change-Id: I022e8e14fd41447898760a4d57a4702e2c00a0d5
Signed-off-by: Kaiyen Chang <kaiyen.chang@intel.com>
Reviewed-on: https://chromium-review.googlesource.com/290280
Reviewed-by: Shawn N <shawnn@chromium.org>
(cherry picked from commit 8f6e54aca00ac2336aab636267824d5210942c17)
Reviewed-on: https://chromium-review.googlesource.com/294223
Reviewed-by: Mohammed Habibulla <moch@google.com>
Commit-Queue: Vineeth Starly <vineeths@google.com>
Trybot-Ready: Vineeth Starly <vineeths@google.com>
Tested-by: Vineeth Starly <vineeths@google.com>
-rw-r--r-- | power/common.c | 46 |
1 files changed, 41 insertions, 5 deletions
diff --git a/power/common.c b/power/common.c index 3a92780bf4..d7987537c0 100644 --- a/power/common.c +++ b/power/common.c @@ -126,6 +126,15 @@ void power_set_state(enum power_state new_state) last_shutdown_time = get_time().val; state = new_state; + + /* + * Reset want_g3_exit flag here to prevent the situation that if the + * error handler in POWER_S5S3 decides to force shutdown the system and + * the flag is set, the system will go to G3 and then immediately exit + * G3 again. + */ + if (state == POWER_S5S3) + want_g3_exit = 0; } /** @@ -169,12 +178,23 @@ static enum power_state power_common_state(enum power_state state) break; case POWER_S5: + /* + * If the power button is pressed before S5 inactivity timer + * expires, the timer will be cancelled and the task of the + * power state machine will be back here again. Since we are + * here, which means the system has been waiting for CPU + * starting up, we don't need want_g3_exit flag to be set + * anymore. Therefore, we can reset the flag here to prevent + * the situation that the flag is still set after S5 inactivity + * timer expires, which can cause the system to exit G3 again. + */ + want_g3_exit = 0; + /* Wait for inactivity timeout */ power_wait_signals(0); if (task_wait_event(S5_INACTIVITY_TIMEOUT) == TASK_EVENT_TIMER) { - /* Drop to G3; wake not requested yet */ - want_g3_exit = 0; + /* Prepare to drop to G3; wake not requested yet */ return POWER_S5G3; } break; @@ -248,13 +268,29 @@ int chipset_in_state(int state_mask) void chipset_exit_hard_off(void) { - /* If not in the hard-off state nor headed there, nothing to do */ - if (state != POWER_G3 && state != POWER_S5G3) + /* + * If not in the soft-off state, hard-off state, or headed there, + * nothing to do. + */ + if (state != POWER_G3 && state != POWER_S5G3 && state != POWER_S5) return; - /* Set a flag to leave G3, then wake the task */ + /* + * Set a flag to leave G3, then wake the task. If the power state is + * POWER_S5G3, or is POWER_S5 but the S5 inactivity timer has + * expired, set this flag can let system go to G3 and then exit G3 + * immediately for powering on. + */ want_g3_exit = 1; + /* + * If the power state is in POWER_S5 and S5 inactivity timer is + * running, to wake the chipset task can cancel S5 inactivity timer and + * then restart the timer. This will give cpu a chance to start up if + * S5 inactivity timer is about to expire while power button is + * pressed. For other states here, to wake the chipset task to trigger + * the event for leaving G3 is necessary. + */ if (task_start_called()) task_wake(TASK_ID_CHIPSET); } |