From 6ecda4b0f1ea6c9aa6c1c249d1dcd4ace87cbda0 Mon Sep 17 00:00:00 2001 From: Randall Spangler Date: Wed, 28 Aug 2013 14:17:58 -0700 Subject: [PATCH] pit: pulse AP_RESET_L when resetting EC or forcing AP shutdown If the AP is suspended, it consumes little enough power that just shutting its rails off doesn't cause it to reset to a known state. This caused a problem where suspending the AP then rebooting the EC would wedge the system; the EC would think the AP was on (since XPSHOLD was asserted), but wouldn't be able to figure out how to turn it back off. Silego reset wouldn't help, because that again just reset the EC. Even setting PMIC_RESET to brown out the system wouldn't drop power for long enough. Simply pulsing AP_RESET_L low for 1 ms at EC boot (when not sysjump) or AP force-shutdown forces the AP into a good state. BUG=chrome-os-partner:22233 BRANCH=pit TEST=from root shell, 'powerd_dbus_suspend' from ec console 'reboot' - or just power+refresh system should power on normally Change-Id: I65f1239b5f6766f1c093c3064bce323df4acaf7d Signed-off-by: Randall Spangler Reviewed-on: https://chromium-review.googlesource.com/167355 Reviewed-by: Doug Anderson Commit-Queue: Doug Anderson --- common/chipset_gaia.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/common/chipset_gaia.c b/common/chipset_gaia.c index 1d36345612..1dcebd87e4 100644 --- a/common/chipset_gaia.c +++ b/common/chipset_gaia.c @@ -309,6 +309,21 @@ static int gaia_power_init(void) auto_power_on = 1; } +#ifdef BOARD_pit + /* + * Force the AP into reset unless we're doing a sysjump. Otherwise a + * suspended AP may still be in a strange state from the last reboot, + * and will hold XPSHOLD for a long time if it's in a low power state. + * See crosbug.com/p/22233. + */ + if (!(system_get_reset_flags() & RESET_FLAG_SYSJUMP)) { + CPRINTF("[%T not sysjump; forcing AP reset]\n"); + gpio_set_level(GPIO_AP_RESET_L, 0); + udelay(1000); + gpio_set_level(GPIO_AP_RESET_L, 1); + } +#endif + return EC_SUCCESS; } @@ -375,6 +390,16 @@ void chipset_force_shutdown(void) #ifndef BOARD_kirby gpio_set_level(GPIO_EN_PP5000, 0); #endif + +#ifdef BOARD_pit + /* + * Force the AP into reset. Otherwise it will hold XPSHOLD for a long + * time if it's in a low power state. See crosbug.com/p/22233. + */ + gpio_set_level(GPIO_AP_RESET_L, 0); + udelay(1000); + gpio_set_level(GPIO_AP_RESET_L, 1); +#endif } /*****************************************************************************/