From ab88ce1416cfcbf0cd6a81cb16e0890eaef1eff1 Mon Sep 17 00:00:00 2001 From: Wai-Hong Tam Date: Thu, 30 Jan 2020 10:37:12 -0800 Subject: Trogdor: Separate the interrupt handlers of WARM_RESET_L and POWER_GOOD The original one interrupt handler for two signals will cause a false-postive for the WARM_RESET_L release case, during a transition state that POWER_GOOD goes low but WARM_RESET_L is still high. Use two interrupt handlers for WARM_RESET_L and its pull-up rail POWER_GOOD. It is clear that what signal triggers the interrupt. BRANCH=None BUG=b:148478178 TEST=Called "dut-control warm_reset:on sleep:0.2 warm_reset:off" and saw the message "Long warm reset ended, cold resetting to restore sanity" once. Change-Id: I5a14f91c0dbfacd6a70d01d45f3e8de2b6c6a1cc Signed-off-by: Wai-Hong Tam Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2031647 Reviewed-by: Alexandru M Stan Tested-by: Alexandru M Stan --- board/trogdor/gpio.inc | 2 +- include/chipset.h | 10 +++++++++- power/sc7180.c | 29 +++++++++++++++++------------ 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/board/trogdor/gpio.inc b/board/trogdor/gpio.inc index ed717a99bc..6320f6ce44 100644 --- a/board/trogdor/gpio.inc +++ b/board/trogdor/gpio.inc @@ -36,7 +36,7 @@ GPIO_INT(AP_SUSPEND, PIN(5, 7), GPIO_INT_BOTH | GPIO_SEL_1P8V, power_sign * for not only signalling power_signal_interrupt but also handling the logic * of WARM_RESET_L which is pulled-up by the same rail of POWER_GOOD. */ -GPIO_INT(POWER_GOOD, PIN(5, 4), GPIO_INT_BOTH | GPIO_PULL_DOWN, chipset_warm_reset_interrupt) /* SRC_PP1800_S10A from PMIC */ +GPIO_INT(POWER_GOOD, PIN(5, 4), GPIO_INT_BOTH | GPIO_PULL_DOWN, chipset_power_good_interrupt) /* SRC_PP1800_S10A from PMIC */ GPIO_INT(WARM_RESET_L, PIN(F, 4), GPIO_INT_BOTH | GPIO_SEL_1P8V, chipset_warm_reset_interrupt) /* AP warm reset */ GPIO_INT(AP_EC_SPI_CS_L, PIN(5, 3), GPIO_INT_FALLING | GPIO_PULL_DOWN, shi_cs_event) /* EC SPI Chip Select */ diff --git a/include/chipset.h b/include/chipset.h index 7b684598cb..d69f86a340 100644 --- a/include/chipset.h +++ b/include/chipset.h @@ -202,6 +202,7 @@ static inline void chipset_handle_espi_reset_assert(void) { } static inline void chipset_handle_reboot(void) { } static inline void chipset_reset_request_interrupt(enum gpio_signal signal) { } static inline void chipset_warm_reset_interrupt(enum gpio_signal signal) { } +static inline void chipset_power_good_interrupt(enum gpio_signal signal) { } static inline void chipset_watchdog_interrupt(enum gpio_signal signal) { } #endif /* !HAS_TASK_CHIPSET */ @@ -228,10 +229,17 @@ void chipset_reset_request_interrupt(enum gpio_signal signal); /** * GPIO interrupt handler of warm reset signal from servo or H1. * - * It is used in SDM845 chipset power sequence. + * It is used in Qualcomm chipset power sequence. */ void chipset_warm_reset_interrupt(enum gpio_signal signal); +/** + * GPIO interrupt handler of the power good signal (pull rail of warm reset). + * + * It is used in Qualcomm chipset power sequence. + */ +void chipset_power_good_interrupt(enum gpio_signal signal); + /** * GPIO interrupt handler of watchdog from AP. * diff --git a/power/sc7180.c b/power/sc7180.c index 7d8b5b9cb0..7788f04833 100644 --- a/power/sc7180.c +++ b/power/sc7180.c @@ -171,19 +171,8 @@ void chipset_warm_reset_interrupt(enum gpio_signal signal) GPIO_SEL_1P8V | GPIO_OUT_HIGH); gpio_set_flags(GPIO_AP_RST_L, GPIO_INT_BOTH | GPIO_SEL_1P8V | GPIO_OUT_LOW); - } else { - /* - * The pull-up rail POWER_GOOD drops. - * - * High-Z both AP_RST_L and PS_HOLD to restore their - * states. - */ - gpio_set_flags(GPIO_AP_RST_L, GPIO_INT_BOTH | - GPIO_SEL_1P8V); - gpio_set_flags(GPIO_PS_HOLD, GPIO_INT_BOTH | - GPIO_SEL_1P8V); - ap_rst_overdriven = 0; } + /* Ignore the else clause, the pull-up rail drops. */ } else { if (ap_rst_overdriven) { /* @@ -201,7 +190,23 @@ void chipset_warm_reset_interrupt(enum gpio_signal signal) } /* If not overdriven, just a normal power-up, do nothing. */ } + power_signal_interrupt(signal); +} +void chipset_power_good_interrupt(enum gpio_signal signal) +{ + if (!gpio_get_level(GPIO_POWER_GOOD) && ap_rst_overdriven) { + /* + * POWER_GOOD is the pull-up rail of WARM_RESET_L. + * When POWER_GOOD drops, high-Z both AP_RST_L and PS_HOLD + * to restore their states. + */ + gpio_set_flags(GPIO_AP_RST_L, GPIO_INT_BOTH | + GPIO_SEL_1P8V); + gpio_set_flags(GPIO_PS_HOLD, GPIO_INT_BOTH | + GPIO_SEL_1P8V); + ap_rst_overdriven = 0; + } power_signal_interrupt(signal); } -- cgit v1.2.1