From 4a8ce9ac348916f25f8bed5bcfc5c1432ea3c4d1 Mon Sep 17 00:00:00 2001 From: Alexandru M Stan Date: Thu, 22 Jan 2015 11:29:23 -0800 Subject: Rockchip: Wait till we actually power down in power_off() If we don't do this, some code later on (like the S3 hook) might check the POWER_GOOD too early, note that it's on and move to the wrong state: [8.457344 power button not released in time] [8.457541 long-press button, shutdown] // power_off() happens: [8.459853 power shutdown complete] [8.593443 power state 7 = S0->S3, in 0x0001] [8.593653 power state 2 = S3, in 0x0001] // power_get_signals check happens here ^^^, but POWER_GOOD did not have enough // time to fall and cause the power_update_signals interrupt [8.593863 power state 6 = S3->S0, in 0x0001] [8.594132 power state 3 = S0, in 0x0000] // system is actually off here BUG=chrome-os-partner:34816 TEST=Hold Power+Refresh, release after about 10 seconds, the ec should not have an assertion error and reboot BRANCH=veyron Change-Id: Ic7a06a5d255f2b8d056b0b454fc32a4c05c998b4 Signed-off-by: Alexandru M Stan Reviewed-on: https://chromium-review.googlesource.com/242620 Reviewed-by: Randall Spangler (cherry picked from commit 5f954620fa3d36e8e1a88bf7d3963dc7996ec445) Reviewed-on: https://chromium-review.googlesource.com/242711 --- power/rockchip.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/power/rockchip.c b/power/rockchip.c index 1a5c6c656a..25d1addb71 100644 --- a/power/rockchip.c +++ b/power/rockchip.c @@ -415,6 +415,8 @@ static int wait_for_power_button_release(unsigned int timeout_us) */ static void power_off(void) { + unsigned int power_off_timeout = 100; /* ms */ + /* Call hooks before we drop power rails */ hook_notify(HOOK_CHIPSET_SHUTDOWN); /* switch off all rails */ @@ -423,6 +425,13 @@ static void power_off(void) gpio_set_flags(GPIO_SUSPEND_L, GPIO_INPUT); gpio_set_flags(GPIO_EC_INT, GPIO_INPUT); + /* Wait till we actually turn off to not mess up the state machine. */ + while (power_get_signals() & IN_POWER_GOOD) { + msleep(1); + power_off_timeout--; + ASSERT(power_off_timeout); + } + lid_opened = 0; enable_sleep(SLEEP_MASK_AP_RUN); powerled_set_state(POWERLED_STATE_OFF); -- cgit v1.2.1