Commit 9b346118 authored by Paul Cercueil's avatar Paul Cercueil Committed by Wim Van Sebroeck

watchdog: jz4740: Avoid starting watchdog in set_timeout

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: default avatarPaul Cercueil <paul@crapouillou.net>
Reviewed-by: default avatarGuenter Roeck <linux@roeck-us.net>
Signed-off-by: default avatarGuenter Roeck <linux@roeck-us.net>
Signed-off-by: default avatarWim Van Sebroeck <wim@linux-watchdog.org>
parent df04cce3
...@@ -68,6 +68,7 @@ static int jz4740_wdt_set_timeout(struct watchdog_device *wdt_dev, ...@@ -68,6 +68,7 @@ static int jz4740_wdt_set_timeout(struct watchdog_device *wdt_dev,
unsigned int rtc_clk_rate; unsigned int rtc_clk_rate;
unsigned int timeout_value; unsigned int timeout_value;
unsigned short clock_div = JZ_WDT_CLOCK_DIV_1; unsigned short clock_div = JZ_WDT_CLOCK_DIV_1;
u8 tcer;
rtc_clk_rate = clk_get_rate(drvdata->rtc_clk); rtc_clk_rate = clk_get_rate(drvdata->rtc_clk);
...@@ -83,6 +84,7 @@ static int jz4740_wdt_set_timeout(struct watchdog_device *wdt_dev, ...@@ -83,6 +84,7 @@ static int jz4740_wdt_set_timeout(struct watchdog_device *wdt_dev,
clock_div += (1 << TCU_TCSR_PRESCALE_LSB); clock_div += (1 << TCU_TCSR_PRESCALE_LSB);
} }
tcer = readb(drvdata->base + TCU_REG_WDT_TCER);
writeb(0x0, drvdata->base + TCU_REG_WDT_TCER); writeb(0x0, drvdata->base + TCU_REG_WDT_TCER);
writew(clock_div, drvdata->base + TCU_REG_WDT_TCSR); writew(clock_div, drvdata->base + TCU_REG_WDT_TCSR);
...@@ -90,7 +92,8 @@ static int jz4740_wdt_set_timeout(struct watchdog_device *wdt_dev, ...@@ -90,7 +92,8 @@ static int jz4740_wdt_set_timeout(struct watchdog_device *wdt_dev,
writew(0x0, drvdata->base + TCU_REG_WDT_TCNT); writew(0x0, drvdata->base + TCU_REG_WDT_TCNT);
writew(clock_div | JZ_WDT_CLOCK_RTC, drvdata->base + TCU_REG_WDT_TCSR); 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; wdt_dev->timeout = new_timeout;
return 0; return 0;
...@@ -98,9 +101,18 @@ static int jz4740_wdt_set_timeout(struct watchdog_device *wdt_dev, ...@@ -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) 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_timer_enable_watchdog();
jz4740_wdt_set_timeout(wdt_dev, wdt_dev->timeout); 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; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment