]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/commitdiff
watchdog: jz4740: Avoid starting watchdog in set_timeout
authorPaul Cercueil <paul@crapouillou.net>
Fri, 7 Jun 2019 16:24:27 +0000 (18:24 +0200)
committerWim Van Sebroeck <wim@linux-watchdog.org>
Mon, 8 Jul 2019 14:10:11 +0000 (16:10 +0200)
Previously the jz4740_wdt_set_timeout() function was starting the timer
unconditionally, even if it was stopped when that function was entered.

Now, the timer will be restarted only if it was already running before
this function is called.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
drivers/watchdog/jz4740_wdt.c

index f1199db7bffa57ad29d979e6eb7819ee4827ab29..d4a90916dd382d7f876915b5ec3eb968ea978e87 100644 (file)
@@ -68,6 +68,7 @@ static int jz4740_wdt_set_timeout(struct watchdog_device *wdt_dev,
        unsigned int rtc_clk_rate;
        unsigned int timeout_value;
        unsigned short clock_div = JZ_WDT_CLOCK_DIV_1;
+       u8 tcer;
 
        rtc_clk_rate = clk_get_rate(drvdata->rtc_clk);
 
@@ -83,6 +84,7 @@ static int jz4740_wdt_set_timeout(struct watchdog_device *wdt_dev,
                clock_div += (1 << TCU_TCSR_PRESCALE_LSB);
        }
 
+       tcer = readb(drvdata->base + TCU_REG_WDT_TCER);
        writeb(0x0, drvdata->base + TCU_REG_WDT_TCER);
        writew(clock_div, drvdata->base + TCU_REG_WDT_TCSR);
 
@@ -90,7 +92,8 @@ static int jz4740_wdt_set_timeout(struct watchdog_device *wdt_dev,
        writew(0x0, drvdata->base + TCU_REG_WDT_TCNT);
        writew(clock_div | JZ_WDT_CLOCK_RTC, drvdata->base + TCU_REG_WDT_TCSR);
 
-       writeb(0x1, drvdata->base + TCU_REG_WDT_TCER);
+       if (tcer & TCU_WDT_TCER_TCEN)
+               writeb(TCU_WDT_TCER_TCEN, drvdata->base + TCU_REG_WDT_TCER);
 
        wdt_dev->timeout = new_timeout;
        return 0;
@@ -98,9 +101,18 @@ static int jz4740_wdt_set_timeout(struct watchdog_device *wdt_dev,
 
 static int jz4740_wdt_start(struct watchdog_device *wdt_dev)
 {
+       struct jz4740_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev);
+       u8 tcer;
+
+       tcer = readb(drvdata->base + TCU_REG_WDT_TCER);
+
        jz4740_timer_enable_watchdog();
        jz4740_wdt_set_timeout(wdt_dev, wdt_dev->timeout);
 
+       /* Start watchdog if it wasn't started already */
+       if (!(tcer & TCU_WDT_TCER_TCEN))
+               writeb(TCU_WDT_TCER_TCEN, drvdata->base + TCU_REG_WDT_TCER);
+
        return 0;
 }