aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/watchdog
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-13 19:10:08 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-13 19:10:08 -0500
commit58a3bb59973e33a428d72fa530a3d1d81feb0e8f (patch)
tree11a6f4838ec20d96bc287a62f21c4b10f0c86b1a /drivers/char/watchdog
parent7f1f86a0d04e79f8165e6f50d329a520b8cd11e5 (diff)
parent88d5a7bb75b5e8f600e79b16abaf008c7fdfd27d (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog
* master.kernel.org:/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog: (23 commits) [WATCHDOG] timers cleanup [WATCHDOG] ib700wdt.c - convert to platform_device part 2 [WATCHDOG] ib700wdt.c - convert to platform_device [WATCHDOG] ib700wdt.c spinlock/WDIOC_SETOPTIONS changes [WATCHDOG] ib700wdt.c small clean-up's [WATCHDOG] ib700wdt.c clean-up init and exit routines [WATCHDOG] ib700_wdt.c stop + set_heartbeat operations [WATCHDOG] show default value for nowayout in module parameter [WATCHDOG] advantechwdt.c - convert to platform_device part 2 [WATCHDOG] advantechwdt.c - convert to platform_device [WATCHDOG] advantechwdt.c - move set_heartbeat to a seperate function [WATCHDOG] advantechwdt.c - cleanup before platform_device patches [WATCHDOG] acquirewdt.c - convert to platform_device part 2 [WATCHDOG] acquirewdt.c - convert to platform_device [WATCHDOG] acquirewdt.c - clean before platform_device patches [WATCHDOG] pcwd_usb.c - get heartbeat from dip switches [WATCHDOG] pcwd.c - e-mail adres update [WATCHDOG] pcwd_usb.c - get heartbeat from dip switches [WATCHDOG] pcwd_usb.c - document includes [WATCHDOG] pcwd_pci.c - spinlock fixes ...
Diffstat (limited to 'drivers/char/watchdog')
-rw-r--r--drivers/char/watchdog/acquirewdt.c155
-rw-r--r--drivers/char/watchdog/advantechwdt.c142
-rw-r--r--drivers/char/watchdog/alim1535_wdt.c2
-rw-r--r--drivers/char/watchdog/alim7101_wdt.c15
-rw-r--r--drivers/char/watchdog/cpu5wdt.c13
-rw-r--r--drivers/char/watchdog/eurotechwdt.c2
-rw-r--r--drivers/char/watchdog/i6300esb.c2
-rw-r--r--drivers/char/watchdog/i8xx_tco.c2
-rw-r--r--drivers/char/watchdog/iTCO_wdt.c6
-rw-r--r--drivers/char/watchdog/ib700wdt.c192
-rw-r--r--drivers/char/watchdog/ibmasr.c2
-rw-r--r--drivers/char/watchdog/indydog.c2
-rw-r--r--drivers/char/watchdog/machzwd.c18
-rw-r--r--drivers/char/watchdog/mixcomwd.c16
-rw-r--r--drivers/char/watchdog/pc87413_wdt.c2
-rw-r--r--drivers/char/watchdog/pcwd.c32
-rw-r--r--drivers/char/watchdog/pcwd_pci.c34
-rw-r--r--drivers/char/watchdog/pcwd_usb.c63
-rw-r--r--drivers/char/watchdog/pnx4008_wdt.c3
-rw-r--r--drivers/char/watchdog/s3c2410_wdt.c62
-rw-r--r--drivers/char/watchdog/sbc60xxwdt.c14
-rw-r--r--drivers/char/watchdog/sbc8360.c2
-rw-r--r--drivers/char/watchdog/sbc_epx_c3.c2
-rw-r--r--drivers/char/watchdog/sc1200wdt.c2
-rw-r--r--drivers/char/watchdog/sc520_wdt.c14
-rw-r--r--drivers/char/watchdog/shwdt.c8
-rw-r--r--drivers/char/watchdog/smsc37b787_wdt.c2
-rw-r--r--drivers/char/watchdog/softdog.c2
-rw-r--r--drivers/char/watchdog/w83627hf_wdt.c2
-rw-r--r--drivers/char/watchdog/w83697hf_wdt.c2
-rw-r--r--drivers/char/watchdog/w83877f_wdt.c14
-rw-r--r--drivers/char/watchdog/w83977f_wdt.c2
-rw-r--r--drivers/char/watchdog/wafer5823wdt.c2
-rw-r--r--drivers/char/watchdog/wdt.c2
-rw-r--r--drivers/char/watchdog/wdt977.c2
-rw-r--r--drivers/char/watchdog/wdt_pci.c2
36 files changed, 489 insertions, 350 deletions
diff --git a/drivers/char/watchdog/acquirewdt.c b/drivers/char/watchdog/acquirewdt.c
index 154d67e591e5..85269c365a10 100644
--- a/drivers/char/watchdog/acquirewdt.c
+++ b/drivers/char/watchdog/acquirewdt.c
@@ -48,46 +48,52 @@
48 * It can be 1, 2, 10, 20, 110 or 220 seconds. 48 * It can be 1, 2, 10, 20, 110 or 220 seconds.
49 */ 49 */
50 50
51#include <linux/module.h> 51/*
52#include <linux/moduleparam.h> 52 * Includes, defines, variables, module parameters, ...
53#include <linux/types.h> 53 */
54#include <linux/miscdevice.h>
55#include <linux/watchdog.h>
56#include <linux/fs.h>
57#include <linux/ioport.h>
58#include <linux/notifier.h>
59#include <linux/reboot.h>
60#include <linux/init.h>
61
62#include <asm/io.h>
63#include <asm/uaccess.h>
64#include <asm/system.h>
65 54
55/* Includes */
56#include <linux/module.h> /* For module specific items */
57#include <linux/moduleparam.h> /* For new moduleparam's */
58#include <linux/types.h> /* For standard types (like size_t) */
59#include <linux/errno.h> /* For the -ENODEV/... values */
60#include <linux/kernel.h> /* For printk/panic/... */
61#include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) */
62#include <linux/watchdog.h> /* For the watchdog specific items */
63#include <linux/fs.h> /* For file operations */
64#include <linux/ioport.h> /* For io-port access */
65#include <linux/platform_device.h> /* For platform_driver framework */
66#include <linux/init.h> /* For __init/__exit/... */
67
68#include <asm/uaccess.h> /* For copy_to_user/put_user/... */
69#include <asm/io.h> /* For inb/outb/... */
70
71/* Module information */
72#define DRV_NAME "acquirewdt"
73#define PFX DRV_NAME ": "
66#define WATCHDOG_NAME "Acquire WDT" 74#define WATCHDOG_NAME "Acquire WDT"
67#define PFX WATCHDOG_NAME ": "
68#define WATCHDOG_HEARTBEAT 0 /* There is no way to see what the correct time-out period is */ 75#define WATCHDOG_HEARTBEAT 0 /* There is no way to see what the correct time-out period is */
69 76
77/* internal variables */
78static struct platform_device *acq_platform_device; /* the watchdog platform device */
70static unsigned long acq_is_open; 79static unsigned long acq_is_open;
71static char expect_close; 80static char expect_close;
72 81
73/* 82/* module parameters */
74 * You must set these - there is no sane way to probe for this board. 83static int wdt_stop = 0x43; /* You must set this - there is no sane way to probe for this board. */
75 */
76
77static int wdt_stop = 0x43;
78module_param(wdt_stop, int, 0); 84module_param(wdt_stop, int, 0);
79MODULE_PARM_DESC(wdt_stop, "Acquire WDT 'stop' io port (default 0x43)"); 85MODULE_PARM_DESC(wdt_stop, "Acquire WDT 'stop' io port (default 0x43)");
80 86
81static int wdt_start = 0x443; 87static int wdt_start = 0x443; /* You must set this - there is no sane way to probe for this board. */
82module_param(wdt_start, int, 0); 88module_param(wdt_start, int, 0);
83MODULE_PARM_DESC(wdt_start, "Acquire WDT 'start' io port (default 0x443)"); 89MODULE_PARM_DESC(wdt_start, "Acquire WDT 'start' io port (default 0x443)");
84 90
85static int nowayout = WATCHDOG_NOWAYOUT; 91static int nowayout = WATCHDOG_NOWAYOUT;
86module_param(nowayout, int, 0); 92module_param(nowayout, int, 0);
87MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 93MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
88 94
89/* 95/*
90 * Kernel methods. 96 * Watchdog Operations
91 */ 97 */
92 98
93static void acq_keepalive(void) 99static void acq_keepalive(void)
@@ -103,7 +109,7 @@ static void acq_stop(void)
103} 109}
104 110
105/* 111/*
106 * /dev/watchdog handling. 112 * /dev/watchdog handling
107 */ 113 */
108 114
109static ssize_t acq_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) 115static ssize_t acq_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
@@ -143,7 +149,7 @@ static int acq_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
143 { 149 {
144 .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, 150 .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
145 .firmware_version = 1, 151 .firmware_version = 1,
146 .identity = "Acquire WDT", 152 .identity = WATCHDOG_NAME,
147 }; 153 };
148 154
149 switch(cmd) 155 switch(cmd)
@@ -214,20 +220,6 @@ static int acq_close(struct inode *inode, struct file *file)
214} 220}
215 221
216/* 222/*
217 * Notifier for system down
218 */
219
220static int acq_notify_sys(struct notifier_block *this, unsigned long code,
221 void *unused)
222{
223 if(code==SYS_DOWN || code==SYS_HALT) {
224 /* Turn the WDT off */
225 acq_stop();
226 }
227 return NOTIFY_DONE;
228}
229
230/*
231 * Kernel Interfaces 223 * Kernel Interfaces
232 */ 224 */
233 225
@@ -240,29 +232,20 @@ static const struct file_operations acq_fops = {
240 .release = acq_close, 232 .release = acq_close,
241}; 233};
242 234
243static struct miscdevice acq_miscdev= 235static struct miscdevice acq_miscdev = {
244{ 236 .minor = WATCHDOG_MINOR,
245 .minor = WATCHDOG_MINOR, 237 .name = "watchdog",
246 .name = "watchdog", 238 .fops = &acq_fops,
247 .fops = &acq_fops,
248}; 239};
249 240
250/* 241/*
251 * The WDT card needs to learn about soft shutdowns in order to 242 * Init & exit routines
252 * turn the timebomb registers off.
253 */ 243 */
254 244
255static struct notifier_block acq_notifier = 245static int __devinit acq_probe(struct platform_device *dev)
256{
257 .notifier_call = acq_notify_sys,
258};
259
260static int __init acq_init(void)
261{ 246{
262 int ret; 247 int ret;
263 248
264 printk(KERN_INFO "WDT driver for Acquire single board computer initialising.\n");
265
266 if (wdt_stop != wdt_start) { 249 if (wdt_stop != wdt_start) {
267 if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) { 250 if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) {
268 printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", 251 printk (KERN_ERR PFX "I/O address 0x%04x already in use\n",
@@ -279,18 +262,11 @@ static int __init acq_init(void)
279 goto unreg_stop; 262 goto unreg_stop;
280 } 263 }
281 264
282 ret = register_reboot_notifier(&acq_notifier);
283 if (ret != 0) {
284 printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
285 ret);
286 goto unreg_regions;
287 }
288
289 ret = misc_register(&acq_miscdev); 265 ret = misc_register(&acq_miscdev);
290 if (ret != 0) { 266 if (ret != 0) {
291 printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 267 printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
292 WATCHDOG_MINOR, ret); 268 WATCHDOG_MINOR, ret);
293 goto unreg_reboot; 269 goto unreg_regions;
294 } 270 }
295 271
296 printk (KERN_INFO PFX "initialized. (nowayout=%d)\n", 272 printk (KERN_INFO PFX "initialized. (nowayout=%d)\n",
@@ -298,8 +274,6 @@ static int __init acq_init(void)
298 274
299 return 0; 275 return 0;
300 276
301unreg_reboot:
302 unregister_reboot_notifier(&acq_notifier);
303unreg_regions: 277unreg_regions:
304 release_region(wdt_start, 1); 278 release_region(wdt_start, 1);
305unreg_stop: 279unreg_stop:
@@ -309,13 +283,60 @@ out:
309 return ret; 283 return ret;
310} 284}
311 285
312static void __exit acq_exit(void) 286static int __devexit acq_remove(struct platform_device *dev)
313{ 287{
314 misc_deregister(&acq_miscdev); 288 misc_deregister(&acq_miscdev);
315 unregister_reboot_notifier(&acq_notifier); 289 release_region(wdt_start,1);
316 if(wdt_stop != wdt_start) 290 if(wdt_stop != wdt_start)
317 release_region(wdt_stop,1); 291 release_region(wdt_stop,1);
318 release_region(wdt_start,1); 292
293 return 0;
294}
295
296static void acq_shutdown(struct platform_device *dev)
297{
298 /* Turn the WDT off if we have a soft shutdown */
299 acq_stop();
300}
301
302static struct platform_driver acquirewdt_driver = {
303 .probe = acq_probe,
304 .remove = __devexit_p(acq_remove),
305 .shutdown = acq_shutdown,
306 .driver = {
307 .owner = THIS_MODULE,
308 .name = DRV_NAME,
309 },
310};
311
312static int __init acq_init(void)
313{
314 int err;
315
316 printk(KERN_INFO "WDT driver for Acquire single board computer initialising.\n");
317
318 err = platform_driver_register(&acquirewdt_driver);
319 if (err)
320 return err;
321
322 acq_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0);
323 if (IS_ERR(acq_platform_device)) {
324 err = PTR_ERR(acq_platform_device);
325 goto unreg_platform_driver;
326 }
327
328 return 0;
329
330unreg_platform_driver:
331 platform_driver_unregister(&acquirewdt_driver);
332 return err;
333}
334
335static void __exit acq_exit(void)
336{
337 platform_device_unregister(acq_platform_device);
338 platform_driver_unregister(&acquirewdt_driver);
339 printk(KERN_INFO PFX "Watchdog Module Unloaded.\n");
319} 340}
320 341
321module_init(acq_init); 342module_init(acq_init);
diff --git a/drivers/char/watchdog/advantechwdt.c b/drivers/char/watchdog/advantechwdt.c
index 9d732769ba01..8121cc247343 100644
--- a/drivers/char/watchdog/advantechwdt.c
+++ b/drivers/char/watchdog/advantechwdt.c
@@ -35,18 +35,19 @@
35#include <linux/watchdog.h> 35#include <linux/watchdog.h>
36#include <linux/fs.h> 36#include <linux/fs.h>
37#include <linux/ioport.h> 37#include <linux/ioport.h>
38#include <linux/notifier.h> 38#include <linux/platform_device.h>
39#include <linux/reboot.h>
40#include <linux/init.h> 39#include <linux/init.h>
41 40
42#include <asm/io.h> 41#include <asm/io.h>
43#include <asm/uaccess.h> 42#include <asm/uaccess.h>
44#include <asm/system.h> 43#include <asm/system.h>
45 44
45#define DRV_NAME "advantechwdt"
46#define PFX DRV_NAME ": "
46#define WATCHDOG_NAME "Advantech WDT" 47#define WATCHDOG_NAME "Advantech WDT"
47#define PFX WATCHDOG_NAME ": "
48#define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */ 48#define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */
49 49
50static struct platform_device *advwdt_platform_device; /* the watchdog platform device */
50static unsigned long advwdt_is_open; 51static unsigned long advwdt_is_open;
51static char adv_expect_close; 52static char adv_expect_close;
52 53
@@ -75,10 +76,10 @@ MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=63, defaul
75 76
76static int nowayout = WATCHDOG_NOWAYOUT; 77static int nowayout = WATCHDOG_NOWAYOUT;
77module_param(nowayout, int, 0); 78module_param(nowayout, int, 0);
78MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 79MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
79 80
80/* 81/*
81 * Kernel methods. 82 * Watchdog Operations
82 */ 83 */
83 84
84static void 85static void
@@ -94,6 +95,20 @@ advwdt_disable(void)
94 inb_p(wdt_stop); 95 inb_p(wdt_stop);
95} 96}
96 97
98static int
99advwdt_set_heartbeat(int t)
100{
101 if ((t < 1) || (t > 63))
102 return -EINVAL;
103
104 timeout = t;
105 return 0;
106}
107
108/*
109 * /dev/watchdog handling
110 */
111
97static ssize_t 112static ssize_t
98advwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) 113advwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
99{ 114{
@@ -126,7 +141,7 @@ advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
126 static struct watchdog_info ident = { 141 static struct watchdog_info ident = {
127 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, 142 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
128 .firmware_version = 1, 143 .firmware_version = 1,
129 .identity = "Advantech WDT", 144 .identity = WATCHDOG_NAME,
130 }; 145 };
131 146
132 switch (cmd) { 147 switch (cmd) {
@@ -146,9 +161,8 @@ advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
146 case WDIOC_SETTIMEOUT: 161 case WDIOC_SETTIMEOUT:
147 if (get_user(new_timeout, p)) 162 if (get_user(new_timeout, p))
148 return -EFAULT; 163 return -EFAULT;
149 if ((new_timeout < 1) || (new_timeout > 63)) 164 if (advwdt_set_heartbeat(new_timeout))
150 return -EINVAL; 165 return -EINVAL;
151 timeout = new_timeout;
152 advwdt_ping(); 166 advwdt_ping();
153 /* Fall */ 167 /* Fall */
154 168
@@ -209,21 +223,6 @@ advwdt_close(struct inode *inode, struct file *file)
209} 223}
210 224
211/* 225/*
212 * Notifier for system down
213 */
214
215static int
216advwdt_notify_sys(struct notifier_block *this, unsigned long code,
217 void *unused)
218{
219 if (code == SYS_DOWN || code == SYS_HALT) {
220 /* Turn the WDT off */
221 advwdt_disable();
222 }
223 return NOTIFY_DONE;
224}
225
226/*
227 * Kernel Interfaces 226 * Kernel Interfaces
228 */ 227 */
229 228
@@ -237,33 +236,20 @@ static const struct file_operations advwdt_fops = {
237}; 236};
238 237
239static struct miscdevice advwdt_miscdev = { 238static struct miscdevice advwdt_miscdev = {
240 .minor = WATCHDOG_MINOR, 239 .minor = WATCHDOG_MINOR,
241 .name = "watchdog", 240 .name = "watchdog",
242 .fops = &advwdt_fops, 241 .fops = &advwdt_fops,
243}; 242};
244 243
245/* 244/*
246 * The WDT needs to learn about soft shutdowns in order to 245 * Init & exit routines
247 * turn the timebomb registers off.
248 */ 246 */
249 247
250static struct notifier_block advwdt_notifier = { 248static int __devinit
251 .notifier_call = advwdt_notify_sys, 249advwdt_probe(struct platform_device *dev)
252};
253
254static int __init
255advwdt_init(void)
256{ 250{
257 int ret; 251 int ret;
258 252
259 printk(KERN_INFO "WDT driver for Advantech single board computer initialising.\n");
260
261 if (timeout < 1 || timeout > 63) {
262 timeout = WATCHDOG_TIMEOUT;
263 printk (KERN_INFO PFX "timeout value must be 1<=x<=63, using %d\n",
264 timeout);
265 }
266
267 if (wdt_stop != wdt_start) { 253 if (wdt_stop != wdt_start) {
268 if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) { 254 if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) {
269 printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", 255 printk (KERN_ERR PFX "I/O address 0x%04x already in use\n",
@@ -280,18 +266,18 @@ advwdt_init(void)
280 goto unreg_stop; 266 goto unreg_stop;
281 } 267 }
282 268
283 ret = register_reboot_notifier(&advwdt_notifier); 269 /* Check that the heartbeat value is within it's range ; if not reset to the default */
284 if (ret != 0) { 270 if (advwdt_set_heartbeat(timeout)) {
285 printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 271 advwdt_set_heartbeat(WATCHDOG_TIMEOUT);
286 ret); 272 printk (KERN_INFO PFX "timeout value must be 1<=x<=63, using %d\n",
287 goto unreg_regions; 273 timeout);
288 } 274 }
289 275
290 ret = misc_register(&advwdt_miscdev); 276 ret = misc_register(&advwdt_miscdev);
291 if (ret != 0) { 277 if (ret != 0) {
292 printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 278 printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
293 WATCHDOG_MINOR, ret); 279 WATCHDOG_MINOR, ret);
294 goto unreg_reboot; 280 goto unreg_regions;
295 } 281 }
296 282
297 printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n", 283 printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n",
@@ -299,8 +285,6 @@ advwdt_init(void)
299 285
300out: 286out:
301 return ret; 287 return ret;
302unreg_reboot:
303 unregister_reboot_notifier(&advwdt_notifier);
304unreg_regions: 288unreg_regions:
305 release_region(wdt_start, 1); 289 release_region(wdt_start, 1);
306unreg_stop: 290unreg_stop:
@@ -309,14 +293,64 @@ unreg_stop:
309 goto out; 293 goto out;
310} 294}
311 295
312static void __exit 296static int __devexit
313advwdt_exit(void) 297advwdt_remove(struct platform_device *dev)
314{ 298{
315 misc_deregister(&advwdt_miscdev); 299 misc_deregister(&advwdt_miscdev);
316 unregister_reboot_notifier(&advwdt_notifier); 300 release_region(wdt_start,1);
317 if(wdt_stop != wdt_start) 301 if(wdt_stop != wdt_start)
318 release_region(wdt_stop,1); 302 release_region(wdt_stop,1);
319 release_region(wdt_start,1); 303
304 return 0;
305}
306
307static void
308advwdt_shutdown(struct platform_device *dev)
309{
310 /* Turn the WDT off if we have a soft shutdown */
311 advwdt_disable();
312}
313
314static struct platform_driver advwdt_driver = {
315 .probe = advwdt_probe,
316 .remove = __devexit_p(advwdt_remove),
317 .shutdown = advwdt_shutdown,
318 .driver = {
319 .owner = THIS_MODULE,
320 .name = DRV_NAME,
321 },
322};
323
324static int __init
325advwdt_init(void)
326{
327 int err;
328
329 printk(KERN_INFO "WDT driver for Advantech single board computer initialising.\n");
330
331 err = platform_driver_register(&advwdt_driver);
332 if (err)
333 return err;
334
335 advwdt_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0);
336 if (IS_ERR(advwdt_platform_device)) {
337 err = PTR_ERR(advwdt_platform_device);
338 goto unreg_platform_driver;
339 }
340
341 return 0;
342
343unreg_platform_driver:
344 platform_driver_unregister(&advwdt_driver);
345 return err;
346}
347
348static void __exit
349advwdt_exit(void)
350{
351 platform_device_unregister(advwdt_platform_device);
352 platform_driver_unregister(&advwdt_driver);
353 printk(KERN_INFO PFX "Watchdog Module Unloaded.\n");
320} 354}
321 355
322module_init(advwdt_init); 356module_init(advwdt_init);
diff --git a/drivers/char/watchdog/alim1535_wdt.c b/drivers/char/watchdog/alim1535_wdt.c
index 01b0d132ee41..e3f6a7d0c83d 100644
--- a/drivers/char/watchdog/alim1535_wdt.c
+++ b/drivers/char/watchdog/alim1535_wdt.c
@@ -40,7 +40,7 @@ MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (0<timeout<18000, defaul
40 40
41static int nowayout = WATCHDOG_NOWAYOUT; 41static int nowayout = WATCHDOG_NOWAYOUT;
42module_param(nowayout, int, 0); 42module_param(nowayout, int, 0);
43MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 43MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
44 44
45/* 45/*
46 * ali_start - start watchdog countdown 46 * ali_start - start watchdog countdown
diff --git a/drivers/char/watchdog/alim7101_wdt.c b/drivers/char/watchdog/alim7101_wdt.c
index e5b2c2ee292c..67aed9f8c362 100644
--- a/drivers/char/watchdog/alim7101_wdt.c
+++ b/drivers/char/watchdog/alim7101_wdt.c
@@ -69,7 +69,7 @@ module_param(use_gpio, int, 0);
69MODULE_PARM_DESC(use_gpio, "Use the gpio watchdog. (required by old cobalt boards)"); 69MODULE_PARM_DESC(use_gpio, "Use the gpio watchdog. (required by old cobalt boards)");
70 70
71static void wdt_timer_ping(unsigned long); 71static void wdt_timer_ping(unsigned long);
72static struct timer_list timer; 72static DEFINE_TIMER(timer, wdt_timer_ping, 0, 1);
73static unsigned long next_heartbeat; 73static unsigned long next_heartbeat;
74static unsigned long wdt_is_open; 74static unsigned long wdt_is_open;
75static char wdt_expect_close; 75static char wdt_expect_close;
@@ -78,7 +78,7 @@ static struct pci_dev *alim7101_pmu;
78static int nowayout = WATCHDOG_NOWAYOUT; 78static int nowayout = WATCHDOG_NOWAYOUT;
79module_param(nowayout, int, 0); 79module_param(nowayout, int, 0);
80MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" 80MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
81 __stringify(CONFIG_WATCHDOG_NOWAYOUT) ")"); 81 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
82 82
83/* 83/*
84 * Whack the dog 84 * Whack the dog
@@ -108,8 +108,7 @@ static void wdt_timer_ping(unsigned long data)
108 printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); 108 printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n");
109 } 109 }
110 /* Re-set the timer interval */ 110 /* Re-set the timer interval */
111 timer.expires = jiffies + WDT_INTERVAL; 111 mod_timer(&timer, jiffies + WDT_INTERVAL);
112 add_timer(&timer);
113} 112}
114 113
115/* 114/*
@@ -147,9 +146,7 @@ static void wdt_startup(void)
147 wdt_change(WDT_ENABLE); 146 wdt_change(WDT_ENABLE);
148 147
149 /* Start the timer */ 148 /* Start the timer */
150 timer.expires = jiffies + WDT_INTERVAL; 149 mod_timer(&timer, jiffies + WDT_INTERVAL);
151 add_timer(&timer);
152
153 150
154 printk(KERN_INFO PFX "Watchdog timer is now enabled.\n"); 151 printk(KERN_INFO PFX "Watchdog timer is now enabled.\n");
155} 152}
@@ -380,10 +377,6 @@ static int __init alim7101_wdt_init(void)
380 timeout); 377 timeout);
381 } 378 }
382 379
383 init_timer(&timer);
384 timer.function = wdt_timer_ping;
385 timer.data = 1;
386
387 rc = misc_register(&wdt_miscdev); 380 rc = misc_register(&wdt_miscdev);
388 if (rc) { 381 if (rc) {
389 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 382 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
diff --git a/drivers/char/watchdog/cpu5wdt.c b/drivers/char/watchdog/cpu5wdt.c
index 00bdabb90f27..bcd7e36ca0aa 100644
--- a/drivers/char/watchdog/cpu5wdt.c
+++ b/drivers/char/watchdog/cpu5wdt.c
@@ -80,10 +80,8 @@ static void cpu5wdt_trigger(unsigned long unused)
80 outb(1, port + CPU5WDT_TRIGGER_REG); 80 outb(1, port + CPU5WDT_TRIGGER_REG);
81 81
82 /* requeue?? */ 82 /* requeue?? */
83 if( cpu5wdt_device.queue && ticks ) { 83 if (cpu5wdt_device.queue && ticks)
84 cpu5wdt_device.timer.expires = jiffies + CPU5WDT_INTERVAL; 84 mod_timer(&cpu5wdt_device.timer, jiffies + CPU5WDT_INTERVAL);
85 add_timer(&cpu5wdt_device.timer);
86 }
87 else { 85 else {
88 /* ticks doesn't matter anyway */ 86 /* ticks doesn't matter anyway */
89 complete(&cpu5wdt_device.stop); 87 complete(&cpu5wdt_device.stop);
@@ -109,8 +107,7 @@ static void cpu5wdt_start(void)
109 outb(1, port + CPU5WDT_MODE_REG); 107 outb(1, port + CPU5WDT_MODE_REG);
110 outb(0, port + CPU5WDT_RESET_REG); 108 outb(0, port + CPU5WDT_RESET_REG);
111 outb(0, port + CPU5WDT_ENABLE_REG); 109 outb(0, port + CPU5WDT_ENABLE_REG);
112 cpu5wdt_device.timer.expires = jiffies + CPU5WDT_INTERVAL; 110 mod_timer(&cpu5wdt_device.timer, jiffies + CPU5WDT_INTERVAL);
113 add_timer(&cpu5wdt_device.timer);
114 } 111 }
115 /* if process dies, counter is not decremented */ 112 /* if process dies, counter is not decremented */
116 cpu5wdt_device.running++; 113 cpu5wdt_device.running++;
@@ -245,9 +242,7 @@ static int __devinit cpu5wdt_init(void)
245 242
246 clear_bit(0, &cpu5wdt_device.inuse); 243 clear_bit(0, &cpu5wdt_device.inuse);
247 244
248 init_timer(&cpu5wdt_device.timer); 245 setup_timer(&cpu5wdt_device.timer, cpu5wdt_trigger, 0);
249 cpu5wdt_device.timer.function = cpu5wdt_trigger;
250 cpu5wdt_device.timer.data = 0;
251 246
252 cpu5wdt_device.default_ticks = ticks; 247 cpu5wdt_device.default_ticks = ticks;
253 248
diff --git a/drivers/char/watchdog/eurotechwdt.c b/drivers/char/watchdog/eurotechwdt.c
index e228d6e173ce..f70387f01b2b 100644
--- a/drivers/char/watchdog/eurotechwdt.c
+++ b/drivers/char/watchdog/eurotechwdt.c
@@ -73,7 +73,7 @@ static char *ev = "int";
73 73
74static int nowayout = WATCHDOG_NOWAYOUT; 74static int nowayout = WATCHDOG_NOWAYOUT;
75module_param(nowayout, int, 0); 75module_param(nowayout, int, 0);
76MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 76MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
77 77
78/* 78/*
79 * Some symbolic names 79 * Some symbolic names
diff --git a/drivers/char/watchdog/i6300esb.c b/drivers/char/watchdog/i6300esb.c
index fb64df4d7c87..c5982502c03d 100644
--- a/drivers/char/watchdog/i6300esb.c
+++ b/drivers/char/watchdog/i6300esb.c
@@ -91,7 +91,7 @@ MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (1<heartbeat<2046, d
91 91
92static int nowayout = WATCHDOG_NOWAYOUT; 92static int nowayout = WATCHDOG_NOWAYOUT;
93module_param(nowayout, int, 0); 93module_param(nowayout, int, 0);
94MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 94MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
95 95
96/* 96/*
97 * Some i6300ESB specific functions 97 * Some i6300ESB specific functions
diff --git a/drivers/char/watchdog/i8xx_tco.c b/drivers/char/watchdog/i8xx_tco.c
index e0627d79707b..a62ef48a15ae 100644
--- a/drivers/char/watchdog/i8xx_tco.c
+++ b/drivers/char/watchdog/i8xx_tco.c
@@ -109,7 +109,7 @@ MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<heartbeat<39, def
109 109
110static int nowayout = WATCHDOG_NOWAYOUT; 110static int nowayout = WATCHDOG_NOWAYOUT;
111module_param(nowayout, int, 0); 111module_param(nowayout, int, 0);
112MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 112MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
113 113
114/* 114/*
115 * Some TCO specific functions 115 * Some TCO specific functions
diff --git a/drivers/char/watchdog/iTCO_wdt.c b/drivers/char/watchdog/iTCO_wdt.c
index fd8a44a08cd3..3c9684ccd2f9 100644
--- a/drivers/char/watchdog/iTCO_wdt.c
+++ b/drivers/char/watchdog/iTCO_wdt.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * intel TCO Watchdog Driver (Used in i82801 and i6300ESB chipsets) 2 * intel TCO Watchdog Driver (Used in i82801 and i6300ESB chipsets)
3 * 3 *
4 * (c) Copyright 2006 Wim Van Sebroeck <wim@iguana.be>. 4 * (c) Copyright 2006-2007 Wim Van Sebroeck <wim@iguana.be>.
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License 7 * modify it under the terms of the GNU General Public License
@@ -49,7 +49,7 @@
49/* Module and version information */ 49/* Module and version information */
50#define DRV_NAME "iTCO_wdt" 50#define DRV_NAME "iTCO_wdt"
51#define DRV_VERSION "1.01" 51#define DRV_VERSION "1.01"
52#define DRV_RELDATE "11-Nov-2006" 52#define DRV_RELDATE "21-Jan-2007"
53#define PFX DRV_NAME ": " 53#define PFX DRV_NAME ": "
54 54
55/* Includes */ 55/* Includes */
@@ -187,7 +187,7 @@ MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<heartbeat<39 (TCO
187 187
188static int nowayout = WATCHDOG_NOWAYOUT; 188static int nowayout = WATCHDOG_NOWAYOUT;
189module_param(nowayout, int, 0); 189module_param(nowayout, int, 0);
190MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 190MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
191 191
192/* iTCO Vendor Specific Support hooks */ 192/* iTCO Vendor Specific Support hooks */
193#ifdef CONFIG_ITCO_VENDOR_SUPPORT 193#ifdef CONFIG_ITCO_VENDOR_SUPPORT
diff --git a/drivers/char/watchdog/ib700wdt.c b/drivers/char/watchdog/ib700wdt.c
index c1ed209a138c..c3a60f52ccb9 100644
--- a/drivers/char/watchdog/ib700wdt.c
+++ b/drivers/char/watchdog/ib700wdt.c
@@ -3,8 +3,8 @@
3 * 3 *
4 * (c) Copyright 2001 Charles Howes <chowes@vsol.net> 4 * (c) Copyright 2001 Charles Howes <chowes@vsol.net>
5 * 5 *
6 * Based on advantechwdt.c which is based on acquirewdt.c which 6 * Based on advantechwdt.c which is based on acquirewdt.c which
7 * is based on wdt.c. 7 * is based on wdt.c.
8 * 8 *
9 * (c) Copyright 2000-2001 Marek Michalkiewicz <marekm@linux.org.pl> 9 * (c) Copyright 2000-2001 Marek Michalkiewicz <marekm@linux.org.pl>
10 * 10 *
@@ -25,9 +25,9 @@
25 * 25 *
26 * (c) Copyright 1995 Alan Cox <alan@redhat.com> 26 * (c) Copyright 1995 Alan Cox <alan@redhat.com>
27 * 27 *
28 * 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com> 28 * 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
29 * Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT 29 * Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
30 * Added timeout module option to override default 30 * Added timeout module option to override default
31 * 31 *
32 */ 32 */
33 33
@@ -36,22 +36,24 @@
36#include <linux/miscdevice.h> 36#include <linux/miscdevice.h>
37#include <linux/watchdog.h> 37#include <linux/watchdog.h>
38#include <linux/ioport.h> 38#include <linux/ioport.h>
39#include <linux/notifier.h>
40#include <linux/fs.h> 39#include <linux/fs.h>
41#include <linux/reboot.h>
42#include <linux/init.h> 40#include <linux/init.h>
43#include <linux/spinlock.h> 41#include <linux/spinlock.h>
44#include <linux/moduleparam.h> 42#include <linux/moduleparam.h>
43#include <linux/platform_device.h>
45 44
46#include <asm/io.h> 45#include <asm/io.h>
47#include <asm/uaccess.h> 46#include <asm/uaccess.h>
48#include <asm/system.h> 47#include <asm/system.h>
49 48
49static struct platform_device *ibwdt_platform_device;
50static unsigned long ibwdt_is_open; 50static unsigned long ibwdt_is_open;
51static spinlock_t ibwdt_lock; 51static spinlock_t ibwdt_lock;
52static char expect_close; 52static char expect_close;
53 53
54#define PFX "ib700wdt: " 54/* Module information */
55#define DRV_NAME "ib700wdt"
56#define PFX DRV_NAME ": "
55 57
56/* 58/*
57 * 59 *
@@ -118,20 +120,51 @@ static int wd_margin = WD_TIMO;
118 120
119static int nowayout = WATCHDOG_NOWAYOUT; 121static int nowayout = WATCHDOG_NOWAYOUT;
120module_param(nowayout, int, 0); 122module_param(nowayout, int, 0);
121MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 123MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
122 124
123 125
124/* 126/*
125 * Kernel methods. 127 * Watchdog Operations
126 */ 128 */
127 129
128static void 130static void
129ibwdt_ping(void) 131ibwdt_ping(void)
130{ 132{
133 spin_lock(&ibwdt_lock);
134
131 /* Write a watchdog value */ 135 /* Write a watchdog value */
132 outb_p(wd_margin, WDT_START); 136 outb_p(wd_margin, WDT_START);
137
138 spin_unlock(&ibwdt_lock);
133} 139}
134 140
141static void
142ibwdt_disable(void)
143{
144 spin_lock(&ibwdt_lock);
145 outb_p(0, WDT_STOP);
146 spin_unlock(&ibwdt_lock);
147}
148
149static int
150ibwdt_set_heartbeat(int t)
151{
152 int i;
153
154 if ((t < 0) || (t > 30))
155 return -EINVAL;
156
157 for (i = 0x0F; i > -1; i--)
158 if (wd_times[i] > t)
159 break;
160 wd_margin = i;
161 return 0;
162}
163
164/*
165 * /dev/watchdog handling
166 */
167
135static ssize_t 168static ssize_t
136ibwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) 169ibwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
137{ 170{
@@ -159,7 +192,7 @@ static int
159ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 192ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
160 unsigned long arg) 193 unsigned long arg)
161{ 194{
162 int i, new_margin; 195 int new_margin;
163 void __user *argp = (void __user *)arg; 196 void __user *argp = (void __user *)arg;
164 int __user *p = argp; 197 int __user *p = argp;
165 198
@@ -176,6 +209,7 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
176 break; 209 break;
177 210
178 case WDIOC_GETSTATUS: 211 case WDIOC_GETSTATUS:
212 case WDIOC_GETBOOTSTATUS:
179 return put_user(0, p); 213 return put_user(0, p);
180 214
181 case WDIOC_KEEPALIVE: 215 case WDIOC_KEEPALIVE:
@@ -185,18 +219,33 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
185 case WDIOC_SETTIMEOUT: 219 case WDIOC_SETTIMEOUT:
186 if (get_user(new_margin, p)) 220 if (get_user(new_margin, p))
187 return -EFAULT; 221 return -EFAULT;
188 if ((new_margin < 0) || (new_margin > 30)) 222 if (ibwdt_set_heartbeat(new_margin))
189 return -EINVAL; 223 return -EINVAL;
190 for (i = 0x0F; i > -1; i--)
191 if (wd_times[i] > new_margin)
192 break;
193 wd_margin = i;
194 ibwdt_ping(); 224 ibwdt_ping();
195 /* Fall */ 225 /* Fall */
196 226
197 case WDIOC_GETTIMEOUT: 227 case WDIOC_GETTIMEOUT:
198 return put_user(wd_times[wd_margin], p); 228 return put_user(wd_times[wd_margin], p);
199 break; 229
230 case WDIOC_SETOPTIONS:
231 {
232 int options, retval = -EINVAL;
233
234 if (get_user(options, p))
235 return -EFAULT;
236
237 if (options & WDIOS_DISABLECARD) {
238 ibwdt_disable();
239 retval = 0;
240 }
241
242 if (options & WDIOS_ENABLECARD) {
243 ibwdt_ping();
244 retval = 0;
245 }
246
247 return retval;
248 }
200 249
201 default: 250 default:
202 return -ENOTTY; 251 return -ENOTTY;
@@ -207,9 +256,7 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
207static int 256static int
208ibwdt_open(struct inode *inode, struct file *file) 257ibwdt_open(struct inode *inode, struct file *file)
209{ 258{
210 spin_lock(&ibwdt_lock);
211 if (test_and_set_bit(0, &ibwdt_is_open)) { 259 if (test_and_set_bit(0, &ibwdt_is_open)) {
212 spin_unlock(&ibwdt_lock);
213 return -EBUSY; 260 return -EBUSY;
214 } 261 }
215 if (nowayout) 262 if (nowayout)
@@ -217,41 +264,24 @@ ibwdt_open(struct inode *inode, struct file *file)
217 264
218 /* Activate */ 265 /* Activate */
219 ibwdt_ping(); 266 ibwdt_ping();
220 spin_unlock(&ibwdt_lock);
221 return nonseekable_open(inode, file); 267 return nonseekable_open(inode, file);
222} 268}
223 269
224static int 270static int
225ibwdt_close(struct inode *inode, struct file *file) 271ibwdt_close(struct inode *inode, struct file *file)
226{ 272{
227 spin_lock(&ibwdt_lock); 273 if (expect_close == 42) {
228 if (expect_close == 42) 274 ibwdt_disable();
229 outb_p(0, WDT_STOP); 275 } else {
230 else
231 printk(KERN_CRIT PFX "WDT device closed unexpectedly. WDT will not stop!\n"); 276 printk(KERN_CRIT PFX "WDT device closed unexpectedly. WDT will not stop!\n");
232 277 ibwdt_ping();
278 }
233 clear_bit(0, &ibwdt_is_open); 279 clear_bit(0, &ibwdt_is_open);
234 expect_close = 0; 280 expect_close = 0;
235 spin_unlock(&ibwdt_lock);
236 return 0; 281 return 0;
237} 282}
238 283
239/* 284/*
240 * Notifier for system down
241 */
242
243static int
244ibwdt_notify_sys(struct notifier_block *this, unsigned long code,
245 void *unused)
246{
247 if (code == SYS_DOWN || code == SYS_HALT) {
248 /* Turn the WDT off */
249 outb_p(0, WDT_STOP);
250 }
251 return NOTIFY_DONE;
252}
253
254/*
255 * Kernel Interfaces 285 * Kernel Interfaces
256 */ 286 */
257 287
@@ -271,26 +301,14 @@ static struct miscdevice ibwdt_miscdev = {
271}; 301};
272 302
273/* 303/*
274 * The WDT needs to learn about soft shutdowns in order to 304 * Init & exit routines
275 * turn the timebomb registers off.
276 */ 305 */
277 306
278static struct notifier_block ibwdt_notifier = { 307static int __devinit ibwdt_probe(struct platform_device *dev)
279 .notifier_call = ibwdt_notify_sys,
280};
281
282static int __init ibwdt_init(void)
283{ 308{
284 int res; 309 int res;
285 310
286 printk(KERN_INFO PFX "WDT driver for IB700 single board computer initialising.\n");
287
288 spin_lock_init(&ibwdt_lock); 311 spin_lock_init(&ibwdt_lock);
289 res = misc_register(&ibwdt_miscdev);
290 if (res) {
291 printk (KERN_ERR PFX "failed to register misc device\n");
292 goto out_nomisc;
293 }
294 312
295#if WDT_START != WDT_STOP 313#if WDT_START != WDT_STOP
296 if (!request_region(WDT_STOP, 1, "IB700 WDT")) { 314 if (!request_region(WDT_STOP, 1, "IB700 WDT")) {
@@ -305,34 +323,78 @@ static int __init ibwdt_init(void)
305 res = -EIO; 323 res = -EIO;
306 goto out_nostartreg; 324 goto out_nostartreg;
307 } 325 }
308 res = register_reboot_notifier(&ibwdt_notifier); 326
327 res = misc_register(&ibwdt_miscdev);
309 if (res) { 328 if (res) {
310 printk (KERN_ERR PFX "Failed to register reboot notifier.\n"); 329 printk (KERN_ERR PFX "failed to register misc device\n");
311 goto out_noreboot; 330 goto out_nomisc;
312 } 331 }
313 return 0; 332 return 0;
314 333
315out_noreboot: 334out_nomisc:
316 release_region(WDT_START, 1); 335 release_region(WDT_START, 1);
317out_nostartreg: 336out_nostartreg:
318#if WDT_START != WDT_STOP 337#if WDT_START != WDT_STOP
319 release_region(WDT_STOP, 1); 338 release_region(WDT_STOP, 1);
320#endif 339#endif
321out_nostopreg: 340out_nostopreg:
322 misc_deregister(&ibwdt_miscdev);
323out_nomisc:
324 return res; 341 return res;
325} 342}
326 343
327static void __exit 344static int __devexit ibwdt_remove(struct platform_device *dev)
328ibwdt_exit(void)
329{ 345{
330 misc_deregister(&ibwdt_miscdev); 346 misc_deregister(&ibwdt_miscdev);
331 unregister_reboot_notifier(&ibwdt_notifier); 347 release_region(WDT_START,1);
332#if WDT_START != WDT_STOP 348#if WDT_START != WDT_STOP
333 release_region(WDT_STOP,1); 349 release_region(WDT_STOP,1);
334#endif 350#endif
335 release_region(WDT_START,1); 351 return 0;
352}
353
354static void ibwdt_shutdown(struct platform_device *dev)
355{
356 /* Turn the WDT off if we have a soft shutdown */
357 ibwdt_disable();
358}
359
360static struct platform_driver ibwdt_driver = {
361 .probe = ibwdt_probe,
362 .remove = __devexit_p(ibwdt_remove),
363 .shutdown = ibwdt_shutdown,
364 .driver = {
365 .owner = THIS_MODULE,
366 .name = DRV_NAME,
367 },
368};
369
370static int __init ibwdt_init(void)
371{
372 int err;
373
374 printk(KERN_INFO PFX "WDT driver for IB700 single board computer initialising.\n");
375
376 err = platform_driver_register(&ibwdt_driver);
377 if (err)
378 return err;
379
380 ibwdt_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0);
381 if (IS_ERR(ibwdt_platform_device)) {
382 err = PTR_ERR(ibwdt_platform_device);
383 goto unreg_platform_driver;
384 }
385
386 return 0;
387
388unreg_platform_driver:
389 platform_driver_unregister(&ibwdt_driver);
390 return err;
391}
392
393static void __exit ibwdt_exit(void)
394{
395 platform_device_unregister(ibwdt_platform_device);
396 platform_driver_unregister(&ibwdt_driver);
397 printk(KERN_INFO PFX "Watchdog Module Unloaded.\n");
336} 398}
337 399
338module_init(ibwdt_init); 400module_init(ibwdt_init);
diff --git a/drivers/char/watchdog/ibmasr.c b/drivers/char/watchdog/ibmasr.c
index dd6760f1a23b..8195f5023d85 100644
--- a/drivers/char/watchdog/ibmasr.c
+++ b/drivers/char/watchdog/ibmasr.c
@@ -396,7 +396,7 @@ module_init(ibmasr_init);
396module_exit(ibmasr_exit); 396module_exit(ibmasr_exit);
397 397
398module_param(nowayout, int, 0); 398module_param(nowayout, int, 0);
399MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 399MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
400 400
401MODULE_DESCRIPTION("IBM Automatic Server Restart driver"); 401MODULE_DESCRIPTION("IBM Automatic Server Restart driver");
402MODULE_AUTHOR("Andrey Panin"); 402MODULE_AUTHOR("Andrey Panin");
diff --git a/drivers/char/watchdog/indydog.c b/drivers/char/watchdog/indydog.c
index 0bc239308989..788245bdaa7f 100644
--- a/drivers/char/watchdog/indydog.c
+++ b/drivers/char/watchdog/indydog.c
@@ -32,7 +32,7 @@ static int indydog_alive;
32 32
33static int nowayout = WATCHDOG_NOWAYOUT; 33static int nowayout = WATCHDOG_NOWAYOUT;
34module_param(nowayout, int, 0); 34module_param(nowayout, int, 0);
35MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 35MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
36 36
37static void indydog_start(void) 37static void indydog_start(void)
38{ 38{
diff --git a/drivers/char/watchdog/machzwd.c b/drivers/char/watchdog/machzwd.c
index 4d730fdbd528..81fb3dec180f 100644
--- a/drivers/char/watchdog/machzwd.c
+++ b/drivers/char/watchdog/machzwd.c
@@ -95,7 +95,7 @@ MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
95 95
96static int nowayout = WATCHDOG_NOWAYOUT; 96static int nowayout = WATCHDOG_NOWAYOUT;
97module_param(nowayout, int, 0); 97module_param(nowayout, int, 0);
98MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 98MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
99 99
100#define PFX "machzwd" 100#define PFX "machzwd"
101 101
@@ -118,12 +118,14 @@ static int action = 0;
118module_param(action, int, 0); 118module_param(action, int, 0);
119MODULE_PARM_DESC(action, "after watchdog resets, generate: 0 = RESET(*) 1 = SMI 2 = NMI 3 = SCI"); 119MODULE_PARM_DESC(action, "after watchdog resets, generate: 0 = RESET(*) 1 = SMI 2 = NMI 3 = SCI");
120 120
121static void zf_ping(unsigned long data);
122
121static int zf_action = GEN_RESET; 123static int zf_action = GEN_RESET;
122static unsigned long zf_is_open; 124static unsigned long zf_is_open;
123static char zf_expect_close; 125static char zf_expect_close;
124static spinlock_t zf_lock; 126static spinlock_t zf_lock;
125static spinlock_t zf_port_lock; 127static spinlock_t zf_port_lock;
126static struct timer_list zf_timer; 128static DEFINE_TIMER(zf_timer, zf_ping, 0, 0);
127static unsigned long next_heartbeat = 0; 129static unsigned long next_heartbeat = 0;
128 130
129 131
@@ -220,9 +222,7 @@ static void zf_timer_on(void)
220 next_heartbeat = jiffies + ZF_USER_TIMEO; 222 next_heartbeat = jiffies + ZF_USER_TIMEO;
221 223
222 /* start the timer for internal ping */ 224 /* start the timer for internal ping */
223 zf_timer.expires = jiffies + ZF_HW_TIMEO; 225 mod_timer(&zf_timer, jiffies + ZF_HW_TIMEO);
224
225 add_timer(&zf_timer);
226 226
227 /* start watchdog timer */ 227 /* start watchdog timer */
228 ctrl_reg = zf_get_control(); 228 ctrl_reg = zf_get_control();
@@ -260,8 +260,7 @@ static void zf_ping(unsigned long data)
260 zf_set_control(ctrl_reg); 260 zf_set_control(ctrl_reg);
261 spin_unlock_irqrestore(&zf_port_lock, flags); 261 spin_unlock_irqrestore(&zf_port_lock, flags);
262 262
263 zf_timer.expires = jiffies + ZF_HW_TIMEO; 263 mod_timer(&zf_timer, jiffies + ZF_HW_TIMEO);
264 add_timer(&zf_timer);
265 }else{ 264 }else{
266 printk(KERN_CRIT PFX ": I will reset your machine\n"); 265 printk(KERN_CRIT PFX ": I will reset your machine\n");
267 } 266 }
@@ -465,11 +464,6 @@ static int __init zf_init(void)
465 zf_set_status(0); 464 zf_set_status(0);
466 zf_set_control(0); 465 zf_set_control(0);
467 466
468 /* this is the timer that will do the hard work */
469 init_timer(&zf_timer);
470 zf_timer.function = zf_ping;
471 zf_timer.data = 0;
472
473 return 0; 467 return 0;
474 468
475no_reboot: 469no_reboot:
diff --git a/drivers/char/watchdog/mixcomwd.c b/drivers/char/watchdog/mixcomwd.c
index c2dac0aa1d62..f35e2848aa3e 100644
--- a/drivers/char/watchdog/mixcomwd.c
+++ b/drivers/char/watchdog/mixcomwd.c
@@ -56,16 +56,18 @@ static int mixcomwd_ioports[] = { 0x180, 0x280, 0x380, 0x000 };
56#define FLASHCOM_WATCHDOG_OFFSET 0x4 56#define FLASHCOM_WATCHDOG_OFFSET 0x4
57#define FLASHCOM_ID 0x18 57#define FLASHCOM_ID 0x18
58 58
59static void mixcomwd_timerfun(unsigned long d);
60
59static unsigned long mixcomwd_opened; /* long req'd for setbit --RR */ 61static unsigned long mixcomwd_opened; /* long req'd for setbit --RR */
60 62
61static int watchdog_port; 63static int watchdog_port;
62static int mixcomwd_timer_alive; 64static int mixcomwd_timer_alive;
63static DEFINE_TIMER(mixcomwd_timer, NULL, 0, 0); 65static DEFINE_TIMER(mixcomwd_timer, mixcomwd_timerfun, 0, 0);
64static char expect_close; 66static char expect_close;
65 67
66static int nowayout = WATCHDOG_NOWAYOUT; 68static int nowayout = WATCHDOG_NOWAYOUT;
67module_param(nowayout, int, 0); 69module_param(nowayout, int, 0);
68MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 70MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
69 71
70static void mixcomwd_ping(void) 72static void mixcomwd_ping(void)
71{ 73{
@@ -77,7 +79,7 @@ static void mixcomwd_timerfun(unsigned long d)
77{ 79{
78 mixcomwd_ping(); 80 mixcomwd_ping();
79 81
80 mod_timer(&mixcomwd_timer,jiffies+ 5*HZ); 82 mod_timer(&mixcomwd_timer, jiffies + 5 * HZ);
81} 83}
82 84
83/* 85/*
@@ -114,12 +116,8 @@ static int mixcomwd_release(struct inode *inode, struct file *file)
114 printk(KERN_ERR "mixcomwd: release called while internal timer alive"); 116 printk(KERN_ERR "mixcomwd: release called while internal timer alive");
115 return -EBUSY; 117 return -EBUSY;
116 } 118 }
117 init_timer(&mixcomwd_timer);
118 mixcomwd_timer.expires=jiffies + 5 * HZ;
119 mixcomwd_timer.function=mixcomwd_timerfun;
120 mixcomwd_timer.data=0;
121 mixcomwd_timer_alive=1; 119 mixcomwd_timer_alive=1;
122 add_timer(&mixcomwd_timer); 120 mod_timer(&mixcomwd_timer, jiffies + 5 * HZ);
123 } else { 121 } else {
124 printk(KERN_CRIT "mixcomwd: WDT device closed unexpectedly. WDT will not stop!\n"); 122 printk(KERN_CRIT "mixcomwd: WDT device closed unexpectedly. WDT will not stop!\n");
125 } 123 }
@@ -285,7 +283,7 @@ static void __exit mixcomwd_exit(void)
285 if(mixcomwd_timer_alive) { 283 if(mixcomwd_timer_alive) {
286 printk(KERN_WARNING "mixcomwd: I quit now, hardware will" 284 printk(KERN_WARNING "mixcomwd: I quit now, hardware will"
287 " probably reboot!\n"); 285 " probably reboot!\n");
288 del_timer(&mixcomwd_timer); 286 del_timer_sync(&mixcomwd_timer);
289 mixcomwd_timer_alive=0; 287 mixcomwd_timer_alive=0;
290 } 288 }
291 } 289 }
diff --git a/drivers/char/watchdog/pc87413_wdt.c b/drivers/char/watchdog/pc87413_wdt.c
index a77a90717ad2..3d3deae0d64b 100644
--- a/drivers/char/watchdog/pc87413_wdt.c
+++ b/drivers/char/watchdog/pc87413_wdt.c
@@ -631,5 +631,5 @@ module_param(timeout, int, 0);
631MODULE_PARM_DESC(timeout, "Watchdog timeout in minutes (default=" __MODULE_STRING(timeout) ")."); 631MODULE_PARM_DESC(timeout, "Watchdog timeout in minutes (default=" __MODULE_STRING(timeout) ").");
632 632
633module_param(nowayout, int, 0); 633module_param(nowayout, int, 0);
634MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 634MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
635 635
diff --git a/drivers/char/watchdog/pcwd.c b/drivers/char/watchdog/pcwd.c
index 8e1e6e48e0a7..6e8b5705b5b7 100644
--- a/drivers/char/watchdog/pcwd.c
+++ b/drivers/char/watchdog/pcwd.c
@@ -2,7 +2,7 @@
2 * PC Watchdog Driver 2 * PC Watchdog Driver
3 * by Ken Hollis (khollis@bitgate.com) 3 * by Ken Hollis (khollis@bitgate.com)
4 * 4 *
5 * Permission granted from Simon Machell (73244.1270@compuserve.com) 5 * Permission granted from Simon Machell (smachell@berkprod.com)
6 * Written for the Linux Kernel, and GPLed by Ken Hollis 6 * Written for the Linux Kernel, and GPLed by Ken Hollis
7 * 7 *
8 * 960107 Added request_region routines, modulized the whole thing. 8 * 960107 Added request_region routines, modulized the whole thing.
@@ -70,8 +70,8 @@
70#include <asm/io.h> /* For inb/outb/... */ 70#include <asm/io.h> /* For inb/outb/... */
71 71
72/* Module and version information */ 72/* Module and version information */
73#define WATCHDOG_VERSION "1.17" 73#define WATCHDOG_VERSION "1.18"
74#define WATCHDOG_DATE "12 Feb 2006" 74#define WATCHDOG_DATE "21 Jan 2007"
75#define WATCHDOG_DRIVER_NAME "ISA-PC Watchdog" 75#define WATCHDOG_DRIVER_NAME "ISA-PC Watchdog"
76#define WATCHDOG_NAME "pcwd" 76#define WATCHDOG_NAME "pcwd"
77#define PFX WATCHDOG_NAME ": " 77#define PFX WATCHDOG_NAME ": "
@@ -132,6 +132,18 @@
132#define CMD_ISA_DELAY_TIME_8SECS 0x0C 132#define CMD_ISA_DELAY_TIME_8SECS 0x0C
133#define CMD_ISA_RESET_RELAYS 0x0D 133#define CMD_ISA_RESET_RELAYS 0x0D
134 134
135/* Watchdog's Dip Switch heartbeat values */
136static const int heartbeat_tbl [] = {
137 20, /* OFF-OFF-OFF = 20 Sec */
138 40, /* OFF-OFF-ON = 40 Sec */
139 60, /* OFF-ON-OFF = 1 Min */
140 300, /* OFF-ON-ON = 5 Min */
141 600, /* ON-OFF-OFF = 10 Min */
142 1800, /* ON-OFF-ON = 30 Min */
143 3600, /* ON-ON-OFF = 1 Hour */
144 7200, /* ON-ON-ON = 2 hour */
145};
146
135/* 147/*
136 * We are using an kernel timer to do the pinging of the watchdog 148 * We are using an kernel timer to do the pinging of the watchdog
137 * every ~500ms. We try to set the internal heartbeat of the 149 * every ~500ms. We try to set the internal heartbeat of the
@@ -167,14 +179,14 @@ static int debug = QUIET;
167module_param(debug, int, 0); 179module_param(debug, int, 0);
168MODULE_PARM_DESC(debug, "Debug level: 0=Quiet, 1=Verbose, 2=Debug (default=0)"); 180MODULE_PARM_DESC(debug, "Debug level: 0=Quiet, 1=Verbose, 2=Debug (default=0)");
169 181
170#define WATCHDOG_HEARTBEAT 60 /* 60 sec default heartbeat */ 182#define WATCHDOG_HEARTBEAT 0 /* default heartbeat = delay-time from dip-switches */
171static int heartbeat = WATCHDOG_HEARTBEAT; 183static int heartbeat = WATCHDOG_HEARTBEAT;
172module_param(heartbeat, int, 0); 184module_param(heartbeat, int, 0);
173MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<=heartbeat<=7200, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); 185MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<=heartbeat<=7200 or 0=delay-time from dip-switches, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
174 186
175static int nowayout = WATCHDOG_NOWAYOUT; 187static int nowayout = WATCHDOG_NOWAYOUT;
176module_param(nowayout, int, 0); 188module_param(nowayout, int, 0);
177MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 189MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
178 190
179/* 191/*
180 * Internal functions 192 * Internal functions
@@ -831,9 +843,7 @@ static int __devinit pcwatchdog_init(int base_addr)
831 /* clear the "card caused reboot" flag */ 843 /* clear the "card caused reboot" flag */
832 pcwd_clear_status(); 844 pcwd_clear_status();
833 845
834 init_timer(&pcwd_private.timer); 846 setup_timer(&pcwd_private.timer, pcwd_timer_ping, 0);
835 pcwd_private.timer.function = pcwd_timer_ping;
836 pcwd_private.timer.data = 0;
837 847
838 /* Disable the board */ 848 /* Disable the board */
839 pcwd_stop(); 849 pcwd_stop();
@@ -844,6 +854,10 @@ static int __devinit pcwatchdog_init(int base_addr)
844 /* Show info about the card itself */ 854 /* Show info about the card itself */
845 pcwd_show_card_info(); 855 pcwd_show_card_info();
846 856
857 /* If heartbeat = 0 then we use the heartbeat from the dip-switches */
858 if (heartbeat == 0)
859 heartbeat = heartbeat_tbl[(pcwd_get_option_switches() & 0x07)];
860
847 /* Check that the heartbeat value is within it's range ; if not reset to the default */ 861 /* Check that the heartbeat value is within it's range ; if not reset to the default */
848 if (pcwd_set_heartbeat(heartbeat)) { 862 if (pcwd_set_heartbeat(heartbeat)) {
849 pcwd_set_heartbeat(WATCHDOG_HEARTBEAT); 863 pcwd_set_heartbeat(WATCHDOG_HEARTBEAT);
diff --git a/drivers/char/watchdog/pcwd_pci.c b/drivers/char/watchdog/pcwd_pci.c
index f4872c871063..61a89e959642 100644
--- a/drivers/char/watchdog/pcwd_pci.c
+++ b/drivers/char/watchdog/pcwd_pci.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Berkshire PCI-PC Watchdog Card Driver 2 * Berkshire PCI-PC Watchdog Card Driver
3 * 3 *
4 * (c) Copyright 2003-2005 Wim Van Sebroeck <wim@iguana.be>. 4 * (c) Copyright 2003-2007 Wim Van Sebroeck <wim@iguana.be>.
5 * 5 *
6 * Based on source code of the following authors: 6 * Based on source code of the following authors:
7 * Ken Hollis <kenji@bitgate.com>, 7 * Ken Hollis <kenji@bitgate.com>,
@@ -51,8 +51,8 @@
51#include <asm/io.h> /* For inb/outb/... */ 51#include <asm/io.h> /* For inb/outb/... */
52 52
53/* Module and version information */ 53/* Module and version information */
54#define WATCHDOG_VERSION "1.02" 54#define WATCHDOG_VERSION "1.03"
55#define WATCHDOG_DATE "03 Sep 2005" 55#define WATCHDOG_DATE "21 Jan 2007"
56#define WATCHDOG_DRIVER_NAME "PCI-PC Watchdog" 56#define WATCHDOG_DRIVER_NAME "PCI-PC Watchdog"
57#define WATCHDOG_NAME "pcwd_pci" 57#define WATCHDOG_NAME "pcwd_pci"
58#define PFX WATCHDOG_NAME ": " 58#define PFX WATCHDOG_NAME ": "
@@ -96,6 +96,18 @@
96#define CMD_WRITE_WATCHDOG_TIMEOUT 0x19 96#define CMD_WRITE_WATCHDOG_TIMEOUT 0x19
97#define CMD_GET_CLEAR_RESET_COUNT 0x84 97#define CMD_GET_CLEAR_RESET_COUNT 0x84
98 98
99/* Watchdog's Dip Switch heartbeat values */
100static const int heartbeat_tbl [] = {
101 5, /* OFF-OFF-OFF = 5 Sec */
102 10, /* OFF-OFF-ON = 10 Sec */
103 30, /* OFF-ON-OFF = 30 Sec */
104 60, /* OFF-ON-ON = 1 Min */
105 300, /* ON-OFF-OFF = 5 Min */
106 600, /* ON-OFF-ON = 10 Min */
107 1800, /* ON-ON-OFF = 30 Min */
108 3600, /* ON-ON-ON = 1 hour */
109};
110
99/* We can only use 1 card due to the /dev/watchdog restriction */ 111/* We can only use 1 card due to the /dev/watchdog restriction */
100static int cards_found; 112static int cards_found;
101 113
@@ -119,14 +131,14 @@ static int debug = QUIET;
119module_param(debug, int, 0); 131module_param(debug, int, 0);
120MODULE_PARM_DESC(debug, "Debug level: 0=Quiet, 1=Verbose, 2=Debug (default=0)"); 132MODULE_PARM_DESC(debug, "Debug level: 0=Quiet, 1=Verbose, 2=Debug (default=0)");
121 133
122#define WATCHDOG_HEARTBEAT 2 /* 2 sec default heartbeat */ 134#define WATCHDOG_HEARTBEAT 0 /* default heartbeat = delay-time from dip-switches */
123static int heartbeat = WATCHDOG_HEARTBEAT; 135static int heartbeat = WATCHDOG_HEARTBEAT;
124module_param(heartbeat, int, 0); 136module_param(heartbeat, int, 0);
125MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); 137MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536 or 0=delay-time from dip-switches, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
126 138
127static int nowayout = WATCHDOG_NOWAYOUT; 139static int nowayout = WATCHDOG_NOWAYOUT;
128module_param(nowayout, int, 0); 140module_param(nowayout, int, 0);
129MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 141MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
130 142
131/* 143/*
132 * Internal functions 144 * Internal functions
@@ -286,7 +298,9 @@ static int pcipcwd_stop(void)
286static int pcipcwd_keepalive(void) 298static int pcipcwd_keepalive(void)
287{ 299{
288 /* Re-trigger watchdog by writing to port 0 */ 300 /* Re-trigger watchdog by writing to port 0 */
301 spin_lock(&pcipcwd_private.io_lock);
289 outb_p(0x42, pcipcwd_private.io_addr); /* send out any data */ 302 outb_p(0x42, pcipcwd_private.io_addr); /* send out any data */
303 spin_unlock(&pcipcwd_private.io_lock);
290 304
291 if (debug >= DEBUG) 305 if (debug >= DEBUG)
292 printk(KERN_DEBUG PFX "Watchdog keepalive signal send\n"); 306 printk(KERN_DEBUG PFX "Watchdog keepalive signal send\n");
@@ -373,7 +387,9 @@ static int pcipcwd_get_temperature(int *temperature)
373 if (!pcipcwd_private.supports_temp) 387 if (!pcipcwd_private.supports_temp)
374 return -ENODEV; 388 return -ENODEV;
375 389
390 spin_lock(&pcipcwd_private.io_lock);
376 *temperature = inb_p(pcipcwd_private.io_addr); 391 *temperature = inb_p(pcipcwd_private.io_addr);
392 spin_unlock(&pcipcwd_private.io_lock);
377 393
378 /* 394 /*
379 * Convert celsius to fahrenheit, since this was 395 * Convert celsius to fahrenheit, since this was
@@ -711,6 +727,10 @@ static int __devinit pcipcwd_card_init(struct pci_dev *pdev,
711 /* Show info about the card itself */ 727 /* Show info about the card itself */
712 pcipcwd_show_card_info(); 728 pcipcwd_show_card_info();
713 729
730 /* If heartbeat = 0 then we use the heartbeat from the dip-switches */
731 if (heartbeat == 0)
732 heartbeat = heartbeat_tbl[(pcipcwd_get_option_switches() & 0x07)];
733
714 /* Check that the heartbeat value is within it's range ; if not reset to the default */ 734 /* Check that the heartbeat value is within it's range ; if not reset to the default */
715 if (pcipcwd_set_heartbeat(heartbeat)) { 735 if (pcipcwd_set_heartbeat(heartbeat)) {
716 pcipcwd_set_heartbeat(WATCHDOG_HEARTBEAT); 736 pcipcwd_set_heartbeat(WATCHDOG_HEARTBEAT);
@@ -798,6 +818,8 @@ static int __init pcipcwd_init_module(void)
798static void __exit pcipcwd_cleanup_module(void) 818static void __exit pcipcwd_cleanup_module(void)
799{ 819{
800 pci_unregister_driver(&pcipcwd_driver); 820 pci_unregister_driver(&pcipcwd_driver);
821
822 printk(KERN_INFO PFX "Watchdog Module Unloaded.\n");
801} 823}
802 824
803module_init(pcipcwd_init_module); 825module_init(pcipcwd_init_module);
diff --git a/drivers/char/watchdog/pcwd_usb.c b/drivers/char/watchdog/pcwd_usb.c
index 2da5ac99687c..31037f9c9ffe 100644
--- a/drivers/char/watchdog/pcwd_usb.c
+++ b/drivers/char/watchdog/pcwd_usb.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Berkshire USB-PC Watchdog Card Driver 2 * Berkshire USB-PC Watchdog Card Driver
3 * 3 *
4 * (c) Copyright 2004 Wim Van Sebroeck <wim@iguana.be>. 4 * (c) Copyright 2004-2007 Wim Van Sebroeck <wim@iguana.be>.
5 * 5 *
6 * Based on source code of the following authors: 6 * Based on source code of the following authors:
7 * Ken Hollis <kenji@bitgate.com>, 7 * Ken Hollis <kenji@bitgate.com>,
@@ -24,26 +24,25 @@
24 * http://www.berkprod.com/ or http://www.pcwatchdog.com/ 24 * http://www.berkprod.com/ or http://www.pcwatchdog.com/
25 */ 25 */
26 26
27#include <linux/kernel.h> 27#include <linux/module.h> /* For module specific items */
28#include <linux/errno.h> 28#include <linux/moduleparam.h> /* For new moduleparam's */
29#include <linux/init.h> 29#include <linux/types.h> /* For standard types (like size_t) */
30#include <linux/slab.h> 30#include <linux/errno.h> /* For the -ENODEV/... values */
31#include <linux/module.h> 31#include <linux/kernel.h> /* For printk/panic/... */
32#include <linux/moduleparam.h> 32#include <linux/delay.h> /* For mdelay function */
33#include <linux/types.h> 33#include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) */
34#include <linux/delay.h> 34#include <linux/watchdog.h> /* For the watchdog specific items */
35#include <linux/miscdevice.h> 35#include <linux/notifier.h> /* For notifier support */
36#include <linux/watchdog.h> 36#include <linux/reboot.h> /* For reboot_notifier stuff */
37#include <linux/notifier.h> 37#include <linux/init.h> /* For __init/__exit/... */
38#include <linux/reboot.h> 38#include <linux/fs.h> /* For file operations */
39#include <linux/fs.h> 39#include <linux/usb.h> /* For USB functions */
40#include <linux/smp_lock.h> 40#include <linux/slab.h> /* For kmalloc, ... */
41#include <linux/completion.h> 41#include <linux/mutex.h> /* For mutex locking */
42#include <asm/uaccess.h>
43#include <linux/usb.h>
44#include <linux/mutex.h>
45#include <linux/hid.h> /* For HID_REQ_SET_REPORT & HID_DT_REPORT */ 42#include <linux/hid.h> /* For HID_REQ_SET_REPORT & HID_DT_REPORT */
46 43
44#include <asm/uaccess.h> /* For copy_to_user/put_user/... */
45
47 46
48#ifdef CONFIG_USB_DEBUG 47#ifdef CONFIG_USB_DEBUG
49 static int debug = 1; 48 static int debug = 1;
@@ -57,8 +56,8 @@
57 56
58 57
59/* Module and Version Information */ 58/* Module and Version Information */
60#define DRIVER_VERSION "1.01" 59#define DRIVER_VERSION "1.02"
61#define DRIVER_DATE "15 Mar 2005" 60#define DRIVER_DATE "21 Jan 2007"
62#define DRIVER_AUTHOR "Wim Van Sebroeck <wim@iguana.be>" 61#define DRIVER_AUTHOR "Wim Van Sebroeck <wim@iguana.be>"
63#define DRIVER_DESC "Berkshire USB-PC Watchdog driver" 62#define DRIVER_DESC "Berkshire USB-PC Watchdog driver"
64#define DRIVER_LICENSE "GPL" 63#define DRIVER_LICENSE "GPL"
@@ -75,14 +74,14 @@ MODULE_ALIAS_MISCDEV(TEMP_MINOR);
75module_param(debug, int, 0); 74module_param(debug, int, 0);
76MODULE_PARM_DESC(debug, "Debug enabled or not"); 75MODULE_PARM_DESC(debug, "Debug enabled or not");
77 76
78#define WATCHDOG_HEARTBEAT 2 /* 2 sec default heartbeat */ 77#define WATCHDOG_HEARTBEAT 0 /* default heartbeat = delay-time from dip-switches */
79static int heartbeat = WATCHDOG_HEARTBEAT; 78static int heartbeat = WATCHDOG_HEARTBEAT;
80module_param(heartbeat, int, 0); 79module_param(heartbeat, int, 0);
81MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); 80MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536 or 0=delay-time from dip-switches, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
82 81
83static int nowayout = WATCHDOG_NOWAYOUT; 82static int nowayout = WATCHDOG_NOWAYOUT;
84module_param(nowayout, int, 0); 83module_param(nowayout, int, 0);
85MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 84MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
86 85
87/* The vendor and product id's for the USB-PC Watchdog card */ 86/* The vendor and product id's for the USB-PC Watchdog card */
88#define USB_PCWD_VENDOR_ID 0x0c98 87#define USB_PCWD_VENDOR_ID 0x0c98
@@ -110,6 +109,18 @@ MODULE_DEVICE_TABLE (usb, usb_pcwd_table);
110#define CMD_ENABLE_WATCHDOG 0x30 /* Enable / Disable Watchdog */ 109#define CMD_ENABLE_WATCHDOG 0x30 /* Enable / Disable Watchdog */
111#define CMD_DISABLE_WATCHDOG CMD_ENABLE_WATCHDOG 110#define CMD_DISABLE_WATCHDOG CMD_ENABLE_WATCHDOG
112 111
112/* Watchdog's Dip Switch heartbeat values */
113static const int heartbeat_tbl [] = {
114 5, /* OFF-OFF-OFF = 5 Sec */
115 10, /* OFF-OFF-ON = 10 Sec */
116 30, /* OFF-ON-OFF = 30 Sec */
117 60, /* OFF-ON-ON = 1 Min */
118 300, /* ON-OFF-OFF = 5 Min */
119 600, /* ON-OFF-ON = 10 Min */
120 1800, /* ON-ON-OFF = 30 Min */
121 3600, /* ON-ON-ON = 1 hour */
122};
123
113/* We can only use 1 card due to the /dev/watchdog restriction */ 124/* We can only use 1 card due to the /dev/watchdog restriction */
114static int cards_found; 125static int cards_found;
115 126
@@ -682,6 +693,10 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi
682 ((option_switches & 0x10) ? "ON" : "OFF"), 693 ((option_switches & 0x10) ? "ON" : "OFF"),
683 ((option_switches & 0x08) ? "ON" : "OFF")); 694 ((option_switches & 0x08) ? "ON" : "OFF"));
684 695
696 /* If heartbeat = 0 then we use the heartbeat from the dip-switches */
697 if (heartbeat == 0)
698 heartbeat = heartbeat_tbl[(option_switches & 0x07)];
699
685 /* Check that the heartbeat value is within it's range ; if not reset to the default */ 700 /* Check that the heartbeat value is within it's range ; if not reset to the default */
686 if (usb_pcwd_set_heartbeat(usb_pcwd, heartbeat)) { 701 if (usb_pcwd_set_heartbeat(usb_pcwd, heartbeat)) {
687 usb_pcwd_set_heartbeat(usb_pcwd, WATCHDOG_HEARTBEAT); 702 usb_pcwd_set_heartbeat(usb_pcwd, WATCHDOG_HEARTBEAT);
diff --git a/drivers/char/watchdog/pnx4008_wdt.c b/drivers/char/watchdog/pnx4008_wdt.c
index ff6f1ca1e5e7..5991add702b0 100644
--- a/drivers/char/watchdog/pnx4008_wdt.c
+++ b/drivers/char/watchdog/pnx4008_wdt.c
@@ -283,7 +283,8 @@ static int pnx4008_wdt_probe(struct platform_device *pdev)
283 wdt_base = (void __iomem *)IO_ADDRESS(res->start); 283 wdt_base = (void __iomem *)IO_ADDRESS(res->start);
284 284
285 wdt_clk = clk_get(&pdev->dev, "wdt_ck"); 285 wdt_clk = clk_get(&pdev->dev, "wdt_ck");
286 if (!wdt_clk) { 286 if (IS_ERR(wdt_clk)) {
287 ret = PTR_ERR(wdt_clk);
287 release_resource(wdt_mem); 288 release_resource(wdt_mem);
288 kfree(wdt_mem); 289 kfree(wdt_mem);
289 goto out; 290 goto out;
diff --git a/drivers/char/watchdog/s3c2410_wdt.c b/drivers/char/watchdog/s3c2410_wdt.c
index 18cb050c3862..dff6cb5dc9a7 100644
--- a/drivers/char/watchdog/s3c2410_wdt.c
+++ b/drivers/char/watchdog/s3c2410_wdt.c
@@ -78,7 +78,7 @@ MODULE_PARM_DESC(tmr_margin, "Watchdog tmr_margin in seconds. default=" __MODULE
78 78
79MODULE_PARM_DESC(tmr_atboot, "Watchdog is started at boot time if set to 1, default=" __MODULE_STRING(CONFIG_S3C2410_WATCHDOG_ATBOOT)); 79MODULE_PARM_DESC(tmr_atboot, "Watchdog is started at boot time if set to 1, default=" __MODULE_STRING(CONFIG_S3C2410_WATCHDOG_ATBOOT));
80 80
81MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 81MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
82 82
83MODULE_PARM_DESC(soft_noboot, "Watchdog action, set to 1 to ignore reboots, 0 to reboot (default depends on ONLY_TESTING)"); 83MODULE_PARM_DESC(soft_noboot, "Watchdog action, set to 1 to ignore reboots, 0 to reboot (default depends on ONLY_TESTING)");
84 84
@@ -366,13 +366,15 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
366 wdt_mem = request_mem_region(res->start, size, pdev->name); 366 wdt_mem = request_mem_region(res->start, size, pdev->name);
367 if (wdt_mem == NULL) { 367 if (wdt_mem == NULL) {
368 printk(KERN_INFO PFX "failed to get memory region\n"); 368 printk(KERN_INFO PFX "failed to get memory region\n");
369 return -ENOENT; 369 ret = -ENOENT;
370 goto err_req;
370 } 371 }
371 372
372 wdt_base = ioremap(res->start, size); 373 wdt_base = ioremap(res->start, size);
373 if (wdt_base == 0) { 374 if (wdt_base == 0) {
374 printk(KERN_INFO PFX "failed to ioremap() region\n"); 375 printk(KERN_INFO PFX "failed to ioremap() region\n");
375 return -EINVAL; 376 ret = -EINVAL;
377 goto err_req;
376 } 378 }
377 379
378 DBG("probe: mapped wdt_base=%p\n", wdt_base); 380 DBG("probe: mapped wdt_base=%p\n", wdt_base);
@@ -380,22 +382,21 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
380 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 382 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
381 if (res == NULL) { 383 if (res == NULL) {
382 printk(KERN_INFO PFX "failed to get irq resource\n"); 384 printk(KERN_INFO PFX "failed to get irq resource\n");
383 iounmap(wdt_base); 385 ret = -ENOENT;
384 return -ENOENT; 386 goto err_map;
385 } 387 }
386 388
387 ret = request_irq(res->start, s3c2410wdt_irq, 0, pdev->name, pdev); 389 ret = request_irq(res->start, s3c2410wdt_irq, 0, pdev->name, pdev);
388 if (ret != 0) { 390 if (ret != 0) {
389 printk(KERN_INFO PFX "failed to install irq (%d)\n", ret); 391 printk(KERN_INFO PFX "failed to install irq (%d)\n", ret);
390 iounmap(wdt_base); 392 goto err_map;
391 return ret;
392 } 393 }
393 394
394 wdt_clock = clk_get(&pdev->dev, "watchdog"); 395 wdt_clock = clk_get(&pdev->dev, "watchdog");
395 if (wdt_clock == NULL) { 396 if (IS_ERR(wdt_clock)) {
396 printk(KERN_INFO PFX "failed to find watchdog clock source\n"); 397 printk(KERN_INFO PFX "failed to find watchdog clock source\n");
397 iounmap(wdt_base); 398 ret = PTR_ERR(wdt_clock);
398 return -ENOENT; 399 goto err_irq;
399 } 400 }
400 401
401 clk_enable(wdt_clock); 402 clk_enable(wdt_clock);
@@ -418,8 +419,7 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
418 if (ret) { 419 if (ret) {
419 printk (KERN_ERR PFX "cannot register miscdev on minor=%d (%d)\n", 420 printk (KERN_ERR PFX "cannot register miscdev on minor=%d (%d)\n",
420 WATCHDOG_MINOR, ret); 421 WATCHDOG_MINOR, ret);
421 iounmap(wdt_base); 422 goto err_clk;
422 return ret;
423 } 423 }
424 424
425 if (tmr_atboot && started == 0) { 425 if (tmr_atboot && started == 0) {
@@ -434,26 +434,36 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
434 } 434 }
435 435
436 return 0; 436 return 0;
437
438 err_clk:
439 clk_disable(wdt_clock);
440 clk_put(wdt_clock);
441
442 err_irq:
443 free_irq(wdt_irq->start, pdev);
444
445 err_map:
446 iounmap(wdt_base);
447
448 err_req:
449 release_resource(wdt_mem);
450 kfree(wdt_mem);
451
452 return ret;
437} 453}
438 454
439static int s3c2410wdt_remove(struct platform_device *dev) 455static int s3c2410wdt_remove(struct platform_device *dev)
440{ 456{
441 if (wdt_mem != NULL) { 457 release_resource(wdt_mem);
442 release_resource(wdt_mem); 458 kfree(wdt_mem);
443 kfree(wdt_mem); 459 wdt_mem = NULL;
444 wdt_mem = NULL;
445 }
446 460
447 if (wdt_irq != NULL) { 461 free_irq(wdt_irq->start, dev);
448 free_irq(wdt_irq->start, dev); 462 wdt_irq = NULL;
449 wdt_irq = NULL;
450 }
451 463
452 if (wdt_clock != NULL) { 464 clk_disable(wdt_clock);
453 clk_disable(wdt_clock); 465 clk_put(wdt_clock);
454 clk_put(wdt_clock); 466 wdt_clock = NULL;
455 wdt_clock = NULL;
456 }
457 467
458 iounmap(wdt_base); 468 iounmap(wdt_base);
459 misc_deregister(&s3c2410wdt_miscdev); 469 misc_deregister(&s3c2410wdt_miscdev);
diff --git a/drivers/char/watchdog/sbc60xxwdt.c b/drivers/char/watchdog/sbc60xxwdt.c
index c7b2045bc76b..b6282039198c 100644
--- a/drivers/char/watchdog/sbc60xxwdt.c
+++ b/drivers/char/watchdog/sbc60xxwdt.c
@@ -100,10 +100,10 @@ MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, defau
100 100
101static int nowayout = WATCHDOG_NOWAYOUT; 101static int nowayout = WATCHDOG_NOWAYOUT;
102module_param(nowayout, int, 0); 102module_param(nowayout, int, 0);
103MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 103MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
104 104
105static void wdt_timer_ping(unsigned long); 105static void wdt_timer_ping(unsigned long);
106static struct timer_list timer; 106static DEFINE_TIMER(timer, wdt_timer_ping, 0, 0);
107static unsigned long next_heartbeat; 107static unsigned long next_heartbeat;
108static unsigned long wdt_is_open; 108static unsigned long wdt_is_open;
109static char wdt_expect_close; 109static char wdt_expect_close;
@@ -122,8 +122,7 @@ static void wdt_timer_ping(unsigned long data)
122 /* Ping the WDT by reading from wdt_start */ 122 /* Ping the WDT by reading from wdt_start */
123 inb_p(wdt_start); 123 inb_p(wdt_start);
124 /* Re-set the timer interval */ 124 /* Re-set the timer interval */
125 timer.expires = jiffies + WDT_INTERVAL; 125 mod_timer(&timer, jiffies + WDT_INTERVAL);
126 add_timer(&timer);
127 } else { 126 } else {
128 printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); 127 printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n");
129 } 128 }
@@ -138,8 +137,7 @@ static void wdt_startup(void)
138 next_heartbeat = jiffies + (timeout * HZ); 137 next_heartbeat = jiffies + (timeout * HZ);
139 138
140 /* Start the timer */ 139 /* Start the timer */
141 timer.expires = jiffies + WDT_INTERVAL; 140 mod_timer(&timer, jiffies + WDT_INTERVAL);
142 add_timer(&timer);
143 printk(KERN_INFO PFX "Watchdog timer is now enabled.\n"); 141 printk(KERN_INFO PFX "Watchdog timer is now enabled.\n");
144} 142}
145 143
@@ -363,10 +361,6 @@ static int __init sbc60xxwdt_init(void)
363 } 361 }
364 } 362 }
365 363
366 init_timer(&timer);
367 timer.function = wdt_timer_ping;
368 timer.data = 0;
369
370 rc = misc_register(&wdt_miscdev); 364 rc = misc_register(&wdt_miscdev);
371 if (rc) 365 if (rc)
372 { 366 {
diff --git a/drivers/char/watchdog/sbc8360.c b/drivers/char/watchdog/sbc8360.c
index 41fc6f80c493..67ae42685e75 100644
--- a/drivers/char/watchdog/sbc8360.c
+++ b/drivers/char/watchdog/sbc8360.c
@@ -204,7 +204,7 @@ module_param(timeout, int, 0);
204MODULE_PARM_DESC(timeout, "Index into timeout table (0-63) (default=27 (60s))"); 204MODULE_PARM_DESC(timeout, "Index into timeout table (0-63) (default=27 (60s))");
205module_param(nowayout, int, 0); 205module_param(nowayout, int, 0);
206MODULE_PARM_DESC(nowayout, 206MODULE_PARM_DESC(nowayout,
207 "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 207 "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
208 208
209/* 209/*
210 * Kernel methods. 210 * Kernel methods.
diff --git a/drivers/char/watchdog/sbc_epx_c3.c b/drivers/char/watchdog/sbc_epx_c3.c
index 8882b427d24f..82cbd8809a69 100644
--- a/drivers/char/watchdog/sbc_epx_c3.c
+++ b/drivers/char/watchdog/sbc_epx_c3.c
@@ -35,7 +35,7 @@ static int epx_c3_alive;
35 35
36static int nowayout = WATCHDOG_NOWAYOUT; 36static int nowayout = WATCHDOG_NOWAYOUT;
37module_param(nowayout, int, 0); 37module_param(nowayout, int, 0);
38MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 38MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
39 39
40#define EPXC3_WATCHDOG_CTL_REG 0x1ee /* write 1 to enable, 0 to disable */ 40#define EPXC3_WATCHDOG_CTL_REG 0x1ee /* write 1 to enable, 0 to disable */
41#define EPXC3_WATCHDOG_PET_REG 0x1ef /* write anything to pet once enabled */ 41#define EPXC3_WATCHDOG_PET_REG 0x1ef /* write anything to pet once enabled */
diff --git a/drivers/char/watchdog/sc1200wdt.c b/drivers/char/watchdog/sc1200wdt.c
index e3239833e4b0..1e4a8d751a71 100644
--- a/drivers/char/watchdog/sc1200wdt.c
+++ b/drivers/char/watchdog/sc1200wdt.c
@@ -92,7 +92,7 @@ MODULE_PARM_DESC(timeout, "range is 0-255 minutes, default is 1");
92 92
93static int nowayout = WATCHDOG_NOWAYOUT; 93static int nowayout = WATCHDOG_NOWAYOUT;
94module_param(nowayout, int, 0); 94module_param(nowayout, int, 0);
95MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 95MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
96 96
97 97
98 98
diff --git a/drivers/char/watchdog/sc520_wdt.c b/drivers/char/watchdog/sc520_wdt.c
index caec37ba750a..2676a43895a7 100644
--- a/drivers/char/watchdog/sc520_wdt.c
+++ b/drivers/char/watchdog/sc520_wdt.c
@@ -97,7 +97,7 @@ MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, defau
97 97
98static int nowayout = WATCHDOG_NOWAYOUT; 98static int nowayout = WATCHDOG_NOWAYOUT;
99module_param(nowayout, int, 0); 99module_param(nowayout, int, 0);
100MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 100MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
101 101
102/* 102/*
103 * AMD Elan SC520 - Watchdog Timer Registers 103 * AMD Elan SC520 - Watchdog Timer Registers
@@ -121,7 +121,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CON
121static __u16 __iomem *wdtmrctl; 121static __u16 __iomem *wdtmrctl;
122 122
123static void wdt_timer_ping(unsigned long); 123static void wdt_timer_ping(unsigned long);
124static struct timer_list timer; 124static DEFINE_TIMER(timer, wdt_timer_ping, 0, 0);
125static unsigned long next_heartbeat; 125static unsigned long next_heartbeat;
126static unsigned long wdt_is_open; 126static unsigned long wdt_is_open;
127static char wdt_expect_close; 127static char wdt_expect_close;
@@ -145,8 +145,7 @@ static void wdt_timer_ping(unsigned long data)
145 spin_unlock(&wdt_spinlock); 145 spin_unlock(&wdt_spinlock);
146 146
147 /* Re-set the timer interval */ 147 /* Re-set the timer interval */
148 timer.expires = jiffies + WDT_INTERVAL; 148 mod_timer(&timer, jiffies + WDT_INTERVAL);
149 add_timer(&timer);
150 } else { 149 } else {
151 printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); 150 printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n");
152 } 151 }
@@ -179,8 +178,7 @@ static int wdt_startup(void)
179 next_heartbeat = jiffies + (timeout * HZ); 178 next_heartbeat = jiffies + (timeout * HZ);
180 179
181 /* Start the timer */ 180 /* Start the timer */
182 timer.expires = jiffies + WDT_INTERVAL; 181 mod_timer(&timer, jiffies + WDT_INTERVAL);
183 add_timer(&timer);
184 182
185 /* Start the watchdog */ 183 /* Start the watchdog */
186 wdt_config(WDT_ENB | WDT_WRST_ENB | WDT_EXP_SEL_04); 184 wdt_config(WDT_ENB | WDT_WRST_ENB | WDT_EXP_SEL_04);
@@ -389,10 +387,6 @@ static int __init sc520_wdt_init(void)
389 387
390 spin_lock_init(&wdt_spinlock); 388 spin_lock_init(&wdt_spinlock);
391 389
392 init_timer(&timer);
393 timer.function = wdt_timer_ping;
394 timer.data = 0;
395
396 /* Check that the timeout value is within it's range ; if not reset to the default */ 390 /* Check that the timeout value is within it's range ; if not reset to the default */
397 if (wdt_set_heartbeat(timeout)) { 391 if (wdt_set_heartbeat(timeout)) {
398 wdt_set_heartbeat(WATCHDOG_TIMEOUT); 392 wdt_set_heartbeat(WATCHDOG_TIMEOUT);
diff --git a/drivers/char/watchdog/shwdt.c b/drivers/char/watchdog/shwdt.c
index dc403629aeb3..cecbedd473a4 100644
--- a/drivers/char/watchdog/shwdt.c
+++ b/drivers/char/watchdog/shwdt.c
@@ -65,10 +65,12 @@ static int clock_division_ratio = WTCSR_CKS_4096;
65 65
66#define next_ping_period(cks) msecs_to_jiffies(cks - 4) 66#define next_ping_period(cks) msecs_to_jiffies(cks - 4)
67 67
68static void sh_wdt_ping(unsigned long data);
69
68static unsigned long shwdt_is_open; 70static unsigned long shwdt_is_open;
69static struct watchdog_info sh_wdt_info; 71static struct watchdog_info sh_wdt_info;
70static char shwdt_expect_close; 72static char shwdt_expect_close;
71static struct timer_list timer; 73static DEFINE_TIMER(timer, sh_wdt_ping, 0, 0);
72static unsigned long next_heartbeat; 74static unsigned long next_heartbeat;
73 75
74#define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */ 76#define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */
@@ -433,10 +435,6 @@ static int __init sh_wdt_init(void)
433 "be 1<=x<=3600, using %d\n", heartbeat); 435 "be 1<=x<=3600, using %d\n", heartbeat);
434 } 436 }
435 437
436 init_timer(&timer);
437 timer.function = sh_wdt_ping;
438 timer.data = 0;
439
440 rc = register_reboot_notifier(&sh_wdt_notifier); 438 rc = register_reboot_notifier(&sh_wdt_notifier);
441 if (unlikely(rc)) { 439 if (unlikely(rc)) {
442 printk(KERN_ERR PFX "Can't register reboot notifier (err=%d)\n", 440 printk(KERN_ERR PFX "Can't register reboot notifier (err=%d)\n",
diff --git a/drivers/char/watchdog/smsc37b787_wdt.c b/drivers/char/watchdog/smsc37b787_wdt.c
index a9681d580dd3..d3cb0a766020 100644
--- a/drivers/char/watchdog/smsc37b787_wdt.c
+++ b/drivers/char/watchdog/smsc37b787_wdt.c
@@ -624,4 +624,4 @@ module_param(timeout, int, 0);
624MODULE_PARM_DESC(timeout, "range is 1-255 units, default is 60"); 624MODULE_PARM_DESC(timeout, "range is 1-255 units, default is 60");
625 625
626module_param(nowayout, int, 0); 626module_param(nowayout, int, 0);
627MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 627MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
diff --git a/drivers/char/watchdog/softdog.c b/drivers/char/watchdog/softdog.c
index 4067e1f8a368..9c3694909243 100644
--- a/drivers/char/watchdog/softdog.c
+++ b/drivers/char/watchdog/softdog.c
@@ -59,7 +59,7 @@ MODULE_PARM_DESC(soft_margin, "Watchdog soft_margin in seconds. (0<soft_margin<6
59 59
60static int nowayout = WATCHDOG_NOWAYOUT; 60static int nowayout = WATCHDOG_NOWAYOUT;
61module_param(nowayout, int, 0); 61module_param(nowayout, int, 0);
62MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 62MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
63 63
64#ifdef ONLY_TESTING 64#ifdef ONLY_TESTING
65static int soft_noboot = 1; 65static int soft_noboot = 1;
diff --git a/drivers/char/watchdog/w83627hf_wdt.c b/drivers/char/watchdog/w83627hf_wdt.c
index 07d4bff27226..337ee42c90dd 100644
--- a/drivers/char/watchdog/w83627hf_wdt.c
+++ b/drivers/char/watchdog/w83627hf_wdt.c
@@ -58,7 +58,7 @@ MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=63, defaul
58 58
59static int nowayout = WATCHDOG_NOWAYOUT; 59static int nowayout = WATCHDOG_NOWAYOUT;
60module_param(nowayout, int, 0); 60module_param(nowayout, int, 0);
61MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 61MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
62 62
63/* 63/*
64 * Kernel methods. 64 * Kernel methods.
diff --git a/drivers/char/watchdog/w83697hf_wdt.c b/drivers/char/watchdog/w83697hf_wdt.c
index c960ec110dd7..d9e821d08deb 100644
--- a/drivers/char/watchdog/w83697hf_wdt.c
+++ b/drivers/char/watchdog/w83697hf_wdt.c
@@ -60,7 +60,7 @@ MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=255, defau
60 60
61static int nowayout = WATCHDOG_NOWAYOUT; 61static int nowayout = WATCHDOG_NOWAYOUT;
62module_param(nowayout, int, 0); 62module_param(nowayout, int, 0);
63MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 63MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
64 64
65/* 65/*
66 * Kernel methods. 66 * Kernel methods.
diff --git a/drivers/char/watchdog/w83877f_wdt.c b/drivers/char/watchdog/w83877f_wdt.c
index b0e5f84d6baf..3c88fe18f4f4 100644
--- a/drivers/char/watchdog/w83877f_wdt.c
+++ b/drivers/char/watchdog/w83877f_wdt.c
@@ -87,10 +87,10 @@ MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, defau
87 87
88static int nowayout = WATCHDOG_NOWAYOUT; 88static int nowayout = WATCHDOG_NOWAYOUT;
89module_param(nowayout, int, 0); 89module_param(nowayout, int, 0);
90MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 90MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
91 91
92static void wdt_timer_ping(unsigned long); 92static void wdt_timer_ping(unsigned long);
93static struct timer_list timer; 93static DEFINE_TIMER(timer, wdt_timer_ping, 0, 0);
94static unsigned long next_heartbeat; 94static unsigned long next_heartbeat;
95static unsigned long wdt_is_open; 95static unsigned long wdt_is_open;
96static char wdt_expect_close; 96static char wdt_expect_close;
@@ -114,8 +114,7 @@ static void wdt_timer_ping(unsigned long data)
114 inb_p(WDT_PING); 114 inb_p(WDT_PING);
115 115
116 /* Re-set the timer interval */ 116 /* Re-set the timer interval */
117 timer.expires = jiffies + WDT_INTERVAL; 117 mod_timer(&timer, jiffies + WDT_INTERVAL);
118 add_timer(&timer);
119 118
120 spin_unlock(&wdt_spinlock); 119 spin_unlock(&wdt_spinlock);
121 120
@@ -155,8 +154,7 @@ static void wdt_startup(void)
155 next_heartbeat = jiffies + (timeout * HZ); 154 next_heartbeat = jiffies + (timeout * HZ);
156 155
157 /* Start the timer */ 156 /* Start the timer */
158 timer.expires = jiffies + WDT_INTERVAL; 157 mod_timer(&timer, jiffies + WDT_INTERVAL);
159 add_timer(&timer);
160 158
161 wdt_change(WDT_ENABLE); 159 wdt_change(WDT_ENABLE);
162 160
@@ -377,10 +375,6 @@ static int __init w83877f_wdt_init(void)
377 goto err_out_region1; 375 goto err_out_region1;
378 } 376 }
379 377
380 init_timer(&timer);
381 timer.function = wdt_timer_ping;
382 timer.data = 0;
383
384 rc = misc_register(&wdt_miscdev); 378 rc = misc_register(&wdt_miscdev);
385 if (rc) 379 if (rc)
386 { 380 {
diff --git a/drivers/char/watchdog/w83977f_wdt.c b/drivers/char/watchdog/w83977f_wdt.c
index 2c8d5d8bd4e8..157968442891 100644
--- a/drivers/char/watchdog/w83977f_wdt.c
+++ b/drivers/char/watchdog/w83977f_wdt.c
@@ -59,7 +59,7 @@ MODULE_PARM_DESC(testmode,"Watchdog testmode (1 = no reboot), default=0");
59 59
60static int nowayout = WATCHDOG_NOWAYOUT; 60static int nowayout = WATCHDOG_NOWAYOUT;
61module_param(nowayout, int, 0); 61module_param(nowayout, int, 0);
62MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 62MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
63 63
64/* 64/*
65 * Start the watchdog 65 * Start the watchdog
diff --git a/drivers/char/watchdog/wafer5823wdt.c b/drivers/char/watchdog/wafer5823wdt.c
index 163e028ef9ed..950905d3c39f 100644
--- a/drivers/char/watchdog/wafer5823wdt.c
+++ b/drivers/char/watchdog/wafer5823wdt.c
@@ -65,7 +65,7 @@ MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=255, defau
65 65
66static int nowayout = WATCHDOG_NOWAYOUT; 66static int nowayout = WATCHDOG_NOWAYOUT;
67module_param(nowayout, int, 0); 67module_param(nowayout, int, 0);
68MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 68MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
69 69
70static void wafwdt_ping(void) 70static void wafwdt_ping(void)
71{ 71{
diff --git a/drivers/char/watchdog/wdt.c b/drivers/char/watchdog/wdt.c
index 517fbd8643f8..0a3de6a02442 100644
--- a/drivers/char/watchdog/wdt.c
+++ b/drivers/char/watchdog/wdt.c
@@ -64,7 +64,7 @@ MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536,
64 64
65static int nowayout = WATCHDOG_NOWAYOUT; 65static int nowayout = WATCHDOG_NOWAYOUT;
66module_param(nowayout, int, 0); 66module_param(nowayout, int, 0);
67MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 67MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
68 68
69/* You must set these - there is no sane way to probe for this board. */ 69/* You must set these - there is no sane way to probe for this board. */
70static int io=0x240; 70static int io=0x240;
diff --git a/drivers/char/watchdog/wdt977.c b/drivers/char/watchdog/wdt977.c
index 6253041b235b..7d300ff7ab07 100644
--- a/drivers/char/watchdog/wdt977.c
+++ b/drivers/char/watchdog/wdt977.c
@@ -68,7 +68,7 @@ MODULE_PARM_DESC(testmode,"Watchdog testmode (1 = no reboot), default=0");
68 68
69static int nowayout = WATCHDOG_NOWAYOUT; 69static int nowayout = WATCHDOG_NOWAYOUT;
70module_param(nowayout, int, 0); 70module_param(nowayout, int, 0);
71MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 71MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
72 72
73/* 73/*
74 * Start the watchdog 74 * Start the watchdog
diff --git a/drivers/char/watchdog/wdt_pci.c b/drivers/char/watchdog/wdt_pci.c
index ce1261c5cbce..6baf4ae42c9d 100644
--- a/drivers/char/watchdog/wdt_pci.c
+++ b/drivers/char/watchdog/wdt_pci.c
@@ -90,7 +90,7 @@ MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536,
90 90
91static int nowayout = WATCHDOG_NOWAYOUT; 91static int nowayout = WATCHDOG_NOWAYOUT;
92module_param(nowayout, int, 0); 92module_param(nowayout, int, 0);
93MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 93MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
94 94
95#ifdef CONFIG_WDT_501_PCI 95#ifdef CONFIG_WDT_501_PCI
96/* Support for the Fan Tachometer on the PCI-WDT501 */ 96/* Support for the Fan Tachometer on the PCI-WDT501 */