summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/watchdog/rc32434_wdt.c47
1 files changed, 31 insertions, 16 deletions
diff --git a/drivers/watchdog/rc32434_wdt.c b/drivers/watchdog/rc32434_wdt.c
index 68fb22625cdc..89f326a39b6b 100644
--- a/drivers/watchdog/rc32434_wdt.c
+++ b/drivers/watchdog/rc32434_wdt.c
@@ -34,7 +34,7 @@
#define PFX KBUILD_MODNAME ": "
-#define VERSION "0.4"
+#define VERSION "0.5"
static struct {
unsigned long inuse;
@@ -58,6 +58,9 @@ extern unsigned int idt_cpu_freq;
#define WATCHDOG_TIMEOUT 20
static int timeout = WATCHDOG_TIMEOUT;
+module_param(timeout, int, 0);
+MODULE_PARM_DESC(timeout, "Watchdog timeout value, in seconds (default="
+ WATCHDOG_TIMEOUT ")");
static int nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, int, 0);
@@ -68,6 +71,21 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
#define SET_BITS(addr, or, nand) \
writel((readl(&addr) | or) & ~nand, &addr)
+static int rc32434_wdt_set(int new_timeout)
+{
+ int max_to = WTCOMP2SEC((u32)-1);
+
+ if (new_timeout < 0 || new_timeout > max_to) {
+ printk(KERN_ERR PFX "timeout value must be between 0 and %d",
+ max_to);
+ return -EINVAL;
+ }
+ timeout = new_timeout;
+ writel(SEC2WTCOMP(timeout), &wdt_reg->wtcompare);
+
+ return 0;
+}
+
static void rc32434_wdt_start(void)
{
u32 or, nand;
@@ -85,6 +103,9 @@ static void rc32434_wdt_start(void)
SET_BITS(wdt_reg->errcs, or, nand);
+ /* set the timeout (either default or based on module param) */
+ rc32434_wdt_set(timeout);
+
/* reset WTC timeout bit and enable WDT */
nand = 1 << RC32434_WTC_TO;
or = 1 << RC32434_WTC_EN;
@@ -102,21 +123,6 @@ static void rc32434_wdt_stop(void)
printk(KERN_INFO PFX "Stopped watchdog timer.\n");
}
-static int rc32434_wdt_set(int new_timeout)
-{
- int max_to = WTCOMP2SEC((u32)-1);
-
- if (new_timeout < 0 || new_timeout > max_to) {
- printk(KERN_ERR PFX "timeout value must be between 0 and %d",
- max_to);
- return -EINVAL;
- }
- timeout = new_timeout;
- writel(SEC2WTCOMP(timeout), &wdt_reg->wtcompare);
-
- return 0;
-}
-
static void rc32434_wdt_ping(void)
{
writel(0, &wdt_reg->wtcount);
@@ -264,6 +270,15 @@ static int __devinit rc32434_wdt_probe(struct platform_device *pdev)
return -ENXIO;
}
+ /* Check that the heartbeat value is within it's range;
+ * if not reset to the default */
+ if (rc32434_wdt_set(timeout)) {
+ rc32434_wdt_set(WATCHDOG_TIMEOUT);
+ printk(KERN_INFO PFX
+ "timeout value must be between 0 and %d\n",
+ WTCOMP2SEC((u32)-1));
+ }
+
ret = misc_register(&rc32434_wdt_miscdev);
if (ret < 0) {
printk(KERN_ERR PFX "failed to register watchdog device\n");