diff options
author | Ben Lok <ben.lok@mediatek.com> | 2015-10-30 16:16:03 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2015-11-04 07:08:49 -0800 |
commit | 64a812d4b7710981499ce81e0a7a088d7d122098 (patch) | |
tree | bddd9d0edbc387e843edda04fb3beec8ba5a24c6 /power | |
parent | d5e49bc23da47bca149b85682c01ef61a69e7bb8 (diff) | |
download | chrome-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>
Diffstat (limited to 'power')
-rw-r--r-- | power/mediatek.c | 36 |
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); |