summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaiyen Chang <kaiyen.chang@intel.com>2015-08-03 21:16:11 +0800
committerChromeOS bot <3su6n15k.default@developer.gserviceaccount.com>2015-09-21 18:58:20 +0000
commitd532781727e031acf5f6a7a207807f4461be3b4f (patch)
tree1c42a0192fca8fb3cb26fa4c7fe792db10233498
parent7668ef2d7e0430fc5a2e901de13c29509189399c (diff)
downloadchrome-ec-d532781727e031acf5f6a7a207807f4461be3b4f.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/291700 Tested-by: Icarus W Sparry <icarus.w.sparry@intel.com> Commit-Queue: Icarus W Sparry <icarus.w.sparry@intel.com>
-rw-r--r--power/common.c46
1 files changed, 41 insertions, 5 deletions
diff --git a/power/common.c b/power/common.c
index 2520d06010..fa0ccc2816 100644
--- a/power/common.c
+++ b/power/common.c
@@ -131,6 +131,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;
}
/**
@@ -188,12 +197,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;
@@ -267,13 +287,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);
}