aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorWim Van Sebroeck <wim@iguana.be>2007-02-09 15:35:36 -0500
committerWim Van Sebroeck <wim@iguana.be>2007-02-09 15:35:36 -0500
commit9af9fc45ddd3e315c51f87392b5048967e4343cd (patch)
tree78f00b28dab7d8f222be20d5503570394b586b23 /drivers
parent62d0cfcb27cf755cebdc93ca95dabc83608007cd (diff)
parentf3dc07330c3e43a8d365eaa74693e320e6ed79d9 (diff)
Merge ../linux-2.6-watchdog-mm
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/watchdog/pcwd.c26
-rw-r--r--drivers/char/watchdog/pcwd_pci.c32
-rw-r--r--drivers/char/watchdog/pcwd_usb.c61
-rw-r--r--drivers/char/watchdog/pnx4008_wdt.c3
-rw-r--r--drivers/char/watchdog/s3c2410_wdt.c60
5 files changed, 123 insertions, 59 deletions
diff --git a/drivers/char/watchdog/pcwd.c b/drivers/char/watchdog/pcwd.c
index 8e1e6e48e0a7..aab6621817a0 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 "06 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,10 +179,10 @@ 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);
@@ -844,6 +856,10 @@ static int __devinit pcwatchdog_init(int base_addr)
844 /* Show info about the card itself */ 856 /* Show info about the card itself */
845 pcwd_show_card_info(); 857 pcwd_show_card_info();
846 858
859 /* If heartbeat = 0 then we use the heartbeat from the dip-switches */
860 if (heartbeat == 0)
861 heartbeat = heartbeat_tbl[(pcwd_get_option_switches() & 0x07)];
862
847 /* Check that the heartbeat value is within it's range ; if not reset to the default */ 863 /* Check that the heartbeat value is within it's range ; if not reset to the default */
848 if (pcwd_set_heartbeat(heartbeat)) { 864 if (pcwd_set_heartbeat(heartbeat)) {
849 pcwd_set_heartbeat(WATCHDOG_HEARTBEAT); 865 pcwd_set_heartbeat(WATCHDOG_HEARTBEAT);
diff --git a/drivers/char/watchdog/pcwd_pci.c b/drivers/char/watchdog/pcwd_pci.c
index f4872c871063..95ddcd8c1db2 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 "06 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,10 +131,10 @@ 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);
@@ -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..1ad1f22e97d7 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 "06 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,10 +74,10 @@ 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);
@@ -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 3a55fc6abcd8..0e3d589d6332 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..5a5cc2a2c5af 100644
--- a/drivers/char/watchdog/s3c2410_wdt.c
+++ b/drivers/char/watchdog/s3c2410_wdt.c
@@ -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);