aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/watchdog
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/watchdog')
-rw-r--r--drivers/watchdog/Kconfig10
-rw-r--r--drivers/watchdog/bcm63xx_wdt.c4
-rw-r--r--drivers/watchdog/booke_wdt.c4
-rw-r--r--drivers/watchdog/coh901327_wdt.c7
-rw-r--r--drivers/watchdog/f71808e_wdt.c4
-rw-r--r--drivers/watchdog/iTCO_wdt.c213
-rw-r--r--drivers/watchdog/ie6xx_wdt.c4
-rw-r--r--drivers/watchdog/of_xilinx_wdt.c2
-rw-r--r--drivers/watchdog/omap_wdt.c24
-rw-r--r--drivers/watchdog/orion_wdt.c203
-rw-r--r--drivers/watchdog/s3c2410_wdt.c16
-rw-r--r--drivers/watchdog/sch311x_wdt.c10
12 files changed, 134 insertions, 367 deletions
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index fe819b76de56..53d75719078e 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -279,6 +279,7 @@ config DAVINCI_WATCHDOG
279config ORION_WATCHDOG 279config ORION_WATCHDOG
280 tristate "Orion watchdog" 280 tristate "Orion watchdog"
281 depends on ARCH_ORION5X || ARCH_KIRKWOOD 281 depends on ARCH_ORION5X || ARCH_KIRKWOOD
282 select WATCHDOG_CORE
282 help 283 help
283 Say Y here if to include support for the watchdog timer 284 Say Y here if to include support for the watchdog timer
284 in the Marvell Orion5x and Kirkwood ARM SoCs. 285 in the Marvell Orion5x and Kirkwood ARM SoCs.
@@ -578,6 +579,7 @@ config INTEL_SCU_WATCHDOG
578config ITCO_WDT 579config ITCO_WDT
579 tristate "Intel TCO Timer/Watchdog" 580 tristate "Intel TCO Timer/Watchdog"
580 depends on (X86 || IA64) && PCI 581 depends on (X86 || IA64) && PCI
582 select WATCHDOG_CORE
581 select LPC_ICH 583 select LPC_ICH
582 ---help--- 584 ---help---
583 Hardware driver for the intel TCO timer based watchdog devices. 585 Hardware driver for the intel TCO timer based watchdog devices.
@@ -1115,10 +1117,10 @@ config BOOKE_WDT
1115config BOOKE_WDT_DEFAULT_TIMEOUT 1117config BOOKE_WDT_DEFAULT_TIMEOUT
1116 int "PowerPC Book-E Watchdog Timer Default Timeout" 1118 int "PowerPC Book-E Watchdog Timer Default Timeout"
1117 depends on BOOKE_WDT 1119 depends on BOOKE_WDT
1118 default 38 if FSL_BOOKE 1120 default 38 if PPC_FSL_BOOK3E
1119 range 0 63 if FSL_BOOKE 1121 range 0 63 if PPC_FSL_BOOK3E
1120 default 3 if !FSL_BOOKE 1122 default 3 if !PPC_FSL_BOOK3E
1121 range 0 3 if !FSL_BOOKE 1123 range 0 3 if !PPC_FSL_BOOK3E
1122 help 1124 help
1123 Select the default watchdog timer period to be used by the PowerPC 1125 Select the default watchdog timer period to be used by the PowerPC
1124 Book-E watchdog driver. A watchdog "event" occurs when the bit 1126 Book-E watchdog driver. A watchdog "event" occurs when the bit
diff --git a/drivers/watchdog/bcm63xx_wdt.c b/drivers/watchdog/bcm63xx_wdt.c
index 8379dc32fd90..551880bfd629 100644
--- a/drivers/watchdog/bcm63xx_wdt.c
+++ b/drivers/watchdog/bcm63xx_wdt.c
@@ -302,7 +302,7 @@ static void bcm63xx_wdt_shutdown(struct platform_device *pdev)
302 bcm63xx_wdt_pause(); 302 bcm63xx_wdt_pause();
303} 303}
304 304
305static struct platform_driver bcm63xx_wdt = { 305static struct platform_driver bcm63xx_wdt_driver = {
306 .probe = bcm63xx_wdt_probe, 306 .probe = bcm63xx_wdt_probe,
307 .remove = __devexit_p(bcm63xx_wdt_remove), 307 .remove = __devexit_p(bcm63xx_wdt_remove),
308 .shutdown = bcm63xx_wdt_shutdown, 308 .shutdown = bcm63xx_wdt_shutdown,
@@ -312,7 +312,7 @@ static struct platform_driver bcm63xx_wdt = {
312 } 312 }
313}; 313};
314 314
315module_platform_driver(bcm63xx_wdt); 315module_platform_driver(bcm63xx_wdt_driver);
316 316
317MODULE_AUTHOR("Miguel Gaio <miguel.gaio@efixo.com>"); 317MODULE_AUTHOR("Miguel Gaio <miguel.gaio@efixo.com>");
318MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>"); 318MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c
index ce0ab4415eff..3fe82d0e8caa 100644
--- a/drivers/watchdog/booke_wdt.c
+++ b/drivers/watchdog/booke_wdt.c
@@ -37,7 +37,7 @@
37u32 booke_wdt_enabled; 37u32 booke_wdt_enabled;
38u32 booke_wdt_period = CONFIG_BOOKE_WDT_DEFAULT_TIMEOUT; 38u32 booke_wdt_period = CONFIG_BOOKE_WDT_DEFAULT_TIMEOUT;
39 39
40#ifdef CONFIG_FSL_BOOKE 40#ifdef CONFIG_PPC_FSL_BOOK3E
41#define WDTP(x) ((((x)&0x3)<<30)|(((x)&0x3c)<<15)) 41#define WDTP(x) ((((x)&0x3)<<30)|(((x)&0x3c)<<15))
42#define WDTP_MASK (WDTP(0x3f)) 42#define WDTP_MASK (WDTP(0x3f))
43#else 43#else
@@ -190,7 +190,7 @@ static long booke_wdt_ioctl(struct file *file,
190 case WDIOC_SETTIMEOUT: 190 case WDIOC_SETTIMEOUT:
191 if (get_user(tmp, p)) 191 if (get_user(tmp, p))
192 return -EFAULT; 192 return -EFAULT;
193#ifdef CONFIG_FSL_BOOKE 193#ifdef CONFIG_PPC_FSL_BOOK3E
194 /* period of 1 gives the largest possible timeout */ 194 /* period of 1 gives the largest possible timeout */
195 if (tmp > period_to_sec(1)) 195 if (tmp > period_to_sec(1))
196 return -EINVAL; 196 return -EINVAL;
diff --git a/drivers/watchdog/coh901327_wdt.c b/drivers/watchdog/coh901327_wdt.c
index 6876430a9f5e..cb5da5c3ece2 100644
--- a/drivers/watchdog/coh901327_wdt.c
+++ b/drivers/watchdog/coh901327_wdt.c
@@ -263,6 +263,7 @@ static int __exit coh901327_remove(struct platform_device *pdev)
263 watchdog_unregister_device(&coh901327_wdt); 263 watchdog_unregister_device(&coh901327_wdt);
264 coh901327_disable(); 264 coh901327_disable();
265 free_irq(irq, pdev); 265 free_irq(irq, pdev);
266 clk_unprepare(clk);
266 clk_put(clk); 267 clk_put(clk);
267 iounmap(virtbase); 268 iounmap(virtbase);
268 release_mem_region(phybase, physize); 269 release_mem_region(phybase, physize);
@@ -300,9 +301,9 @@ static int __init coh901327_probe(struct platform_device *pdev)
300 dev_err(&pdev->dev, "could not get clock\n"); 301 dev_err(&pdev->dev, "could not get clock\n");
301 goto out_no_clk; 302 goto out_no_clk;
302 } 303 }
303 ret = clk_enable(clk); 304 ret = clk_prepare_enable(clk);
304 if (ret) { 305 if (ret) {
305 dev_err(&pdev->dev, "could not enable clock\n"); 306 dev_err(&pdev->dev, "could not prepare and enable clock\n");
306 goto out_no_clk_enable; 307 goto out_no_clk_enable;
307 } 308 }
308 309
@@ -369,7 +370,7 @@ static int __init coh901327_probe(struct platform_device *pdev)
369out_no_wdog: 370out_no_wdog:
370 free_irq(irq, pdev); 371 free_irq(irq, pdev);
371out_no_irq: 372out_no_irq:
372 clk_disable(clk); 373 clk_disable_unprepare(clk);
373out_no_clk_enable: 374out_no_clk_enable:
374 clk_put(clk); 375 clk_put(clk);
375out_no_clk: 376out_no_clk:
diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c
index c65b0a5a020c..016bd9355190 100644
--- a/drivers/watchdog/f71808e_wdt.c
+++ b/drivers/watchdog/f71808e_wdt.c
@@ -56,6 +56,7 @@
56#define SIO_F71858_ID 0x0507 /* Chipset ID */ 56#define SIO_F71858_ID 0x0507 /* Chipset ID */
57#define SIO_F71862_ID 0x0601 /* Chipset ID */ 57#define SIO_F71862_ID 0x0601 /* Chipset ID */
58#define SIO_F71869_ID 0x0814 /* Chipset ID */ 58#define SIO_F71869_ID 0x0814 /* Chipset ID */
59#define SIO_F71869A_ID 0x1007 /* Chipset ID */
59#define SIO_F71882_ID 0x0541 /* Chipset ID */ 60#define SIO_F71882_ID 0x0541 /* Chipset ID */
60#define SIO_F71889_ID 0x0723 /* Chipset ID */ 61#define SIO_F71889_ID 0x0723 /* Chipset ID */
61 62
@@ -195,7 +196,7 @@ static inline int superio_enter(int base)
195 return -EBUSY; 196 return -EBUSY;
196 } 197 }
197 198
198 /* according to the datasheet the key must be send twice! */ 199 /* according to the datasheet the key must be sent twice! */
199 outb(SIO_UNLOCK_KEY, base); 200 outb(SIO_UNLOCK_KEY, base);
200 outb(SIO_UNLOCK_KEY, base); 201 outb(SIO_UNLOCK_KEY, base);
201 202
@@ -756,6 +757,7 @@ static int __init f71808e_find(int sioaddr)
756 err = f71862fg_pin_configure(0); /* validate module parameter */ 757 err = f71862fg_pin_configure(0); /* validate module parameter */
757 break; 758 break;
758 case SIO_F71869_ID: 759 case SIO_F71869_ID:
760 case SIO_F71869A_ID:
759 watchdog.type = f71869; 761 watchdog.type = f71869;
760 break; 762 break;
761 case SIO_F71882_ID: 763 case SIO_F71882_ID:
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
index 9c2c27c3b424..ceed39f26011 100644
--- a/drivers/watchdog/iTCO_wdt.c
+++ b/drivers/watchdog/iTCO_wdt.c
@@ -47,7 +47,7 @@
47 47
48/* Module and version information */ 48/* Module and version information */
49#define DRV_NAME "iTCO_wdt" 49#define DRV_NAME "iTCO_wdt"
50#define DRV_VERSION "1.07" 50#define DRV_VERSION "1.10"
51 51
52/* Includes */ 52/* Includes */
53#include <linux/module.h> /* For module specific items */ 53#include <linux/module.h> /* For module specific items */
@@ -88,8 +88,6 @@
88#define TCOv2_TMR (TCOBASE + 0x12) /* TCOv2 Timer Initial Value */ 88#define TCOv2_TMR (TCOBASE + 0x12) /* TCOv2 Timer Initial Value */
89 89
90/* internal variables */ 90/* internal variables */
91static unsigned long is_active;
92static char expect_release;
93static struct { /* this is private data for the iTCO_wdt device */ 91static struct { /* this is private data for the iTCO_wdt device */
94 /* TCO version/generation */ 92 /* TCO version/generation */
95 unsigned int iTCO_version; 93 unsigned int iTCO_version;
@@ -106,12 +104,12 @@ static struct { /* this is private data for the iTCO_wdt device */
106} iTCO_wdt_private; 104} iTCO_wdt_private;
107 105
108/* module parameters */ 106/* module parameters */
109#define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */ 107#define WATCHDOG_TIMEOUT 30 /* 30 sec default heartbeat */
110static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ 108static int heartbeat = WATCHDOG_TIMEOUT; /* in seconds */
111module_param(heartbeat, int, 0); 109module_param(heartbeat, int, 0);
112MODULE_PARM_DESC(heartbeat, "Watchdog timeout in seconds. " 110MODULE_PARM_DESC(heartbeat, "Watchdog timeout in seconds. "
113 "5..76 (TCO v1) or 3..614 (TCO v2), default=" 111 "5..76 (TCO v1) or 3..614 (TCO v2), default="
114 __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); 112 __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
115 113
116static bool nowayout = WATCHDOG_NOWAYOUT; 114static bool nowayout = WATCHDOG_NOWAYOUT;
117module_param(nowayout, bool, 0); 115module_param(nowayout, bool, 0);
@@ -178,13 +176,13 @@ static int iTCO_wdt_unset_NO_REBOOT_bit(void)
178 return ret; /* returns: 0 = OK, -EIO = Error */ 176 return ret; /* returns: 0 = OK, -EIO = Error */
179} 177}
180 178
181static int iTCO_wdt_start(void) 179static int iTCO_wdt_start(struct watchdog_device *wd_dev)
182{ 180{
183 unsigned int val; 181 unsigned int val;
184 182
185 spin_lock(&iTCO_wdt_private.io_lock); 183 spin_lock(&iTCO_wdt_private.io_lock);
186 184
187 iTCO_vendor_pre_start(iTCO_wdt_private.smi_res, heartbeat); 185 iTCO_vendor_pre_start(iTCO_wdt_private.smi_res, wd_dev->timeout);
188 186
189 /* disable chipset's NO_REBOOT bit */ 187 /* disable chipset's NO_REBOOT bit */
190 if (iTCO_wdt_unset_NO_REBOOT_bit()) { 188 if (iTCO_wdt_unset_NO_REBOOT_bit()) {
@@ -212,7 +210,7 @@ static int iTCO_wdt_start(void)
212 return 0; 210 return 0;
213} 211}
214 212
215static int iTCO_wdt_stop(void) 213static int iTCO_wdt_stop(struct watchdog_device *wd_dev)
216{ 214{
217 unsigned int val; 215 unsigned int val;
218 216
@@ -236,11 +234,11 @@ static int iTCO_wdt_stop(void)
236 return 0; 234 return 0;
237} 235}
238 236
239static int iTCO_wdt_keepalive(void) 237static int iTCO_wdt_ping(struct watchdog_device *wd_dev)
240{ 238{
241 spin_lock(&iTCO_wdt_private.io_lock); 239 spin_lock(&iTCO_wdt_private.io_lock);
242 240
243 iTCO_vendor_pre_keepalive(iTCO_wdt_private.smi_res, heartbeat); 241 iTCO_vendor_pre_keepalive(iTCO_wdt_private.smi_res, wd_dev->timeout);
244 242
245 /* Reload the timer by writing to the TCO Timer Counter register */ 243 /* Reload the timer by writing to the TCO Timer Counter register */
246 if (iTCO_wdt_private.iTCO_version == 2) 244 if (iTCO_wdt_private.iTCO_version == 2)
@@ -257,7 +255,7 @@ static int iTCO_wdt_keepalive(void)
257 return 0; 255 return 0;
258} 256}
259 257
260static int iTCO_wdt_set_heartbeat(int t) 258static int iTCO_wdt_set_timeout(struct watchdog_device *wd_dev, unsigned int t)
261{ 259{
262 unsigned int val16; 260 unsigned int val16;
263 unsigned char val8; 261 unsigned char val8;
@@ -304,14 +302,15 @@ static int iTCO_wdt_set_heartbeat(int t)
304 return -EINVAL; 302 return -EINVAL;
305 } 303 }
306 304
307 heartbeat = t; 305 wd_dev->timeout = t;
308 return 0; 306 return 0;
309} 307}
310 308
311static int iTCO_wdt_get_timeleft(int *time_left) 309static unsigned int iTCO_wdt_get_timeleft(struct watchdog_device *wd_dev)
312{ 310{
313 unsigned int val16; 311 unsigned int val16;
314 unsigned char val8; 312 unsigned char val8;
313 unsigned int time_left = 0;
315 314
316 /* read the TCO Timer */ 315 /* read the TCO Timer */
317 if (iTCO_wdt_private.iTCO_version == 2) { 316 if (iTCO_wdt_private.iTCO_version == 2) {
@@ -320,7 +319,7 @@ static int iTCO_wdt_get_timeleft(int *time_left)
320 val16 &= 0x3ff; 319 val16 &= 0x3ff;
321 spin_unlock(&iTCO_wdt_private.io_lock); 320 spin_unlock(&iTCO_wdt_private.io_lock);
322 321
323 *time_left = (val16 * 6) / 10; 322 time_left = (val16 * 6) / 10;
324 } else if (iTCO_wdt_private.iTCO_version == 1) { 323 } else if (iTCO_wdt_private.iTCO_version == 1) {
325 spin_lock(&iTCO_wdt_private.io_lock); 324 spin_lock(&iTCO_wdt_private.io_lock);
326 val8 = inb(TCO_RLD); 325 val8 = inb(TCO_RLD);
@@ -329,156 +328,35 @@ static int iTCO_wdt_get_timeleft(int *time_left)
329 val8 += (inb(TCOv1_TMR) & 0x3f); 328 val8 += (inb(TCOv1_TMR) & 0x3f);
330 spin_unlock(&iTCO_wdt_private.io_lock); 329 spin_unlock(&iTCO_wdt_private.io_lock);
331 330
332 *time_left = (val8 * 6) / 10; 331 time_left = (val8 * 6) / 10;
333 } else
334 return -EINVAL;
335 return 0;
336}
337
338/*
339 * /dev/watchdog handling
340 */
341
342static int iTCO_wdt_open(struct inode *inode, struct file *file)
343{
344 /* /dev/watchdog can only be opened once */
345 if (test_and_set_bit(0, &is_active))
346 return -EBUSY;
347
348 /*
349 * Reload and activate timer
350 */
351 iTCO_wdt_start();
352 return nonseekable_open(inode, file);
353}
354
355static int iTCO_wdt_release(struct inode *inode, struct file *file)
356{
357 /*
358 * Shut off the timer.
359 */
360 if (expect_release == 42) {
361 iTCO_wdt_stop();
362 } else {
363 pr_crit("Unexpected close, not stopping watchdog!\n");
364 iTCO_wdt_keepalive();
365 }
366 clear_bit(0, &is_active);
367 expect_release = 0;
368 return 0;
369}
370
371static ssize_t iTCO_wdt_write(struct file *file, const char __user *data,
372 size_t len, loff_t *ppos)
373{
374 /* See if we got the magic character 'V' and reload the timer */
375 if (len) {
376 if (!nowayout) {
377 size_t i;
378
379 /* note: just in case someone wrote the magic
380 character five months ago... */
381 expect_release = 0;
382
383 /* scan to see whether or not we got the
384 magic character */
385 for (i = 0; i != len; i++) {
386 char c;
387 if (get_user(c, data + i))
388 return -EFAULT;
389 if (c == 'V')
390 expect_release = 42;
391 }
392 }
393
394 /* someone wrote to us, we should reload the timer */
395 iTCO_wdt_keepalive();
396 }
397 return len;
398}
399
400static long iTCO_wdt_ioctl(struct file *file, unsigned int cmd,
401 unsigned long arg)
402{
403 int new_options, retval = -EINVAL;
404 int new_heartbeat;
405 void __user *argp = (void __user *)arg;
406 int __user *p = argp;
407 static const struct watchdog_info ident = {
408 .options = WDIOF_SETTIMEOUT |
409 WDIOF_KEEPALIVEPING |
410 WDIOF_MAGICCLOSE,
411 .firmware_version = 0,
412 .identity = DRV_NAME,
413 };
414
415 switch (cmd) {
416 case WDIOC_GETSUPPORT:
417 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
418 case WDIOC_GETSTATUS:
419 case WDIOC_GETBOOTSTATUS:
420 return put_user(0, p);
421
422 case WDIOC_SETOPTIONS:
423 {
424 if (get_user(new_options, p))
425 return -EFAULT;
426
427 if (new_options & WDIOS_DISABLECARD) {
428 iTCO_wdt_stop();
429 retval = 0;
430 }
431 if (new_options & WDIOS_ENABLECARD) {
432 iTCO_wdt_keepalive();
433 iTCO_wdt_start();
434 retval = 0;
435 }
436 return retval;
437 }
438 case WDIOC_KEEPALIVE:
439 iTCO_wdt_keepalive();
440 return 0;
441
442 case WDIOC_SETTIMEOUT:
443 {
444 if (get_user(new_heartbeat, p))
445 return -EFAULT;
446 if (iTCO_wdt_set_heartbeat(new_heartbeat))
447 return -EINVAL;
448 iTCO_wdt_keepalive();
449 /* Fall */
450 }
451 case WDIOC_GETTIMEOUT:
452 return put_user(heartbeat, p);
453 case WDIOC_GETTIMELEFT:
454 {
455 int time_left;
456 if (iTCO_wdt_get_timeleft(&time_left))
457 return -EINVAL;
458 return put_user(time_left, p);
459 }
460 default:
461 return -ENOTTY;
462 } 332 }
333 return time_left;
463} 334}
464 335
465/* 336/*
466 * Kernel Interfaces 337 * Kernel Interfaces
467 */ 338 */
468 339
469static const struct file_operations iTCO_wdt_fops = { 340static const struct watchdog_info ident = {
341 .options = WDIOF_SETTIMEOUT |
342 WDIOF_KEEPALIVEPING |
343 WDIOF_MAGICCLOSE,
344 .firmware_version = 0,
345 .identity = DRV_NAME,
346};
347
348static const struct watchdog_ops iTCO_wdt_ops = {
470 .owner = THIS_MODULE, 349 .owner = THIS_MODULE,
471 .llseek = no_llseek, 350 .start = iTCO_wdt_start,
472 .write = iTCO_wdt_write, 351 .stop = iTCO_wdt_stop,
473 .unlocked_ioctl = iTCO_wdt_ioctl, 352 .ping = iTCO_wdt_ping,
474 .open = iTCO_wdt_open, 353 .set_timeout = iTCO_wdt_set_timeout,
475 .release = iTCO_wdt_release, 354 .get_timeleft = iTCO_wdt_get_timeleft,
476}; 355};
477 356
478static struct miscdevice iTCO_wdt_miscdev = { 357static struct watchdog_device iTCO_wdt_watchdog_dev = {
479 .minor = WATCHDOG_MINOR, 358 .info = &ident,
480 .name = "watchdog", 359 .ops = &iTCO_wdt_ops,
481 .fops = &iTCO_wdt_fops,
482}; 360};
483 361
484/* 362/*
@@ -489,10 +367,10 @@ static void __devexit iTCO_wdt_cleanup(void)
489{ 367{
490 /* Stop the timer before we leave */ 368 /* Stop the timer before we leave */
491 if (!nowayout) 369 if (!nowayout)
492 iTCO_wdt_stop(); 370 iTCO_wdt_stop(&iTCO_wdt_watchdog_dev);
493 371
494 /* Deregister */ 372 /* Deregister */
495 misc_deregister(&iTCO_wdt_miscdev); 373 watchdog_unregister_device(&iTCO_wdt_watchdog_dev);
496 374
497 /* release resources */ 375 /* release resources */
498 release_region(iTCO_wdt_private.tco_res->start, 376 release_region(iTCO_wdt_private.tco_res->start,
@@ -605,20 +483,25 @@ static int __devinit iTCO_wdt_probe(struct platform_device *dev)
605 outw(0x0002, TCO2_STS); /* Clear SECOND_TO_STS bit */ 483 outw(0x0002, TCO2_STS); /* Clear SECOND_TO_STS bit */
606 outw(0x0004, TCO2_STS); /* Clear BOOT_STS bit */ 484 outw(0x0004, TCO2_STS); /* Clear BOOT_STS bit */
607 485
486 iTCO_wdt_watchdog_dev.bootstatus = 0;
487 iTCO_wdt_watchdog_dev.timeout = WATCHDOG_TIMEOUT;
488 watchdog_set_nowayout(&iTCO_wdt_watchdog_dev, nowayout);
489 iTCO_wdt_watchdog_dev.parent = dev->dev.parent;
490
608 /* Make sure the watchdog is not running */ 491 /* Make sure the watchdog is not running */
609 iTCO_wdt_stop(); 492 iTCO_wdt_stop(&iTCO_wdt_watchdog_dev);
610 493
611 /* Check that the heartbeat value is within it's range; 494 /* Check that the heartbeat value is within it's range;
612 if not reset to the default */ 495 if not reset to the default */
613 if (iTCO_wdt_set_heartbeat(heartbeat)) { 496 if (iTCO_wdt_set_timeout(&iTCO_wdt_watchdog_dev, heartbeat)) {
614 iTCO_wdt_set_heartbeat(WATCHDOG_HEARTBEAT); 497 iTCO_wdt_set_timeout(&iTCO_wdt_watchdog_dev, WATCHDOG_TIMEOUT);
615 pr_info("timeout value out of range, using %d\n", heartbeat); 498 pr_info("timeout value out of range, using %d\n",
499 WATCHDOG_TIMEOUT);
616 } 500 }
617 501
618 ret = misc_register(&iTCO_wdt_miscdev); 502 ret = watchdog_register_device(&iTCO_wdt_watchdog_dev);
619 if (ret != 0) { 503 if (ret != 0) {
620 pr_err("cannot register miscdev on minor=%d (err=%d)\n", 504 pr_err("cannot register watchdog device (err=%d)\n", ret);
621 WATCHDOG_MINOR, ret);
622 goto unreg_tco; 505 goto unreg_tco;
623 } 506 }
624 507
@@ -659,7 +542,7 @@ static int __devexit iTCO_wdt_remove(struct platform_device *dev)
659 542
660static void iTCO_wdt_shutdown(struct platform_device *dev) 543static void iTCO_wdt_shutdown(struct platform_device *dev)
661{ 544{
662 iTCO_wdt_stop(); 545 iTCO_wdt_stop(NULL);
663} 546}
664 547
665static struct platform_driver iTCO_wdt_driver = { 548static struct platform_driver iTCO_wdt_driver = {
diff --git a/drivers/watchdog/ie6xx_wdt.c b/drivers/watchdog/ie6xx_wdt.c
index 5f0d776f902c..8f541b940053 100644
--- a/drivers/watchdog/ie6xx_wdt.c
+++ b/drivers/watchdog/ie6xx_wdt.c
@@ -232,7 +232,7 @@ static void __devinit ie6xx_wdt_debugfs_init(void)
232 S_IFREG | S_IRUGO, NULL, NULL, &ie6xx_wdt_dbg_operations); 232 S_IFREG | S_IRUGO, NULL, NULL, &ie6xx_wdt_dbg_operations);
233} 233}
234 234
235static void __devexit ie6xx_wdt_debugfs_exit(void) 235static void ie6xx_wdt_debugfs_exit(void)
236{ 236{
237 debugfs_remove(ie6xx_wdt_data.debugfs); 237 debugfs_remove(ie6xx_wdt_data.debugfs);
238} 238}
@@ -242,7 +242,7 @@ static void __devinit ie6xx_wdt_debugfs_init(void)
242{ 242{
243} 243}
244 244
245static void __devexit ie6xx_wdt_debugfs_exit(void) 245static void ie6xx_wdt_debugfs_exit(void)
246{ 246{
247} 247}
248#endif 248#endif
diff --git a/drivers/watchdog/of_xilinx_wdt.c b/drivers/watchdog/of_xilinx_wdt.c
index 55d2f66dbeae..294fb4e00521 100644
--- a/drivers/watchdog/of_xilinx_wdt.c
+++ b/drivers/watchdog/of_xilinx_wdt.c
@@ -297,7 +297,7 @@ static int __devinit xwdt_probe(struct platform_device *pdev)
297 297
298 no_timeout = 0; 298 no_timeout = 0;
299 299
300 pfreq = (u32 *)of_get_property(pdev->dev.of_node->parent, 300 pfreq = (u32 *)of_get_property(pdev->dev.of_node,
301 "clock-frequency", NULL); 301 "clock-frequency", NULL);
302 302
303 if (pfreq == NULL) { 303 if (pfreq == NULL) {
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index 8285d65cd207..fceec4f4eb7e 100644
--- a/drivers/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -126,8 +126,6 @@ static void omap_wdt_set_timeout(struct omap_wdt_dev *wdev)
126 u32 pre_margin = GET_WLDR_VAL(timer_margin); 126 u32 pre_margin = GET_WLDR_VAL(timer_margin);
127 void __iomem *base = wdev->base; 127 void __iomem *base = wdev->base;
128 128
129 pm_runtime_get_sync(wdev->dev);
130
131 /* just count up at 32 KHz */ 129 /* just count up at 32 KHz */
132 while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x04) 130 while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x04)
133 cpu_relax(); 131 cpu_relax();
@@ -135,8 +133,6 @@ static void omap_wdt_set_timeout(struct omap_wdt_dev *wdev)
135 __raw_writel(pre_margin, base + OMAP_WATCHDOG_LDR); 133 __raw_writel(pre_margin, base + OMAP_WATCHDOG_LDR);
136 while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x04) 134 while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x04)
137 cpu_relax(); 135 cpu_relax();
138
139 pm_runtime_put_sync(wdev->dev);
140} 136}
141 137
142/* 138/*
@@ -166,8 +162,6 @@ static int omap_wdt_open(struct inode *inode, struct file *file)
166 omap_wdt_ping(wdev); /* trigger loading of new timeout value */ 162 omap_wdt_ping(wdev); /* trigger loading of new timeout value */
167 omap_wdt_enable(wdev); 163 omap_wdt_enable(wdev);
168 164
169 pm_runtime_put_sync(wdev->dev);
170
171 return nonseekable_open(inode, file); 165 return nonseekable_open(inode, file);
172} 166}
173 167
@@ -179,8 +173,6 @@ static int omap_wdt_release(struct inode *inode, struct file *file)
179 * Shut off the timer unless NOWAYOUT is defined. 173 * Shut off the timer unless NOWAYOUT is defined.
180 */ 174 */
181#ifndef CONFIG_WATCHDOG_NOWAYOUT 175#ifndef CONFIG_WATCHDOG_NOWAYOUT
182 pm_runtime_get_sync(wdev->dev);
183
184 omap_wdt_disable(wdev); 176 omap_wdt_disable(wdev);
185 177
186 pm_runtime_put_sync(wdev->dev); 178 pm_runtime_put_sync(wdev->dev);
@@ -199,11 +191,9 @@ static ssize_t omap_wdt_write(struct file *file, const char __user *data,
199 191
200 /* Refresh LOAD_TIME. */ 192 /* Refresh LOAD_TIME. */
201 if (len) { 193 if (len) {
202 pm_runtime_get_sync(wdev->dev);
203 spin_lock(&wdt_lock); 194 spin_lock(&wdt_lock);
204 omap_wdt_ping(wdev); 195 omap_wdt_ping(wdev);
205 spin_unlock(&wdt_lock); 196 spin_unlock(&wdt_lock);
206 pm_runtime_put_sync(wdev->dev);
207 } 197 }
208 return len; 198 return len;
209} 199}
@@ -236,18 +226,15 @@ static long omap_wdt_ioctl(struct file *file, unsigned int cmd,
236 (int __user *)arg); 226 (int __user *)arg);
237 return put_user(0, (int __user *)arg); 227 return put_user(0, (int __user *)arg);
238 case WDIOC_KEEPALIVE: 228 case WDIOC_KEEPALIVE:
239 pm_runtime_get_sync(wdev->dev);
240 spin_lock(&wdt_lock); 229 spin_lock(&wdt_lock);
241 omap_wdt_ping(wdev); 230 omap_wdt_ping(wdev);
242 spin_unlock(&wdt_lock); 231 spin_unlock(&wdt_lock);
243 pm_runtime_put_sync(wdev->dev);
244 return 0; 232 return 0;
245 case WDIOC_SETTIMEOUT: 233 case WDIOC_SETTIMEOUT:
246 if (get_user(new_margin, (int __user *)arg)) 234 if (get_user(new_margin, (int __user *)arg))
247 return -EFAULT; 235 return -EFAULT;
248 omap_wdt_adjust_timeout(new_margin); 236 omap_wdt_adjust_timeout(new_margin);
249 237
250 pm_runtime_get_sync(wdev->dev);
251 spin_lock(&wdt_lock); 238 spin_lock(&wdt_lock);
252 omap_wdt_disable(wdev); 239 omap_wdt_disable(wdev);
253 omap_wdt_set_timeout(wdev); 240 omap_wdt_set_timeout(wdev);
@@ -255,7 +242,6 @@ static long omap_wdt_ioctl(struct file *file, unsigned int cmd,
255 242
256 omap_wdt_ping(wdev); 243 omap_wdt_ping(wdev);
257 spin_unlock(&wdt_lock); 244 spin_unlock(&wdt_lock);
258 pm_runtime_put_sync(wdev->dev);
259 /* Fall */ 245 /* Fall */
260 case WDIOC_GETTIMEOUT: 246 case WDIOC_GETTIMEOUT:
261 return put_user(timer_margin, (int __user *)arg); 247 return put_user(timer_margin, (int __user *)arg);
@@ -363,7 +349,6 @@ static void omap_wdt_shutdown(struct platform_device *pdev)
363 struct omap_wdt_dev *wdev = platform_get_drvdata(pdev); 349 struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
364 350
365 if (wdev->omap_wdt_users) { 351 if (wdev->omap_wdt_users) {
366 pm_runtime_get_sync(wdev->dev);
367 omap_wdt_disable(wdev); 352 omap_wdt_disable(wdev);
368 pm_runtime_put_sync(wdev->dev); 353 pm_runtime_put_sync(wdev->dev);
369 } 354 }
@@ -403,7 +388,6 @@ static int omap_wdt_suspend(struct platform_device *pdev, pm_message_t state)
403 struct omap_wdt_dev *wdev = platform_get_drvdata(pdev); 388 struct omap_wdt_dev *wdev = platform_get_drvdata(pdev);
404 389
405 if (wdev->omap_wdt_users) { 390 if (wdev->omap_wdt_users) {
406 pm_runtime_get_sync(wdev->dev);
407 omap_wdt_disable(wdev); 391 omap_wdt_disable(wdev);
408 pm_runtime_put_sync(wdev->dev); 392 pm_runtime_put_sync(wdev->dev);
409 } 393 }
@@ -419,7 +403,6 @@ static int omap_wdt_resume(struct platform_device *pdev)
419 pm_runtime_get_sync(wdev->dev); 403 pm_runtime_get_sync(wdev->dev);
420 omap_wdt_enable(wdev); 404 omap_wdt_enable(wdev);
421 omap_wdt_ping(wdev); 405 omap_wdt_ping(wdev);
422 pm_runtime_put_sync(wdev->dev);
423 } 406 }
424 407
425 return 0; 408 return 0;
@@ -430,6 +413,12 @@ static int omap_wdt_resume(struct platform_device *pdev)
430#define omap_wdt_resume NULL 413#define omap_wdt_resume NULL
431#endif 414#endif
432 415
416static const struct of_device_id omap_wdt_of_match[] = {
417 { .compatible = "ti,omap3-wdt", },
418 {},
419};
420MODULE_DEVICE_TABLE(of, omap_wdt_of_match);
421
433static struct platform_driver omap_wdt_driver = { 422static struct platform_driver omap_wdt_driver = {
434 .probe = omap_wdt_probe, 423 .probe = omap_wdt_probe,
435 .remove = __devexit_p(omap_wdt_remove), 424 .remove = __devexit_p(omap_wdt_remove),
@@ -439,6 +428,7 @@ static struct platform_driver omap_wdt_driver = {
439 .driver = { 428 .driver = {
440 .owner = THIS_MODULE, 429 .owner = THIS_MODULE,
441 .name = "omap_wdt", 430 .name = "omap_wdt",
431 .of_match_table = omap_wdt_of_match,
442 }, 432 },
443}; 433};
444 434
diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c
index 0f5736949c61..a73bea4aa1ba 100644
--- a/drivers/watchdog/orion_wdt.c
+++ b/drivers/watchdog/orion_wdt.c
@@ -16,22 +16,21 @@
16#include <linux/moduleparam.h> 16#include <linux/moduleparam.h>
17#include <linux/types.h> 17#include <linux/types.h>
18#include <linux/kernel.h> 18#include <linux/kernel.h>
19#include <linux/fs.h>
20#include <linux/miscdevice.h> 19#include <linux/miscdevice.h>
21#include <linux/platform_device.h> 20#include <linux/platform_device.h>
22#include <linux/watchdog.h> 21#include <linux/watchdog.h>
23#include <linux/init.h> 22#include <linux/init.h>
24#include <linux/uaccess.h>
25#include <linux/io.h> 23#include <linux/io.h>
26#include <linux/spinlock.h> 24#include <linux/spinlock.h>
27#include <linux/clk.h> 25#include <linux/clk.h>
26#include <linux/err.h>
28#include <mach/bridge-regs.h> 27#include <mach/bridge-regs.h>
29 28
30/* 29/*
31 * Watchdog timer block registers. 30 * Watchdog timer block registers.
32 */ 31 */
33#define TIMER_CTRL 0x0000 32#define TIMER_CTRL 0x0000
34#define WDT_EN 0x0010 33#define WDT_EN 0x0010
35#define WDT_VAL 0x0024 34#define WDT_VAL 0x0024
36 35
37#define WDT_MAX_CYCLE_COUNT 0xffffffff 36#define WDT_MAX_CYCLE_COUNT 0xffffffff
@@ -44,27 +43,27 @@ static unsigned int wdt_max_duration; /* (seconds) */
44static struct clk *clk; 43static struct clk *clk;
45static unsigned int wdt_tclk; 44static unsigned int wdt_tclk;
46static void __iomem *wdt_reg; 45static void __iomem *wdt_reg;
47static unsigned long wdt_status;
48static DEFINE_SPINLOCK(wdt_lock); 46static DEFINE_SPINLOCK(wdt_lock);
49 47
50static void orion_wdt_ping(void) 48static int orion_wdt_ping(struct watchdog_device *wdt_dev)
51{ 49{
52 spin_lock(&wdt_lock); 50 spin_lock(&wdt_lock);
53 51
54 /* Reload watchdog duration */ 52 /* Reload watchdog duration */
55 writel(wdt_tclk * heartbeat, wdt_reg + WDT_VAL); 53 writel(wdt_tclk * wdt_dev->timeout, wdt_reg + WDT_VAL);
56 54
57 spin_unlock(&wdt_lock); 55 spin_unlock(&wdt_lock);
56 return 0;
58} 57}
59 58
60static void orion_wdt_enable(void) 59static int orion_wdt_start(struct watchdog_device *wdt_dev)
61{ 60{
62 u32 reg; 61 u32 reg;
63 62
64 spin_lock(&wdt_lock); 63 spin_lock(&wdt_lock);
65 64
66 /* Set watchdog duration */ 65 /* Set watchdog duration */
67 writel(wdt_tclk * heartbeat, wdt_reg + WDT_VAL); 66 writel(wdt_tclk * wdt_dev->timeout, wdt_reg + WDT_VAL);
68 67
69 /* Clear watchdog timer interrupt */ 68 /* Clear watchdog timer interrupt */
70 reg = readl(BRIDGE_CAUSE); 69 reg = readl(BRIDGE_CAUSE);
@@ -82,9 +81,10 @@ static void orion_wdt_enable(void)
82 writel(reg, RSTOUTn_MASK); 81 writel(reg, RSTOUTn_MASK);
83 82
84 spin_unlock(&wdt_lock); 83 spin_unlock(&wdt_lock);
84 return 0;
85} 85}
86 86
87static void orion_wdt_disable(void) 87static int orion_wdt_stop(struct watchdog_device *wdt_dev)
88{ 88{
89 u32 reg; 89 u32 reg;
90 90
@@ -101,139 +101,44 @@ static void orion_wdt_disable(void)
101 writel(reg, wdt_reg + TIMER_CTRL); 101 writel(reg, wdt_reg + TIMER_CTRL);
102 102
103 spin_unlock(&wdt_lock); 103 spin_unlock(&wdt_lock);
104 return 0;
104} 105}
105 106
106static int orion_wdt_get_timeleft(int *time_left) 107static unsigned int orion_wdt_get_timeleft(struct watchdog_device *wdt_dev)
107{ 108{
109 unsigned int time_left;
110
108 spin_lock(&wdt_lock); 111 spin_lock(&wdt_lock);
109 *time_left = readl(wdt_reg + WDT_VAL) / wdt_tclk; 112 time_left = readl(wdt_reg + WDT_VAL) / wdt_tclk;
110 spin_unlock(&wdt_lock); 113 spin_unlock(&wdt_lock);
111 return 0;
112}
113 114
114static int orion_wdt_open(struct inode *inode, struct file *file) 115 return time_left;
115{
116 if (test_and_set_bit(WDT_IN_USE, &wdt_status))
117 return -EBUSY;
118 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
119 orion_wdt_enable();
120 return nonseekable_open(inode, file);
121} 116}
122 117
123static ssize_t orion_wdt_write(struct file *file, const char *data, 118static int orion_wdt_set_timeout(struct watchdog_device *wdt_dev,
124 size_t len, loff_t *ppos) 119 unsigned int timeout)
125{ 120{
126 if (len) { 121 wdt_dev->timeout = timeout;
127 if (!nowayout) {
128 size_t i;
129
130 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
131 for (i = 0; i != len; i++) {
132 char c;
133
134 if (get_user(c, data + i))
135 return -EFAULT;
136 if (c == 'V')
137 set_bit(WDT_OK_TO_CLOSE, &wdt_status);
138 }
139 }
140 orion_wdt_ping();
141 }
142 return len;
143}
144
145static int orion_wdt_settimeout(int new_time)
146{
147 if ((new_time <= 0) || (new_time > wdt_max_duration))
148 return -EINVAL;
149
150 /* Set new watchdog time to be used when
151 * orion_wdt_enable() or orion_wdt_ping() is called. */
152 heartbeat = new_time;
153 return 0; 122 return 0;
154} 123}
155 124
156static const struct watchdog_info ident = { 125static const struct watchdog_info orion_wdt_info = {
157 .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | 126 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
158 WDIOF_KEEPALIVEPING, 127 .identity = "Orion Watchdog",
159 .identity = "Orion Watchdog",
160}; 128};
161 129
162static long orion_wdt_ioctl(struct file *file, unsigned int cmd, 130static const struct watchdog_ops orion_wdt_ops = {
163 unsigned long arg) 131 .owner = THIS_MODULE,
164{ 132 .start = orion_wdt_start,
165 int ret = -ENOTTY; 133 .stop = orion_wdt_stop,
166 int time; 134 .ping = orion_wdt_ping,
167 135 .set_timeout = orion_wdt_set_timeout,
168 switch (cmd) { 136 .get_timeleft = orion_wdt_get_timeleft,
169 case WDIOC_GETSUPPORT:
170 ret = copy_to_user((struct watchdog_info *)arg, &ident,
171 sizeof(ident)) ? -EFAULT : 0;
172 break;
173
174 case WDIOC_GETSTATUS:
175 case WDIOC_GETBOOTSTATUS:
176 ret = put_user(0, (int *)arg);
177 break;
178
179 case WDIOC_KEEPALIVE:
180 orion_wdt_ping();
181 ret = 0;
182 break;
183
184 case WDIOC_SETTIMEOUT:
185 ret = get_user(time, (int *)arg);
186 if (ret)
187 break;
188
189 if (orion_wdt_settimeout(time)) {
190 ret = -EINVAL;
191 break;
192 }
193 orion_wdt_ping();
194 /* Fall through */
195
196 case WDIOC_GETTIMEOUT:
197 ret = put_user(heartbeat, (int *)arg);
198 break;
199
200 case WDIOC_GETTIMELEFT:
201 if (orion_wdt_get_timeleft(&time)) {
202 ret = -EINVAL;
203 break;
204 }
205 ret = put_user(time, (int *)arg);
206 break;
207 }
208 return ret;
209}
210
211static int orion_wdt_release(struct inode *inode, struct file *file)
212{
213 if (test_bit(WDT_OK_TO_CLOSE, &wdt_status))
214 orion_wdt_disable();
215 else
216 pr_crit("Device closed unexpectedly - timer will not stop\n");
217 clear_bit(WDT_IN_USE, &wdt_status);
218 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
219
220 return 0;
221}
222
223
224static const struct file_operations orion_wdt_fops = {
225 .owner = THIS_MODULE,
226 .llseek = no_llseek,
227 .write = orion_wdt_write,
228 .unlocked_ioctl = orion_wdt_ioctl,
229 .open = orion_wdt_open,
230 .release = orion_wdt_release,
231}; 137};
232 138
233static struct miscdevice orion_wdt_miscdev = { 139static struct watchdog_device orion_wdt = {
234 .minor = WATCHDOG_MINOR, 140 .info = &orion_wdt_info,
235 .name = "watchdog", 141 .ops = &orion_wdt_ops,
236 .fops = &orion_wdt_fops,
237}; 142};
238 143
239static int __devinit orion_wdt_probe(struct platform_device *pdev) 144static int __devinit orion_wdt_probe(struct platform_device *pdev)
@@ -241,29 +146,34 @@ static int __devinit orion_wdt_probe(struct platform_device *pdev)
241 struct resource *res; 146 struct resource *res;
242 int ret; 147 int ret;
243 148
244 clk = clk_get(&pdev->dev, NULL); 149 clk = devm_clk_get(&pdev->dev, NULL);
245 if (IS_ERR(clk)) { 150 if (IS_ERR(clk)) {
246 printk(KERN_ERR "Orion Watchdog missing clock\n"); 151 dev_err(&pdev->dev, "Orion Watchdog missing clock\n");
247 return -ENODEV; 152 return -ENODEV;
248 } 153 }
249 clk_prepare_enable(clk); 154 clk_prepare_enable(clk);
250 wdt_tclk = clk_get_rate(clk); 155 wdt_tclk = clk_get_rate(clk);
251 156
252 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 157 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
253 158 wdt_reg = devm_ioremap(&pdev->dev, res->start, resource_size(res));
254 wdt_reg = ioremap(res->start, resource_size(res)); 159 if (!wdt_reg)
255 160 return -ENOMEM;
256 if (orion_wdt_miscdev.parent)
257 return -EBUSY;
258 orion_wdt_miscdev.parent = &pdev->dev;
259 161
260 wdt_max_duration = WDT_MAX_CYCLE_COUNT / wdt_tclk; 162 wdt_max_duration = WDT_MAX_CYCLE_COUNT / wdt_tclk;
261 if (orion_wdt_settimeout(heartbeat)) 163
164 if ((heartbeat < 1) || (heartbeat > wdt_max_duration))
262 heartbeat = wdt_max_duration; 165 heartbeat = wdt_max_duration;
263 166
264 ret = misc_register(&orion_wdt_miscdev); 167 orion_wdt.timeout = heartbeat;
265 if (ret) 168 orion_wdt.min_timeout = 1;
169 orion_wdt.max_timeout = wdt_max_duration;
170
171 watchdog_set_nowayout(&orion_wdt, nowayout);
172 ret = watchdog_register_device(&orion_wdt);
173 if (ret) {
174 clk_disable_unprepare(clk);
266 return ret; 175 return ret;
176 }
267 177
268 pr_info("Initial timeout %d sec%s\n", 178 pr_info("Initial timeout %d sec%s\n",
269 heartbeat, nowayout ? ", nowayout" : ""); 179 heartbeat, nowayout ? ", nowayout" : "");
@@ -272,27 +182,14 @@ static int __devinit orion_wdt_probe(struct platform_device *pdev)
272 182
273static int __devexit orion_wdt_remove(struct platform_device *pdev) 183static int __devexit orion_wdt_remove(struct platform_device *pdev)
274{ 184{
275 int ret; 185 watchdog_unregister_device(&orion_wdt);
276
277 if (test_bit(WDT_IN_USE, &wdt_status)) {
278 orion_wdt_disable();
279 clear_bit(WDT_IN_USE, &wdt_status);
280 }
281
282 ret = misc_deregister(&orion_wdt_miscdev);
283 if (!ret)
284 orion_wdt_miscdev.parent = NULL;
285
286 clk_disable_unprepare(clk); 186 clk_disable_unprepare(clk);
287 clk_put(clk); 187 return 0;
288
289 return ret;
290} 188}
291 189
292static void orion_wdt_shutdown(struct platform_device *pdev) 190static void orion_wdt_shutdown(struct platform_device *pdev)
293{ 191{
294 if (test_bit(WDT_IN_USE, &wdt_status)) 192 orion_wdt_stop(&orion_wdt);
295 orion_wdt_disable();
296} 193}
297 194
298static struct platform_driver orion_wdt_driver = { 195static struct platform_driver orion_wdt_driver = {
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index 200ece5e2a22..9245b4d23bfe 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -519,21 +519,7 @@ static struct platform_driver s3c2410wdt_driver = {
519 }, 519 },
520}; 520};
521 521
522 522module_platform_driver(s3c2410wdt_driver);
523static int __init watchdog_init(void)
524{
525 pr_info("S3C2410 Watchdog Timer, (c) 2004 Simtec Electronics\n");
526
527 return platform_driver_register(&s3c2410wdt_driver);
528}
529
530static void __exit watchdog_exit(void)
531{
532 platform_driver_unregister(&s3c2410wdt_driver);
533}
534
535module_init(watchdog_init);
536module_exit(watchdog_exit);
537 523
538MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>, " 524MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>, "
539 "Dimitry Andric <dimitry.andric@tomtom.com>"); 525 "Dimitry Andric <dimitry.andric@tomtom.com>");
diff --git a/drivers/watchdog/sch311x_wdt.c b/drivers/watchdog/sch311x_wdt.c
index f8477002b728..9681ada0f252 100644
--- a/drivers/watchdog/sch311x_wdt.c
+++ b/drivers/watchdog/sch311x_wdt.c
@@ -136,6 +136,8 @@ static void sch311x_wdt_set_timeout(int t)
136 136
137static void sch311x_wdt_start(void) 137static void sch311x_wdt_start(void)
138{ 138{
139 unsigned char t;
140
139 spin_lock(&sch311x_wdt_data.io_lock); 141 spin_lock(&sch311x_wdt_data.io_lock);
140 142
141 /* set watchdog's timeout */ 143 /* set watchdog's timeout */
@@ -149,7 +151,8 @@ static void sch311x_wdt_start(void)
149 * Bit 4-6 (Reserved) 151 * Bit 4-6 (Reserved)
150 * Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain 152 * Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain
151 */ 153 */
152 outb(0x0e, sch311x_wdt_data.runtime_reg + GP60); 154 t = inb(sch311x_wdt_data.runtime_reg + GP60);
155 outb((t & ~0x0d) | 0x0c, sch311x_wdt_data.runtime_reg + GP60);
153 156
154 spin_unlock(&sch311x_wdt_data.io_lock); 157 spin_unlock(&sch311x_wdt_data.io_lock);
155 158
@@ -157,10 +160,13 @@ static void sch311x_wdt_start(void)
157 160
158static void sch311x_wdt_stop(void) 161static void sch311x_wdt_stop(void)
159{ 162{
163 unsigned char t;
164
160 spin_lock(&sch311x_wdt_data.io_lock); 165 spin_lock(&sch311x_wdt_data.io_lock);
161 166
162 /* stop the watchdog */ 167 /* stop the watchdog */
163 outb(0x01, sch311x_wdt_data.runtime_reg + GP60); 168 t = inb(sch311x_wdt_data.runtime_reg + GP60);
169 outb((t & ~0x0d) | 0x01, sch311x_wdt_data.runtime_reg + GP60);
164 /* disable timeout by setting it to 0 */ 170 /* disable timeout by setting it to 0 */
165 sch311x_wdt_set_timeout(0); 171 sch311x_wdt_set_timeout(0);
166 172