Skip to content

Commit 528d139

Browse files
ChiHuaLnashif
authored andcommitted
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]> (cherry picked from commit 6c3b617)
1 parent bc26e1a commit 528d139

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)