summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Lok <ben.lok@mediatek.com>2015-10-30 16:16:03 +0800
committerchrome-bot <chrome-bot@chromium.org>2015-11-04 07:08:49 -0800
commit64a812d4b7710981499ce81e0a7a088d7d122098 (patch)
treebddd9d0edbc387e843edda04fb3beec8ba5a24c6
parentd5e49bc23da47bca149b85682c01ef61a69e7bb8 (diff)
downloadchrome-ec-64a812d4b7710981499ce81e0a7a088d7d122098.tar.gz
oak: cancel long press timer when lost power_good or entering S3
1. refer to commit 8bd44bf4, oak has similar issue: if power good is lost and the power button still press, we need cancel the long press timer, otherwise EC will crash. 2. Furthermore, EC will crash too if long press timer is still active during entering S3. 3. The debounce of suspend & power_good signal can be removed on rev4 because rev4 doesn't adopt level shifter. BRANCH=None BUG=chrome-os-partner:46857 TEST=Manual 1. press power button during coreboot, and it can shutdown normally, or 2. run test case: > test_that -b oak <DUT IP> firmware_FwScreenPressPower Change-Id: I584d8beeb31b6c01289bfe4790453a4a3bd35b1c Signed-off-by: Ben Lok <ben.lok@mediatek.com> Reviewed-on: https://chromium-review.googlesource.com/309942 Reviewed-by: Rong Chang <rongchang@chromium.org>
-rw-r--r--power/mediatek.c36
1 files changed, 23 insertions, 13 deletions
diff --git a/power/mediatek.c b/power/mediatek.c
index 87ccec5629..a3817c1a06 100644
--- a/power/mediatek.c
+++ b/power/mediatek.c
@@ -52,12 +52,6 @@
#define DELAY_FORCE_SHUTDOWN (8000 * MSEC) /* 8 seconds */
/*
- * The minimum time to assert the PMIC PWRON pin is 20ms.
- * Give it longer to ensure the PMIC doesn't lose it.
- */
-#define PMIC_PWRON_DEBOUNCE_TIME (60 * MSEC)
-
-/*
* The power signal from SoC should be kept at least 50ms.
*/
#define POWER_DEBOUNCE_TIME (50 * MSEC)
@@ -181,7 +175,8 @@ static void chipset_turn_off_power_rails(void);
*/
static int is_suspend_asserted(void)
{
- if (power_get_signals() & IN_SUSPEND)
+ if ((power_get_signals() & IN_SUSPEND) &&
+ (system_get_board_version() < 4))
usleep(SUSPEND_DEBOUNCE_TIME);
return power_get_signals() & IN_SUSPEND;
@@ -195,7 +190,8 @@ static int is_suspend_asserted(void)
*/
static int is_suspend_deasserted(void)
{
- if (!(power_get_signals() & IN_SUSPEND))
+ if (!(power_get_signals() & IN_SUSPEND) &&
+ (system_get_board_version() < 4))
usleep(SUSPEND_DEBOUNCE_TIME);
return !(power_get_signals() & IN_SUSPEND);
@@ -211,7 +207,8 @@ static int is_power_good_asserted(void)
{
if (!gpio_get_level(GPIO_SYSTEM_POWER_H))
return 0;
- else if (power_get_signals() & IN_POWER_GOOD)
+ else if ((power_get_signals() & IN_POWER_GOOD) &&
+ (system_get_board_version() < 4))
usleep(POWER_DEBOUNCE_TIME);
return power_get_signals() & IN_POWER_GOOD;
@@ -237,7 +234,8 @@ static int is_power_good_deasserted(void)
}
}
- if (!(power_get_signals() & IN_POWER_GOOD))
+ if (!(power_get_signals() & IN_POWER_GOOD) &&
+ (system_get_board_version() < 4))
usleep(POWER_DEBOUNCE_TIME);
return !(power_get_signals() & IN_POWER_GOOD);
@@ -257,7 +255,7 @@ static void set_system_power(int asserted)
/**
* Set the PMIC PWRON signal.
*
- * Note that asserting requires holding for PMIC_PWRON_DEBOUNCE_TIME.
+ * Note that asserting requires holding for PMIC_PWRON_PRESS_TIME.
*
* @param asserted Assert (=1) or deassert (=0) the signal. This is the
* logical level of the pin, not the physical level.
@@ -271,7 +269,6 @@ static void set_pmic_pwron(int asserted)
* raise GPIO_SYSTEM_POWER_H
* wait for 5V power good, timeout 1 second
*/
- /* if (system_get_board_version() > 1) { */
if (asserted) {
set_system_power(asserted);
poll_deadline = get_time();
@@ -335,7 +332,6 @@ static int check_for_power_off_event(void)
*/
CPRINTS("PMIC long-press power off\n");
set_pmic_pwron(1);
- usleep(PMIC_PWRON_DEBOUNCE_TIME);
#endif
if (!power_button_was_pressed) {
@@ -364,6 +360,13 @@ static int check_for_power_off_event(void)
/* POWER_GOOD released by AP : shutdown immediate */
if (is_power_good_deasserted()) {
+ /*
+ * Cancel long press timer if power is lost and the power button
+ * still press, otherwise EC will crash.
+ */
+ if (power_button_was_pressed)
+ timer_cancel(TASK_ID_CHIPSET);
+
CPRINTS("POWER_GOOD is lost");
return POWER_OFF_BY_POWER_GOOD_LOST;
}
@@ -769,6 +772,13 @@ enum power_state power_handle_state(enum power_state state)
else
powerled_set_state(POWERLED_STATE_OFF);
#endif
+ /*
+ * if the power button is pressing, we need cancel the long
+ * press timer, otherwise EC will crash.
+ */
+ if (power_button_was_pressed)
+ timer_cancel(TASK_ID_CHIPSET);
+
/* Call hooks here since we don't know it prior to AP suspend */
hook_notify(HOOK_CHIPSET_SUSPEND);
enable_sleep(SLEEP_MASK_AP_RUN);