Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions drivers/watchdog/wdt_npcx.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ LOG_MODULE_REGISTER(wdt_npcx, CONFIG_WDT_LOG_LEVEL);
#define NPCX_WDT_MIN_WND_TIME 100UL

/* Timeout for reloading and restarting Timer 0. (Unit:ms) */
#define NPCX_T0CSR_RST_TIMEOUT 2
#define NPCX_T0CSR_RST_CLEAR_TIMEOUT 2
#define NPCX_T0CSR_RST_SET_TIMEOUT 1

/* Timeout for stopping watchdog. (Unit:ms) */
#define NPCX_WATCHDOG_STOP_TIMEOUT 1
Expand Down Expand Up @@ -100,10 +101,22 @@ static inline int wdt_t0out_reload(const struct device *dev)
/* Reload and restart T0 timer */
inst->T0CSR = (inst->T0CSR & ~BIT(NPCX_T0CSR_WDRST_STS)) |
BIT(NPCX_T0CSR_RST);
/*
* Wait for the T0CSR_RST bit to change from 0 to 1. This transition is expected to occur
* over multiple LFCLK cycles. If a timeout occurs, we can assume that the bit has changed
* from 0 -> 1 -> 0, but the polling thread missed it because it was preempted by
* higher-priority threads. In this case, we can simply return.
*/
st = k_uptime_get();
while (!IS_BIT_SET(inst->T0CSR, NPCX_T0CSR_RST)) {
if (k_uptime_get() - st > NPCX_T0CSR_RST_SET_TIMEOUT) {
return 0;
}
}
/* Wait for timer is loaded and restart */
st = k_uptime_get();
while (IS_BIT_SET(inst->T0CSR, NPCX_T0CSR_RST)) {
if (k_uptime_get() - st > NPCX_T0CSR_RST_TIMEOUT) {
if (k_uptime_get() - st > NPCX_T0CSR_RST_CLEAR_TIMEOUT) {
/* RST bit is still set? */
if (IS_BIT_SET(inst->T0CSR, NPCX_T0CSR_RST)) {
LOG_ERR("Timeout: reload T0 timer!");
Expand Down
Loading