Skip to content

Commit f76084b

Browse files
committed
drivers: watchdog: npcx: fix T0 timer reload procedure
The correct procedure to reload the T0 timer is: 1. Load TWDT0 register with the new value or write 1 to RST bit in T0CSR register to load the old value. 2. Wait until RST bit in T0CSR register becomes 1. 3. Wait until RST bit in T0CSR register becomes 0. The current watchdog driver misses step 2. Fix the issue in this commit. Signed-off-by: Jun Lin <[email protected]>
1 parent c387fca commit f76084b

File tree

1 file changed

+15
-2
lines changed

1 file changed

+15
-2
lines changed

drivers/watchdog/wdt_npcx.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ LOG_MODULE_REGISTER(wdt_npcx, CONFIG_WDT_LOG_LEVEL);
6161
#define NPCX_WDT_MIN_WND_TIME 100UL
6262

6363
/* Timeout for reloading and restarting Timer 0. (Unit:ms) */
64-
#define NPCX_T0CSR_RST_TIMEOUT 2
64+
#define NPCX_T0CSR_RST_CLEAR_TIMEOUT 2
65+
#define NPCX_T0CSR_RST_SET_TIMEOUT 1
6566

6667
/* Timeout for stopping watchdog. (Unit:ms) */
6768
#define NPCX_WATCHDOG_STOP_TIMEOUT 1
@@ -100,10 +101,22 @@ static inline int wdt_t0out_reload(const struct device *dev)
100101
/* Reload and restart T0 timer */
101102
inst->T0CSR = (inst->T0CSR & ~BIT(NPCX_T0CSR_WDRST_STS)) |
102103
BIT(NPCX_T0CSR_RST);
104+
/*
105+
* Wait for the T0CSR_RST bit to change from 0 to 1. This transition is expected to occur
106+
* over multiple LFCLK cycles. If a timeout occurs, we can assume that the bit has changed
107+
* from 0 -> 1 -> 0, but the polling thread missed it because it was preempted by
108+
* higher-priority threads. In this case, we can simply return.
109+
*/
110+
st = k_uptime_get();
111+
while (!IS_BIT_SET(inst->T0CSR, NPCX_T0CSR_RST)) {
112+
if (k_uptime_get() - st > NPCX_T0CSR_RST_SET_TIMEOUT) {
113+
return 0;
114+
}
115+
}
103116
/* Wait for timer is loaded and restart */
104117
st = k_uptime_get();
105118
while (IS_BIT_SET(inst->T0CSR, NPCX_T0CSR_RST)) {
106-
if (k_uptime_get() - st > NPCX_T0CSR_RST_TIMEOUT) {
119+
if (k_uptime_get() - st > NPCX_T0CSR_RST_CLEAR_TIMEOUT) {
107120
/* RST bit is still set? */
108121
if (IS_BIT_SET(inst->T0CSR, NPCX_T0CSR_RST)) {
109122
LOG_ERR("Timeout: reload T0 timer!");

0 commit comments

Comments
 (0)