From 9c43da5f0222cb79243f37e963fb6f26082abadf Mon Sep 17 00:00:00 2001 From: Diana Z Date: Mon, 30 Nov 2020 23:01:50 -0700 Subject: Dedede: Bail out of hibernate if z-state fails If we fail to enter z-state, this likely indicates that the z-state circuitry is in a state from which wake sources will not work. This would mean the EC would hibernate until a refresh+power sequence is run. Instead, choose to reset the system with the AP off. The battery will drain more quickly, but will be able to turn on when the power button is pressed normally. BRANCH=dedede BUG=b:166476907 TEST=on drawcia, remove C1 interrupt line sharing and wedge line low. Ensure "hibernate" run on the EC console from both S0 and G3 results in a reset with the AP off, and the system can be turned on with a power button press. Run with normal C1 interrupt line sharing in place and verify "hibernate" enters z-state as expected in S0 and G3. Signed-off-by: Diana Z Change-Id: I8408522dd1b0bbbce6f4e2bf6d0c550febd27bbf Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2567582 Reviewed-by: Aseda Aboagye Commit-Queue: Aseda Aboagye --- baseboard/dedede/baseboard.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'baseboard/dedede') diff --git a/baseboard/dedede/baseboard.c b/baseboard/dedede/baseboard.c index 87eba1771b..642133373e 100644 --- a/baseboard/dedede/baseboard.c +++ b/baseboard/dedede/baseboard.c @@ -229,6 +229,8 @@ DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, baseboard_chipset_shutdown, void board_hibernate_late(void) { + volatile uint32_t busy = 0; + /* Disable any pull-ups on C0 and C1 interrupt lines */ gpio_set_flags(GPIO_USB_C0_INT_ODL, GPIO_INPUT); gpio_set_flags(GPIO_USB_C1_INT_ODL, GPIO_INPUT); @@ -238,6 +240,24 @@ void board_hibernate_late(void) * the EC. */ gpio_set_level(GPIO_EN_SLP_Z, 1); + + /* + * Interrupts are disabled at this point, so busy-loop to consume some + * time (something on the order of at least 1 second, depending on EC + * chip being used) + */ + while (busy < 100000) + busy++; + + /* + * Still awake despite turning on zombie state? Reset with AP off is + * the best we can do in this situation. + */ + system_reset(SYSTEM_RESET_LEAVE_AP_OFF); + + /* Await our reset */ + while (1) + ; } int board_is_i2c_port_powered(int port) -- cgit v1.2.1