diff options
-rw-r--r-- | board/cr50/board.c | 12 | ||||
-rw-r--r-- | board/cr50/board.h | 7 | ||||
-rw-r--r-- | board/cr50/power_button.c | 35 | ||||
-rw-r--r-- | chip/g/rbox.c | 9 |
4 files changed, 58 insertions, 5 deletions
diff --git a/board/cr50/board.c b/board/cr50/board.c index 30e8fc8791..f9b36d8eed 100644 --- a/board/cr50/board.c +++ b/board/cr50/board.c @@ -943,10 +943,22 @@ void assert_ec_rst(void) if (uart_bitbang_is_enabled()) task_disable_irq(bitbang_config.rx_irq); + /* + * If ec_rst was explicitly asserted, then do not let + * "power button release" deassert it if set earlier to do so. + */ + power_button_release_enable_interrupt(0); + GWRITE(RBOX, ASSERT_EC_RST, 1); } void deassert_ec_rst(void) { + /* + * If ec_rst was explicitly deasserted, then do not let + * "power button release" deassert it again if set earlier to do so. + */ + power_button_release_enable_interrupt(0); + GWRITE(RBOX, ASSERT_EC_RST, 0); if (uart_bitbang_is_enabled()) diff --git a/board/cr50/board.h b/board/cr50/board.h index 140f230d02..9e8da8acb1 100644 --- a/board/cr50/board.h +++ b/board/cr50/board.h @@ -269,6 +269,13 @@ int board_deep_sleep_allowed(void); void power_button_record(void); +/** + * Enable/disable power button release interrupt. + * + * @param enable Enable (!=0) or disable (==0) + */ +void power_button_release_enable_interrupt(int enable); + /* Functions needed by CCD config */ int board_battery_is_present(void); int board_fwmp_allows_unlock(void); diff --git a/board/cr50/power_button.c b/board/cr50/power_button.c index 96b3bb7774..efa402259a 100644 --- a/board/cr50/power_button.c +++ b/board/cr50/power_button.c @@ -17,6 +17,23 @@ #define CPRINTS(format, args...) cprints(CC_RBOX, format, ## args) #define CPRINTF(format, args...) cprintf(CC_RBOX, format, ## args) +DECLARE_DEFERRED(deassert_ec_rst); + +void power_button_release_enable_interrupt(int enable) +{ + /* Clear any leftover power button rising edge detection interrupts */ + GWRITE_FIELD(RBOX, INT_STATE, INTR_PWRB_IN_RED, 1); + + if (enable) { + /* Enable power button rising edge detection interrupt */ + GWRITE_FIELD(RBOX, INT_ENABLE, INTR_PWRB_IN_RED, 1); + task_enable_irq(GC_IRQNUM_RBOX0_INTR_PWRB_IN_RED_INT); + } else { + GWRITE_FIELD(RBOX, INT_ENABLE, INTR_PWRB_IN_RED, 0); + task_disable_irq(GC_IRQNUM_RBOX0_INTR_PWRB_IN_RED_INT); + } +} + /** * Enable/disable power button interrupt. * @@ -53,6 +70,24 @@ static void power_button_handler(void) } DECLARE_IRQ(GC_IRQNUM_RBOX0_INTR_PWRB_IN_FED_INT, power_button_handler, 1); +static void power_button_release_handler(void) +{ +#ifdef CR50_DEV + CPRINTS("power button released"); +#endif + + /* + * Let deassert_ec_rst be called deferred rather than + * by interrupt handler. + */ + hook_call_deferred(&deassert_ec_rst_data, 0); + + /* Note that this is for one-time use through the current power on. */ + power_button_release_enable_interrupt(0); +} +DECLARE_IRQ(GC_IRQNUM_RBOX0_INTR_PWRB_IN_RED_INT, power_button_release_handler, + 1); + #ifdef CONFIG_U2F static void power_button_init(void) { diff --git a/chip/g/rbox.c b/chip/g/rbox.c index 513e6ebb58..00fac521b6 100644 --- a/chip/g/rbox.c +++ b/chip/g/rbox.c @@ -10,8 +10,6 @@ #include "system.h" #include "timer.h" -#define DELAY_EC_BOOT_USEC (2 * SECOND) -DECLARE_DEFERRED(deassert_ec_rst); void rbox_clear_wakeup(void) { @@ -39,12 +37,13 @@ static void rbox_release_ec_reset(void) /* Unfreeze the PINMUX */ GREG32(PINMUX, HOLD) = 0; - /* After a POR, if it finds RDD cable plugged and Power button pressed, - * then it delays booting EC by DELAY_EC_BOOT_USEC. + /* + * After a POR, if it finds RDD cable plugged and Power button pressed, + * then it delays releasing EC-reset until power button gets released. */ if ((system_get_reset_flags() & RESET_FLAG_POWER_ON) && rdd_is_detected() && rbox_powerbtn_is_pressed()) { - hook_call_deferred(&deassert_ec_rst_data, DELAY_EC_BOOT_USEC); + power_button_release_enable_interrupt(1); return; } |