summaryrefslogtreecommitdiff
path: root/drivers/watchdog
diff options
context:
space:
mode:
authorBai Ping <ping.bai@nxp.com>2016-11-29 14:52:46 +0800
committerJason Liu <jason.hui.liu@nxp.com>2019-02-12 10:25:18 +0800
commite2751fdc94618015b406ba1845b800271e22292d (patch)
treeaf6d09f48487176b1d69be50a893ae39de7c7aa4 /drivers/watchdog
parent86d61639098358efde31884bdcc16bc93ba457dc (diff)
MLK-13535 driver: watchdog: fix wdog reset after resume from vlls mode
When resuming from VLLS mode, the wdog will be reset, the first we configure the wdog, an initial timeout value should be write into the TOVAL register, otherwise, the wdog will not be initialized successfully. Signed-off-by: Bai Ping <ping.bai@nxp.com>
Diffstat (limited to 'drivers/watchdog')
-rw-r--r--drivers/watchdog/imx7ulp_wdt.c34
1 files changed, 19 insertions, 15 deletions
diff --git a/drivers/watchdog/imx7ulp_wdt.c b/drivers/watchdog/imx7ulp_wdt.c
index a6fb6f441bb4..55769b1a44f5 100644
--- a/drivers/watchdog/imx7ulp_wdt.c
+++ b/drivers/watchdog/imx7ulp_wdt.c
@@ -119,7 +119,7 @@ static const struct watchdog_info imx7ulp_wdt_info = {
| WDIOF_MAGICCLOSE,
};
-static inline void imx7ulp_wdt_init(void __iomem *base)
+static inline void imx7ulp_wdt_init(void __iomem *base, unsigned int timeout)
{
u32 val;
@@ -127,14 +127,15 @@ static inline void imx7ulp_wdt_init(void __iomem *base)
/*
* if the wdog is in unlocked status, the UNLOCK
- * sequence should not be send.
+ * sequence no need to be send.
*/
val = readl(base + WDOG_CS);
if (!(val & WDOG_CS_ULK)) {
- writew(UNLOCK_SEQ0, base + WDOG_CNT);
- writew(UNLOCK_SEQ1, base + WDOG_CNT);
+ writel(UNLOCK_SEQ0, base + WDOG_CNT);
+ writel(UNLOCK_SEQ1, base + WDOG_CNT);
}
-
+ /*set an initial timeout value in TOVAL */
+ writel(timeout, base + WDOG_TOVAL);
/* enable 32bit command sequence and reconfigure */
val = (1 << 13) | (1 << 8) | (1 << 5);
writel(val, base + WDOG_CS);
@@ -147,6 +148,7 @@ static int imx7ulp_wdt_probe(struct platform_device *pdev)
struct imx7ulp_wdt *wdt;
struct resource *res;
int err;
+ u32 timeout;
wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt)
@@ -159,9 +161,6 @@ static int imx7ulp_wdt_probe(struct platform_device *pdev)
if (IS_ERR(wdt->base))
return PTR_ERR(wdt->base);
- /* reconfigure the watchdog timer.*/
- imx7ulp_wdt_init(wdt->base);
-
/* use the 1KHz LPO as the counter clock */
wdt->rate = 1000;
@@ -176,9 +175,15 @@ static int imx7ulp_wdt_probe(struct platform_device *pdev)
* set the timeout_parm to 0 to get the timeout
* from 'timeout-sec' property in dtb.
*/
- watchdog_init_timeout(&wdt->wdd, 0, &pdev->dev);
- /* set the initial timout value into TOVAL */
- imx7ulp_wdt_set_timeout(&wdt->wdd, wdt->wdd.timeout);
+ err = watchdog_init_timeout(&wdt->wdd, 0, &pdev->dev);
+ if (err) {
+ dev_err(&pdev->dev, "Failed to init the wdog timeout\n");
+ return err;
+ }
+
+ timeout = wdt->wdd.timeout * wdt->rate;
+ /* reconfigure the watchdog timer.*/
+ imx7ulp_wdt_init(wdt->base, timeout);
err = watchdog_register_device(&wdt->wdd);
if (err) {
@@ -222,14 +227,13 @@ static int imx7ulp_wdt_suspend(struct device *dev)
static int imx7ulp_wdt_resume(struct device *dev)
{
struct imx7ulp_wdt *wdt = dev_get_drvdata(dev);
+ u32 timeout = wdt->wdd.timeout * wdt->rate;
if (imx7ulp_wdt_is_enabled(wdt->base))
- imx7ulp_wdt_init(wdt->base);
+ imx7ulp_wdt_init(wdt->base, timeout);
- if (watchdog_active(&wdt->wdd)) {
- imx7ulp_wdt_set_timeout(&wdt->wdd, wdt->wdd.timeout);
+ if (watchdog_active(&wdt->wdd))
imx7ulp_wdt_enable(wdt->base, true);
- }
return 0;
}