aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhil Sutter <n0-1@freewrt.org>2009-02-08 10:44:42 -0500
committerWim Van Sebroeck <wim@iguana.be>2009-03-25 05:00:05 -0400
commit08eb2e0c084778f30691e3f18540cdb754c56530 (patch)
tree3bf0dc94b35e4db2452944db4391874d7672b2f8
parent9b655e07d77e3b1a00c1c8302e2ef3b7fb719de3 (diff)
[WATCHDOG] rc32434_wdt: add timeout module parameter
The WDT timer ticks quite fast (half of the CPU clock speed, which may be between 198MHz and 330MHz (or 400MHz on newer boards)). Given it's size of 32Bit, the maximum timeout value ranges from about 21s to 43s, depending on the configured CPU clock speed. This patch add's the timeout module parameter and checks that it's not bigger then the maximum timeout for the given clock speed. Signed-off-by: Phil Sutter <n0-1@freewrt.org> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
-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");