diff --git a/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts b/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts index c60f4c59d81..42716adfb2a 100644 --- a/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts +++ b/boards/riscv/it8xxx2_evb/it8xxx2_evb.dts @@ -31,6 +31,7 @@ aliases { led0 = &led0; kscan0 = &kscan0; + watchdog0 = &twd0; }; leds { diff --git a/drivers/watchdog/Kconfig.it8xxx2 b/drivers/watchdog/Kconfig.it8xxx2 index 63aae1a66eb..85f117599c0 100644 --- a/drivers/watchdog/Kconfig.it8xxx2 +++ b/drivers/watchdog/Kconfig.it8xxx2 @@ -17,3 +17,12 @@ config WDT_ITE_WARNING_LEADING_TIME_MS This option defines the window in which a watchdog event must be handled. After this time window, the watchdog reset triggers immediately. + +config WDT_ITE_REDUCE_WARNING_LEADING_TIME + bool "Reduce warning leading time" + depends on SOC_IT8XXX2 + default n + help + Once warning timer triggered, if watchdog timer isn't reloaded, + then we will reduce interval of warning timer to 30ms to print + more warning messages before watchdog reset. diff --git a/drivers/watchdog/wdt_ite_it8xxx2.c b/drivers/watchdog/wdt_ite_it8xxx2.c index 486165b8495..cb2856631c6 100644 --- a/drivers/watchdog/wdt_ite_it8xxx2.c +++ b/drivers/watchdog/wdt_ite_it8xxx2.c @@ -51,8 +51,11 @@ static int wdt_it8xxx2_install_timeout(const struct device *dev, return -EBUSY; } - /* no window watchdog support */ - if (config->window.min != 0) { + /* + * Not support lower limit window timeouts (min value must be equal to + * 0). Upper limit window timeouts can't be 0 when we install timeout. + */ + if ((config->window.min != 0) || (config->window.max == 0)) { data->timeout_installed = false; return -EINVAL; } @@ -95,11 +98,6 @@ static int wdt_it8xxx2_setup(const struct device *dev, uint8_t options) return -ENOTSUP; } - if ((options & WDT_OPT_PAUSE_HALTED_BY_DBG) != 0) { - LOG_ERR("WDT_OPT_PAUSE_HALTED_BY_DBG is not supported"); - return -ENOTSUP; - } - /* pre-warning timer1 is 16-bit counter down timer */ inst->ET1CNTLHR = (cnt0 >> 8) & 0xff; inst->ET1CNTLLR = cnt0 & 0xff; @@ -110,6 +108,9 @@ static int wdt_it8xxx2_setup(const struct device *dev, uint8_t options) /* enable pre-warning timer1 interrupt */ irq_enable(DT_INST_IRQN(0)); + /* don't stop watchdog timer counting */ + inst->ETWCTRL &= ~IT8XXX2_WDT_EWDSCEN; + /* set watchdog timer count */ inst->EWDCNTHR = (cnt1 >> 8) & 0xff; inst->EWDCNTLR = cnt1 & 0xff; @@ -120,15 +121,13 @@ static int wdt_it8xxx2_setup(const struct device *dev, uint8_t options) /* * bit5 = 1: enable key match function to touch watchdog * bit4 = 1: select watchdog clock source from prescaler - * bit3 = 1: lock watchdog count register + * bit3 = 1: lock watchdog count register (also mark as watchdog running) * bit1 = 1: lock timer1 prescaler register - * bit0 = 1: lock watchdog and timer1 config register */ inst->ETWCFG = (IT8XXX2_WDT_EWDKEYEN | IT8XXX2_WDT_EWDSRC | IT8XXX2_WDT_LEWDCNTL | - IT8XXX2_WDT_LET1PS | - IT8XXX2_WDT_LETWCFG); + IT8XXX2_WDT_LET1PS); LOG_DBG("WDT Setup and enabled"); @@ -184,6 +183,9 @@ static int wdt_it8xxx2_disable(const struct device *dev) /* stop watchdog timer counting */ inst->ETWCTRL |= IT8XXX2_WDT_EWDSCEN; + /* unlock watchdog count register (also mark as watchdog not running) */ + inst->ETWCFG &= ~IT8XXX2_WDT_LEWDCNTL; + /* disable pre-warning timer1 interrupt */ irq_disable(DT_INST_IRQN(0)); @@ -211,12 +213,13 @@ static void wdt_it8xxx2_isr(const struct device *dev) data->callback(dev, 0); } +#ifdef CONFIG_WDT_ITE_REDUCE_WARNING_LEADING_TIME /* * Once warning timer triggered: if watchdog timer isn't reloaded, * then we will reduce interval of warning timer to 30ms to print * more warning messages before watchdog reset. */ - if (!wdt_warning_fired++) { + if (!wdt_warning_fired) { uint16_t cnt0 = WARNING_TIMER_PERIOD_MS_TO_1024HZ_COUNT(30); /* pre-warning timer1 is 16-bit counter down timer */ @@ -226,6 +229,8 @@ static void wdt_it8xxx2_isr(const struct device *dev) /* clear pre-warning timer1 interrupt status */ ite_intc_isr_clear(DT_INST_IRQN(0)); } +#endif + wdt_warning_fired++; LOG_DBG("WDT ISR"); } @@ -255,7 +260,10 @@ static int wdt_it8xxx2_init(const struct device *dev) inst->ETWCFG = (IT8XXX2_WDT_EWDKEYEN | IT8XXX2_WDT_EWDSRC); - /* watchdog can be stopped */ + /* + * select the mode that watchdog can be stopped, this is needed for + * wdt_it8xxx2_disable() api and WDT_OPT_PAUSE_HALTED_BY_DBG flag + */ inst->ETWCTRL |= IT8XXX2_WDT_EWDSCMS; IRQ_CONNECT(DT_INST_IRQN(0), 0, wdt_it8xxx2_isr,