summaryrefslogtreecommitdiff
path: root/drivers/watchdog
diff options
context:
space:
mode:
authorAndrej Picej <andrej.picej@norik.com>2021-12-16 13:26:53 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2022-01-17 14:30:21 +0100
commitc3787a81f26bb1daa82136ddc392c40c36d3317e (patch)
treee8d35aada92bd89b3152633232f9d43c459b424a /drivers/watchdog
parent806ab9d9c7a08e41fe40f56ec0a8bd065200e2b8 (diff)
downloadbarebox-c3787a81f26bb1daa82136ddc392c40c36d3317e.tar.gz
watchdog: imxwd: suspend watchdog timer in low power mode
Watchdog timer should be disabled in low power mode. The problem that was observed was that when the watchdog is started from barebox, kernel driver doesn't do its own setup again and in turn this bit is left unset. Moreover, this bit is write-once and has to be set before enabling the watchdog, leaving responsibility for proper setup to a party first using the watchdog timer (e.g. bootloader). Issue manifests itself later on, when device enters low power mode (e.g. suspend) for more amount of time than what is maximum watchdog timeout (128s). After that period of time, device will not recover ever as there is no service patting the watchdog (CPU is suspended). This means that the device can hang in suspend mode or it performs an unexpected reset. Thus to avoid suspend/resume problems when watchdog is started already in the bootloader, align bootloader driver settings with kernel settings. Kernel driver has been already setting this bit since 2014. Signed-off-by: Andrej Picej <andrej.picej@norik.com> Link: https://lore.barebox.org/20211216122653.2335949-1-andrej.picej@norik.com Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/watchdog')
-rw-r--r--drivers/watchdog/imxwd.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/drivers/watchdog/imxwd.c b/drivers/watchdog/imxwd.c
index 25b11077b9..31ea388c2c 100644
--- a/drivers/watchdog/imxwd.c
+++ b/drivers/watchdog/imxwd.c
@@ -47,6 +47,7 @@ struct imx_wd {
#define IMX21_WDOG_WSR 0x02 /* Watchdog Service Register */
#define IMX21_WDOG_WSTR 0x04 /* Watchdog Status Register */
#define IMX21_WDOG_WMCR 0x08 /* Misc Register */
+#define IMX21_WDOG_WCR_WDZST (1 << 0)
#define IMX21_WDOG_WCR_WDE (1 << 2)
#define IMX21_WDOG_WCR_WDT (1 << 3)
#define IMX21_WDOG_WCR_SRS (1 << 4)
@@ -125,6 +126,9 @@ static int imx21_watchdog_set_timeout(struct imx_wd *priv, unsigned timeout)
if (priv->ext_reset)
val |= IMX21_WDOG_WCR_WDT;
+ /* Suspend timer in low power mode */
+ val |= IMX21_WDOG_WCR_WDZST;
+
/*
* set time and some write once bits first prior enabling the
* watchdog according to the datasheet