aboutsummaryrefslogtreecommitdiffstats
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 @@
34 34
35#define PFX KBUILD_MODNAME ": " 35#define PFX KBUILD_MODNAME ": "
36 36
37#define VERSION "0.4" 37#define VERSION "0.5"
38 38
39static struct { 39static struct {
40 unsigned long inuse; 40 unsigned long inuse;
@@ -58,6 +58,9 @@ extern unsigned int idt_cpu_freq;
58#define WATCHDOG_TIMEOUT 20 58#define WATCHDOG_TIMEOUT 20
59 59
60static int timeout = WATCHDOG_TIMEOUT; 60static int timeout = WATCHDOG_TIMEOUT;
61module_param(timeout, int, 0);
62MODULE_PARM_DESC(timeout, "Watchdog timeout value, in seconds (default="
63 WATCHDOG_TIMEOUT ")");
61 64
62static int nowayout = WATCHDOG_NOWAYOUT; 65static int nowayout = WATCHDOG_NOWAYOUT;
63module_param(nowayout, int, 0); 66module_param(nowayout, int, 0);
@@ -68,6 +71,21 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
68#define SET_BITS(addr, or, nand) \ 71#define SET_BITS(addr, or, nand) \
69 writel((readl(&addr) | or) & ~nand, &addr) 72 writel((readl(&addr) | or) & ~nand, &addr)
70 73
74static int rc32434_wdt_set(int new_timeout)
75{
76 int max_to = WTCOMP2SEC((u32)-1);
77
78 if (new_timeout < 0 || new_timeout > max_to) {
79 printk(KERN_ERR PFX "timeout value must be between 0 and %d",
80 max_to);
81 return -EINVAL;
82 }
83 timeout = new_timeout;
84 writel(SEC2WTCOMP(timeout), &wdt_reg->wtcompare);
85
86 return 0;
87}
88
71static void rc32434_wdt_start(void) 89static void rc32434_wdt_start(void)
72{ 90{
73 u32 or, nand; 91 u32 or, nand;
@@ -85,6 +103,9 @@ static void rc32434_wdt_start(void)
85 103
86 SET_BITS(wdt_reg->errcs, or, nand); 104 SET_BITS(wdt_reg->errcs, or, nand);
87 105
106 /* set the timeout (either default or based on module param) */
107 rc32434_wdt_set(timeout);
108
88 /* reset WTC timeout bit and enable WDT */ 109 /* reset WTC timeout bit and enable WDT */
89 nand = 1 << RC32434_WTC_TO; 110 nand = 1 << RC32434_WTC_TO;
90 or = 1 << RC32434_WTC_EN; 111 or = 1 << RC32434_WTC_EN;
@@ -102,21 +123,6 @@ static void rc32434_wdt_stop(void)
102 printk(KERN_INFO PFX "Stopped watchdog timer.\n"); 123 printk(KERN_INFO PFX "Stopped watchdog timer.\n");
103} 124}
104 125
105static int rc32434_wdt_set(int new_timeout)
106{
107 int max_to = WTCOMP2SEC((u32)-1);
108
109 if (new_timeout < 0 || new_timeout > max_to) {
110 printk(KERN_ERR PFX "timeout value must be between 0 and %d",
111 max_to);
112 return -EINVAL;
113 }
114 timeout = new_timeout;
115 writel(SEC2WTCOMP(timeout), &wdt_reg->wtcompare);
116
117 return 0;
118}
119
120static void rc32434_wdt_ping(void) 126static void rc32434_wdt_ping(void)
121{ 127{
122 writel(0, &wdt_reg->wtcount); 128 writel(0, &wdt_reg->wtcount);
@@ -264,6 +270,15 @@ static int __devinit rc32434_wdt_probe(struct platform_device *pdev)
264 return -ENXIO; 270 return -ENXIO;
265 } 271 }
266 272
273 /* Check that the heartbeat value is within it's range;
274 * if not reset to the default */
275 if (rc32434_wdt_set(timeout)) {
276 rc32434_wdt_set(WATCHDOG_TIMEOUT);
277 printk(KERN_INFO PFX
278 "timeout value must be between 0 and %d\n",
279 WTCOMP2SEC((u32)-1));
280 }
281
267 ret = misc_register(&rc32434_wdt_miscdev); 282 ret = misc_register(&rc32434_wdt_miscdev);
268 if (ret < 0) { 283 if (ret < 0) {
269 printk(KERN_ERR PFX "failed to register watchdog device\n"); 284 printk(KERN_ERR PFX "failed to register watchdog device\n");