drivers: wdt: sam0: fix register access in feed()

The wdt CLEAR register is a write synchronized register.
To avoid bus stall, check the status of SYNCBUSY before
accessing the register.

Use SYNCBUSY register for SAM E.
If the wdt is syncing, return -EAGAIN to avoid bus stall.

Signed-off-by: Steven Slupsky <sslupsky@gmail.com>
This commit is contained in:
Steven Slupsky 2020-02-20 08:13:46 -07:00 committed by Anas Nashif
commit a18a73c19b

View file

@ -26,6 +26,13 @@ LOG_MODULE_REGISTER(wdt_sam0);
#define WDT_CONFIG_PER_16K_Val WDT_CONFIG_PER_CYC16384_Val #define WDT_CONFIG_PER_16K_Val WDT_CONFIG_PER_CYC16384_Val
#endif #endif
/* syncbusy check is different for SAM D/E */
#ifdef WDT_STATUS_SYNCBUSY
#define WDT_SYNCBUSY WDT_REGS->STATUS.bit.SYNCBUSY
#else
#define WDT_SYNCBUSY WDT_REGS->SYNCBUSY.reg
#endif
struct wdt_sam0_dev_data { struct wdt_sam0_dev_data {
wdt_callback_t cb; wdt_callback_t cb;
bool timeout_valid; bool timeout_valid;
@ -37,13 +44,9 @@ static struct wdt_sam0_dev_data wdt_sam0_data = { 0 };
static void wdt_sam0_wait_synchronization(void) static void wdt_sam0_wait_synchronization(void)
{ {
#ifdef WDT_STATUS_SYNCBUSY while (WDT_SYNCBUSY) {
while (WDT_REGS->STATUS.bit.SYNCBUSY) { /* wait for SYNCBUSY */
} }
#else
while (WDT_REGS->SYNCBUSY.reg) {
}
#endif
} }
static inline void wdt_sam0_set_enable(bool on) static inline void wdt_sam0_set_enable(bool on)
@ -231,6 +234,10 @@ static int wdt_sam0_feed(struct device *dev, int channel_id)
return -EINVAL; return -EINVAL;
} }
if (WDT_SYNCBUSY) {
return -EAGAIN;
}
WDT_REGS->CLEAR.reg = WDT_CLEAR_CLEAR_KEY_Val; WDT_REGS->CLEAR.reg = WDT_CLEAR_CLEAR_KEY_Val;
return 0; return 0;