|
@@ -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");
|