diff options
Diffstat (limited to 'board')
-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 |
3 files changed, 54 insertions, 0 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) { |