aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/watchdog
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2008-08-08 12:33:47 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2008-08-08 14:18:18 -0400
commit097d9eb537ff4d88b74c3fe67392e27c478ca3c5 (patch)
tree9034d676d9096857a380aab9d99e3e88fccb6bfe /drivers/watchdog
parentc41107c2d4fd31924533f4dbc4c3428acc2b5894 (diff)
parentaeee90dfa01844168cd7f8051d0a0f969c573067 (diff)
Merge Linus' latest into master
Conflicts: drivers/watchdog/at91rm9200_wdt.c drivers/watchdog/davinci_wdt.c drivers/watchdog/ep93xx_wdt.c drivers/watchdog/ixp2000_wdt.c drivers/watchdog/ixp4xx_wdt.c drivers/watchdog/ks8695_wdt.c drivers/watchdog/omap_wdt.c drivers/watchdog/pnx4008_wdt.c drivers/watchdog/sa1100_wdt.c drivers/watchdog/wdt285.c
Diffstat (limited to 'drivers/watchdog')
-rw-r--r--drivers/watchdog/Kconfig16
-rw-r--r--drivers/watchdog/Makefile4
-rw-r--r--drivers/watchdog/acquirewdt.c130
-rw-r--r--drivers/watchdog/advantechwdt.c162
-rw-r--r--drivers/watchdog/alim1535_wdt.c189
-rw-r--r--drivers/watchdog/alim7101_wdt.c228
-rw-r--r--drivers/watchdog/ar7_wdt.c8
-rw-r--r--drivers/watchdog/at32ap700x_wdt.c43
-rw-r--r--drivers/watchdog/at91rm9200_wdt.c109
-rw-r--r--drivers/watchdog/bfin_wdt.c147
-rw-r--r--drivers/watchdog/booke_wdt.c44
-rw-r--r--drivers/watchdog/cpu5wdt.c144
-rw-r--r--drivers/watchdog/davinci_wdt.c20
-rw-r--r--drivers/watchdog/ep93xx_wdt.c28
-rw-r--r--drivers/watchdog/eurotechwdt.c95
-rw-r--r--drivers/watchdog/geodewdt.c96
-rw-r--r--drivers/watchdog/hpwdt.c6
-rw-r--r--drivers/watchdog/i6300esb.c366
-rw-r--r--drivers/watchdog/iTCO_vendor.h15
-rw-r--r--drivers/watchdog/iTCO_vendor_support.c62
-rw-r--r--drivers/watchdog/iTCO_wdt.c310
-rw-r--r--drivers/watchdog/ib700wdt.c123
-rw-r--r--drivers/watchdog/ibmasr.c151
-rw-r--r--drivers/watchdog/indydog.c114
-rw-r--r--drivers/watchdog/iop_wdt.c62
-rw-r--r--drivers/watchdog/it8712f_wdt.c6
-rw-r--r--drivers/watchdog/ixp2000_wdt.c61
-rw-r--r--drivers/watchdog/ixp4xx_wdt.c67
-rw-r--r--drivers/watchdog/ks8695_wdt.c120
-rw-r--r--drivers/watchdog/machzwd.c108
-rw-r--r--drivers/watchdog/mixcomwd.c133
-rw-r--r--drivers/watchdog/mpc5200_wdt.c24
-rw-r--r--drivers/watchdog/mpc83xx_wdt.c230
-rw-r--r--drivers/watchdog/mpc8xx_wdt.c37
-rw-r--r--drivers/watchdog/mpc8xxx_wdt.c316
-rw-r--r--drivers/watchdog/mpcore_wdt.c73
-rw-r--r--drivers/watchdog/mtx-1_wdt.c111
-rw-r--r--drivers/watchdog/mv64x60_wdt.c21
-rw-r--r--drivers/watchdog/omap_wdt.c41
-rw-r--r--drivers/watchdog/pc87413_wdt.c249
-rw-r--r--drivers/watchdog/pcwd.c191
-rw-r--r--drivers/watchdog/pcwd_pci.c161
-rw-r--r--drivers/watchdog/pcwd_usb.c168
-rw-r--r--drivers/watchdog/pnx4008_wdt.c29
-rw-r--r--drivers/watchdog/rm9k_wdt.c34
-rw-r--r--drivers/watchdog/s3c2410_wdt.c15
-rw-r--r--drivers/watchdog/sa1100_wdt.c42
-rw-r--r--drivers/watchdog/sb_wdog.c92
-rw-r--r--drivers/watchdog/sbc60xxwdt.c223
-rw-r--r--drivers/watchdog/sbc7240_wdt.c70
-rw-r--r--drivers/watchdog/sbc8360.c46
-rw-r--r--drivers/watchdog/sbc_epx_c3.c22
-rw-r--r--drivers/watchdog/sc1200wdt.c39
-rw-r--r--drivers/watchdog/sc520_wdt.c162
-rw-r--r--drivers/watchdog/scx200_wdt.c65
-rw-r--r--drivers/watchdog/shwdt.c139
-rw-r--r--drivers/watchdog/smsc37b787_wdt.c448
-rw-r--r--drivers/watchdog/softdog.c87
-rw-r--r--drivers/watchdog/txx9wdt.c37
-rw-r--r--drivers/watchdog/w83627hf_wdt.c190
-rw-r--r--drivers/watchdog/w83697hf_wdt.c189
-rw-r--r--drivers/watchdog/w83877f_wdt.c199
-rw-r--r--drivers/watchdog/w83977f_wdt.c239
-rw-r--r--drivers/watchdog/wafer5823wdt.c132
-rw-r--r--drivers/watchdog/wd501p.h2
-rw-r--r--drivers/watchdog/wdrtas.c105
-rw-r--r--drivers/watchdog/wdt.c4
-rw-r--r--drivers/watchdog/wdt285.c33
-rw-r--r--drivers/watchdog/wdt977.c162
-rw-r--r--drivers/watchdog/wdt_pci.c8
70 files changed, 3837 insertions, 3765 deletions
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 48399e134c0d..32b9fe153641 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -463,7 +463,7 @@ config PC87413_WDT
463 module will be called pc87413_wdt. 463 module will be called pc87413_wdt.
464 464
465 Most people will say N. 465 Most people will say N.
466 466
467config 60XX_WDT 467config 60XX_WDT
468 tristate "SBC-60XX Watchdog Timer" 468 tristate "SBC-60XX Watchdog Timer"
469 depends on X86 469 depends on X86
@@ -695,9 +695,17 @@ config 8xx_WDT
695 tristate "MPC8xx Watchdog Timer" 695 tristate "MPC8xx Watchdog Timer"
696 depends on 8xx 696 depends on 8xx
697 697
698config 83xx_WDT 698config 8xxx_WDT
699 tristate "MPC83xx Watchdog Timer" 699 tristate "MPC8xxx Platform Watchdog Timer"
700 depends on PPC_83xx 700 depends on PPC_8xx || PPC_83xx || PPC_86xx
701 help
702 This driver is for a SoC level watchdog that exists on some
703 Freescale PowerPC processors. So far this driver supports:
704 - MPC8xx watchdogs
705 - MPC83xx watchdogs
706 - MPC86xx watchdogs
707
708 For BookE processors (MPC85xx) use the BOOKE_WDT driver instead.
701 709
702config MV64X60_WDT 710config MV64X60_WDT
703 tristate "MV64X60 (Marvell Discovery) Watchdog Timer" 711 tristate "MV64X60 (Marvell Discovery) Watchdog Timer"
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index edd305a64e63..049c91895699 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -92,7 +92,7 @@ obj-$(CONFIG_SBC_EPX_C3_WATCHDOG) += sbc_epx_c3.o
92 92
93# MIPS Architecture 93# MIPS Architecture
94obj-$(CONFIG_INDYDOG) += indydog.o 94obj-$(CONFIG_INDYDOG) += indydog.o
95obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o 95obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o
96obj-$(CONFIG_WDT_RM9K_GPI) += rm9k_wdt.o 96obj-$(CONFIG_WDT_RM9K_GPI) += rm9k_wdt.o
97obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o 97obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o
98obj-$(CONFIG_AR7_WDT) += ar7_wdt.o 98obj-$(CONFIG_AR7_WDT) += ar7_wdt.o
@@ -103,7 +103,7 @@ obj-$(CONFIG_TXX9_WDT) += txx9wdt.o
103# POWERPC Architecture 103# POWERPC Architecture
104obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o 104obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o
105obj-$(CONFIG_MPC5200_WDT) += mpc5200_wdt.o 105obj-$(CONFIG_MPC5200_WDT) += mpc5200_wdt.o
106obj-$(CONFIG_83xx_WDT) += mpc83xx_wdt.o 106obj-$(CONFIG_8xxx_WDT) += mpc8xxx_wdt.o
107obj-$(CONFIG_MV64X60_WDT) += mv64x60_wdt.o 107obj-$(CONFIG_MV64X60_WDT) += mv64x60_wdt.o
108obj-$(CONFIG_BOOKE_WDT) += booke_wdt.o 108obj-$(CONFIG_BOOKE_WDT) += booke_wdt.o
109 109
diff --git a/drivers/watchdog/acquirewdt.c b/drivers/watchdog/acquirewdt.c
index 85269c365a10..6e46a551395c 100644
--- a/drivers/watchdog/acquirewdt.c
+++ b/drivers/watchdog/acquirewdt.c
@@ -58,39 +58,45 @@
58#include <linux/types.h> /* For standard types (like size_t) */ 58#include <linux/types.h> /* For standard types (like size_t) */
59#include <linux/errno.h> /* For the -ENODEV/... values */ 59#include <linux/errno.h> /* For the -ENODEV/... values */
60#include <linux/kernel.h> /* For printk/panic/... */ 60#include <linux/kernel.h> /* For printk/panic/... */
61#include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) */ 61#include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV
62 (WATCHDOG_MINOR) */
62#include <linux/watchdog.h> /* For the watchdog specific items */ 63#include <linux/watchdog.h> /* For the watchdog specific items */
63#include <linux/fs.h> /* For file operations */ 64#include <linux/fs.h> /* For file operations */
64#include <linux/ioport.h> /* For io-port access */ 65#include <linux/ioport.h> /* For io-port access */
65#include <linux/platform_device.h> /* For platform_driver framework */ 66#include <linux/platform_device.h> /* For platform_driver framework */
66#include <linux/init.h> /* For __init/__exit/... */ 67#include <linux/init.h> /* For __init/__exit/... */
67 68#include <linux/uaccess.h> /* For copy_to_user/put_user/... */
68#include <asm/uaccess.h> /* For copy_to_user/put_user/... */ 69#include <linux/io.h> /* For inb/outb/... */
69#include <asm/io.h> /* For inb/outb/... */
70 70
71/* Module information */ 71/* Module information */
72#define DRV_NAME "acquirewdt" 72#define DRV_NAME "acquirewdt"
73#define PFX DRV_NAME ": " 73#define PFX DRV_NAME ": "
74#define WATCHDOG_NAME "Acquire WDT" 74#define WATCHDOG_NAME "Acquire WDT"
75#define WATCHDOG_HEARTBEAT 0 /* There is no way to see what the correct time-out period is */ 75/* There is no way to see what the correct time-out period is */
76#define WATCHDOG_HEARTBEAT 0
76 77
77/* internal variables */ 78/* internal variables */
78static struct platform_device *acq_platform_device; /* the watchdog platform device */ 79/* the watchdog platform device */
80static struct platform_device *acq_platform_device;
79static unsigned long acq_is_open; 81static unsigned long acq_is_open;
80static char expect_close; 82static char expect_close;
81 83
82/* module parameters */ 84/* module parameters */
83static int wdt_stop = 0x43; /* You must set this - there is no sane way to probe for this board. */ 85/* You must set this - there is no sane way to probe for this board. */
86static int wdt_stop = 0x43;
84module_param(wdt_stop, int, 0); 87module_param(wdt_stop, int, 0);
85MODULE_PARM_DESC(wdt_stop, "Acquire WDT 'stop' io port (default 0x43)"); 88MODULE_PARM_DESC(wdt_stop, "Acquire WDT 'stop' io port (default 0x43)");
86 89
87static int wdt_start = 0x443; /* You must set this - there is no sane way to probe for this board. */ 90/* You must set this - there is no sane way to probe for this board. */
91static int wdt_start = 0x443;
88module_param(wdt_start, int, 0); 92module_param(wdt_start, int, 0);
89MODULE_PARM_DESC(wdt_start, "Acquire WDT 'start' io port (default 0x443)"); 93MODULE_PARM_DESC(wdt_start, "Acquire WDT 'start' io port (default 0x443)");
90 94
91static int nowayout = WATCHDOG_NOWAYOUT; 95static int nowayout = WATCHDOG_NOWAYOUT;
92module_param(nowayout, int, 0); 96module_param(nowayout, int, 0);
93MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 97MODULE_PARM_DESC(nowayout,
98 "Watchdog cannot be stopped once started (default="
99 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
94 100
95/* 101/*
96 * Watchdog Operations 102 * Watchdog Operations
@@ -112,18 +118,18 @@ static void acq_stop(void)
112 * /dev/watchdog handling 118 * /dev/watchdog handling
113 */ 119 */
114 120
115static ssize_t acq_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) 121static ssize_t acq_write(struct file *file, const char __user *buf,
122 size_t count, loff_t *ppos)
116{ 123{
117 /* See if we got the magic character 'V' and reload the timer */ 124 /* See if we got the magic character 'V' and reload the timer */
118 if(count) { 125 if (count) {
119 if (!nowayout) { 126 if (!nowayout) {
120 size_t i; 127 size_t i;
121
122 /* note: just in case someone wrote the magic character 128 /* note: just in case someone wrote the magic character
123 * five months ago... */ 129 five months ago... */
124 expect_close = 0; 130 expect_close = 0;
125 131 /* scan to see whether or not we got the
126 /* scan to see whether or not we got the magic character */ 132 magic character */
127 for (i = 0; i != count; i++) { 133 for (i = 0; i != count; i++) {
128 char c; 134 char c;
129 if (get_user(c, buf + i)) 135 if (get_user(c, buf + i))
@@ -132,64 +138,55 @@ static ssize_t acq_write(struct file *file, const char __user *buf, size_t count
132 expect_close = 42; 138 expect_close = 42;
133 } 139 }
134 } 140 }
135 141 /* Well, anyhow someone wrote to us, we should
136 /* Well, anyhow someone wrote to us, we should return that favour */ 142 return that favour */
137 acq_keepalive(); 143 acq_keepalive();
138 } 144 }
139 return count; 145 return count;
140} 146}
141 147
142static int acq_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 148static long acq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
143 unsigned long arg)
144{ 149{
145 int options, retval = -EINVAL; 150 int options, retval = -EINVAL;
146 void __user *argp = (void __user *)arg; 151 void __user *argp = (void __user *)arg;
147 int __user *p = argp; 152 int __user *p = argp;
148 static struct watchdog_info ident = 153 static struct watchdog_info ident = {
149 {
150 .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, 154 .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
151 .firmware_version = 1, 155 .firmware_version = 1,
152 .identity = WATCHDOG_NAME, 156 .identity = WATCHDOG_NAME,
153 }; 157 };
154 158
155 switch(cmd) 159 switch (cmd) {
156 {
157 case WDIOC_GETSUPPORT: 160 case WDIOC_GETSUPPORT:
158 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; 161 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
159 162
160 case WDIOC_GETSTATUS: 163 case WDIOC_GETSTATUS:
161 case WDIOC_GETBOOTSTATUS: 164 case WDIOC_GETBOOTSTATUS:
162 return put_user(0, p); 165 return put_user(0, p);
163
164 case WDIOC_KEEPALIVE:
165 acq_keepalive();
166 return 0;
167
168 case WDIOC_GETTIMEOUT:
169 return put_user(WATCHDOG_HEARTBEAT, p);
170 166
171 case WDIOC_SETOPTIONS: 167 case WDIOC_SETOPTIONS:
172 { 168 {
173 if (get_user(options, p)) 169 if (get_user(options, p))
174 return -EFAULT; 170 return -EFAULT;
175 171 if (options & WDIOS_DISABLECARD) {
176 if (options & WDIOS_DISABLECARD) 172 acq_stop();
177 { 173 retval = 0;
178 acq_stop(); 174 }
179 retval = 0; 175 if (options & WDIOS_ENABLECARD) {
180 } 176 acq_keepalive();
181 177 retval = 0;
182 if (options & WDIOS_ENABLECARD) 178 }
183 { 179 return retval;
184 acq_keepalive();
185 retval = 0;
186 }
187
188 return retval;
189 } 180 }
181 case WDIOC_KEEPALIVE:
182 acq_keepalive();
183 return 0;
184
185 case WDIOC_GETTIMEOUT:
186 return put_user(WATCHDOG_HEARTBEAT, p);
190 187
191 default: 188 default:
192 return -ENOTTY; 189 return -ENOTTY;
193 } 190 }
194} 191}
195 192
@@ -211,7 +208,8 @@ static int acq_close(struct inode *inode, struct file *file)
211 if (expect_close == 42) { 208 if (expect_close == 42) {
212 acq_stop(); 209 acq_stop();
213 } else { 210 } else {
214 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); 211 printk(KERN_CRIT PFX
212 "Unexpected close, not stopping watchdog!\n");
215 acq_keepalive(); 213 acq_keepalive();
216 } 214 }
217 clear_bit(0, &acq_is_open); 215 clear_bit(0, &acq_is_open);
@@ -227,7 +225,7 @@ static const struct file_operations acq_fops = {
227 .owner = THIS_MODULE, 225 .owner = THIS_MODULE,
228 .llseek = no_llseek, 226 .llseek = no_llseek,
229 .write = acq_write, 227 .write = acq_write,
230 .ioctl = acq_ioctl, 228 .unlocked_ioctl = acq_ioctl,
231 .open = acq_open, 229 .open = acq_open,
232 .release = acq_close, 230 .release = acq_close,
233}; 231};
@@ -248,32 +246,29 @@ static int __devinit acq_probe(struct platform_device *dev)
248 246
249 if (wdt_stop != wdt_start) { 247 if (wdt_stop != wdt_start) {
250 if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) { 248 if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) {
251 printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", 249 printk(KERN_ERR PFX
252 wdt_stop); 250 "I/O address 0x%04x already in use\n", wdt_stop);
253 ret = -EIO; 251 ret = -EIO;
254 goto out; 252 goto out;
255 } 253 }
256 } 254 }
257 255
258 if (!request_region(wdt_start, 1, WATCHDOG_NAME)) { 256 if (!request_region(wdt_start, 1, WATCHDOG_NAME)) {
259 printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", 257 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n",
260 wdt_start); 258 wdt_start);
261 ret = -EIO; 259 ret = -EIO;
262 goto unreg_stop; 260 goto unreg_stop;
263 } 261 }
264
265 ret = misc_register(&acq_miscdev); 262 ret = misc_register(&acq_miscdev);
266 if (ret != 0) { 263 if (ret != 0) {
267 printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 264 printk(KERN_ERR PFX
268 WATCHDOG_MINOR, ret); 265 "cannot register miscdev on minor=%d (err=%d)\n",
266 WATCHDOG_MINOR, ret);
269 goto unreg_regions; 267 goto unreg_regions;
270 } 268 }
271 269 printk(KERN_INFO PFX "initialized. (nowayout=%d)\n", nowayout);
272 printk (KERN_INFO PFX "initialized. (nowayout=%d)\n",
273 nowayout);
274 270
275 return 0; 271 return 0;
276
277unreg_regions: 272unreg_regions:
278 release_region(wdt_start, 1); 273 release_region(wdt_start, 1);
279unreg_stop: 274unreg_stop:
@@ -286,9 +281,9 @@ out:
286static int __devexit acq_remove(struct platform_device *dev) 281static int __devexit acq_remove(struct platform_device *dev)
287{ 282{
288 misc_deregister(&acq_miscdev); 283 misc_deregister(&acq_miscdev);
289 release_region(wdt_start,1); 284 release_region(wdt_start, 1);
290 if(wdt_stop != wdt_start) 285 if (wdt_stop != wdt_start)
291 release_region(wdt_stop,1); 286 release_region(wdt_stop, 1);
292 287
293 return 0; 288 return 0;
294} 289}
@@ -313,18 +308,19 @@ static int __init acq_init(void)
313{ 308{
314 int err; 309 int err;
315 310
316 printk(KERN_INFO "WDT driver for Acquire single board computer initialising.\n"); 311 printk(KERN_INFO
312 "WDT driver for Acquire single board computer initialising.\n");
317 313
318 err = platform_driver_register(&acquirewdt_driver); 314 err = platform_driver_register(&acquirewdt_driver);
319 if (err) 315 if (err)
320 return err; 316 return err;
321 317
322 acq_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0); 318 acq_platform_device = platform_device_register_simple(DRV_NAME,
319 -1, NULL, 0);
323 if (IS_ERR(acq_platform_device)) { 320 if (IS_ERR(acq_platform_device)) {
324 err = PTR_ERR(acq_platform_device); 321 err = PTR_ERR(acq_platform_device);
325 goto unreg_platform_driver; 322 goto unreg_platform_driver;
326 } 323 }
327
328 return 0; 324 return 0;
329 325
330unreg_platform_driver: 326unreg_platform_driver:
diff --git a/drivers/watchdog/advantechwdt.c b/drivers/watchdog/advantechwdt.c
index 8121cc247343..a5110f93a755 100644
--- a/drivers/watchdog/advantechwdt.c
+++ b/drivers/watchdog/advantechwdt.c
@@ -37,9 +37,9 @@
37#include <linux/ioport.h> 37#include <linux/ioport.h>
38#include <linux/platform_device.h> 38#include <linux/platform_device.h>
39#include <linux/init.h> 39#include <linux/init.h>
40#include <linux/io.h>
41#include <linux/uaccess.h>
40 42
41#include <asm/io.h>
42#include <asm/uaccess.h>
43#include <asm/system.h> 43#include <asm/system.h>
44 44
45#define DRV_NAME "advantechwdt" 45#define DRV_NAME "advantechwdt"
@@ -47,7 +47,8 @@
47#define WATCHDOG_NAME "Advantech WDT" 47#define WATCHDOG_NAME "Advantech WDT"
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 */ 50/* the watchdog platform device */
51static struct platform_device *advwdt_platform_device;
51static unsigned long advwdt_is_open; 52static unsigned long advwdt_is_open;
52static char adv_expect_close; 53static char adv_expect_close;
53 54
@@ -72,35 +73,35 @@ MODULE_PARM_DESC(wdt_start, "Advantech WDT 'start' io port (default 0x443)");
72 73
73static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ 74static int timeout = WATCHDOG_TIMEOUT; /* in seconds */
74module_param(timeout, int, 0); 75module_param(timeout, int, 0);
75MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=63, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) "."); 76MODULE_PARM_DESC(timeout,
77 "Watchdog timeout in seconds. 1<= timeout <=63, default="
78 __MODULE_STRING(WATCHDOG_TIMEOUT) ".");
76 79
77static int nowayout = WATCHDOG_NOWAYOUT; 80static int nowayout = WATCHDOG_NOWAYOUT;
78module_param(nowayout, int, 0); 81module_param(nowayout, int, 0);
79MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 82MODULE_PARM_DESC(nowayout,
83 "Watchdog cannot be stopped once started (default="
84 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
80 85
81/* 86/*
82 * Watchdog Operations 87 * Watchdog Operations
83 */ 88 */
84 89
85static void 90static void advwdt_ping(void)
86advwdt_ping(void)
87{ 91{
88 /* Write a watchdog value */ 92 /* Write a watchdog value */
89 outb_p(timeout, wdt_start); 93 outb_p(timeout, wdt_start);
90} 94}
91 95
92static void 96static void advwdt_disable(void)
93advwdt_disable(void)
94{ 97{
95 inb_p(wdt_stop); 98 inb_p(wdt_stop);
96} 99}
97 100
98static int 101static int advwdt_set_heartbeat(int t)
99advwdt_set_heartbeat(int t)
100{ 102{
101 if ((t < 1) || (t > 63)) 103 if (t < 1 || t > 63)
102 return -EINVAL; 104 return -EINVAL;
103
104 timeout = t; 105 timeout = t;
105 return 0; 106 return 0;
106} 107}
@@ -109,8 +110,8 @@ advwdt_set_heartbeat(int t)
109 * /dev/watchdog handling 110 * /dev/watchdog handling
110 */ 111 */
111 112
112static ssize_t 113static ssize_t advwdt_write(struct file *file, const char __user *buf,
113advwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) 114 size_t count, loff_t *ppos)
114{ 115{
115 if (count) { 116 if (count) {
116 if (!nowayout) { 117 if (!nowayout) {
@@ -120,7 +121,7 @@ advwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *pp
120 121
121 for (i = 0; i != count; i++) { 122 for (i = 0; i != count; i++) {
122 char c; 123 char c;
123 if (get_user(c, buf+i)) 124 if (get_user(c, buf + i))
124 return -EFAULT; 125 return -EFAULT;
125 if (c == 'V') 126 if (c == 'V')
126 adv_expect_close = 42; 127 adv_expect_close = 42;
@@ -131,9 +132,7 @@ advwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *pp
131 return count; 132 return count;
132} 133}
133 134
134static int 135static long advwdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
135advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
136 unsigned long arg)
137{ 136{
138 int new_timeout; 137 int new_timeout;
139 void __user *argp = (void __user *)arg; 138 void __user *argp = (void __user *)arg;
@@ -146,57 +145,50 @@ advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
146 145
147 switch (cmd) { 146 switch (cmd) {
148 case WDIOC_GETSUPPORT: 147 case WDIOC_GETSUPPORT:
149 if (copy_to_user(argp, &ident, sizeof(ident))) 148 if (copy_to_user(argp, &ident, sizeof(ident)))
150 return -EFAULT; 149 return -EFAULT;
151 break; 150 break;
152 151
153 case WDIOC_GETSTATUS: 152 case WDIOC_GETSTATUS:
154 case WDIOC_GETBOOTSTATUS: 153 case WDIOC_GETBOOTSTATUS:
155 return put_user(0, p); 154 return put_user(0, p);
156
157 case WDIOC_KEEPALIVE:
158 advwdt_ping();
159 break;
160
161 case WDIOC_SETTIMEOUT:
162 if (get_user(new_timeout, p))
163 return -EFAULT;
164 if (advwdt_set_heartbeat(new_timeout))
165 return -EINVAL;
166 advwdt_ping();
167 /* Fall */
168
169 case WDIOC_GETTIMEOUT:
170 return put_user(timeout, p);
171 155
172 case WDIOC_SETOPTIONS: 156 case WDIOC_SETOPTIONS:
173 { 157 {
174 int options, retval = -EINVAL; 158 int options, retval = -EINVAL;
175
176 if (get_user(options, p))
177 return -EFAULT;
178
179 if (options & WDIOS_DISABLECARD) {
180 advwdt_disable();
181 retval = 0;
182 }
183 159
184 if (options & WDIOS_ENABLECARD) { 160 if (get_user(options, p))
185 advwdt_ping(); 161 return -EFAULT;
186 retval = 0; 162 if (options & WDIOS_DISABLECARD) {
187 } 163 advwdt_disable();
188 164 retval = 0;
189 return retval; 165 }
166 if (options & WDIOS_ENABLECARD) {
167 advwdt_ping();
168 retval = 0;
169 }
170 return retval;
190 } 171 }
172 case WDIOC_KEEPALIVE:
173 advwdt_ping();
174 break;
191 175
176 case WDIOC_SETTIMEOUT:
177 if (get_user(new_timeout, p))
178 return -EFAULT;
179 if (advwdt_set_heartbeat(new_timeout))
180 return -EINVAL;
181 advwdt_ping();
182 /* Fall */
183 case WDIOC_GETTIMEOUT:
184 return put_user(timeout, p);
192 default: 185 default:
193 return -ENOTTY; 186 return -ENOTTY;
194 } 187 }
195 return 0; 188 return 0;
196} 189}
197 190
198static int 191static int advwdt_open(struct inode *inode, struct file *file)
199advwdt_open(struct inode *inode, struct file *file)
200{ 192{
201 if (test_and_set_bit(0, &advwdt_is_open)) 193 if (test_and_set_bit(0, &advwdt_is_open))
202 return -EBUSY; 194 return -EBUSY;
@@ -208,13 +200,13 @@ advwdt_open(struct inode *inode, struct file *file)
208 return nonseekable_open(inode, file); 200 return nonseekable_open(inode, file);
209} 201}
210 202
211static int 203static int advwdt_close(struct inode *inode, struct file *file)
212advwdt_close(struct inode *inode, struct file *file)
213{ 204{
214 if (adv_expect_close == 42) { 205 if (adv_expect_close == 42) {
215 advwdt_disable(); 206 advwdt_disable();
216 } else { 207 } else {
217 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); 208 printk(KERN_CRIT PFX
209 "Unexpected close, not stopping watchdog!\n");
218 advwdt_ping(); 210 advwdt_ping();
219 } 211 }
220 clear_bit(0, &advwdt_is_open); 212 clear_bit(0, &advwdt_is_open);
@@ -230,7 +222,7 @@ static const struct file_operations advwdt_fops = {
230 .owner = THIS_MODULE, 222 .owner = THIS_MODULE,
231 .llseek = no_llseek, 223 .llseek = no_llseek,
232 .write = advwdt_write, 224 .write = advwdt_write,
233 .ioctl = advwdt_ioctl, 225 .unlocked_ioctl = advwdt_ioctl,
234 .open = advwdt_open, 226 .open = advwdt_open,
235 .release = advwdt_close, 227 .release = advwdt_close,
236}; 228};
@@ -245,23 +237,24 @@ static struct miscdevice advwdt_miscdev = {
245 * Init & exit routines 237 * Init & exit routines
246 */ 238 */
247 239
248static int __devinit 240static int __devinit advwdt_probe(struct platform_device *dev)
249advwdt_probe(struct platform_device *dev)
250{ 241{
251 int ret; 242 int ret;
252 243
253 if (wdt_stop != wdt_start) { 244 if (wdt_stop != wdt_start) {
254 if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) { 245 if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) {
255 printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", 246 printk(KERN_ERR PFX
256 wdt_stop); 247 "I/O address 0x%04x already in use\n",
248 wdt_stop);
257 ret = -EIO; 249 ret = -EIO;
258 goto out; 250 goto out;
259 } 251 }
260 } 252 }
261 253
262 if (!request_region(wdt_start, 1, WATCHDOG_NAME)) { 254 if (!request_region(wdt_start, 1, WATCHDOG_NAME)) {
263 printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", 255 printk(KERN_ERR PFX
264 wdt_start); 256 "I/O address 0x%04x already in use\n",
257 wdt_start);
265 ret = -EIO; 258 ret = -EIO;
266 goto unreg_stop; 259 goto unreg_stop;
267 } 260 }
@@ -269,20 +262,19 @@ advwdt_probe(struct platform_device *dev)
269 /* Check that the heartbeat value is within it's range ; if not reset to the default */ 262 /* Check that the heartbeat value is within it's range ; if not reset to the default */
270 if (advwdt_set_heartbeat(timeout)) { 263 if (advwdt_set_heartbeat(timeout)) {
271 advwdt_set_heartbeat(WATCHDOG_TIMEOUT); 264 advwdt_set_heartbeat(WATCHDOG_TIMEOUT);
272 printk (KERN_INFO PFX "timeout value must be 1<=x<=63, using %d\n", 265 printk(KERN_INFO PFX
273 timeout); 266 "timeout value must be 1<=x<=63, using %d\n", timeout);
274 } 267 }
275 268
276 ret = misc_register(&advwdt_miscdev); 269 ret = misc_register(&advwdt_miscdev);
277 if (ret != 0) { 270 if (ret != 0) {
278 printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 271 printk(KERN_ERR PFX
279 WATCHDOG_MINOR, ret); 272 "cannot register miscdev on minor=%d (err=%d)\n",
273 WATCHDOG_MINOR, ret);
280 goto unreg_regions; 274 goto unreg_regions;
281 } 275 }
282 276 printk(KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n",
283 printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n",
284 timeout, nowayout); 277 timeout, nowayout);
285
286out: 278out:
287 return ret; 279 return ret;
288unreg_regions: 280unreg_regions:
@@ -293,19 +285,17 @@ unreg_stop:
293 goto out; 285 goto out;
294} 286}
295 287
296static int __devexit 288static int __devexit advwdt_remove(struct platform_device *dev)
297advwdt_remove(struct platform_device *dev)
298{ 289{
299 misc_deregister(&advwdt_miscdev); 290 misc_deregister(&advwdt_miscdev);
300 release_region(wdt_start,1); 291 release_region(wdt_start, 1);
301 if(wdt_stop != wdt_start) 292 if (wdt_stop != wdt_start)
302 release_region(wdt_stop,1); 293 release_region(wdt_stop, 1);
303 294
304 return 0; 295 return 0;
305} 296}
306 297
307static void 298static void advwdt_shutdown(struct platform_device *dev)
308advwdt_shutdown(struct platform_device *dev)
309{ 299{
310 /* Turn the WDT off if we have a soft shutdown */ 300 /* Turn the WDT off if we have a soft shutdown */
311 advwdt_disable(); 301 advwdt_disable();
@@ -321,18 +311,19 @@ static struct platform_driver advwdt_driver = {
321 }, 311 },
322}; 312};
323 313
324static int __init 314static int __init advwdt_init(void)
325advwdt_init(void)
326{ 315{
327 int err; 316 int err;
328 317
329 printk(KERN_INFO "WDT driver for Advantech single board computer initialising.\n"); 318 printk(KERN_INFO
319 "WDT driver for Advantech single board computer initialising.\n");
330 320
331 err = platform_driver_register(&advwdt_driver); 321 err = platform_driver_register(&advwdt_driver);
332 if (err) 322 if (err)
333 return err; 323 return err;
334 324
335 advwdt_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0); 325 advwdt_platform_device = platform_device_register_simple(DRV_NAME,
326 -1, NULL, 0);
336 if (IS_ERR(advwdt_platform_device)) { 327 if (IS_ERR(advwdt_platform_device)) {
337 err = PTR_ERR(advwdt_platform_device); 328 err = PTR_ERR(advwdt_platform_device);
338 goto unreg_platform_driver; 329 goto unreg_platform_driver;
@@ -345,8 +336,7 @@ unreg_platform_driver:
345 return err; 336 return err;
346} 337}
347 338
348static void __exit 339static void __exit advwdt_exit(void)
349advwdt_exit(void)
350{ 340{
351 platform_device_unregister(advwdt_platform_device); 341 platform_device_unregister(advwdt_platform_device);
352 platform_driver_unregister(&advwdt_driver); 342 platform_driver_unregister(&advwdt_driver);
diff --git a/drivers/watchdog/alim1535_wdt.c b/drivers/watchdog/alim1535_wdt.c
index 2b1fbdb2fcf7..2a7690ecf97d 100644
--- a/drivers/watchdog/alim1535_wdt.c
+++ b/drivers/watchdog/alim1535_wdt.c
@@ -18,9 +18,8 @@
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/fs.h> 19#include <linux/fs.h>
20#include <linux/pci.h> 20#include <linux/pci.h>
21 21#include <linux/uaccess.h>
22#include <asm/uaccess.h> 22#include <linux/io.h>
23#include <asm/io.h>
24 23
25#define WATCHDOG_NAME "ALi_M1535" 24#define WATCHDOG_NAME "ALi_M1535"
26#define PFX WATCHDOG_NAME ": " 25#define PFX WATCHDOG_NAME ": "
@@ -30,17 +29,21 @@
30static unsigned long ali_is_open; 29static unsigned long ali_is_open;
31static char ali_expect_release; 30static char ali_expect_release;
32static struct pci_dev *ali_pci; 31static struct pci_dev *ali_pci;
33static u32 ali_timeout_bits; /* stores the computed timeout */ 32static u32 ali_timeout_bits; /* stores the computed timeout */
34static DEFINE_SPINLOCK(ali_lock); /* Guards the hardware */ 33static DEFINE_SPINLOCK(ali_lock); /* Guards the hardware */
35 34
36/* module parameters */ 35/* module parameters */
37static int timeout = WATCHDOG_TIMEOUT; 36static int timeout = WATCHDOG_TIMEOUT;
38module_param(timeout, int, 0); 37module_param(timeout, int, 0);
39MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (0<timeout<18000, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); 38MODULE_PARM_DESC(timeout,
39 "Watchdog timeout in seconds. (0 < timeout < 18000, default="
40 __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
40 41
41static int nowayout = WATCHDOG_NOWAYOUT; 42static int nowayout = WATCHDOG_NOWAYOUT;
42module_param(nowayout, int, 0); 43module_param(nowayout, int, 0);
43MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 44MODULE_PARM_DESC(nowayout,
45 "Watchdog cannot be stopped once started (default="
46 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
44 47
45/* 48/*
46 * ali_start - start watchdog countdown 49 * ali_start - start watchdog countdown
@@ -103,15 +106,16 @@ static void ali_keepalive(void)
103 106
104static int ali_settimer(int t) 107static int ali_settimer(int t)
105{ 108{
106 if(t < 0) 109 if (t < 0)
107 return -EINVAL; 110 return -EINVAL;
108 else if(t < 60) 111 else if (t < 60)
109 ali_timeout_bits = t|(1<<6); 112 ali_timeout_bits = t|(1<<6);
110 else if(t < 3600) 113 else if (t < 3600)
111 ali_timeout_bits = (t/60)|(1<<7); 114 ali_timeout_bits = (t/60)|(1<<7);
112 else if(t < 18000) 115 else if (t < 18000)
113 ali_timeout_bits = (t/300)|(1<<6)|(1<<7); 116 ali_timeout_bits = (t/300)|(1<<6)|(1<<7);
114 else return -EINVAL; 117 else
118 return -EINVAL;
115 119
116 timeout = t; 120 timeout = t;
117 return 0; 121 return 0;
@@ -134,21 +138,22 @@ static int ali_settimer(int t)
134 */ 138 */
135 139
136static ssize_t ali_write(struct file *file, const char __user *data, 140static ssize_t ali_write(struct file *file, const char __user *data,
137 size_t len, loff_t * ppos) 141 size_t len, loff_t *ppos)
138{ 142{
139 /* See if we got the magic character 'V' and reload the timer */ 143 /* See if we got the magic character 'V' and reload the timer */
140 if (len) { 144 if (len) {
141 if (!nowayout) { 145 if (!nowayout) {
142 size_t i; 146 size_t i;
143 147
144 /* note: just in case someone wrote the magic character 148 /* note: just in case someone wrote the
145 * five months ago... */ 149 magic character five months ago... */
146 ali_expect_release = 0; 150 ali_expect_release = 0;
147 151
148 /* scan to see whether or not we got the magic character */ 152 /* scan to see whether or not we got
153 the magic character */
149 for (i = 0; i != len; i++) { 154 for (i = 0; i != len; i++) {
150 char c; 155 char c;
151 if(get_user(c, data+i)) 156 if (get_user(c, data + i))
152 return -EFAULT; 157 return -EFAULT;
153 if (c == 'V') 158 if (c == 'V')
154 ali_expect_release = 42; 159 ali_expect_release = 42;
@@ -163,7 +168,6 @@ static ssize_t ali_write(struct file *file, const char __user *data,
163 168
164/* 169/*
165 * ali_ioctl - handle watchdog ioctls 170 * ali_ioctl - handle watchdog ioctls
166 * @inode: VFS inode
167 * @file: VFS file pointer 171 * @file: VFS file pointer
168 * @cmd: ioctl number 172 * @cmd: ioctl number
169 * @arg: arguments to the ioctl 173 * @arg: arguments to the ioctl
@@ -172,8 +176,7 @@ static ssize_t ali_write(struct file *file, const char __user *data,
172 * we want an extension to enable irq ack monitoring and the like 176 * we want an extension to enable irq ack monitoring and the like
173 */ 177 */
174 178
175static int ali_ioctl(struct inode *inode, struct file *file, 179static long ali_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
176 unsigned int cmd, unsigned long arg)
177{ 180{
178 void __user *argp = (void __user *)arg; 181 void __user *argp = (void __user *)arg;
179 int __user *p = argp; 182 int __user *p = argp;
@@ -186,57 +189,45 @@ static int ali_ioctl(struct inode *inode, struct file *file,
186 }; 189 };
187 190
188 switch (cmd) { 191 switch (cmd) {
189 case WDIOC_GETSUPPORT: 192 case WDIOC_GETSUPPORT:
190 return copy_to_user(argp, &ident, 193 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
191 sizeof (ident)) ? -EFAULT : 0; 194
192 195 case WDIOC_GETSTATUS:
193 case WDIOC_GETSTATUS: 196 case WDIOC_GETBOOTSTATUS:
194 case WDIOC_GETBOOTSTATUS: 197 return put_user(0, p);
195 return put_user(0, p); 198 case WDIOC_SETOPTIONS:
196 199 {
197 case WDIOC_KEEPALIVE: 200 int new_options, retval = -EINVAL;
198 ali_keepalive(); 201
199 return 0; 202 if (get_user(new_options, p))
200 203 return -EFAULT;
201 case WDIOC_SETOPTIONS: 204 if (new_options & WDIOS_DISABLECARD) {
202 { 205 ali_stop();
203 int new_options, retval = -EINVAL; 206 retval = 0;
204
205 if (get_user (new_options, p))
206 return -EFAULT;
207
208 if (new_options & WDIOS_DISABLECARD) {
209 ali_stop();
210 retval = 0;
211 }
212
213 if (new_options & WDIOS_ENABLECARD) {
214 ali_start();
215 retval = 0;
216 }
217
218 return retval;
219 } 207 }
220 208 if (new_options & WDIOS_ENABLECARD) {
221 case WDIOC_SETTIMEOUT: 209 ali_start();
222 { 210 retval = 0;
223 int new_timeout;
224
225 if (get_user(new_timeout, p))
226 return -EFAULT;
227
228 if (ali_settimer(new_timeout))
229 return -EINVAL;
230
231 ali_keepalive();
232 /* Fall */
233 } 211 }
234 212 return retval;
235 case WDIOC_GETTIMEOUT: 213 }
236 return put_user(timeout, p); 214 case WDIOC_KEEPALIVE:
237 215 ali_keepalive();
238 default: 216 return 0;
239 return -ENOTTY; 217 case WDIOC_SETTIMEOUT:
218 {
219 int new_timeout;
220 if (get_user(new_timeout, p))
221 return -EFAULT;
222 if (ali_settimer(new_timeout))
223 return -EINVAL;
224 ali_keepalive();
225 /* Fall */
226 }
227 case WDIOC_GETTIMEOUT:
228 return put_user(timeout, p);
229 default:
230 return -ENOTTY;
240 } 231 }
241} 232}
242 233
@@ -274,10 +265,11 @@ static int ali_release(struct inode *inode, struct file *file)
274 /* 265 /*
275 * Shut off the timer. 266 * Shut off the timer.
276 */ 267 */
277 if (ali_expect_release == 42) { 268 if (ali_expect_release == 42)
278 ali_stop(); 269 ali_stop();
279 } else { 270 else {
280 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); 271 printk(KERN_CRIT PFX
272 "Unexpected close, not stopping watchdog!\n");
281 ali_keepalive(); 273 ali_keepalive();
282 } 274 }
283 clear_bit(0, &ali_is_open); 275 clear_bit(0, &ali_is_open);
@@ -292,13 +284,11 @@ static int ali_release(struct inode *inode, struct file *file)
292 */ 284 */
293 285
294 286
295static int ali_notify_sys(struct notifier_block *this, unsigned long code, void *unused) 287static int ali_notify_sys(struct notifier_block *this,
288 unsigned long code, void *unused)
296{ 289{
297 if (code==SYS_DOWN || code==SYS_HALT) { 290 if (code == SYS_DOWN || code == SYS_HALT)
298 /* Turn the WDT off */ 291 ali_stop(); /* Turn the WDT off */
299 ali_stop();
300 }
301
302 return NOTIFY_DONE; 292 return NOTIFY_DONE;
303} 293}
304 294
@@ -340,10 +330,10 @@ static int __init ali_find_watchdog(void)
340 330
341 /* Check for the a 7101 PMU */ 331 /* Check for the a 7101 PMU */
342 pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x7101, NULL); 332 pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x7101, NULL);
343 if(pdev == NULL) 333 if (pdev == NULL)
344 return -ENODEV; 334 return -ENODEV;
345 335
346 if(pci_enable_device(pdev)) { 336 if (pci_enable_device(pdev)) {
347 pci_dev_put(pdev); 337 pci_dev_put(pdev);
348 return -EIO; 338 return -EIO;
349 } 339 }
@@ -355,9 +345,12 @@ static int __init ali_find_watchdog(void)
355 */ 345 */
356 pci_read_config_dword(pdev, 0xCC, &wdog); 346 pci_read_config_dword(pdev, 0xCC, &wdog);
357 347
358 wdog &= ~0x3F; /* Timer bits */ 348 /* Timer bits */
359 wdog &= ~((1<<27)|(1<<26)|(1<<25)|(1<<24)); /* Issued events */ 349 wdog &= ~0x3F;
360 wdog &= ~((1<<16)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)); /* No monitor bits */ 350 /* Issued events */
351 wdog &= ~((1<<27)|(1<<26)|(1<<25)|(1<<24));
352 /* No monitor bits */
353 wdog &= ~((1<<16)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9));
361 354
362 pci_write_config_dword(pdev, 0xCC, wdog); 355 pci_write_config_dword(pdev, 0xCC, wdog);
363 356
@@ -369,12 +362,12 @@ static int __init ali_find_watchdog(void)
369 */ 362 */
370 363
371static const struct file_operations ali_fops = { 364static const struct file_operations ali_fops = {
372 .owner = THIS_MODULE, 365 .owner = THIS_MODULE,
373 .llseek = no_llseek, 366 .llseek = no_llseek,
374 .write = ali_write, 367 .write = ali_write,
375 .ioctl = ali_ioctl, 368 .unlocked_ioctl = ali_ioctl,
376 .open = ali_open, 369 .open = ali_open,
377 .release = ali_release, 370 .release = ali_release,
378}; 371};
379 372
380static struct miscdevice ali_miscdev = { 373static struct miscdevice ali_miscdev = {
@@ -399,15 +392,16 @@ static int __init watchdog_init(void)
399 int ret; 392 int ret;
400 393
401 /* Check whether or not the hardware watchdog is there */ 394 /* Check whether or not the hardware watchdog is there */
402 if (ali_find_watchdog() != 0) { 395 if (ali_find_watchdog() != 0)
403 return -ENODEV; 396 return -ENODEV;
404 }
405 397
406 /* Check that the timeout value is within it's range ; if not reset to the default */ 398 /* Check that the timeout value is within it's range;
399 if not reset to the default */
407 if (timeout < 1 || timeout >= 18000) { 400 if (timeout < 1 || timeout >= 18000) {
408 timeout = WATCHDOG_TIMEOUT; 401 timeout = WATCHDOG_TIMEOUT;
409 printk(KERN_INFO PFX "timeout value must be 0<timeout<18000, using %d\n", 402 printk(KERN_INFO PFX
410 timeout); 403 "timeout value must be 0 < timeout < 18000, using %d\n",
404 timeout);
411 } 405 }
412 406
413 /* Calculate the watchdog's timeout */ 407 /* Calculate the watchdog's timeout */
@@ -415,15 +409,16 @@ static int __init watchdog_init(void)
415 409
416 ret = register_reboot_notifier(&ali_notifier); 410 ret = register_reboot_notifier(&ali_notifier);
417 if (ret != 0) { 411 if (ret != 0) {
418 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 412 printk(KERN_ERR PFX
419 ret); 413 "cannot register reboot notifier (err=%d)\n", ret);
420 goto out; 414 goto out;
421 } 415 }
422 416
423 ret = misc_register(&ali_miscdev); 417 ret = misc_register(&ali_miscdev);
424 if (ret != 0) { 418 if (ret != 0) {
425 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 419 printk(KERN_ERR PFX
426 WATCHDOG_MINOR, ret); 420 "cannot register miscdev on minor=%d (err=%d)\n",
421 WATCHDOG_MINOR, ret);
427 goto unreg_reboot; 422 goto unreg_reboot;
428 } 423 }
429 424
diff --git a/drivers/watchdog/alim7101_wdt.c b/drivers/watchdog/alim7101_wdt.c
index 238273c98656..a045ef869439 100644
--- a/drivers/watchdog/alim7101_wdt.c
+++ b/drivers/watchdog/alim7101_wdt.c
@@ -31,9 +31,9 @@
31#include <linux/init.h> 31#include <linux/init.h>
32#include <linux/fs.h> 32#include <linux/fs.h>
33#include <linux/pci.h> 33#include <linux/pci.h>
34#include <linux/io.h>
35#include <linux/uaccess.h>
34 36
35#include <asm/io.h>
36#include <asm/uaccess.h>
37#include <asm/system.h> 37#include <asm/system.h>
38 38
39#define OUR_NAME "alim7101_wdt" 39#define OUR_NAME "alim7101_wdt"
@@ -60,13 +60,17 @@
60 */ 60 */
61 61
62#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ 62#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */
63static int timeout = WATCHDOG_TIMEOUT; /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */ 63/* in seconds, will be multiplied by HZ to get seconds to wait for a ping */
64static int timeout = WATCHDOG_TIMEOUT;
64module_param(timeout, int, 0); 65module_param(timeout, int, 0);
65MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); 66MODULE_PARM_DESC(timeout,
67 "Watchdog timeout in seconds. (1<=timeout<=3600, default="
68 __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
66 69
67static int use_gpio = 0; /* Use the pic (for a1d revision alim7101) */ 70static int use_gpio; /* Use the pic (for a1d revision alim7101) */
68module_param(use_gpio, int, 0); 71module_param(use_gpio, int, 0);
69MODULE_PARM_DESC(use_gpio, "Use the gpio watchdog. (required by old cobalt boards)"); 72MODULE_PARM_DESC(use_gpio,
73 "Use the gpio watchdog (required by old cobalt boards).");
70 74
71static void wdt_timer_ping(unsigned long); 75static void wdt_timer_ping(unsigned long);
72static DEFINE_TIMER(timer, wdt_timer_ping, 0, 1); 76static DEFINE_TIMER(timer, wdt_timer_ping, 0, 1);
@@ -77,8 +81,9 @@ static struct pci_dev *alim7101_pmu;
77 81
78static int nowayout = WATCHDOG_NOWAYOUT; 82static int nowayout = WATCHDOG_NOWAYOUT;
79module_param(nowayout, int, 0); 83module_param(nowayout, int, 0);
80MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" 84MODULE_PARM_DESC(nowayout,
81 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 85 "Watchdog cannot be stopped once started (default="
86 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
82 87
83/* 88/*
84 * Whack the dog 89 * Whack the dog
@@ -89,23 +94,26 @@ static void wdt_timer_ping(unsigned long data)
89 /* If we got a heartbeat pulse within the WDT_US_INTERVAL 94 /* If we got a heartbeat pulse within the WDT_US_INTERVAL
90 * we agree to ping the WDT 95 * we agree to ping the WDT
91 */ 96 */
92 char tmp; 97 char tmp;
93 98
94 if(time_before(jiffies, next_heartbeat)) 99 if (time_before(jiffies, next_heartbeat)) {
95 {
96 /* Ping the WDT (this is actually a disarm/arm sequence) */ 100 /* Ping the WDT (this is actually a disarm/arm sequence) */
97 pci_read_config_byte(alim7101_pmu, 0x92, &tmp); 101 pci_read_config_byte(alim7101_pmu, 0x92, &tmp);
98 pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp & ~ALI_WDT_ARM)); 102 pci_write_config_byte(alim7101_pmu,
99 pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp | ALI_WDT_ARM)); 103 ALI_7101_WDT, (tmp & ~ALI_WDT_ARM));
104 pci_write_config_byte(alim7101_pmu,
105 ALI_7101_WDT, (tmp | ALI_WDT_ARM));
100 if (use_gpio) { 106 if (use_gpio) {
101 pci_read_config_byte(alim7101_pmu, ALI_7101_GPIO_O, &tmp); 107 pci_read_config_byte(alim7101_pmu,
102 pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp 108 ALI_7101_GPIO_O, &tmp);
103 | 0x20); 109 pci_write_config_byte(alim7101_pmu,
104 pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp 110 ALI_7101_GPIO_O, tmp | 0x20);
105 & ~0x20); 111 pci_write_config_byte(alim7101_pmu,
112 ALI_7101_GPIO_O, tmp & ~0x20);
106 } 113 }
107 } else { 114 } else {
108 printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); 115 printk(KERN_WARNING PFX
116 "Heartbeat lost! Will not ping the watchdog\n");
109 } 117 }
110 /* Re-set the timer interval */ 118 /* Re-set the timer interval */
111 mod_timer(&timer, jiffies + WDT_INTERVAL); 119 mod_timer(&timer, jiffies + WDT_INTERVAL);
@@ -117,21 +125,27 @@ static void wdt_timer_ping(unsigned long data)
117 125
118static void wdt_change(int writeval) 126static void wdt_change(int writeval)
119{ 127{
120 char tmp; 128 char tmp;
121 129
122 pci_read_config_byte(alim7101_pmu, ALI_7101_WDT, &tmp); 130 pci_read_config_byte(alim7101_pmu, ALI_7101_WDT, &tmp);
123 if (writeval == WDT_ENABLE) { 131 if (writeval == WDT_ENABLE) {
124 pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp | ALI_WDT_ARM)); 132 pci_write_config_byte(alim7101_pmu,
133 ALI_7101_WDT, (tmp | ALI_WDT_ARM));
125 if (use_gpio) { 134 if (use_gpio) {
126 pci_read_config_byte(alim7101_pmu, ALI_7101_GPIO_O, &tmp); 135 pci_read_config_byte(alim7101_pmu,
127 pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp & ~0x20); 136 ALI_7101_GPIO_O, &tmp);
137 pci_write_config_byte(alim7101_pmu,
138 ALI_7101_GPIO_O, tmp & ~0x20);
128 } 139 }
129 140
130 } else { 141 } else {
131 pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp & ~ALI_WDT_ARM)); 142 pci_write_config_byte(alim7101_pmu,
143 ALI_7101_WDT, (tmp & ~ALI_WDT_ARM));
132 if (use_gpio) { 144 if (use_gpio) {
133 pci_read_config_byte(alim7101_pmu, ALI_7101_GPIO_O, &tmp); 145 pci_read_config_byte(alim7101_pmu,
134 pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp | 0x20); 146 ALI_7101_GPIO_O, &tmp);
147 pci_write_config_byte(alim7101_pmu,
148 ALI_7101_GPIO_O, tmp | 0x20);
135 } 149 }
136 } 150 }
137} 151}
@@ -169,10 +183,11 @@ static void wdt_keepalive(void)
169 * /dev/watchdog handling 183 * /dev/watchdog handling
170 */ 184 */
171 185
172static ssize_t fop_write(struct file * file, const char __user * buf, size_t count, loff_t * ppos) 186static ssize_t fop_write(struct file *file, const char __user *buf,
187 size_t count, loff_t *ppos)
173{ 188{
174 /* See if we got the magic character 'V' and reload the timer */ 189 /* See if we got the magic character 'V' and reload the timer */
175 if(count) { 190 if (count) {
176 if (!nowayout) { 191 if (!nowayout) {
177 size_t ofs; 192 size_t ofs;
178 193
@@ -183,7 +198,7 @@ static ssize_t fop_write(struct file * file, const char __user * buf, size_t cou
183 /* now scan */ 198 /* now scan */
184 for (ofs = 0; ofs != count; ofs++) { 199 for (ofs = 0; ofs != count; ofs++) {
185 char c; 200 char c;
186 if (get_user(c, buf+ofs)) 201 if (get_user(c, buf + ofs))
187 return -EFAULT; 202 return -EFAULT;
188 if (c == 'V') 203 if (c == 'V')
189 wdt_expect_close = 42; 204 wdt_expect_close = 42;
@@ -195,119 +210,116 @@ static ssize_t fop_write(struct file * file, const char __user * buf, size_t cou
195 return count; 210 return count;
196} 211}
197 212
198static int fop_open(struct inode * inode, struct file * file) 213static int fop_open(struct inode *inode, struct file *file)
199{ 214{
200 /* Just in case we're already talking to someone... */ 215 /* Just in case we're already talking to someone... */
201 if(test_and_set_bit(0, &wdt_is_open)) 216 if (test_and_set_bit(0, &wdt_is_open))
202 return -EBUSY; 217 return -EBUSY;
203 /* Good, fire up the show */ 218 /* Good, fire up the show */
204 wdt_startup(); 219 wdt_startup();
205 return nonseekable_open(inode, file); 220 return nonseekable_open(inode, file);
206} 221}
207 222
208static int fop_close(struct inode * inode, struct file * file) 223static int fop_close(struct inode *inode, struct file *file)
209{ 224{
210 if(wdt_expect_close == 42) 225 if (wdt_expect_close == 42)
211 wdt_turnoff(); 226 wdt_turnoff();
212 else { 227 else {
213 /* wim: shouldn't there be a: del_timer(&timer); */ 228 /* wim: shouldn't there be a: del_timer(&timer); */
214 printk(KERN_CRIT PFX "device file closed unexpectedly. Will not stop the WDT!\n"); 229 printk(KERN_CRIT PFX
230 "device file closed unexpectedly. Will not stop the WDT!\n");
215 } 231 }
216 clear_bit(0, &wdt_is_open); 232 clear_bit(0, &wdt_is_open);
217 wdt_expect_close = 0; 233 wdt_expect_close = 0;
218 return 0; 234 return 0;
219} 235}
220 236
221static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) 237static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
222{ 238{
223 void __user *argp = (void __user *)arg; 239 void __user *argp = (void __user *)arg;
224 int __user *p = argp; 240 int __user *p = argp;
225 static struct watchdog_info ident = 241 static struct watchdog_info ident = {
226 { 242 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT
227 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, 243 | WDIOF_MAGICCLOSE,
228 .firmware_version = 1, 244 .firmware_version = 1,
229 .identity = "ALiM7101", 245 .identity = "ALiM7101",
230 }; 246 };
231 247
232 switch(cmd) 248 switch (cmd) {
249 case WDIOC_GETSUPPORT:
250 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
251 case WDIOC_GETSTATUS:
252 case WDIOC_GETBOOTSTATUS:
253 return put_user(0, p);
254 case WDIOC_SETOPTIONS:
233 { 255 {
234 case WDIOC_GETSUPPORT: 256 int new_options, retval = -EINVAL;
235 return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
236 case WDIOC_GETSTATUS:
237 case WDIOC_GETBOOTSTATUS:
238 return put_user(0, p);
239 case WDIOC_KEEPALIVE:
240 wdt_keepalive();
241 return 0;
242 case WDIOC_SETOPTIONS:
243 {
244 int new_options, retval = -EINVAL;
245
246 if(get_user(new_options, p))
247 return -EFAULT;
248
249 if(new_options & WDIOS_DISABLECARD) {
250 wdt_turnoff();
251 retval = 0;
252 }
253 257
254 if(new_options & WDIOS_ENABLECARD) { 258 if (get_user(new_options, p))
255 wdt_startup(); 259 return -EFAULT;
256 retval = 0; 260 if (new_options & WDIOS_DISABLECARD) {
257 } 261 wdt_turnoff();
258 262 retval = 0;
259 return retval;
260 } 263 }
261 case WDIOC_SETTIMEOUT: 264 if (new_options & WDIOS_ENABLECARD) {
262 { 265 wdt_startup();
263 int new_timeout; 266 retval = 0;
264
265 if(get_user(new_timeout, p))
266 return -EFAULT;
267
268 if(new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */
269 return -EINVAL;
270
271 timeout = new_timeout;
272 wdt_keepalive();
273 /* Fall through */
274 } 267 }
275 case WDIOC_GETTIMEOUT: 268 return retval;
276 return put_user(timeout, p); 269 }
277 default: 270 case WDIOC_KEEPALIVE:
278 return -ENOTTY; 271 wdt_keepalive();
272 return 0;
273 case WDIOC_SETTIMEOUT:
274 {
275 int new_timeout;
276
277 if (get_user(new_timeout, p))
278 return -EFAULT;
279 /* arbitrary upper limit */
280 if (new_timeout < 1 || new_timeout > 3600)
281 return -EINVAL;
282 timeout = new_timeout;
283 wdt_keepalive();
284 /* Fall through */
285 }
286 case WDIOC_GETTIMEOUT:
287 return put_user(timeout, p);
288 default:
289 return -ENOTTY;
279 } 290 }
280} 291}
281 292
282static const struct file_operations wdt_fops = { 293static const struct file_operations wdt_fops = {
283 .owner= THIS_MODULE, 294 .owner = THIS_MODULE,
284 .llseek= no_llseek, 295 .llseek = no_llseek,
285 .write= fop_write, 296 .write = fop_write,
286 .open= fop_open, 297 .open = fop_open,
287 .release= fop_close, 298 .release = fop_close,
288 .ioctl= fop_ioctl, 299 .unlocked_ioctl = fop_ioctl,
289}; 300};
290 301
291static struct miscdevice wdt_miscdev = { 302static struct miscdevice wdt_miscdev = {
292 .minor=WATCHDOG_MINOR, 303 .minor = WATCHDOG_MINOR,
293 .name="watchdog", 304 .name = "watchdog",
294 .fops=&wdt_fops, 305 .fops = &wdt_fops,
295}; 306};
296 307
297/* 308/*
298 * Notifier for system down 309 * Notifier for system down
299 */ 310 */
300 311
301static int wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) 312static int wdt_notify_sys(struct notifier_block *this,
313 unsigned long code, void *unused)
302{ 314{
303 if (code==SYS_DOWN || code==SYS_HALT) 315 if (code == SYS_DOWN || code == SYS_HALT)
304 wdt_turnoff(); 316 wdt_turnoff();
305 317
306 if (code==SYS_RESTART) { 318 if (code == SYS_RESTART) {
307 /* 319 /*
308 * Cobalt devices have no way of rebooting themselves other than 320 * Cobalt devices have no way of rebooting themselves other
309 * getting the watchdog to pull reset, so we restart the watchdog on 321 * than getting the watchdog to pull reset, so we restart the
310 * reboot with no heartbeat 322 * watchdog on reboot with no heartbeat
311 */ 323 */
312 wdt_change(WDT_ENABLE); 324 wdt_change(WDT_ENABLE);
313 printk(KERN_INFO PFX "Watchdog timer is now enabled with no heartbeat - should reboot in ~1 second.\n"); 325 printk(KERN_INFO PFX "Watchdog timer is now enabled with no heartbeat - should reboot in ~1 second.\n");
@@ -320,8 +332,7 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, void
320 * turn the timebomb registers off. 332 * turn the timebomb registers off.
321 */ 333 */
322 334
323static struct notifier_block wdt_notifier= 335static struct notifier_block wdt_notifier = {
324{
325 .notifier_call = wdt_notify_sys, 336 .notifier_call = wdt_notify_sys,
326}; 337};
327 338
@@ -354,7 +365,8 @@ static int __init alim7101_wdt_init(void)
354 ali1543_south = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, 365 ali1543_south = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533,
355 NULL); 366 NULL);
356 if (!ali1543_south) { 367 if (!ali1543_south) {
357 printk(KERN_INFO PFX "ALi 1543 South-Bridge not present - WDT not set\n"); 368 printk(KERN_INFO PFX
369 "ALi 1543 South-Bridge not present - WDT not set\n");
358 goto err_out; 370 goto err_out;
359 } 371 }
360 pci_read_config_byte(ali1543_south, 0x5e, &tmp); 372 pci_read_config_byte(ali1543_south, 0x5e, &tmp);
@@ -363,24 +375,25 @@ static int __init alim7101_wdt_init(void)
363 if (!use_gpio) { 375 if (!use_gpio) {
364 printk(KERN_INFO PFX "Detected old alim7101 revision 'a1d'. If this is a cobalt board, set the 'use_gpio' module parameter.\n"); 376 printk(KERN_INFO PFX "Detected old alim7101 revision 'a1d'. If this is a cobalt board, set the 'use_gpio' module parameter.\n");
365 goto err_out; 377 goto err_out;
366 } 378 }
367 nowayout = 1; 379 nowayout = 1;
368 } else if ((tmp & 0x1e) != 0x12 && (tmp & 0x1e) != 0x00) { 380 } else if ((tmp & 0x1e) != 0x12 && (tmp & 0x1e) != 0x00) {
369 printk(KERN_INFO PFX "ALi 1543 South-Bridge does not have the correct revision number (???1001?) - WDT not set\n"); 381 printk(KERN_INFO PFX "ALi 1543 South-Bridge does not have the correct revision number (???1001?) - WDT not set\n");
370 goto err_out; 382 goto err_out;
371 } 383 }
372 384
373 if(timeout < 1 || timeout > 3600) /* arbitrary upper limit */ 385 if (timeout < 1 || timeout > 3600) {
374 { 386 /* arbitrary upper limit */
375 timeout = WATCHDOG_TIMEOUT; 387 timeout = WATCHDOG_TIMEOUT;
376 printk(KERN_INFO PFX "timeout value must be 1<=x<=3600, using %d\n", 388 printk(KERN_INFO PFX
377 timeout); 389 "timeout value must be 1 <= x <= 3600, using %d\n",
390 timeout);
378 } 391 }
379 392
380 rc = register_reboot_notifier(&wdt_notifier); 393 rc = register_reboot_notifier(&wdt_notifier);
381 if (rc) { 394 if (rc) {
382 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 395 printk(KERN_ERR PFX
383 rc); 396 "cannot register reboot notifier (err=%d)\n", rc);
384 goto err_out; 397 goto err_out;
385 } 398 }
386 399
@@ -391,9 +404,8 @@ static int __init alim7101_wdt_init(void)
391 goto err_out_reboot; 404 goto err_out_reboot;
392 } 405 }
393 406
394 if (nowayout) { 407 if (nowayout)
395 __module_get(THIS_MODULE); 408 __module_get(THIS_MODULE);
396 }
397 409
398 printk(KERN_INFO PFX "WDT driver for ALi M7101 initialised. timeout=%d sec (nowayout=%d)\n", 410 printk(KERN_INFO PFX "WDT driver for ALi M7101 initialised. timeout=%d sec (nowayout=%d)\n",
399 timeout, nowayout); 411 timeout, nowayout);
diff --git a/drivers/watchdog/ar7_wdt.c b/drivers/watchdog/ar7_wdt.c
index ef7b0d67095e..55dcbfe2bb72 100644
--- a/drivers/watchdog/ar7_wdt.c
+++ b/drivers/watchdog/ar7_wdt.c
@@ -213,7 +213,7 @@ static int ar7_wdt_notify_sys(struct notifier_block *this,
213} 213}
214 214
215static struct notifier_block ar7_wdt_notifier = { 215static struct notifier_block ar7_wdt_notifier = {
216 .notifier_call = ar7_wdt_notify_sys 216 .notifier_call = ar7_wdt_notify_sys,
217}; 217};
218 218
219static ssize_t ar7_wdt_write(struct file *file, const char *data, 219static ssize_t ar7_wdt_write(struct file *file, const char *data,
@@ -230,7 +230,7 @@ static ssize_t ar7_wdt_write(struct file *file, const char *data,
230 expect_close = 0; 230 expect_close = 0;
231 for (i = 0; i < len; ++i) { 231 for (i = 0; i < len; ++i) {
232 char c; 232 char c;
233 if (get_user(c, data+i)) 233 if (get_user(c, data + i))
234 return -EFAULT; 234 return -EFAULT;
235 if (c == 'V') 235 if (c == 'V')
236 expect_close = 1; 236 expect_close = 1;
@@ -251,8 +251,6 @@ static long ar7_wdt_ioctl(struct file *file,
251 int new_margin; 251 int new_margin;
252 252
253 switch (cmd) { 253 switch (cmd) {
254 default:
255 return -ENOTTY;
256 case WDIOC_GETSUPPORT: 254 case WDIOC_GETSUPPORT:
257 if (copy_to_user((struct watchdog_info *)arg, &ident, 255 if (copy_to_user((struct watchdog_info *)arg, &ident,
258 sizeof(ident))) 256 sizeof(ident)))
@@ -281,6 +279,8 @@ static long ar7_wdt_ioctl(struct file *file,
281 if (put_user(margin, (int *)arg)) 279 if (put_user(margin, (int *)arg))
282 return -EFAULT; 280 return -EFAULT;
283 return 0; 281 return 0;
282 default:
283 return -ENOTTY;
284 } 284 }
285} 285}
286 286
diff --git a/drivers/watchdog/at32ap700x_wdt.c b/drivers/watchdog/at32ap700x_wdt.c
index ae0fca5e8749..e8ae638e5804 100644
--- a/drivers/watchdog/at32ap700x_wdt.c
+++ b/drivers/watchdog/at32ap700x_wdt.c
@@ -212,8 +212,8 @@ static struct watchdog_info at32_wdt_info = {
212/* 212/*
213 * Handle commands from user-space. 213 * Handle commands from user-space.
214 */ 214 */
215static int at32_wdt_ioctl(struct inode *inode, struct file *file, 215static long at32_wdt_ioctl(struct file *file,
216 unsigned int cmd, unsigned long arg) 216 unsigned int cmd, unsigned long arg)
217{ 217{
218 int ret = -ENOTTY; 218 int ret = -ENOTTY;
219 int time; 219 int time;
@@ -221,27 +221,10 @@ static int at32_wdt_ioctl(struct inode *inode, struct file *file,
221 int __user *p = argp; 221 int __user *p = argp;
222 222
223 switch (cmd) { 223 switch (cmd) {
224 case WDIOC_KEEPALIVE:
225 at32_wdt_pat();
226 ret = 0;
227 break;
228 case WDIOC_GETSUPPORT: 224 case WDIOC_GETSUPPORT:
229 ret = copy_to_user(argp, &at32_wdt_info, 225 ret = copy_to_user(argp, &at32_wdt_info,
230 sizeof(at32_wdt_info)) ? -EFAULT : 0; 226 sizeof(at32_wdt_info)) ? -EFAULT : 0;
231 break; 227 break;
232 case WDIOC_SETTIMEOUT:
233 ret = get_user(time, p);
234 if (ret)
235 break;
236 ret = at32_wdt_settimeout(time);
237 if (ret)
238 break;
239 /* Enable new time value */
240 at32_wdt_start();
241 /* fall through */
242 case WDIOC_GETTIMEOUT:
243 ret = put_user(wdt->timeout, p);
244 break;
245 case WDIOC_GETSTATUS: 228 case WDIOC_GETSTATUS:
246 ret = put_user(0, p); 229 ret = put_user(0, p);
247 break; 230 break;
@@ -258,6 +241,23 @@ static int at32_wdt_ioctl(struct inode *inode, struct file *file,
258 at32_wdt_start(); 241 at32_wdt_start();
259 ret = 0; 242 ret = 0;
260 break; 243 break;
244 case WDIOC_KEEPALIVE:
245 at32_wdt_pat();
246 ret = 0;
247 break;
248 case WDIOC_SETTIMEOUT:
249 ret = get_user(time, p);
250 if (ret)
251 break;
252 ret = at32_wdt_settimeout(time);
253 if (ret)
254 break;
255 /* Enable new time value */
256 at32_wdt_start();
257 /* fall through */
258 case WDIOC_GETTIMEOUT:
259 ret = put_user(wdt->timeout, p);
260 break;
261 } 261 }
262 262
263 return ret; 263 return ret;
@@ -283,7 +283,7 @@ static ssize_t at32_wdt_write(struct file *file, const char __user *data,
283 */ 283 */
284 for (i = 0; i != len; i++) { 284 for (i = 0; i != len; i++) {
285 char c; 285 char c;
286 if (get_user(c, data+i)) 286 if (get_user(c, data + i))
287 return -EFAULT; 287 return -EFAULT;
288 if (c == 'V') 288 if (c == 'V')
289 expect_release = 42; 289 expect_release = 42;
@@ -298,7 +298,7 @@ static ssize_t at32_wdt_write(struct file *file, const char __user *data,
298static const struct file_operations at32_wdt_fops = { 298static const struct file_operations at32_wdt_fops = {
299 .owner = THIS_MODULE, 299 .owner = THIS_MODULE,
300 .llseek = no_llseek, 300 .llseek = no_llseek,
301 .ioctl = at32_wdt_ioctl, 301 .unlocked_ioctl = at32_wdt_ioctl,
302 .open = at32_wdt_open, 302 .open = at32_wdt_open,
303 .release = at32_wdt_close, 303 .release = at32_wdt_close,
304 .write = at32_wdt_write, 304 .write = at32_wdt_write,
@@ -391,7 +391,6 @@ static int __exit at32_wdt_remove(struct platform_device *pdev)
391 wdt = NULL; 391 wdt = NULL;
392 platform_set_drvdata(pdev, NULL); 392 platform_set_drvdata(pdev, NULL);
393 } 393 }
394
395 return 0; 394 return 0;
396} 395}
397 396
diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c
index bf872aa2b9f3..bacd867dd22e 100644
--- a/drivers/watchdog/at91rm9200_wdt.c
+++ b/drivers/watchdog/at91rm9200_wdt.c
@@ -20,10 +20,9 @@
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/types.h> 21#include <linux/types.h>
22#include <linux/watchdog.h> 22#include <linux/watchdog.h>
23#include <asm/uaccess.h> 23#include <linux/uaccess.h>
24#include <mach/at91_st.h> 24#include <mach/at91_st.h>
25 25
26
27#define WDT_DEFAULT_TIME 5 /* seconds */ 26#define WDT_DEFAULT_TIME 5 /* seconds */
28#define WDT_MAX_TIME 256 /* seconds */ 27#define WDT_MAX_TIME 256 /* seconds */
29 28
@@ -31,11 +30,14 @@ static int wdt_time = WDT_DEFAULT_TIME;
31static int nowayout = WATCHDOG_NOWAYOUT; 30static int nowayout = WATCHDOG_NOWAYOUT;
32 31
33module_param(wdt_time, int, 0); 32module_param(wdt_time, int, 0);
34MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="__MODULE_STRING(WDT_DEFAULT_TIME) ")"); 33MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="
34 __MODULE_STRING(WDT_DEFAULT_TIME) ")");
35 35
36#ifdef CONFIG_WATCHDOG_NOWAYOUT 36#ifdef CONFIG_WATCHDOG_NOWAYOUT
37module_param(nowayout, int, 0); 37module_param(nowayout, int, 0);
38MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 38MODULE_PARM_DESC(nowayout,
39 "Watchdog cannot be stopped once started (default="
40 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
39#endif 41#endif
40 42
41 43
@@ -46,7 +48,7 @@ static unsigned long at91wdt_busy;
46/* 48/*
47 * Disable the watchdog. 49 * Disable the watchdog.
48 */ 50 */
49static void inline at91_wdt_stop(void) 51static inline void at91_wdt_stop(void)
50{ 52{
51 at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN); 53 at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN);
52} 54}
@@ -54,16 +56,17 @@ static void inline at91_wdt_stop(void)
54/* 56/*
55 * Enable and reset the watchdog. 57 * Enable and reset the watchdog.
56 */ 58 */
57static void inline at91_wdt_start(void) 59static inline void at91_wdt_start(void)
58{ 60{
59 at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN | AT91_ST_RSTEN | (((65536 * wdt_time) >> 8) & AT91_ST_WDV)); 61 at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN | AT91_ST_RSTEN |
62 (((65536 * wdt_time) >> 8) & AT91_ST_WDV));
60 at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); 63 at91_sys_write(AT91_ST_CR, AT91_ST_WDRST);
61} 64}
62 65
63/* 66/*
64 * Reload the watchdog timer. (ie, pat the watchdog) 67 * Reload the watchdog timer. (ie, pat the watchdog)
65 */ 68 */
66static void inline at91_wdt_reload(void) 69static inline void at91_wdt_reload(void)
67{ 70{
68 at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); 71 at91_sys_write(AT91_ST_CR, AT91_ST_WDRST);
69} 72}
@@ -89,8 +92,9 @@ static int at91_wdt_open(struct inode *inode, struct file *file)
89 */ 92 */
90static int at91_wdt_close(struct inode *inode, struct file *file) 93static int at91_wdt_close(struct inode *inode, struct file *file)
91{ 94{
95 /* Disable the watchdog when file is closed */
92 if (!nowayout) 96 if (!nowayout)
93 at91_wdt_stop(); /* Disable the watchdog when file is closed */ 97 at91_wdt_stop();
94 98
95 clear_bit(0, &at91wdt_busy); 99 clear_bit(0, &at91wdt_busy);
96 return 0; 100 return 0;
@@ -110,7 +114,8 @@ static int at91_wdt_settimeout(int new_time)
110 if ((new_time <= 0) || (new_time > WDT_MAX_TIME)) 114 if ((new_time <= 0) || (new_time > WDT_MAX_TIME))
111 return -EINVAL; 115 return -EINVAL;
112 116
113 /* Set new watchdog time. It will be used when at91_wdt_start() is called. */ 117 /* Set new watchdog time. It will be used when
118 at91_wdt_start() is called. */
114 wdt_time = new_time; 119 wdt_time = new_time;
115 return 0; 120 return 0;
116} 121}
@@ -123,60 +128,52 @@ static struct watchdog_info at91_wdt_info = {
123/* 128/*
124 * Handle commands from user-space. 129 * Handle commands from user-space.
125 */ 130 */
126static int at91_wdt_ioctl(struct inode *inode, struct file *file, 131static long at91_wdt_ioct(struct file *file,
127 unsigned int cmd, unsigned long arg) 132 unsigned int cmd, unsigned long arg)
128{ 133{
129 void __user *argp = (void __user *)arg; 134 void __user *argp = (void __user *)arg;
130 int __user *p = argp; 135 int __user *p = argp;
131 int new_value; 136 int new_value;
132 137
133 switch(cmd) { 138 switch (cmd) {
134 case WDIOC_KEEPALIVE: 139 case WDIOC_GETSUPPORT:
135 at91_wdt_reload(); /* pat the watchdog */ 140 return copy_to_user(argp, &at91_wdt_info,
136 return 0; 141 sizeof(at91_wdt_info)) ? -EFAULT : 0;
137 142 case WDIOC_GETSTATUS:
138 case WDIOC_GETSUPPORT: 143 case WDIOC_GETBOOTSTATUS:
139 return copy_to_user(argp, &at91_wdt_info, sizeof(at91_wdt_info)) ? -EFAULT : 0; 144 return put_user(0, p);
140 145 case WDIOC_SETOPTIONS:
141 case WDIOC_SETTIMEOUT: 146 if (get_user(new_value, p))
142 if (get_user(new_value, p)) 147 return -EFAULT;
143 return -EFAULT; 148 if (new_value & WDIOS_DISABLECARD)
144 149 at91_wdt_stop();
145 if (at91_wdt_settimeout(new_value)) 150 if (new_value & WDIOS_ENABLECARD)
146 return -EINVAL;
147
148 /* Enable new time value */
149 at91_wdt_start(); 151 at91_wdt_start();
150 152 return 0;
151 /* Return current value */ 153 case WDIOC_KEEPALIVE:
152 return put_user(wdt_time, p); 154 at91_wdt_reload(); /* pat the watchdog */
153 155 return 0;
154 case WDIOC_GETTIMEOUT: 156 case WDIOC_SETTIMEOUT:
155 return put_user(wdt_time, p); 157 if (get_user(new_value, p))
156 158 return -EFAULT;
157 case WDIOC_GETSTATUS: 159 if (at91_wdt_settimeout(new_value))
158 case WDIOC_GETBOOTSTATUS: 160 return -EINVAL;
159 return put_user(0, p); 161 /* Enable new time value */
160 162 at91_wdt_start();
161 case WDIOC_SETOPTIONS: 163 /* Return current value */
162 if (get_user(new_value, p)) 164 return put_user(wdt_time, p);
163 return -EFAULT; 165 case WDIOC_GETTIMEOUT:
164 166 return put_user(wdt_time, p);
165 if (new_value & WDIOS_DISABLECARD) 167 default:
166 at91_wdt_stop(); 168 return -ENOTTY;
167 if (new_value & WDIOS_ENABLECARD)
168 at91_wdt_start();
169 return 0;
170
171 default:
172 return -ENOTTY;
173 } 169 }
174} 170}
175 171
176/* 172/*
177 * Pat the watchdog whenever device is written to. 173 * Pat the watchdog whenever device is written to.
178 */ 174 */
179static ssize_t at91_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) 175static ssize_t at91_wdt_write(struct file *file, const char *data,
176 size_t len, loff_t *ppos)
180{ 177{
181 at91_wdt_reload(); /* pat the watchdog */ 178 at91_wdt_reload(); /* pat the watchdog */
182 return len; 179 return len;
@@ -187,7 +184,7 @@ static ssize_t at91_wdt_write(struct file *file, const char *data, size_t len, l
187static const struct file_operations at91wdt_fops = { 184static const struct file_operations at91wdt_fops = {
188 .owner = THIS_MODULE, 185 .owner = THIS_MODULE,
189 .llseek = no_llseek, 186 .llseek = no_llseek,
190 .ioctl = at91_wdt_ioctl, 187 .unlocked_ioctl = at91_wdt_ioctl,
191 .open = at91_wdt_open, 188 .open = at91_wdt_open,
192 .release = at91_wdt_close, 189 .release = at91_wdt_close,
193 .write = at91_wdt_write, 190 .write = at91_wdt_write,
@@ -211,7 +208,8 @@ static int __init at91wdt_probe(struct platform_device *pdev)
211 if (res) 208 if (res)
212 return res; 209 return res;
213 210
214 printk("AT91 Watchdog Timer enabled (%d seconds%s)\n", wdt_time, nowayout ? ", nowayout" : ""); 211 printk(KERN_INFO "AT91 Watchdog Timer enabled (%d seconds%s)\n",
212 wdt_time, nowayout ? ", nowayout" : "");
215 return 0; 213 return 0;
216} 214}
217 215
@@ -265,7 +263,8 @@ static struct platform_driver at91wdt_driver = {
265 263
266static int __init at91_wdt_init(void) 264static int __init at91_wdt_init(void)
267{ 265{
268 /* Check that the heartbeat value is within range; if not reset to the default */ 266 /* Check that the heartbeat value is within range;
267 if not reset to the default */
269 if (at91_wdt_settimeout(wdt_time)) { 268 if (at91_wdt_settimeout(wdt_time)) {
270 at91_wdt_settimeout(WDT_DEFAULT_TIME); 269 at91_wdt_settimeout(WDT_DEFAULT_TIME);
271 pr_info("at91_wdt: wdt_time value must be 1 <= wdt_time <= 256, using %d\n", wdt_time); 270 pr_info("at91_wdt: wdt_time value must be 1 <= wdt_time <= 256, using %d\n", wdt_time);
diff --git a/drivers/watchdog/bfin_wdt.c b/drivers/watchdog/bfin_wdt.c
index 03b3e3d91e7c..31b42253054e 100644
--- a/drivers/watchdog/bfin_wdt.c
+++ b/drivers/watchdog/bfin_wdt.c
@@ -24,8 +24,8 @@
24#include <linux/reboot.h> 24#include <linux/reboot.h>
25#include <linux/init.h> 25#include <linux/init.h>
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <linux/uaccess.h>
27#include <asm/blackfin.h> 28#include <asm/blackfin.h>
28#include <asm/uaccess.h>
29 29
30#define stamp(fmt, args...) pr_debug("%s:%i: " fmt "\n", __func__, __LINE__, ## args) 30#define stamp(fmt, args...) pr_debug("%s:%i: " fmt "\n", __func__, __LINE__, ## args)
31#define stampit() stamp("here i am") 31#define stampit() stamp("here i am")
@@ -148,7 +148,8 @@ static int bfin_wdt_set_timeout(unsigned long t)
148 int run = bfin_wdt_running(); 148 int run = bfin_wdt_running();
149 bfin_wdt_stop(); 149 bfin_wdt_stop();
150 bfin_write_WDOG_CNT(cnt); 150 bfin_write_WDOG_CNT(cnt);
151 if (run) bfin_wdt_start(); 151 if (run)
152 bfin_wdt_start();
152 } 153 }
153 spin_unlock_irqrestore(&bfin_wdt_spinlock, flags); 154 spin_unlock_irqrestore(&bfin_wdt_spinlock, flags);
154 155
@@ -191,16 +192,15 @@ static int bfin_wdt_release(struct inode *inode, struct file *file)
191{ 192{
192 stampit(); 193 stampit();
193 194
194 if (expect_close == 42) { 195 if (expect_close == 42)
195 bfin_wdt_stop(); 196 bfin_wdt_stop();
196 } else { 197 else {
197 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); 198 printk(KERN_CRIT PFX
199 "Unexpected close, not stopping watchdog!\n");
198 bfin_wdt_keepalive(); 200 bfin_wdt_keepalive();
199 } 201 }
200
201 expect_close = 0; 202 expect_close = 0;
202 clear_bit(0, &open_check); 203 clear_bit(0, &open_check);
203
204 return 0; 204 return 0;
205} 205}
206 206
@@ -214,7 +214,7 @@ static int bfin_wdt_release(struct inode *inode, struct file *file)
214 * Pings the watchdog on write. 214 * Pings the watchdog on write.
215 */ 215 */
216static ssize_t bfin_wdt_write(struct file *file, const char __user *data, 216static ssize_t bfin_wdt_write(struct file *file, const char __user *data,
217 size_t len, loff_t *ppos) 217 size_t len, loff_t *ppos)
218{ 218{
219 stampit(); 219 stampit();
220 220
@@ -241,7 +241,6 @@ static ssize_t bfin_wdt_write(struct file *file, const char __user *data,
241 241
242/** 242/**
243 * bfin_wdt_ioctl - Query Device 243 * bfin_wdt_ioctl - Query Device
244 * @inode: inode of device
245 * @file: file handle of device 244 * @file: file handle of device
246 * @cmd: watchdog command 245 * @cmd: watchdog command
247 * @arg: argument 246 * @arg: argument
@@ -249,8 +248,8 @@ static ssize_t bfin_wdt_write(struct file *file, const char __user *data,
249 * Query basic information from the device or ping it, as outlined by the 248 * Query basic information from the device or ping it, as outlined by the
250 * watchdog API. 249 * watchdog API.
251 */ 250 */
252static int bfin_wdt_ioctl(struct inode *inode, struct file *file, 251static long bfin_wdt_ioctl(struct file *file,
253 unsigned int cmd, unsigned long arg) 252 unsigned int cmd, unsigned long arg)
254{ 253{
255 void __user *argp = (void __user *)arg; 254 void __user *argp = (void __user *)arg;
256 int __user *p = argp; 255 int __user *p = argp;
@@ -258,59 +257,49 @@ static int bfin_wdt_ioctl(struct inode *inode, struct file *file,
258 stampit(); 257 stampit();
259 258
260 switch (cmd) { 259 switch (cmd) {
261 default: 260 case WDIOC_GETSUPPORT:
262 return -ENOTTY; 261 if (copy_to_user(argp, &bfin_wdt_info, sizeof(bfin_wdt_info)))
263 262 return -EFAULT;
264 case WDIOC_GETSUPPORT: 263 else
265 if (copy_to_user(argp, &bfin_wdt_info, sizeof(bfin_wdt_info)))
266 return -EFAULT;
267 else
268 return 0;
269
270 case WDIOC_GETSTATUS:
271 case WDIOC_GETBOOTSTATUS:
272 return put_user(!!(_bfin_swrst & SWRST_RESET_WDOG), p);
273
274 case WDIOC_KEEPALIVE:
275 bfin_wdt_keepalive();
276 return 0; 264 return 0;
277 265 case WDIOC_GETSTATUS:
278 case WDIOC_SETTIMEOUT: { 266 case WDIOC_GETBOOTSTATUS:
279 int new_timeout; 267 return put_user(!!(_bfin_swrst & SWRST_RESET_WDOG), p);
280 268 case WDIOC_SETOPTIONS: {
281 if (get_user(new_timeout, p)) 269 unsigned long flags;
282 return -EFAULT; 270 int options, ret = -EINVAL;
283 271
284 if (bfin_wdt_set_timeout(new_timeout)) 272 if (get_user(options, p))
285 return -EINVAL; 273 return -EFAULT;
274
275 spin_lock_irqsave(&bfin_wdt_spinlock, flags);
276 if (options & WDIOS_DISABLECARD) {
277 bfin_wdt_stop();
278 ret = 0;
286 } 279 }
287 /* Fall */ 280 if (options & WDIOS_ENABLECARD) {
288 case WDIOC_GETTIMEOUT: 281 bfin_wdt_start();
289 return put_user(timeout, p); 282 ret = 0;
290
291 case WDIOC_SETOPTIONS: {
292 unsigned long flags;
293 int options, ret = -EINVAL;
294
295 if (get_user(options, p))
296 return -EFAULT;
297
298 spin_lock_irqsave(&bfin_wdt_spinlock, flags);
299
300 if (options & WDIOS_DISABLECARD) {
301 bfin_wdt_stop();
302 ret = 0;
303 }
304
305 if (options & WDIOS_ENABLECARD) {
306 bfin_wdt_start();
307 ret = 0;
308 }
309
310 spin_unlock_irqrestore(&bfin_wdt_spinlock, flags);
311
312 return ret;
313 } 283 }
284 spin_unlock_irqrestore(&bfin_wdt_spinlock, flags);
285 return ret;
286 }
287 case WDIOC_KEEPALIVE:
288 bfin_wdt_keepalive();
289 return 0;
290 case WDIOC_SETTIMEOUT: {
291 int new_timeout;
292
293 if (get_user(new_timeout, p))
294 return -EFAULT;
295 if (bfin_wdt_set_timeout(new_timeout))
296 return -EINVAL;
297 }
298 /* Fall */
299 case WDIOC_GETTIMEOUT:
300 return put_user(timeout, p);
301 default:
302 return -ENOTTY;
314 } 303 }
315} 304}
316 305
@@ -323,8 +312,8 @@ static int bfin_wdt_ioctl(struct inode *inode, struct file *file,
323 * Handles specific events, such as turning off the watchdog during a 312 * Handles specific events, such as turning off the watchdog during a
324 * shutdown event. 313 * shutdown event.
325 */ 314 */
326static int bfin_wdt_notify_sys(struct notifier_block *this, unsigned long code, 315static int bfin_wdt_notify_sys(struct notifier_block *this,
327 void *unused) 316 unsigned long code, void *unused)
328{ 317{
329 stampit(); 318 stampit();
330 319
@@ -379,12 +368,12 @@ static int bfin_wdt_resume(struct platform_device *pdev)
379#endif 368#endif
380 369
381static const struct file_operations bfin_wdt_fops = { 370static const struct file_operations bfin_wdt_fops = {
382 .owner = THIS_MODULE, 371 .owner = THIS_MODULE,
383 .llseek = no_llseek, 372 .llseek = no_llseek,
384 .write = bfin_wdt_write, 373 .write = bfin_wdt_write,
385 .ioctl = bfin_wdt_ioctl, 374 .unlocked_ioctl = bfin_wdt_ioctl,
386 .open = bfin_wdt_open, 375 .open = bfin_wdt_open,
387 .release = bfin_wdt_release, 376 .release = bfin_wdt_release,
388}; 377};
389 378
390static struct miscdevice bfin_wdt_miscdev = { 379static struct miscdevice bfin_wdt_miscdev = {
@@ -396,8 +385,8 @@ static struct miscdevice bfin_wdt_miscdev = {
396static struct watchdog_info bfin_wdt_info = { 385static struct watchdog_info bfin_wdt_info = {
397 .identity = "Blackfin Watchdog", 386 .identity = "Blackfin Watchdog",
398 .options = WDIOF_SETTIMEOUT | 387 .options = WDIOF_SETTIMEOUT |
399 WDIOF_KEEPALIVEPING | 388 WDIOF_KEEPALIVEPING |
400 WDIOF_MAGICCLOSE, 389 WDIOF_MAGICCLOSE,
401}; 390};
402 391
403static struct notifier_block bfin_wdt_notifier = { 392static struct notifier_block bfin_wdt_notifier = {
@@ -416,14 +405,16 @@ static int __devinit bfin_wdt_probe(struct platform_device *pdev)
416 405
417 ret = register_reboot_notifier(&bfin_wdt_notifier); 406 ret = register_reboot_notifier(&bfin_wdt_notifier);
418 if (ret) { 407 if (ret) {
419 pr_devinit(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", ret); 408 pr_devinit(KERN_ERR PFX
409 "cannot register reboot notifier (err=%d)\n", ret);
420 return ret; 410 return ret;
421 } 411 }
422 412
423 ret = misc_register(&bfin_wdt_miscdev); 413 ret = misc_register(&bfin_wdt_miscdev);
424 if (ret) { 414 if (ret) {
425 pr_devinit(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 415 pr_devinit(KERN_ERR PFX
426 WATCHDOG_MINOR, ret); 416 "cannot register miscdev on minor=%d (err=%d)\n",
417 WATCHDOG_MINOR, ret);
427 unregister_reboot_notifier(&bfin_wdt_notifier); 418 unregister_reboot_notifier(&bfin_wdt_notifier);
428 return ret; 419 return ret;
429 } 420 }
@@ -516,7 +507,11 @@ MODULE_LICENSE("GPL");
516MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); 507MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
517 508
518module_param(timeout, uint, 0); 509module_param(timeout, uint, 0);
519MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=((2^32)/SCLK), default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); 510MODULE_PARM_DESC(timeout,
511 "Watchdog timeout in seconds. (1<=timeout<=((2^32)/SCLK), default="
512 __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
520 513
521module_param(nowayout, int, 0); 514module_param(nowayout, int, 0);
522MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 515MODULE_PARM_DESC(nowayout,
516 "Watchdog cannot be stopped once started (default="
517 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c
index 770824458d45..c3b78a76f173 100644
--- a/drivers/watchdog/booke_wdt.c
+++ b/drivers/watchdog/booke_wdt.c
@@ -18,9 +18,9 @@
18#include <linux/miscdevice.h> 18#include <linux/miscdevice.h>
19#include <linux/notifier.h> 19#include <linux/notifier.h>
20#include <linux/watchdog.h> 20#include <linux/watchdog.h>
21#include <linux/uaccess.h>
21 22
22#include <asm/reg_booke.h> 23#include <asm/reg_booke.h>
23#include <asm/uaccess.h>
24#include <asm/system.h> 24#include <asm/system.h>
25 25
26/* If the kernel parameter wdt=1, the watchdog will be enabled at boot. 26/* If the kernel parameter wdt=1, the watchdog will be enabled at boot.
@@ -32,7 +32,7 @@
32 */ 32 */
33 33
34#ifdef CONFIG_FSL_BOOKE 34#ifdef CONFIG_FSL_BOOKE
35#define WDT_PERIOD_DEFAULT 63 /* Ex. wdt_period=28 bus=333Mhz , reset=~40sec */ 35#define WDT_PERIOD_DEFAULT 63 /* Ex. wdt_period=28 bus=333Mhz,reset=~40sec */
36#else 36#else
37#define WDT_PERIOD_DEFAULT 3 /* Refer to the PPC40x and PPC4xx manuals */ 37#define WDT_PERIOD_DEFAULT 3 /* Refer to the PPC40x and PPC4xx manuals */
38#endif /* for timing information */ 38#endif /* for timing information */
@@ -82,16 +82,15 @@ static struct watchdog_info ident = {
82 .identity = "PowerPC Book-E Watchdog", 82 .identity = "PowerPC Book-E Watchdog",
83}; 83};
84 84
85static int booke_wdt_ioctl(struct inode *inode, struct file *file, 85static long booke_wdt_ioctl(struct file *file,
86 unsigned int cmd, unsigned long arg) 86 unsigned int cmd, unsigned long arg)
87{ 87{
88 u32 tmp = 0; 88 u32 tmp = 0;
89 u32 __user *p = (u32 __user *)arg; 89 u32 __user *p = (u32 __user *)arg;
90 90
91 switch (cmd) { 91 switch (cmd) {
92 case WDIOC_GETSUPPORT: 92 case WDIOC_GETSUPPORT:
93 if (copy_to_user((struct watchdog_info __user *)arg, &ident, 93 if (copy_to_user(arg, &ident, sizeof(struct watchdog_info)))
94 sizeof(struct watchdog_info)))
95 return -EFAULT; 94 return -EFAULT;
96 case WDIOC_GETSTATUS: 95 case WDIOC_GETSTATUS:
97 return put_user(ident.options, p); 96 return put_user(ident.options, p);
@@ -100,16 +99,6 @@ static int booke_wdt_ioctl(struct inode *inode, struct file *file,
100 tmp = mfspr(SPRN_TSR) & TSR_WRS(3); 99 tmp = mfspr(SPRN_TSR) & TSR_WRS(3);
101 /* returns 1 if last reset was caused by the WDT */ 100 /* returns 1 if last reset was caused by the WDT */
102 return (tmp ? 1 : 0); 101 return (tmp ? 1 : 0);
103 case WDIOC_KEEPALIVE:
104 booke_wdt_ping();
105 return 0;
106 case WDIOC_SETTIMEOUT:
107 if (get_user(booke_wdt_period, p))
108 return -EFAULT;
109 mtspr(SPRN_TCR, (mfspr(SPRN_TCR)&~WDTP(0))|WDTP(booke_wdt_period));
110 return 0;
111 case WDIOC_GETTIMEOUT:
112 return put_user(booke_wdt_period, p);
113 case WDIOC_SETOPTIONS: 102 case WDIOC_SETOPTIONS:
114 if (get_user(tmp, p)) 103 if (get_user(tmp, p))
115 return -EINVAL; 104 return -EINVAL;
@@ -119,6 +108,17 @@ static int booke_wdt_ioctl(struct inode *inode, struct file *file,
119 } else 108 } else
120 return -EINVAL; 109 return -EINVAL;
121 return 0; 110 return 0;
111 case WDIOC_KEEPALIVE:
112 booke_wdt_ping();
113 return 0;
114 case WDIOC_SETTIMEOUT:
115 if (get_user(booke_wdt_period, p))
116 return -EFAULT;
117 mtspr(SPRN_TCR, (mfspr(SPRN_TCR) & ~WDTP(0)) |
118 WDTP(booke_wdt_period));
119 return 0;
120 case WDIOC_GETTIMEOUT:
121 return put_user(booke_wdt_period, p);
122 default: 122 default:
123 return -ENOTTY; 123 return -ENOTTY;
124 } 124 }
@@ -132,8 +132,9 @@ static int booke_wdt_open(struct inode *inode, struct file *file)
132 if (booke_wdt_enabled == 0) { 132 if (booke_wdt_enabled == 0) {
133 booke_wdt_enabled = 1; 133 booke_wdt_enabled = 1;
134 on_each_cpu(__booke_wdt_enable, NULL, 0); 134 on_each_cpu(__booke_wdt_enable, NULL, 0);
135 printk(KERN_INFO "PowerPC Book-E Watchdog Timer Enabled " 135 printk(KERN_INFO
136 "(wdt_period=%d)\n", booke_wdt_period); 136 "PowerPC Book-E Watchdog Timer Enabled (wdt_period=%d)\n",
137 booke_wdt_period);
137 } 138 }
138 spin_unlock(&booke_wdt_lock); 139 spin_unlock(&booke_wdt_lock);
139 140
@@ -144,7 +145,7 @@ static const struct file_operations booke_wdt_fops = {
144 .owner = THIS_MODULE, 145 .owner = THIS_MODULE,
145 .llseek = no_llseek, 146 .llseek = no_llseek,
146 .write = booke_wdt_write, 147 .write = booke_wdt_write,
147 .ioctl = booke_wdt_ioctl, 148 .unlocked_ioctl = booke_wdt_ioctl,
148 .open = booke_wdt_open, 149 .open = booke_wdt_open,
149}; 150};
150 151
@@ -175,8 +176,9 @@ static int __init booke_wdt_init(void)
175 176
176 spin_lock(&booke_wdt_lock); 177 spin_lock(&booke_wdt_lock);
177 if (booke_wdt_enabled == 1) { 178 if (booke_wdt_enabled == 1) {
178 printk(KERN_INFO "PowerPC Book-E Watchdog Timer Enabled " 179 printk(KERN_INFO
179 "(wdt_period=%d)\n", booke_wdt_period); 180 "PowerPC Book-E Watchdog Timer Enabled (wdt_period=%d)\n",
181 booke_wdt_period);
180 on_each_cpu(__booke_wdt_enable, NULL, 0); 182 on_each_cpu(__booke_wdt_enable, NULL, 0);
181 } 183 }
182 spin_unlock(&booke_wdt_lock); 184 spin_unlock(&booke_wdt_lock);
diff --git a/drivers/watchdog/cpu5wdt.c b/drivers/watchdog/cpu5wdt.c
index df72f90123df..71f6d7eec9a8 100644
--- a/drivers/watchdog/cpu5wdt.c
+++ b/drivers/watchdog/cpu5wdt.c
@@ -30,16 +30,16 @@
30#include <linux/timer.h> 30#include <linux/timer.h>
31#include <linux/completion.h> 31#include <linux/completion.h>
32#include <linux/jiffies.h> 32#include <linux/jiffies.h>
33#include <asm/io.h> 33#include <linux/io.h>
34#include <asm/uaccess.h> 34#include <linux/uaccess.h>
35
36#include <linux/watchdog.h> 35#include <linux/watchdog.h>
37 36
38/* adjustable parameters */ 37/* adjustable parameters */
39 38
40static int verbose = 0; 39static int verbose;
41static int port = 0x91; 40static int port = 0x91;
42static int ticks = 10000; 41static int ticks = 10000;
42static spinlock_t cpu5wdt_lock;
43 43
44#define PFX "cpu5wdt: " 44#define PFX "cpu5wdt: "
45 45
@@ -70,12 +70,13 @@ static struct {
70 70
71static void cpu5wdt_trigger(unsigned long unused) 71static void cpu5wdt_trigger(unsigned long unused)
72{ 72{
73 if ( verbose > 2 ) 73 if (verbose > 2)
74 printk(KERN_DEBUG PFX "trigger at %i ticks\n", ticks); 74 printk(KERN_DEBUG PFX "trigger at %i ticks\n", ticks);
75 75
76 if( cpu5wdt_device.running ) 76 if (cpu5wdt_device.running)
77 ticks--; 77 ticks--;
78 78
79 spin_lock(&cpu5wdt_lock);
79 /* keep watchdog alive */ 80 /* keep watchdog alive */
80 outb(1, port + CPU5WDT_TRIGGER_REG); 81 outb(1, port + CPU5WDT_TRIGGER_REG);
81 82
@@ -86,6 +87,7 @@ static void cpu5wdt_trigger(unsigned long unused)
86 /* ticks doesn't matter anyway */ 87 /* ticks doesn't matter anyway */
87 complete(&cpu5wdt_device.stop); 88 complete(&cpu5wdt_device.stop);
88 } 89 }
90 spin_unlock(&cpu5wdt_lock);
89 91
90} 92}
91 93
@@ -93,14 +95,17 @@ static void cpu5wdt_reset(void)
93{ 95{
94 ticks = cpu5wdt_device.default_ticks; 96 ticks = cpu5wdt_device.default_ticks;
95 97
96 if ( verbose ) 98 if (verbose)
97 printk(KERN_DEBUG PFX "reset (%i ticks)\n", (int) ticks); 99 printk(KERN_DEBUG PFX "reset (%i ticks)\n", (int) ticks);
98 100
99} 101}
100 102
101static void cpu5wdt_start(void) 103static void cpu5wdt_start(void)
102{ 104{
103 if ( !cpu5wdt_device.queue ) { 105 unsigned long flags;
106
107 spin_lock_irqsave(&cpu5wdt_lock, flags);
108 if (!cpu5wdt_device.queue) {
104 cpu5wdt_device.queue = 1; 109 cpu5wdt_device.queue = 1;
105 outb(0, port + CPU5WDT_TIME_A_REG); 110 outb(0, port + CPU5WDT_TIME_A_REG);
106 outb(0, port + CPU5WDT_TIME_B_REG); 111 outb(0, port + CPU5WDT_TIME_B_REG);
@@ -111,18 +116,20 @@ static void cpu5wdt_start(void)
111 } 116 }
112 /* if process dies, counter is not decremented */ 117 /* if process dies, counter is not decremented */
113 cpu5wdt_device.running++; 118 cpu5wdt_device.running++;
119 spin_unlock_irqrestore(&cpu5wdt_lock, flags);
114} 120}
115 121
116static int cpu5wdt_stop(void) 122static int cpu5wdt_stop(void)
117{ 123{
118 if ( cpu5wdt_device.running ) 124 unsigned long flags;
119 cpu5wdt_device.running = 0;
120 125
126 spin_lock_irqsave(&cpu5wdt_lock, flags);
127 if (cpu5wdt_device.running)
128 cpu5wdt_device.running = 0;
121 ticks = cpu5wdt_device.default_ticks; 129 ticks = cpu5wdt_device.default_ticks;
122 130 spin_unlock_irqrestore(&cpu5wdt_lock, flags);
123 if ( verbose ) 131 if (verbose)
124 printk(KERN_CRIT PFX "stop not possible\n"); 132 printk(KERN_CRIT PFX "stop not possible\n");
125
126 return -EIO; 133 return -EIO;
127} 134}
128 135
@@ -130,9 +137,8 @@ static int cpu5wdt_stop(void)
130 137
131static int cpu5wdt_open(struct inode *inode, struct file *file) 138static int cpu5wdt_open(struct inode *inode, struct file *file)
132{ 139{
133 if ( test_and_set_bit(0, &cpu5wdt_device.inuse) ) 140 if (test_and_set_bit(0, &cpu5wdt_device.inuse))
134 return -EBUSY; 141 return -EBUSY;
135
136 return nonseekable_open(inode, file); 142 return nonseekable_open(inode, file);
137} 143}
138 144
@@ -142,67 +148,58 @@ static int cpu5wdt_release(struct inode *inode, struct file *file)
142 return 0; 148 return 0;
143} 149}
144 150
145static int cpu5wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) 151static long cpu5wdt_ioctl(struct file *file, unsigned int cmd,
152 unsigned long arg)
146{ 153{
147 void __user *argp = (void __user *)arg; 154 void __user *argp = (void __user *)arg;
155 int __user *p = argp;
148 unsigned int value; 156 unsigned int value;
149 static struct watchdog_info ident = 157 static struct watchdog_info ident = {
150 {
151 .options = WDIOF_CARDRESET, 158 .options = WDIOF_CARDRESET,
152 .identity = "CPU5 WDT", 159 .identity = "CPU5 WDT",
153 }; 160 };
154 161
155 switch(cmd) { 162 switch (cmd) {
156 case WDIOC_KEEPALIVE: 163 case WDIOC_GETSUPPORT:
157 cpu5wdt_reset(); 164 if (copy_to_user(argp, &ident, sizeof(ident)))
158 break; 165 return -EFAULT;
159 case WDIOC_GETSTATUS: 166 break;
160 value = inb(port + CPU5WDT_STATUS_REG); 167 case WDIOC_GETSTATUS:
161 value = (value >> 2) & 1; 168 value = inb(port + CPU5WDT_STATUS_REG);
162 if ( copy_to_user(argp, &value, sizeof(int)) ) 169 value = (value >> 2) & 1;
163 return -EFAULT; 170 return put_user(value, p);
164 break; 171 case WDIOC_GETBOOTSTATUS:
165 case WDIOC_GETBOOTSTATUS: 172 return put_user(0, p);
166 if ( copy_to_user(argp, &value, sizeof(int)) ) 173 case WDIOC_SETOPTIONS:
167 return -EFAULT; 174 if (get_user(value, p))
168 break; 175 return -EFAULT;
169 case WDIOC_GETSUPPORT: 176 if (value & WDIOS_ENABLECARD)
170 if ( copy_to_user(argp, &ident, sizeof(ident)) ) 177 cpu5wdt_start();
171 return -EFAULT; 178 if (value & WDIOS_DISABLECARD)
172 break; 179 cpu5wdt_stop();
173 case WDIOC_SETOPTIONS: 180 break;
174 if ( copy_from_user(&value, argp, sizeof(int)) ) 181 case WDIOC_KEEPALIVE:
175 return -EFAULT; 182 cpu5wdt_reset();
176 switch(value) { 183 break;
177 case WDIOS_ENABLECARD: 184 default:
178 cpu5wdt_start(); 185 return -ENOTTY;
179 break;
180 case WDIOS_DISABLECARD:
181 return cpu5wdt_stop();
182 default:
183 return -EINVAL;
184 }
185 break;
186 default:
187 return -ENOTTY;
188 } 186 }
189 return 0; 187 return 0;
190} 188}
191 189
192static ssize_t cpu5wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) 190static ssize_t cpu5wdt_write(struct file *file, const char __user *buf,
191 size_t count, loff_t *ppos)
193{ 192{
194 if ( !count ) 193 if (!count)
195 return -EIO; 194 return -EIO;
196
197 cpu5wdt_reset(); 195 cpu5wdt_reset();
198
199 return count; 196 return count;
200} 197}
201 198
202static const struct file_operations cpu5wdt_fops = { 199static const struct file_operations cpu5wdt_fops = {
203 .owner = THIS_MODULE, 200 .owner = THIS_MODULE,
204 .llseek = no_llseek, 201 .llseek = no_llseek,
205 .ioctl = cpu5wdt_ioctl, 202 .unlocked_ioctl = cpu5wdt_ioctl,
206 .open = cpu5wdt_open, 203 .open = cpu5wdt_open,
207 .write = cpu5wdt_write, 204 .write = cpu5wdt_write,
208 .release = cpu5wdt_release, 205 .release = cpu5wdt_release,
@@ -221,37 +218,36 @@ static int __devinit cpu5wdt_init(void)
221 unsigned int val; 218 unsigned int val;
222 int err; 219 int err;
223 220
224 if ( verbose ) 221 if (verbose)
225 printk(KERN_DEBUG PFX "port=0x%x, verbose=%i\n", port, verbose); 222 printk(KERN_DEBUG PFX
223 "port=0x%x, verbose=%i\n", port, verbose);
226 224
227 if ( !request_region(port, CPU5WDT_EXTENT, PFX) ) { 225 init_completion(&cpu5wdt_device.stop);
226 spin_lock_init(&cpu5wdt_lock);
227 cpu5wdt_device.queue = 0;
228 setup_timer(&cpu5wdt_device.timer, cpu5wdt_trigger, 0);
229 cpu5wdt_device.default_ticks = ticks;
230
231 if (!request_region(port, CPU5WDT_EXTENT, PFX)) {
228 printk(KERN_ERR PFX "request_region failed\n"); 232 printk(KERN_ERR PFX "request_region failed\n");
229 err = -EBUSY; 233 err = -EBUSY;
230 goto no_port; 234 goto no_port;
231 } 235 }
232 236
233 if ( (err = misc_register(&cpu5wdt_misc)) < 0 ) {
234 printk(KERN_ERR PFX "misc_register failed\n");
235 goto no_misc;
236 }
237
238 /* watchdog reboot? */ 237 /* watchdog reboot? */
239 val = inb(port + CPU5WDT_STATUS_REG); 238 val = inb(port + CPU5WDT_STATUS_REG);
240 val = (val >> 2) & 1; 239 val = (val >> 2) & 1;
241 if ( !val ) 240 if (!val)
242 printk(KERN_INFO PFX "sorry, was my fault\n"); 241 printk(KERN_INFO PFX "sorry, was my fault\n");
243 242
244 init_completion(&cpu5wdt_device.stop); 243 err = misc_register(&cpu5wdt_misc);
245 cpu5wdt_device.queue = 0; 244 if (err < 0) {
246 245 printk(KERN_ERR PFX "misc_register failed\n");
247 clear_bit(0, &cpu5wdt_device.inuse); 246 goto no_misc;
248 247 }
249 setup_timer(&cpu5wdt_device.timer, cpu5wdt_trigger, 0);
250 248
251 cpu5wdt_device.default_ticks = ticks;
252 249
253 printk(KERN_INFO PFX "init success\n"); 250 printk(KERN_INFO PFX "init success\n");
254
255 return 0; 251 return 0;
256 252
257no_misc: 253no_misc:
@@ -267,7 +263,7 @@ static int __devinit cpu5wdt_init_module(void)
267 263
268static void __devexit cpu5wdt_exit(void) 264static void __devexit cpu5wdt_exit(void)
269{ 265{
270 if ( cpu5wdt_device.queue ) { 266 if (cpu5wdt_device.queue) {
271 cpu5wdt_device.queue = 0; 267 cpu5wdt_device.queue = 0;
272 wait_for_completion(&cpu5wdt_device.stop); 268 wait_for_completion(&cpu5wdt_device.stop);
273 } 269 }
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
index 003dffe5cb19..2e1360286732 100644
--- a/drivers/watchdog/davinci_wdt.c
+++ b/drivers/watchdog/davinci_wdt.c
@@ -22,10 +22,9 @@
22#include <linux/bitops.h> 22#include <linux/bitops.h>
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/spinlock.h> 24#include <linux/spinlock.h>
25 25#include <linux/uaccess.h>
26#include <linux/io.h>
26#include <mach/hardware.h> 27#include <mach/hardware.h>
27#include <asm/uaccess.h>
28#include <asm/io.h>
29 28
30#define MODULE_NAME "DAVINCI-WDT: " 29#define MODULE_NAME "DAVINCI-WDT: "
31 30
@@ -143,9 +142,8 @@ static struct watchdog_info ident = {
143 .identity = "DaVinci Watchdog", 142 .identity = "DaVinci Watchdog",
144}; 143};
145 144
146static int 145static long davinci_wdt_ioctl(struct file *file,
147davinci_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 146 unsigned int cmd, unsigned long arg)
148 unsigned long arg)
149{ 147{
150 int ret = -ENOTTY; 148 int ret = -ENOTTY;
151 149
@@ -160,14 +158,14 @@ davinci_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
160 ret = put_user(0, (int *)arg); 158 ret = put_user(0, (int *)arg);
161 break; 159 break;
162 160
163 case WDIOC_GETTIMEOUT:
164 ret = put_user(heartbeat, (int *)arg);
165 break;
166
167 case WDIOC_KEEPALIVE: 161 case WDIOC_KEEPALIVE:
168 wdt_service(); 162 wdt_service();
169 ret = 0; 163 ret = 0;
170 break; 164 break;
165
166 case WDIOC_GETTIMEOUT:
167 ret = put_user(heartbeat, (int *)arg);
168 break;
171 } 169 }
172 return ret; 170 return ret;
173} 171}
@@ -184,7 +182,7 @@ static const struct file_operations davinci_wdt_fops = {
184 .owner = THIS_MODULE, 182 .owner = THIS_MODULE,
185 .llseek = no_llseek, 183 .llseek = no_llseek,
186 .write = davinci_wdt_write, 184 .write = davinci_wdt_write,
187 .ioctl = davinci_wdt_ioctl, 185 .unlocked_ioctl = davinci_wdt_ioctl,
188 .open = davinci_wdt_open, 186 .open = davinci_wdt_open,
189 .release = davinci_wdt_release, 187 .release = davinci_wdt_release,
190}; 188};
diff --git a/drivers/watchdog/ep93xx_wdt.c b/drivers/watchdog/ep93xx_wdt.c
index af8ef14c0e4c..e9f950ff86ea 100644
--- a/drivers/watchdog/ep93xx_wdt.c
+++ b/drivers/watchdog/ep93xx_wdt.c
@@ -28,9 +28,8 @@
28#include <linux/miscdevice.h> 28#include <linux/miscdevice.h>
29#include <linux/watchdog.h> 29#include <linux/watchdog.h>
30#include <linux/timer.h> 30#include <linux/timer.h>
31 31#include <linux/uaccess.h>
32#include <mach/hardware.h> 32#include <mach/hardware.h>
33#include <asm/uaccess.h>
34 33
35#define WDT_VERSION "0.3" 34#define WDT_VERSION "0.3"
36#define PFX "ep93xx_wdt: " 35#define PFX "ep93xx_wdt: "
@@ -136,9 +135,8 @@ static struct watchdog_info ident = {
136 .identity = "EP93xx Watchdog", 135 .identity = "EP93xx Watchdog",
137}; 136};
138 137
139static int 138static long ep93xx_wdt_ioctl(struct file *file,
140ep93xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 139 unsigned int cmd, unsigned long arg)
141 unsigned long arg)
142{ 140{
143 int ret = -ENOTTY; 141 int ret = -ENOTTY;
144 142
@@ -156,15 +154,15 @@ ep93xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
156 ret = put_user(boot_status, (int __user *)arg); 154 ret = put_user(boot_status, (int __user *)arg);
157 break; 155 break;
158 156
159 case WDIOC_GETTIMEOUT:
160 /* actually, it is 0.250 seconds.... */
161 ret = put_user(1, (int __user *)arg);
162 break;
163
164 case WDIOC_KEEPALIVE: 157 case WDIOC_KEEPALIVE:
165 wdt_keepalive(); 158 wdt_keepalive();
166 ret = 0; 159 ret = 0;
167 break; 160 break;
161
162 case WDIOC_GETTIMEOUT:
163 /* actually, it is 0.250 seconds.... */
164 ret = put_user(1, (int __user *)arg);
165 break;
168 } 166 }
169 return ret; 167 return ret;
170} 168}
@@ -174,8 +172,8 @@ static int ep93xx_wdt_release(struct inode *inode, struct file *file)
174 if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) 172 if (test_bit(WDT_OK_TO_CLOSE, &wdt_status))
175 wdt_shutdown(); 173 wdt_shutdown();
176 else 174 else
177 printk(KERN_CRIT PFX "Device closed unexpectedly - " 175 printk(KERN_CRIT PFX
178 "timer will not stop\n"); 176 "Device closed unexpectedly - timer will not stop\n");
179 177
180 clear_bit(WDT_IN_USE, &wdt_status); 178 clear_bit(WDT_IN_USE, &wdt_status);
181 clear_bit(WDT_OK_TO_CLOSE, &wdt_status); 179 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
@@ -186,7 +184,7 @@ static int ep93xx_wdt_release(struct inode *inode, struct file *file)
186static const struct file_operations ep93xx_wdt_fops = { 184static const struct file_operations ep93xx_wdt_fops = {
187 .owner = THIS_MODULE, 185 .owner = THIS_MODULE,
188 .write = ep93xx_wdt_write, 186 .write = ep93xx_wdt_write,
189 .ioctl = ep93xx_wdt_ioctl, 187 .unlocked_ioctl = ep93xx_wdt_ioctl,
190 .open = ep93xx_wdt_open, 188 .open = ep93xx_wdt_open,
191 .release = ep93xx_wdt_release, 189 .release = ep93xx_wdt_release,
192}; 190};
@@ -243,7 +241,9 @@ module_param(nowayout, int, 0);
243MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"); 241MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started");
244 242
245module_param(timeout, int, 0); 243module_param(timeout, int, 0);
246MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); 244MODULE_PARM_DESC(timeout,
245 "Watchdog timeout in seconds. (1<=timeout<=3600, default="
246 __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
247 247
248MODULE_AUTHOR("Ray Lehtiniemi <rayl@mail.com>," 248MODULE_AUTHOR("Ray Lehtiniemi <rayl@mail.com>,"
249 "Alessandro Zummo <a.zummo@towertech.it>"); 249 "Alessandro Zummo <a.zummo@towertech.it>");
diff --git a/drivers/watchdog/eurotechwdt.c b/drivers/watchdog/eurotechwdt.c
index b14e9d1f164d..bbd14e34319f 100644
--- a/drivers/watchdog/eurotechwdt.c
+++ b/drivers/watchdog/eurotechwdt.c
@@ -56,14 +56,15 @@
56#include <linux/notifier.h> 56#include <linux/notifier.h>
57#include <linux/reboot.h> 57#include <linux/reboot.h>
58#include <linux/init.h> 58#include <linux/init.h>
59#include <linux/io.h>
60#include <linux/uaccess.h>
59 61
60#include <asm/io.h>
61#include <asm/uaccess.h>
62#include <asm/system.h> 62#include <asm/system.h>
63 63
64static unsigned long eurwdt_is_open; 64static unsigned long eurwdt_is_open;
65static int eurwdt_timeout; 65static int eurwdt_timeout;
66static char eur_expect_close; 66static char eur_expect_close;
67static spinlock_t eurwdt_lock;
67 68
68/* 69/*
69 * You must set these - there is no sane way to probe for this board. 70 * You must set these - there is no sane way to probe for this board.
@@ -78,7 +79,9 @@ static char *ev = "int";
78 79
79static int nowayout = WATCHDOG_NOWAYOUT; 80static int nowayout = WATCHDOG_NOWAYOUT;
80module_param(nowayout, int, 0); 81module_param(nowayout, int, 0);
81MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 82MODULE_PARM_DESC(nowayout,
83 "Watchdog cannot be stopped once started (default="
84 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
82 85
83/* 86/*
84 * Some symbolic names 87 * Some symbolic names
@@ -137,7 +140,8 @@ static void eurwdt_activate_timer(void)
137{ 140{
138 eurwdt_disable_timer(); 141 eurwdt_disable_timer();
139 eurwdt_write_reg(WDT_CTRL_REG, 0x01); /* activate the WDT */ 142 eurwdt_write_reg(WDT_CTRL_REG, 0x01); /* activate the WDT */
140 eurwdt_write_reg(WDT_OUTPIN_CFG, !strcmp("int", ev) ? WDT_EVENT_INT : WDT_EVENT_REBOOT); 143 eurwdt_write_reg(WDT_OUTPIN_CFG,
144 !strcmp("int", ev) ? WDT_EVENT_INT : WDT_EVENT_REBOOT);
141 145
142 /* Setting interrupt line */ 146 /* Setting interrupt line */
143 if (irq == 2 || irq > 15 || irq < 0) { 147 if (irq == 2 || irq > 15 || irq < 0) {
@@ -206,21 +210,21 @@ size_t count, loff_t *ppos)
206 210
207 for (i = 0; i != count; i++) { 211 for (i = 0; i != count; i++) {
208 char c; 212 char c;
209 if(get_user(c, buf+i)) 213 if (get_user(c, buf + i))
210 return -EFAULT; 214 return -EFAULT;
211 if (c == 'V') 215 if (c == 'V')
212 eur_expect_close = 42; 216 eur_expect_close = 42;
213 } 217 }
214 } 218 }
219 spin_lock(&eurwdt_lock);
215 eurwdt_ping(); /* the default timeout */ 220 eurwdt_ping(); /* the default timeout */
221 spin_unlock(&eurwdt_lock);
216 } 222 }
217
218 return count; 223 return count;
219} 224}
220 225
221/** 226/**
222 * eurwdt_ioctl: 227 * eurwdt_ioctl:
223 * @inode: inode of the device
224 * @file: file handle to the device 228 * @file: file handle to the device
225 * @cmd: watchdog command 229 * @cmd: watchdog command
226 * @arg: argument pointer 230 * @arg: argument pointer
@@ -229,13 +233,14 @@ size_t count, loff_t *ppos)
229 * according to their available features. 233 * according to their available features.
230 */ 234 */
231 235
232static int eurwdt_ioctl(struct inode *inode, struct file *file, 236static long eurwdt_ioctl(struct file *file,
233 unsigned int cmd, unsigned long arg) 237 unsigned int cmd, unsigned long arg)
234{ 238{
235 void __user *argp = (void __user *)arg; 239 void __user *argp = (void __user *)arg;
236 int __user *p = argp; 240 int __user *p = argp;
237 static struct watchdog_info ident = { 241 static struct watchdog_info ident = {
238 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, 242 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT
243 | WDIOF_MAGICCLOSE,
239 .firmware_version = 1, 244 .firmware_version = 1,
240 .identity = "WDT Eurotech CPU-1220/1410", 245 .identity = "WDT Eurotech CPU-1220/1410",
241 }; 246 };
@@ -243,10 +248,7 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file,
243 int time; 248 int time;
244 int options, retval = -EINVAL; 249 int options, retval = -EINVAL;
245 250
246 switch(cmd) { 251 switch (cmd) {
247 default:
248 return -ENOTTY;
249
250 case WDIOC_GETSUPPORT: 252 case WDIOC_GETSUPPORT:
251 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; 253 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
252 254
@@ -254,8 +256,26 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file,
254 case WDIOC_GETBOOTSTATUS: 256 case WDIOC_GETBOOTSTATUS:
255 return put_user(0, p); 257 return put_user(0, p);
256 258
259 case WDIOC_SETOPTIONS:
260 if (get_user(options, p))
261 return -EFAULT;
262 spin_lock(&eurwdt_lock);
263 if (options & WDIOS_DISABLECARD) {
264 eurwdt_disable_timer();
265 retval = 0;
266 }
267 if (options & WDIOS_ENABLECARD) {
268 eurwdt_activate_timer();
269 eurwdt_ping();
270 retval = 0;
271 }
272 spin_unlock(&eurwdt_lock);
273 return retval;
274
257 case WDIOC_KEEPALIVE: 275 case WDIOC_KEEPALIVE:
276 spin_lock(&eurwdt_lock);
258 eurwdt_ping(); 277 eurwdt_ping();
278 spin_unlock(&eurwdt_lock);
259 return 0; 279 return 0;
260 280
261 case WDIOC_SETTIMEOUT: 281 case WDIOC_SETTIMEOUT:
@@ -266,26 +286,17 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file,
266 if (time < 0 || time > 255) 286 if (time < 0 || time > 255)
267 return -EINVAL; 287 return -EINVAL;
268 288
289 spin_lock(&eurwdt_lock);
269 eurwdt_timeout = time; 290 eurwdt_timeout = time;
270 eurwdt_set_timeout(time); 291 eurwdt_set_timeout(time);
292 spin_unlock(&eurwdt_lock);
271 /* Fall */ 293 /* Fall */
272 294
273 case WDIOC_GETTIMEOUT: 295 case WDIOC_GETTIMEOUT:
274 return put_user(eurwdt_timeout, p); 296 return put_user(eurwdt_timeout, p);
275 297
276 case WDIOC_SETOPTIONS: 298 default:
277 if (get_user(options, p)) 299 return -ENOTTY;
278 return -EFAULT;
279 if (options & WDIOS_DISABLECARD) {
280 eurwdt_disable_timer();
281 retval = 0;
282 }
283 if (options & WDIOS_ENABLECARD) {
284 eurwdt_activate_timer();
285 eurwdt_ping();
286 retval = 0;
287 }
288 return retval;
289 } 300 }
290} 301}
291 302
@@ -322,10 +333,11 @@ static int eurwdt_open(struct inode *inode, struct file *file)
322 333
323static int eurwdt_release(struct inode *inode, struct file *file) 334static int eurwdt_release(struct inode *inode, struct file *file)
324{ 335{
325 if (eur_expect_close == 42) { 336 if (eur_expect_close == 42)
326 eurwdt_disable_timer(); 337 eurwdt_disable_timer();
327 } else { 338 else {
328 printk(KERN_CRIT "eurwdt: Unexpected close, not stopping watchdog!\n"); 339 printk(KERN_CRIT
340 "eurwdt: Unexpected close, not stopping watchdog!\n");
329 eurwdt_ping(); 341 eurwdt_ping();
330 } 342 }
331 clear_bit(0, &eurwdt_is_open); 343 clear_bit(0, &eurwdt_is_open);
@@ -348,10 +360,8 @@ static int eurwdt_release(struct inode *inode, struct file *file)
348static int eurwdt_notify_sys(struct notifier_block *this, unsigned long code, 360static int eurwdt_notify_sys(struct notifier_block *this, unsigned long code,
349 void *unused) 361 void *unused)
350{ 362{
351 if (code == SYS_DOWN || code == SYS_HALT) { 363 if (code == SYS_DOWN || code == SYS_HALT)
352 /* Turn the card off */ 364 eurwdt_disable_timer(); /* Turn the card off */
353 eurwdt_disable_timer();
354 }
355 365
356 return NOTIFY_DONE; 366 return NOTIFY_DONE;
357} 367}
@@ -362,11 +372,11 @@ static int eurwdt_notify_sys(struct notifier_block *this, unsigned long code,
362 372
363 373
364static const struct file_operations eurwdt_fops = { 374static const struct file_operations eurwdt_fops = {
365 .owner = THIS_MODULE, 375 .owner = THIS_MODULE,
366 .llseek = no_llseek, 376 .llseek = no_llseek,
367 .write = eurwdt_write, 377 .write = eurwdt_write,
368 .ioctl = eurwdt_ioctl, 378 .unlocked_ioctl = eurwdt_ioctl,
369 .open = eurwdt_open, 379 .open = eurwdt_open,
370 .release = eurwdt_release, 380 .release = eurwdt_release,
371}; 381};
372 382
@@ -419,7 +429,7 @@ static int __init eurwdt_init(void)
419 int ret; 429 int ret;
420 430
421 ret = request_irq(irq, eurwdt_interrupt, IRQF_DISABLED, "eurwdt", NULL); 431 ret = request_irq(irq, eurwdt_interrupt, IRQF_DISABLED, "eurwdt", NULL);
422 if(ret) { 432 if (ret) {
423 printk(KERN_ERR "eurwdt: IRQ %d is not free.\n", irq); 433 printk(KERN_ERR "eurwdt: IRQ %d is not free.\n", irq);
424 goto out; 434 goto out;
425 } 435 }
@@ -432,10 +442,13 @@ static int __init eurwdt_init(void)
432 442
433 ret = register_reboot_notifier(&eurwdt_notifier); 443 ret = register_reboot_notifier(&eurwdt_notifier);
434 if (ret) { 444 if (ret) {
435 printk(KERN_ERR "eurwdt: can't register reboot notifier (err=%d)\n", ret); 445 printk(KERN_ERR
446 "eurwdt: can't register reboot notifier (err=%d)\n", ret);
436 goto outreg; 447 goto outreg;
437 } 448 }
438 449
450 spin_lock_init(&eurwdt_lock);
451
439 ret = misc_register(&eurwdt_miscdev); 452 ret = misc_register(&eurwdt_miscdev);
440 if (ret) { 453 if (ret) {
441 printk(KERN_ERR "eurwdt: can't misc_register on minor=%d\n", 454 printk(KERN_ERR "eurwdt: can't misc_register on minor=%d\n",
diff --git a/drivers/watchdog/geodewdt.c b/drivers/watchdog/geodewdt.c
index 30d09cbbad94..614a5c7017b6 100644
--- a/drivers/watchdog/geodewdt.c
+++ b/drivers/watchdog/geodewdt.c
@@ -17,8 +17,8 @@
17#include <linux/fs.h> 17#include <linux/fs.h>
18#include <linux/platform_device.h> 18#include <linux/platform_device.h>
19#include <linux/reboot.h> 19#include <linux/reboot.h>
20#include <linux/uaccess.h>
20 21
21#include <asm/uaccess.h>
22#include <asm/geode.h> 22#include <asm/geode.h>
23 23
24#define GEODEWDT_HZ 500 24#define GEODEWDT_HZ 500
@@ -77,27 +77,24 @@ static int geodewdt_set_heartbeat(int val)
77 return 0; 77 return 0;
78} 78}
79 79
80static int 80static int geodewdt_open(struct inode *inode, struct file *file)
81geodewdt_open(struct inode *inode, struct file *file)
82{ 81{
83 if (test_and_set_bit(WDT_FLAGS_OPEN, &wdt_flags)) 82 if (test_and_set_bit(WDT_FLAGS_OPEN, &wdt_flags))
84 return -EBUSY; 83 return -EBUSY;
85 84
86 if (!test_and_clear_bit(WDT_FLAGS_ORPHAN, &wdt_flags)) 85 if (!test_and_clear_bit(WDT_FLAGS_ORPHAN, &wdt_flags))
87 __module_get(THIS_MODULE); 86 __module_get(THIS_MODULE);
88 87
89 geodewdt_ping(); 88 geodewdt_ping();
90 return nonseekable_open(inode, file); 89 return nonseekable_open(inode, file);
91} 90}
92 91
93static int 92static int geodewdt_release(struct inode *inode, struct file *file)
94geodewdt_release(struct inode *inode, struct file *file)
95{ 93{
96 if (safe_close) { 94 if (safe_close) {
97 geodewdt_disable(); 95 geodewdt_disable();
98 module_put(THIS_MODULE); 96 module_put(THIS_MODULE);
99 } 97 } else {
100 else {
101 printk(KERN_CRIT "Unexpected close - watchdog is not stopping.\n"); 98 printk(KERN_CRIT "Unexpected close - watchdog is not stopping.\n");
102 geodewdt_ping(); 99 geodewdt_ping();
103 100
@@ -109,11 +106,10 @@ geodewdt_release(struct inode *inode, struct file *file)
109 return 0; 106 return 0;
110} 107}
111 108
112static ssize_t 109static ssize_t geodewdt_write(struct file *file, const char __user *data,
113geodewdt_write(struct file *file, const char __user *data, size_t len, 110 size_t len, loff_t *ppos)
114 loff_t *ppos)
115{ 111{
116 if(len) { 112 if (len) {
117 if (!nowayout) { 113 if (!nowayout) {
118 size_t i; 114 size_t i;
119 safe_close = 0; 115 safe_close = 0;
@@ -134,9 +130,8 @@ geodewdt_write(struct file *file, const char __user *data, size_t len,
134 return len; 130 return len;
135} 131}
136 132
137static int 133static int geodewdt_ioctl(struct inode *inode, struct file *file,
138geodewdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 134 unsigned int cmd, unsigned long arg)
139 unsigned long arg)
140{ 135{
141 void __user *argp = (void __user *)arg; 136 void __user *argp = (void __user *)arg;
142 int __user *p = argp; 137 int __user *p = argp;
@@ -147,9 +142,9 @@ geodewdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
147 | WDIOF_MAGICCLOSE, 142 | WDIOF_MAGICCLOSE,
148 .firmware_version = 1, 143 .firmware_version = 1,
149 .identity = WATCHDOG_NAME, 144 .identity = WATCHDOG_NAME,
150 }; 145 };
151 146
152 switch(cmd) { 147 switch (cmd) {
153 case WDIOC_GETSUPPORT: 148 case WDIOC_GETSUPPORT:
154 return copy_to_user(argp, &ident, 149 return copy_to_user(argp, &ident,
155 sizeof(ident)) ? -EFAULT : 0; 150 sizeof(ident)) ? -EFAULT : 0;
@@ -159,22 +154,6 @@ geodewdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
159 case WDIOC_GETBOOTSTATUS: 154 case WDIOC_GETBOOTSTATUS:
160 return put_user(0, p); 155 return put_user(0, p);
161 156
162 case WDIOC_KEEPALIVE:
163 geodewdt_ping();
164 return 0;
165
166 case WDIOC_SETTIMEOUT:
167 if (get_user(interval, p))
168 return -EFAULT;
169
170 if (geodewdt_set_heartbeat(interval))
171 return -EINVAL;
172
173/* Fall through */
174
175 case WDIOC_GETTIMEOUT:
176 return put_user(timeout, p);
177
178 case WDIOC_SETOPTIONS: 157 case WDIOC_SETOPTIONS:
179 { 158 {
180 int options, ret = -EINVAL; 159 int options, ret = -EINVAL;
@@ -194,6 +173,20 @@ geodewdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
194 173
195 return ret; 174 return ret;
196 } 175 }
176 case WDIOC_KEEPALIVE:
177 geodewdt_ping();
178 return 0;
179
180 case WDIOC_SETTIMEOUT:
181 if (get_user(interval, p))
182 return -EFAULT;
183
184 if (geodewdt_set_heartbeat(interval))
185 return -EINVAL;
186 /* Fall through */
187 case WDIOC_GETTIMEOUT:
188 return put_user(timeout, p);
189
197 default: 190 default:
198 return -ENOTTY; 191 return -ENOTTY;
199 } 192 }
@@ -202,22 +195,21 @@ geodewdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
202} 195}
203 196
204static const struct file_operations geodewdt_fops = { 197static const struct file_operations geodewdt_fops = {
205 .owner = THIS_MODULE, 198 .owner = THIS_MODULE,
206 .llseek = no_llseek, 199 .llseek = no_llseek,
207 .write = geodewdt_write, 200 .write = geodewdt_write,
208 .ioctl = geodewdt_ioctl, 201 .ioctl = geodewdt_ioctl,
209 .open = geodewdt_open, 202 .open = geodewdt_open,
210 .release = geodewdt_release, 203 .release = geodewdt_release,
211}; 204};
212 205
213static struct miscdevice geodewdt_miscdev = { 206static struct miscdevice geodewdt_miscdev = {
214 .minor = WATCHDOG_MINOR, 207 .minor = WATCHDOG_MINOR,
215 .name = "watchdog", 208 .name = "watchdog",
216 .fops = &geodewdt_fops 209 .fops = &geodewdt_fops,
217}; 210};
218 211
219static int __devinit 212static int __devinit geodewdt_probe(struct platform_device *dev)
220geodewdt_probe(struct platform_device *dev)
221{ 213{
222 int ret, timer; 214 int ret, timer;
223 215
@@ -248,15 +240,13 @@ geodewdt_probe(struct platform_device *dev)
248 return ret; 240 return ret;
249} 241}
250 242
251static int __devexit 243static int __devexit geodewdt_remove(struct platform_device *dev)
252geodewdt_remove(struct platform_device *dev)
253{ 244{
254 misc_deregister(&geodewdt_miscdev); 245 misc_deregister(&geodewdt_miscdev);
255 return 0; 246 return 0;
256} 247}
257 248
258static void 249static void geodewdt_shutdown(struct platform_device *dev)
259geodewdt_shutdown(struct platform_device *dev)
260{ 250{
261 geodewdt_disable(); 251 geodewdt_disable();
262} 252}
@@ -271,8 +261,7 @@ static struct platform_driver geodewdt_driver = {
271 }, 261 },
272}; 262};
273 263
274static int __init 264static int __init geodewdt_init(void)
275geodewdt_init(void)
276{ 265{
277 int ret; 266 int ret;
278 267
@@ -292,8 +281,7 @@ err:
292 return ret; 281 return ret;
293} 282}
294 283
295static void __exit 284static void __exit geodewdt_exit(void)
296geodewdt_exit(void)
297{ 285{
298 platform_device_unregister(geodewdt_platform_device); 286 platform_device_unregister(geodewdt_platform_device);
299 platform_driver_unregister(&geodewdt_driver); 287 platform_driver_unregister(&geodewdt_driver);
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index ccd6c530782d..d039d5f2fd1c 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -39,9 +39,7 @@
39#include <linux/string.h> 39#include <linux/string.h>
40#include <linux/bootmem.h> 40#include <linux/bootmem.h>
41#include <linux/slab.h> 41#include <linux/slab.h>
42#include <asm/dmi.h>
43#include <asm/desc.h> 42#include <asm/desc.h>
44#include <asm/kdebug.h>
45 43
46#define PCI_BIOS32_SD_VALUE 0x5F32335F /* "_32_" */ 44#define PCI_BIOS32_SD_VALUE 0x5F32335F /* "_32_" */
47#define CRU_BIOS_SIGNATURE_VALUE 0x55524324 45#define CRU_BIOS_SIGNATURE_VALUE 0x55524324
@@ -407,7 +405,7 @@ static int __devinit detect_cru_service(void)
407 dmi_walk(dmi_find_cru); 405 dmi_walk(dmi_find_cru);
408 406
409 /* if cru_rom_addr has been set then we found a CRU service */ 407 /* if cru_rom_addr has been set then we found a CRU service */
410 return ((cru_rom_addr != NULL)? 0: -ENODEV); 408 return ((cru_rom_addr != NULL) ? 0: -ENODEV);
411} 409}
412 410
413/* ------------------------------------------------------------------------- */ 411/* ------------------------------------------------------------------------- */
@@ -535,7 +533,7 @@ static ssize_t hpwdt_write(struct file *file, const char __user *data,
535 /* scan to see whether or not we got the magic char. */ 533 /* scan to see whether or not we got the magic char. */
536 for (i = 0; i != len; i++) { 534 for (i = 0; i != len; i++) {
537 char c; 535 char c;
538 if (get_user(c, data+i)) 536 if (get_user(c, data + i))
539 return -EFAULT; 537 return -EFAULT;
540 if (c == 'V') 538 if (c == 'V')
541 expect_release = 42; 539 expect_release = 42;
diff --git a/drivers/watchdog/i6300esb.c b/drivers/watchdog/i6300esb.c
index ca44fd9b19bb..c13383f7fcb9 100644
--- a/drivers/watchdog/i6300esb.c
+++ b/drivers/watchdog/i6300esb.c
@@ -9,18 +9,18 @@
9 * as published by the Free Software Foundation; either version 9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version. 10 * 2 of the License, or (at your option) any later version.
11 * 11 *
12 * based on i810-tco.c which is in turn based on softdog.c 12 * based on i810-tco.c which is in turn based on softdog.c
13 * 13 *
14 * The timer is implemented in the following I/O controller hubs: 14 * The timer is implemented in the following I/O controller hubs:
15 * (See the intel documentation on http://developer.intel.com.) 15 * (See the intel documentation on http://developer.intel.com.)
16 * 6300ESB chip : document number 300641-003 16 * 6300ESB chip : document number 300641-003
17 * 17 *
18 * 2004YYZZ Ross Biro 18 * 2004YYZZ Ross Biro
19 * Initial version 0.01 19 * Initial version 0.01
20 * 2004YYZZ Ross Biro 20 * 2004YYZZ Ross Biro
21 * Version 0.02 21 * Version 0.02
22 * 20050210 David Härdeman <david@2gen.com> 22 * 20050210 David Härdeman <david@2gen.com>
23 * Ported driver to kernel 2.6 23 * Ported driver to kernel 2.6
24 */ 24 */
25 25
26/* 26/*
@@ -38,9 +38,8 @@
38#include <linux/init.h> 38#include <linux/init.h>
39#include <linux/pci.h> 39#include <linux/pci.h>
40#include <linux/ioport.h> 40#include <linux/ioport.h>
41 41#include <linux/uaccess.h>
42#include <asm/uaccess.h> 42#include <linux/io.h>
43#include <asm/io.h>
44 43
45/* Module and version information */ 44/* Module and version information */
46#define ESB_VERSION "0.03" 45#define ESB_VERSION "0.03"
@@ -59,17 +58,17 @@
59#define ESB_RELOAD_REG BASEADDR + 0x0c /* Reload register */ 58#define ESB_RELOAD_REG BASEADDR + 0x0c /* Reload register */
60 59
61/* Lock register bits */ 60/* Lock register bits */
62#define ESB_WDT_FUNC ( 0x01 << 2 ) /* Watchdog functionality */ 61#define ESB_WDT_FUNC (0x01 << 2) /* Watchdog functionality */
63#define ESB_WDT_ENABLE ( 0x01 << 1 ) /* Enable WDT */ 62#define ESB_WDT_ENABLE (0x01 << 1) /* Enable WDT */
64#define ESB_WDT_LOCK ( 0x01 << 0 ) /* Lock (nowayout) */ 63#define ESB_WDT_LOCK (0x01 << 0) /* Lock (nowayout) */
65 64
66/* Config register bits */ 65/* Config register bits */
67#define ESB_WDT_REBOOT ( 0x01 << 5 ) /* Enable reboot on timeout */ 66#define ESB_WDT_REBOOT (0x01 << 5) /* Enable reboot on timeout */
68#define ESB_WDT_FREQ ( 0x01 << 2 ) /* Decrement frequency */ 67#define ESB_WDT_FREQ (0x01 << 2) /* Decrement frequency */
69#define ESB_WDT_INTTYPE ( 0x11 << 0 ) /* Interrupt type on timer1 timeout */ 68#define ESB_WDT_INTTYPE (0x11 << 0) /* Interrupt type on timer1 timeout */
70 69
71/* Reload register bits */ 70/* Reload register bits */
72#define ESB_WDT_RELOAD ( 0x01 << 8 ) /* prevent timeout */ 71#define ESB_WDT_RELOAD (0x01 << 8) /* prevent timeout */
73 72
74/* Magic constants */ 73/* Magic constants */
75#define ESB_UNLOCK1 0x80 /* Step 1 to unlock reset registers */ 74#define ESB_UNLOCK1 0x80 /* Step 1 to unlock reset registers */
@@ -84,14 +83,20 @@ static unsigned short triggered; /* The status of the watchdog upon boot */
84static char esb_expect_close; 83static char esb_expect_close;
85 84
86/* module parameters */ 85/* module parameters */
87#define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat (1<heartbeat<2*1023) */ 86/* 30 sec default heartbeat (1 < heartbeat < 2*1023) */
87#define WATCHDOG_HEARTBEAT 30
88static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ 88static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */
89
89module_param(heartbeat, int, 0); 90module_param(heartbeat, int, 0);
90MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (1<heartbeat<2046, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); 91MODULE_PARM_DESC(heartbeat,
92 "Watchdog heartbeat in seconds. (1<heartbeat<2046, default="
93 __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
91 94
92static int nowayout = WATCHDOG_NOWAYOUT; 95static int nowayout = WATCHDOG_NOWAYOUT;
93module_param(nowayout, int, 0); 96module_param(nowayout, int, 0);
94MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 97MODULE_PARM_DESC(nowayout,
98 "Watchdog cannot be stopped once started (default="
99 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
95 100
96/* 101/*
97 * Some i6300ESB specific functions 102 * Some i6300ESB specific functions
@@ -103,9 +108,10 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" _
103 * reload register. After this the appropriate registers can be written 108 * reload register. After this the appropriate registers can be written
104 * to once before they need to be unlocked again. 109 * to once before they need to be unlocked again.
105 */ 110 */
106static inline void esb_unlock_registers(void) { 111static inline void esb_unlock_registers(void)
107 writeb(ESB_UNLOCK1, ESB_RELOAD_REG); 112{
108 writeb(ESB_UNLOCK2, ESB_RELOAD_REG); 113 writeb(ESB_UNLOCK1, ESB_RELOAD_REG);
114 writeb(ESB_UNLOCK2, ESB_RELOAD_REG);
109} 115}
110 116
111static void esb_timer_start(void) 117static void esb_timer_start(void)
@@ -114,8 +120,7 @@ static void esb_timer_start(void)
114 120
115 /* Enable or Enable + Lock? */ 121 /* Enable or Enable + Lock? */
116 val = 0x02 | (nowayout ? 0x01 : 0x00); 122 val = 0x02 | (nowayout ? 0x01 : 0x00);
117 123 pci_write_config_byte(esb_pci, ESB_LOCK_REG, val);
118 pci_write_config_byte(esb_pci, ESB_LOCK_REG, val);
119} 124}
120 125
121static int esb_timer_stop(void) 126static int esb_timer_stop(void)
@@ -140,7 +145,7 @@ static void esb_timer_keepalive(void)
140 spin_lock(&esb_lock); 145 spin_lock(&esb_lock);
141 esb_unlock_registers(); 146 esb_unlock_registers();
142 writew(ESB_WDT_RELOAD, ESB_RELOAD_REG); 147 writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
143 /* FIXME: Do we need to flush anything here? */ 148 /* FIXME: Do we need to flush anything here? */
144 spin_unlock(&esb_lock); 149 spin_unlock(&esb_lock);
145} 150}
146 151
@@ -165,9 +170,9 @@ static int esb_timer_set_heartbeat(int time)
165 170
166 /* Write timer 2 */ 171 /* Write timer 2 */
167 esb_unlock_registers(); 172 esb_unlock_registers();
168 writel(val, ESB_TIMER2_REG); 173 writel(val, ESB_TIMER2_REG);
169 174
170 /* Reload */ 175 /* Reload */
171 esb_unlock_registers(); 176 esb_unlock_registers();
172 writew(ESB_WDT_RELOAD, ESB_RELOAD_REG); 177 writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
173 178
@@ -179,54 +184,55 @@ static int esb_timer_set_heartbeat(int time)
179 return 0; 184 return 0;
180} 185}
181 186
182static int esb_timer_read (void) 187static int esb_timer_read(void)
183{ 188{
184 u32 count; 189 u32 count;
185 190
186 /* This isn't documented, and doesn't take into 191 /* This isn't documented, and doesn't take into
187 * acount which stage is running, but it looks 192 * acount which stage is running, but it looks
188 * like a 20 bit count down, so we might as well report it. 193 * like a 20 bit count down, so we might as well report it.
189 */ 194 */
190 pci_read_config_dword(esb_pci, 0x64, &count); 195 pci_read_config_dword(esb_pci, 0x64, &count);
191 return (int)count; 196 return (int)count;
192} 197}
193 198
194/* 199/*
195 * /dev/watchdog handling 200 * /dev/watchdog handling
196 */ 201 */
197 202
198static int esb_open (struct inode *inode, struct file *file) 203static int esb_open(struct inode *inode, struct file *file)
199{ 204{
200 /* /dev/watchdog can only be opened once */ 205 /* /dev/watchdog can only be opened once */
201 if (test_and_set_bit(0, &timer_alive)) 206 if (test_and_set_bit(0, &timer_alive))
202 return -EBUSY; 207 return -EBUSY;
203 208
204 /* Reload and activate timer */ 209 /* Reload and activate timer */
205 esb_timer_keepalive (); 210 esb_timer_keepalive();
206 esb_timer_start (); 211 esb_timer_start();
207 212
208 return nonseekable_open(inode, file); 213 return nonseekable_open(inode, file);
209} 214}
210 215
211static int esb_release (struct inode *inode, struct file *file) 216static int esb_release(struct inode *inode, struct file *file)
212{ 217{
213 /* Shut off the timer. */ 218 /* Shut off the timer. */
214 if (esb_expect_close == 42) { 219 if (esb_expect_close == 42)
215 esb_timer_stop (); 220 esb_timer_stop();
216 } else { 221 else {
217 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); 222 printk(KERN_CRIT PFX
218 esb_timer_keepalive (); 223 "Unexpected close, not stopping watchdog!\n");
219 } 224 esb_timer_keepalive();
220 clear_bit(0, &timer_alive); 225 }
221 esb_expect_close = 0; 226 clear_bit(0, &timer_alive);
222 return 0; 227 esb_expect_close = 0;
228 return 0;
223} 229}
224 230
225static ssize_t esb_write (struct file *file, const char __user *data, 231static ssize_t esb_write(struct file *file, const char __user *data,
226 size_t len, loff_t * ppos) 232 size_t len, loff_t *ppos)
227{ 233{
228 /* See if we got the magic character 'V' and reload the timer */ 234 /* See if we got the magic character 'V' and reload the timer */
229 if (len) { 235 if (len) {
230 if (!nowayout) { 236 if (!nowayout) {
231 size_t i; 237 size_t i;
232 238
@@ -237,7 +243,7 @@ static ssize_t esb_write (struct file *file, const char __user *data,
237 /* scan to see whether or not we got the magic character */ 243 /* scan to see whether or not we got the magic character */
238 for (i = 0; i != len; i++) { 244 for (i = 0; i != len; i++) {
239 char c; 245 char c;
240 if(get_user(c, data+i)) 246 if (get_user(c, data + i))
241 return -EFAULT; 247 return -EFAULT;
242 if (c == 'V') 248 if (c == 'V')
243 esb_expect_close = 42; 249 esb_expect_close = 42;
@@ -245,92 +251,84 @@ static ssize_t esb_write (struct file *file, const char __user *data,
245 } 251 }
246 252
247 /* someone wrote to us, we should reload the timer */ 253 /* someone wrote to us, we should reload the timer */
248 esb_timer_keepalive (); 254 esb_timer_keepalive();
249 } 255 }
250 return len; 256 return len;
251} 257}
252 258
253static int esb_ioctl (struct inode *inode, struct file *file, 259static long esb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
254 unsigned int cmd, unsigned long arg)
255{ 260{
256 int new_options, retval = -EINVAL; 261 int new_options, retval = -EINVAL;
257 int new_heartbeat; 262 int new_heartbeat;
258 void __user *argp = (void __user *)arg; 263 void __user *argp = (void __user *)arg;
259 int __user *p = argp; 264 int __user *p = argp;
260 static struct watchdog_info ident = { 265 static struct watchdog_info ident = {
261 .options = WDIOF_SETTIMEOUT | 266 .options = WDIOF_SETTIMEOUT |
262 WDIOF_KEEPALIVEPING | 267 WDIOF_KEEPALIVEPING |
263 WDIOF_MAGICCLOSE, 268 WDIOF_MAGICCLOSE,
264 .firmware_version = 0, 269 .firmware_version = 0,
265 .identity = ESB_MODULE_NAME, 270 .identity = ESB_MODULE_NAME,
266 }; 271 };
267 272
268 switch (cmd) { 273 switch (cmd) {
269 case WDIOC_GETSUPPORT: 274 case WDIOC_GETSUPPORT:
270 return copy_to_user(argp, &ident, 275 return copy_to_user(argp, &ident,
271 sizeof (ident)) ? -EFAULT : 0; 276 sizeof(ident)) ? -EFAULT : 0;
272
273 case WDIOC_GETSTATUS:
274 return put_user (esb_timer_read(), p);
275
276 case WDIOC_GETBOOTSTATUS:
277 return put_user (triggered, p);
278 277
279 case WDIOC_KEEPALIVE: 278 case WDIOC_GETSTATUS:
280 esb_timer_keepalive (); 279 return put_user(esb_timer_read(), p);
281 return 0;
282 280
283 case WDIOC_SETOPTIONS: 281 case WDIOC_GETBOOTSTATUS:
284 { 282 return put_user(triggered, p);
285 if (get_user (new_options, p))
286 return -EFAULT;
287 283
288 if (new_options & WDIOS_DISABLECARD) { 284 case WDIOC_SETOPTIONS:
289 esb_timer_stop (); 285 {
290 retval = 0; 286 if (get_user(new_options, p))
291 } 287 return -EFAULT;
292 288
293 if (new_options & WDIOS_ENABLECARD) { 289 if (new_options & WDIOS_DISABLECARD) {
294 esb_timer_keepalive (); 290 esb_timer_stop();
295 esb_timer_start (); 291 retval = 0;
296 retval = 0; 292 }
297 }
298
299 return retval;
300 }
301
302 case WDIOC_SETTIMEOUT:
303 {
304 if (get_user(new_heartbeat, p))
305 return -EFAULT;
306
307 if (esb_timer_set_heartbeat(new_heartbeat))
308 return -EINVAL;
309
310 esb_timer_keepalive ();
311 /* Fall */
312 }
313
314 case WDIOC_GETTIMEOUT:
315 return put_user(heartbeat, p);
316 293
317 default: 294 if (new_options & WDIOS_ENABLECARD) {
318 return -ENOTTY; 295 esb_timer_keepalive();
319 } 296 esb_timer_start();
297 retval = 0;
298 }
299 return retval;
300 }
301 case WDIOC_KEEPALIVE:
302 esb_timer_keepalive();
303 return 0;
304
305 case WDIOC_SETTIMEOUT:
306 {
307 if (get_user(new_heartbeat, p))
308 return -EFAULT;
309 if (esb_timer_set_heartbeat(new_heartbeat))
310 return -EINVAL;
311 esb_timer_keepalive();
312 /* Fall */
313 }
314 case WDIOC_GETTIMEOUT:
315 return put_user(heartbeat, p);
316 default:
317 return -ENOTTY;
318 }
320} 319}
321 320
322/* 321/*
323 * Notify system 322 * Notify system
324 */ 323 */
325 324
326static int esb_notify_sys (struct notifier_block *this, unsigned long code, void *unused) 325static int esb_notify_sys(struct notifier_block *this,
326 unsigned long code, void *unused)
327{ 327{
328 if (code==SYS_DOWN || code==SYS_HALT) { 328 if (code == SYS_DOWN || code == SYS_HALT)
329 /* Turn the WDT off */ 329 esb_timer_stop(); /* Turn the WDT off */
330 esb_timer_stop ();
331 }
332 330
333 return NOTIFY_DONE; 331 return NOTIFY_DONE;
334} 332}
335 333
336/* 334/*
@@ -338,22 +336,22 @@ static int esb_notify_sys (struct notifier_block *this, unsigned long code, void
338 */ 336 */
339 337
340static const struct file_operations esb_fops = { 338static const struct file_operations esb_fops = {
341 .owner = THIS_MODULE, 339 .owner = THIS_MODULE,
342 .llseek = no_llseek, 340 .llseek = no_llseek,
343 .write = esb_write, 341 .write = esb_write,
344 .ioctl = esb_ioctl, 342 .unlocked_ioctl = esb_ioctl,
345 .open = esb_open, 343 .open = esb_open,
346 .release = esb_release, 344 .release = esb_release,
347}; 345};
348 346
349static struct miscdevice esb_miscdev = { 347static struct miscdevice esb_miscdev = {
350 .minor = WATCHDOG_MINOR, 348 .minor = WATCHDOG_MINOR,
351 .name = "watchdog", 349 .name = "watchdog",
352 .fops = &esb_fops, 350 .fops = &esb_fops,
353}; 351};
354 352
355static struct notifier_block esb_notifier = { 353static struct notifier_block esb_notifier = {
356 .notifier_call = esb_notify_sys, 354 .notifier_call = esb_notify_sys,
357}; 355};
358 356
359/* 357/*
@@ -365,50 +363,44 @@ static struct notifier_block esb_notifier = {
365 * want to register another driver on the same PCI id. 363 * want to register another driver on the same PCI id.
366 */ 364 */
367static struct pci_device_id esb_pci_tbl[] = { 365static struct pci_device_id esb_pci_tbl[] = {
368 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_9), }, 366 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_9), },
369 { 0, }, /* End of list */ 367 { 0, }, /* End of list */
370}; 368};
371MODULE_DEVICE_TABLE (pci, esb_pci_tbl); 369MODULE_DEVICE_TABLE(pci, esb_pci_tbl);
372 370
373/* 371/*
374 * Init & exit routines 372 * Init & exit routines
375 */ 373 */
376 374
377static unsigned char __init esb_getdevice (void) 375static unsigned char __init esb_getdevice(void)
378{ 376{
379 u8 val1; 377 u8 val1;
380 unsigned short val2; 378 unsigned short val2;
379 /*
380 * Find the PCI device
381 */
381 382
382 struct pci_dev *dev = NULL; 383 esb_pci = pci_get_device(PCI_VENDOR_ID_INTEL,
383 /* 384 PCI_DEVICE_ID_INTEL_ESB_9, NULL);
384 * Find the PCI device
385 */
386
387 for_each_pci_dev(dev) {
388 if (pci_match_id(esb_pci_tbl, dev)) {
389 esb_pci = dev;
390 break;
391 }
392 }
393 385
394 if (esb_pci) { 386 if (esb_pci) {
395 if (pci_enable_device(esb_pci)) { 387 if (pci_enable_device(esb_pci)) {
396 printk (KERN_ERR PFX "failed to enable device\n"); 388 printk(KERN_ERR PFX "failed to enable device\n");
397 goto err_devput; 389 goto err_devput;
398 } 390 }
399 391
400 if (pci_request_region(esb_pci, 0, ESB_MODULE_NAME)) { 392 if (pci_request_region(esb_pci, 0, ESB_MODULE_NAME)) {
401 printk (KERN_ERR PFX "failed to request region\n"); 393 printk(KERN_ERR PFX "failed to request region\n");
402 goto err_disable; 394 goto err_disable;
403 } 395 }
404 396
405 BASEADDR = ioremap(pci_resource_start(esb_pci, 0), 397 BASEADDR = ioremap(pci_resource_start(esb_pci, 0),
406 pci_resource_len(esb_pci, 0)); 398 pci_resource_len(esb_pci, 0));
407 if (BASEADDR == NULL) { 399 if (BASEADDR == NULL) {
408 /* Something's wrong here, BASEADDR has to be set */ 400 /* Something's wrong here, BASEADDR has to be set */
409 printk (KERN_ERR PFX "failed to get BASEADDR\n"); 401 printk(KERN_ERR PFX "failed to get BASEADDR\n");
410 goto err_release; 402 goto err_release;
411 } 403 }
412 404
413 /* 405 /*
414 * The watchdog has two timers, it can be setup so that the 406 * The watchdog has two timers, it can be setup so that the
@@ -425,7 +417,7 @@ static unsigned char __init esb_getdevice (void)
425 /* Check that the WDT isn't already locked */ 417 /* Check that the WDT isn't already locked */
426 pci_read_config_byte(esb_pci, ESB_LOCK_REG, &val1); 418 pci_read_config_byte(esb_pci, ESB_LOCK_REG, &val1);
427 if (val1 & ESB_WDT_LOCK) 419 if (val1 & ESB_WDT_LOCK)
428 printk (KERN_WARNING PFX "nowayout already set\n"); 420 printk(KERN_WARNING PFX "nowayout already set\n");
429 421
430 /* Set the timer to watchdog mode and disable it for now */ 422 /* Set the timer to watchdog mode and disable it for now */
431 pci_write_config_byte(esb_pci, ESB_LOCK_REG, 0x00); 423 pci_write_config_byte(esb_pci, ESB_LOCK_REG, 0x00);
@@ -452,44 +444,44 @@ err_devput:
452 return 0; 444 return 0;
453} 445}
454 446
455static int __init watchdog_init (void) 447static int __init watchdog_init(void)
456{ 448{
457 int ret; 449 int ret;
458 450
459 /* Check whether or not the hardware watchdog is there */ 451 /* Check whether or not the hardware watchdog is there */
460 if (!esb_getdevice () || esb_pci == NULL) 452 if (!esb_getdevice() || esb_pci == NULL)
461 return -ENODEV; 453 return -ENODEV;
462 454
463 /* Check that the heartbeat value is within it's range ; if not reset to the default */ 455 /* Check that the heartbeat value is within it's range;
464 if (esb_timer_set_heartbeat (heartbeat)) { 456 if not reset to the default */
465 esb_timer_set_heartbeat (WATCHDOG_HEARTBEAT); 457 if (esb_timer_set_heartbeat(heartbeat)) {
466 printk(KERN_INFO PFX "heartbeat value must be 1<heartbeat<2046, using %d\n", 458 esb_timer_set_heartbeat(WATCHDOG_HEARTBEAT);
467 heartbeat); 459 printk(KERN_INFO PFX
468 } 460 "heartbeat value must be 1<heartbeat<2046, using %d\n",
469 461 heartbeat);
470 ret = register_reboot_notifier(&esb_notifier); 462 }
471 if (ret != 0) { 463 ret = register_reboot_notifier(&esb_notifier);
472 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 464 if (ret != 0) {
473 ret); 465 printk(KERN_ERR PFX
474 goto err_unmap; 466 "cannot register reboot notifier (err=%d)\n", ret);
475 } 467 goto err_unmap;
476 468 }
477 ret = misc_register(&esb_miscdev);
478 if (ret != 0) {
479 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
480 WATCHDOG_MINOR, ret);
481 goto err_notifier;
482 }
483
484 esb_timer_stop ();
485
486 printk (KERN_INFO PFX "initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n",
487 BASEADDR, heartbeat, nowayout);
488 469
489 return 0; 470 ret = misc_register(&esb_miscdev);
471 if (ret != 0) {
472 printk(KERN_ERR PFX
473 "cannot register miscdev on minor=%d (err=%d)\n",
474 WATCHDOG_MINOR, ret);
475 goto err_notifier;
476 }
477 esb_timer_stop();
478 printk(KERN_INFO PFX
479 "initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n",
480 BASEADDR, heartbeat, nowayout);
481 return 0;
490 482
491err_notifier: 483err_notifier:
492 unregister_reboot_notifier(&esb_notifier); 484 unregister_reboot_notifier(&esb_notifier);
493err_unmap: 485err_unmap:
494 iounmap(BASEADDR); 486 iounmap(BASEADDR);
495/* err_release: */ 487/* err_release: */
@@ -498,18 +490,18 @@ err_unmap:
498 pci_disable_device(esb_pci); 490 pci_disable_device(esb_pci);
499/* err_devput: */ 491/* err_devput: */
500 pci_dev_put(esb_pci); 492 pci_dev_put(esb_pci);
501 return ret; 493 return ret;
502} 494}
503 495
504static void __exit watchdog_cleanup (void) 496static void __exit watchdog_cleanup(void)
505{ 497{
506 /* Stop the timer before we leave */ 498 /* Stop the timer before we leave */
507 if (!nowayout) 499 if (!nowayout)
508 esb_timer_stop (); 500 esb_timer_stop();
509 501
510 /* Deregister */ 502 /* Deregister */
511 misc_deregister(&esb_miscdev); 503 misc_deregister(&esb_miscdev);
512 unregister_reboot_notifier(&esb_notifier); 504 unregister_reboot_notifier(&esb_notifier);
513 iounmap(BASEADDR); 505 iounmap(BASEADDR);
514 pci_release_region(esb_pci, 0); 506 pci_release_region(esb_pci, 0);
515 pci_disable_device(esb_pci); 507 pci_disable_device(esb_pci);
diff --git a/drivers/watchdog/iTCO_vendor.h b/drivers/watchdog/iTCO_vendor.h
new file mode 100644
index 000000000000..9e27e6422f66
--- /dev/null
+++ b/drivers/watchdog/iTCO_vendor.h
@@ -0,0 +1,15 @@
1/* iTCO Vendor Specific Support hooks */
2#ifdef CONFIG_ITCO_VENDOR_SUPPORT
3extern void iTCO_vendor_pre_start(unsigned long, unsigned int);
4extern void iTCO_vendor_pre_stop(unsigned long);
5extern void iTCO_vendor_pre_keepalive(unsigned long, unsigned int);
6extern void iTCO_vendor_pre_set_heartbeat(unsigned int);
7extern int iTCO_vendor_check_noreboot_on(void);
8#else
9#define iTCO_vendor_pre_start(acpibase, heartbeat) {}
10#define iTCO_vendor_pre_stop(acpibase) {}
11#define iTCO_vendor_pre_keepalive(acpibase, heartbeat) {}
12#define iTCO_vendor_pre_set_heartbeat(heartbeat) {}
13#define iTCO_vendor_check_noreboot_on() 1
14 /* 1=check noreboot; 0=don't check */
15#endif
diff --git a/drivers/watchdog/iTCO_vendor_support.c b/drivers/watchdog/iTCO_vendor_support.c
index cafc465f2ae3..ca344a85eb95 100644
--- a/drivers/watchdog/iTCO_vendor_support.c
+++ b/drivers/watchdog/iTCO_vendor_support.c
@@ -18,9 +18,9 @@
18 */ 18 */
19 19
20/* Module and version information */ 20/* Module and version information */
21#define DRV_NAME "iTCO_vendor_support" 21#define DRV_NAME "iTCO_vendor_support"
22#define DRV_VERSION "1.01" 22#define DRV_VERSION "1.01"
23#define DRV_RELDATE "11-Nov-2006" 23#define DRV_RELDATE "11-Nov-2006"
24#define PFX DRV_NAME ": " 24#define PFX DRV_NAME ": "
25 25
26/* Includes */ 26/* Includes */
@@ -31,19 +31,22 @@
31#include <linux/kernel.h> /* For printk/panic/... */ 31#include <linux/kernel.h> /* For printk/panic/... */
32#include <linux/init.h> /* For __init/__exit/... */ 32#include <linux/init.h> /* For __init/__exit/... */
33#include <linux/ioport.h> /* For io-port access */ 33#include <linux/ioport.h> /* For io-port access */
34#include <linux/io.h> /* For inb/outb/... */
34 35
35#include <asm/io.h> /* For inb/outb/... */ 36#include "iTCO_vendor.h"
36 37
37/* iTCO defines */ 38/* iTCO defines */
38#define SMI_EN acpibase + 0x30 /* SMI Control and Enable Register */ 39#define SMI_EN acpibase + 0x30 /* SMI Control and Enable Register */
39#define TCOBASE acpibase + 0x60 /* TCO base address */ 40#define TCOBASE acpibase + 0x60 /* TCO base address */
40#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */ 41#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */
41 42
42/* List of vendor support modes */ 43/* List of vendor support modes */
43#define SUPERMICRO_OLD_BOARD 1 /* SuperMicro Pentium 3 Era 370SSE+-OEM1/P3TSSE */ 44/* SuperMicro Pentium 3 Era 370SSE+-OEM1/P3TSSE */
44#define SUPERMICRO_NEW_BOARD 2 /* SuperMicro Pentium 4 / Xeon 4 / EMT64T Era Systems */ 45#define SUPERMICRO_OLD_BOARD 1
46/* SuperMicro Pentium 4 / Xeon 4 / EMT64T Era Systems */
47#define SUPERMICRO_NEW_BOARD 2
45 48
46static int vendorsupport = 0; 49static int vendorsupport;
47module_param(vendorsupport, int, 0); 50module_param(vendorsupport, int, 0);
48MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default=0 (none), 1=SuperMicro Pent3, 2=SuperMicro Pent4+"); 51MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default=0 (none), 1=SuperMicro Pent3, 2=SuperMicro Pent4+");
49 52
@@ -143,34 +146,35 @@ static void supermicro_old_pre_keepalive(unsigned long acpibase)
143 */ 146 */
144 147
145/* I/O Port's */ 148/* I/O Port's */
146#define SM_REGINDEX 0x2e /* SuperMicro ICH4+ Register Index */ 149#define SM_REGINDEX 0x2e /* SuperMicro ICH4+ Register Index */
147#define SM_DATAIO 0x2f /* SuperMicro ICH4+ Register Data I/O */ 150#define SM_DATAIO 0x2f /* SuperMicro ICH4+ Register Data I/O */
148 151
149/* Control Register's */ 152/* Control Register's */
150#define SM_CTLPAGESW 0x07 /* SuperMicro ICH4+ Control Page Switch */ 153#define SM_CTLPAGESW 0x07 /* SuperMicro ICH4+ Control Page Switch */
151#define SM_CTLPAGE 0x08 /* SuperMicro ICH4+ Control Page Num */ 154#define SM_CTLPAGE 0x08 /* SuperMicro ICH4+ Control Page Num */
152 155
153#define SM_WATCHENABLE 0x30 /* Watchdog enable: Bit 0: 0=off, 1=on */ 156#define SM_WATCHENABLE 0x30 /* Watchdog enable: Bit 0: 0=off, 1=on */
154 157
155#define SM_WATCHPAGE 0x87 /* Watchdog unlock control page */ 158#define SM_WATCHPAGE 0x87 /* Watchdog unlock control page */
156 159
157#define SM_ENDWATCH 0xAA /* Watchdog lock control page */ 160#define SM_ENDWATCH 0xAA /* Watchdog lock control page */
158 161
159#define SM_COUNTMODE 0xf5 /* Watchdog count mode select */ 162#define SM_COUNTMODE 0xf5 /* Watchdog count mode select */
160 /* (Bit 3: 0 = seconds, 1 = minutes */ 163 /* (Bit 3: 0 = seconds, 1 = minutes */
161 164
162#define SM_WATCHTIMER 0xf6 /* 8-bits, Watchdog timer counter (RW) */ 165#define SM_WATCHTIMER 0xf6 /* 8-bits, Watchdog timer counter (RW) */
163 166
164#define SM_RESETCONTROL 0xf7 /* Watchdog reset control */ 167#define SM_RESETCONTROL 0xf7 /* Watchdog reset control */
165 /* Bit 6: timer is reset by kbd interrupt */ 168 /* Bit 6: timer is reset by kbd interrupt */
166 /* Bit 7: timer is reset by mouse interrupt */ 169 /* Bit 7: timer is reset by mouse interrupt */
167 170
168static void supermicro_new_unlock_watchdog(void) 171static void supermicro_new_unlock_watchdog(void)
169{ 172{
170 outb(SM_WATCHPAGE, SM_REGINDEX); /* Write 0x87 to port 0x2e twice */ 173 /* Write 0x87 to port 0x2e twice */
171 outb(SM_WATCHPAGE, SM_REGINDEX); 174 outb(SM_WATCHPAGE, SM_REGINDEX);
172 175 outb(SM_WATCHPAGE, SM_REGINDEX);
173 outb(SM_CTLPAGESW, SM_REGINDEX); /* Switch to watchdog control page */ 176 /* Switch to watchdog control page */
177 outb(SM_CTLPAGESW, SM_REGINDEX);
174 outb(SM_CTLPAGE, SM_DATAIO); 178 outb(SM_CTLPAGE, SM_DATAIO);
175} 179}
176 180
@@ -192,7 +196,7 @@ static void supermicro_new_pre_start(unsigned int heartbeat)
192 outb(val, SM_DATAIO); 196 outb(val, SM_DATAIO);
193 197
194 /* Write heartbeat interval to WDOG */ 198 /* Write heartbeat interval to WDOG */
195 outb (SM_WATCHTIMER, SM_REGINDEX); 199 outb(SM_WATCHTIMER, SM_REGINDEX);
196 outb((heartbeat & 255), SM_DATAIO); 200 outb((heartbeat & 255), SM_DATAIO);
197 201
198 /* Make sure keyboard/mouse interrupts don't interfere */ 202 /* Make sure keyboard/mouse interrupts don't interfere */
@@ -277,7 +281,7 @@ EXPORT_SYMBOL(iTCO_vendor_pre_set_heartbeat);
277 281
278int iTCO_vendor_check_noreboot_on(void) 282int iTCO_vendor_check_noreboot_on(void)
279{ 283{
280 switch(vendorsupport) { 284 switch (vendorsupport) {
281 case SUPERMICRO_OLD_BOARD: 285 case SUPERMICRO_OLD_BOARD:
282 return 0; 286 return 0;
283 default: 287 default:
@@ -288,13 +292,13 @@ EXPORT_SYMBOL(iTCO_vendor_check_noreboot_on);
288 292
289static int __init iTCO_vendor_init_module(void) 293static int __init iTCO_vendor_init_module(void)
290{ 294{
291 printk (KERN_INFO PFX "vendor-support=%d\n", vendorsupport); 295 printk(KERN_INFO PFX "vendor-support=%d\n", vendorsupport);
292 return 0; 296 return 0;
293} 297}
294 298
295static void __exit iTCO_vendor_exit_module(void) 299static void __exit iTCO_vendor_exit_module(void)
296{ 300{
297 printk (KERN_INFO PFX "Module Unloaded\n"); 301 printk(KERN_INFO PFX "Module Unloaded\n");
298} 302}
299 303
300module_init(iTCO_vendor_init_module); 304module_init(iTCO_vendor_init_module);
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
index 95ba985bd341..bfb93bc2ca9f 100644
--- a/drivers/watchdog/iTCO_wdt.c
+++ b/drivers/watchdog/iTCO_wdt.c
@@ -55,9 +55,9 @@
55 */ 55 */
56 56
57/* Module and version information */ 57/* Module and version information */
58#define DRV_NAME "iTCO_wdt" 58#define DRV_NAME "iTCO_wdt"
59#define DRV_VERSION "1.03" 59#define DRV_VERSION "1.03"
60#define DRV_RELDATE "30-Apr-2008" 60#define DRV_RELDATE "30-Apr-2008"
61#define PFX DRV_NAME ": " 61#define PFX DRV_NAME ": "
62 62
63/* Includes */ 63/* Includes */
@@ -66,7 +66,8 @@
66#include <linux/types.h> /* For standard types (like size_t) */ 66#include <linux/types.h> /* For standard types (like size_t) */
67#include <linux/errno.h> /* For the -ENODEV/... values */ 67#include <linux/errno.h> /* For the -ENODEV/... values */
68#include <linux/kernel.h> /* For printk/panic/... */ 68#include <linux/kernel.h> /* For printk/panic/... */
69#include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) */ 69#include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV
70 (WATCHDOG_MINOR) */
70#include <linux/watchdog.h> /* For the watchdog specific items */ 71#include <linux/watchdog.h> /* For the watchdog specific items */
71#include <linux/init.h> /* For __init/__exit/... */ 72#include <linux/init.h> /* For __init/__exit/... */
72#include <linux/fs.h> /* For file operations */ 73#include <linux/fs.h> /* For file operations */
@@ -74,9 +75,10 @@
74#include <linux/pci.h> /* For pci functions */ 75#include <linux/pci.h> /* For pci functions */
75#include <linux/ioport.h> /* For io-port access */ 76#include <linux/ioport.h> /* For io-port access */
76#include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ 77#include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */
78#include <linux/uaccess.h> /* For copy_to_user/put_user/... */
79#include <linux/io.h> /* For inb/outb/... */
77 80
78#include <asm/uaccess.h> /* For copy_to_user/put_user/... */ 81#include "iTCO_vendor.h"
79#include <asm/io.h> /* For inb/outb/... */
80 82
81/* TCO related info */ 83/* TCO related info */
82enum iTCO_chipsets { 84enum iTCO_chipsets {
@@ -105,7 +107,7 @@ enum iTCO_chipsets {
105 TCO_ICH9, /* ICH9 */ 107 TCO_ICH9, /* ICH9 */
106 TCO_ICH9R, /* ICH9R */ 108 TCO_ICH9R, /* ICH9R */
107 TCO_ICH9DH, /* ICH9DH */ 109 TCO_ICH9DH, /* ICH9DH */
108 TCO_ICH9DO, /* ICH9DO */ 110 TCO_ICH9DO, /* ICH9DO */
109 TCO_631XESB, /* 631xESB/632xESB */ 111 TCO_631XESB, /* 631xESB/632xESB */
110}; 112};
111 113
@@ -140,7 +142,7 @@ static struct {
140 {"ICH9DH", 2}, 142 {"ICH9DH", 2},
141 {"ICH9DO", 2}, 143 {"ICH9DO", 2},
142 {"631xESB/632xESB", 2}, 144 {"631xESB/632xESB", 2},
143 {NULL,0} 145 {NULL, 0}
144}; 146};
145 147
146#define ITCO_PCI_DEVICE(dev, data) \ 148#define ITCO_PCI_DEVICE(dev, data) \
@@ -159,32 +161,32 @@ static struct {
159 * functions that probably will be registered by other drivers. 161 * functions that probably will be registered by other drivers.
160 */ 162 */
161static struct pci_device_id iTCO_wdt_pci_tbl[] = { 163static struct pci_device_id iTCO_wdt_pci_tbl[] = {
162 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801AA_0, TCO_ICH )}, 164 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801AA_0, TCO_ICH)},
163 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801AB_0, TCO_ICH0 )}, 165 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801AB_0, TCO_ICH0)},
164 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801BA_0, TCO_ICH2 )}, 166 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801BA_0, TCO_ICH2)},
165 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801BA_10, TCO_ICH2M )}, 167 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801BA_10, TCO_ICH2M)},
166 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801CA_0, TCO_ICH3 )}, 168 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801CA_0, TCO_ICH3)},
167 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801CA_12, TCO_ICH3M )}, 169 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801CA_12, TCO_ICH3M)},
168 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801DB_0, TCO_ICH4 )}, 170 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801DB_0, TCO_ICH4)},
169 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801DB_12, TCO_ICH4M )}, 171 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801DB_12, TCO_ICH4M)},
170 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801E_0, TCO_CICH )}, 172 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801E_0, TCO_CICH)},
171 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801EB_0, TCO_ICH5 )}, 173 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801EB_0, TCO_ICH5)},
172 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ESB_1, TCO_6300ESB)}, 174 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ESB_1, TCO_6300ESB)},
173 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_0, TCO_ICH6 )}, 175 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_0, TCO_ICH6)},
174 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_1, TCO_ICH6M )}, 176 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_1, TCO_ICH6M)},
175 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_2, TCO_ICH6W )}, 177 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_2, TCO_ICH6W)},
176 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_0, TCO_ICH7 )}, 178 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_0, TCO_ICH7)},
177 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_1, TCO_ICH7M )}, 179 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_1, TCO_ICH7M)},
178 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_31, TCO_ICH7MDH)}, 180 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_31, TCO_ICH7MDH)},
179 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_0, TCO_ICH8 )}, 181 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_0, TCO_ICH8)},
180 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_1, TCO_ICH8ME )}, 182 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_1, TCO_ICH8ME)},
181 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_2, TCO_ICH8DH )}, 183 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_2, TCO_ICH8DH)},
182 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_3, TCO_ICH8DO )}, 184 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_3, TCO_ICH8DO)},
183 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_4, TCO_ICH8M )}, 185 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_4, TCO_ICH8M)},
184 { ITCO_PCI_DEVICE(0x2918, TCO_ICH9 )}, 186 { ITCO_PCI_DEVICE(0x2918, TCO_ICH9)},
185 { ITCO_PCI_DEVICE(0x2916, TCO_ICH9R )}, 187 { ITCO_PCI_DEVICE(0x2916, TCO_ICH9R)},
186 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_2, TCO_ICH9DH )}, 188 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_2, TCO_ICH9DH)},
187 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_4, TCO_ICH9DO )}, 189 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_4, TCO_ICH9DO)},
188 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ESB2_0, TCO_631XESB)}, 190 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ESB2_0, TCO_631XESB)},
189 { ITCO_PCI_DEVICE(0x2671, TCO_631XESB)}, 191 { ITCO_PCI_DEVICE(0x2671, TCO_631XESB)},
190 { ITCO_PCI_DEVICE(0x2672, TCO_631XESB)}, 192 { ITCO_PCI_DEVICE(0x2672, TCO_631XESB)},
@@ -203,13 +205,15 @@ static struct pci_device_id iTCO_wdt_pci_tbl[] = {
203 { ITCO_PCI_DEVICE(0x267f, TCO_631XESB)}, 205 { ITCO_PCI_DEVICE(0x267f, TCO_631XESB)},
204 { 0, }, /* End of list */ 206 { 0, }, /* End of list */
205}; 207};
206MODULE_DEVICE_TABLE (pci, iTCO_wdt_pci_tbl); 208MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl);
207 209
208/* Address definitions for the TCO */ 210/* Address definitions for the TCO */
209#define TCOBASE iTCO_wdt_private.ACPIBASE + 0x60 /* TCO base address */ 211/* TCO base address */
210#define SMI_EN iTCO_wdt_private.ACPIBASE + 0x30 /* SMI Control and Enable Register */ 212#define TCOBASE iTCO_wdt_private.ACPIBASE + 0x60
213/* SMI Control and Enable Register */
214#define SMI_EN iTCO_wdt_private.ACPIBASE + 0x30
211 215
212#define TCO_RLD TCOBASE + 0x00 /* TCO Timer Reload and Current Value */ 216#define TCO_RLD TCOBASE + 0x00 /* TCO Timer Reload and Curr. Value */
213#define TCOv1_TMR TCOBASE + 0x01 /* TCOv1 Timer Initial Value */ 217#define TCOv1_TMR TCOBASE + 0x01 /* TCOv1 Timer Initial Value */
214#define TCO_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */ 218#define TCO_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */
215#define TCO_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */ 219#define TCO_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */
@@ -222,15 +226,21 @@ MODULE_DEVICE_TABLE (pci, iTCO_wdt_pci_tbl);
222/* internal variables */ 226/* internal variables */
223static unsigned long is_active; 227static unsigned long is_active;
224static char expect_release; 228static char expect_release;
225static struct { /* this is private data for the iTCO_wdt device */ 229static struct { /* this is private data for the iTCO_wdt device */
226 unsigned int iTCO_version; /* TCO version/generation */ 230 /* TCO version/generation */
227 unsigned long ACPIBASE; /* The cards ACPIBASE address (TCOBASE = ACPIBASE+0x60) */ 231 unsigned int iTCO_version;
228 unsigned long __iomem *gcs; /* NO_REBOOT flag is Memory-Mapped GCS register bit 5 (TCO version 2) */ 232 /* The cards ACPIBASE address (TCOBASE = ACPIBASE+0x60) */
229 spinlock_t io_lock; /* the lock for io operations */ 233 unsigned long ACPIBASE;
230 struct pci_dev *pdev; /* the PCI-device */ 234 /* NO_REBOOT flag is Memory-Mapped GCS register bit 5 (TCO version 2)*/
235 unsigned long __iomem *gcs;
236 /* the lock for io operations */
237 spinlock_t io_lock;
238 /* the PCI-device */
239 struct pci_dev *pdev;
231} iTCO_wdt_private; 240} iTCO_wdt_private;
232 241
233static struct platform_device *iTCO_wdt_platform_device; /* the watchdog platform device */ 242/* the watchdog platform device */
243static struct platform_device *iTCO_wdt_platform_device;
234 244
235/* module parameters */ 245/* module parameters */
236#define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */ 246#define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */
@@ -240,22 +250,9 @@ MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<heartbeat<39 (TCO
240 250
241static int nowayout = WATCHDOG_NOWAYOUT; 251static int nowayout = WATCHDOG_NOWAYOUT;
242module_param(nowayout, int, 0); 252module_param(nowayout, int, 0);
243MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 253MODULE_PARM_DESC(nowayout,
244 254 "Watchdog cannot be stopped once started (default="
245/* iTCO Vendor Specific Support hooks */ 255 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
246#ifdef CONFIG_ITCO_VENDOR_SUPPORT
247extern void iTCO_vendor_pre_start(unsigned long, unsigned int);
248extern void iTCO_vendor_pre_stop(unsigned long);
249extern void iTCO_vendor_pre_keepalive(unsigned long, unsigned int);
250extern void iTCO_vendor_pre_set_heartbeat(unsigned int);
251extern int iTCO_vendor_check_noreboot_on(void);
252#else
253#define iTCO_vendor_pre_start(acpibase, heartbeat) {}
254#define iTCO_vendor_pre_stop(acpibase) {}
255#define iTCO_vendor_pre_keepalive(acpibase,heartbeat) {}
256#define iTCO_vendor_pre_set_heartbeat(heartbeat) {}
257#define iTCO_vendor_check_noreboot_on() 1 /* 1=check noreboot; 0=don't check */
258#endif
259 256
260/* 257/*
261 * Some TCO specific functions 258 * Some TCO specific functions
@@ -369,11 +366,10 @@ static int iTCO_wdt_keepalive(void)
369 iTCO_vendor_pre_keepalive(iTCO_wdt_private.ACPIBASE, heartbeat); 366 iTCO_vendor_pre_keepalive(iTCO_wdt_private.ACPIBASE, heartbeat);
370 367
371 /* Reload the timer by writing to the TCO Timer Counter register */ 368 /* Reload the timer by writing to the TCO Timer Counter register */
372 if (iTCO_wdt_private.iTCO_version == 2) { 369 if (iTCO_wdt_private.iTCO_version == 2)
373 outw(0x01, TCO_RLD); 370 outw(0x01, TCO_RLD);
374 } else if (iTCO_wdt_private.iTCO_version == 1) { 371 else if (iTCO_wdt_private.iTCO_version == 1)
375 outb(0x01, TCO_RLD); 372 outb(0x01, TCO_RLD);
376 }
377 373
378 spin_unlock(&iTCO_wdt_private.io_lock); 374 spin_unlock(&iTCO_wdt_private.io_lock);
379 return 0; 375 return 0;
@@ -425,7 +421,7 @@ static int iTCO_wdt_set_heartbeat(int t)
425 return 0; 421 return 0;
426} 422}
427 423
428static int iTCO_wdt_get_timeleft (int *time_left) 424static int iTCO_wdt_get_timeleft(int *time_left)
429{ 425{
430 unsigned int val16; 426 unsigned int val16;
431 unsigned char val8; 427 unsigned char val8;
@@ -454,7 +450,7 @@ static int iTCO_wdt_get_timeleft (int *time_left)
454 * /dev/watchdog handling 450 * /dev/watchdog handling
455 */ 451 */
456 452
457static int iTCO_wdt_open (struct inode *inode, struct file *file) 453static int iTCO_wdt_open(struct inode *inode, struct file *file)
458{ 454{
459 /* /dev/watchdog can only be opened once */ 455 /* /dev/watchdog can only be opened once */
460 if (test_and_set_bit(0, &is_active)) 456 if (test_and_set_bit(0, &is_active))
@@ -468,7 +464,7 @@ static int iTCO_wdt_open (struct inode *inode, struct file *file)
468 return nonseekable_open(inode, file); 464 return nonseekable_open(inode, file);
469} 465}
470 466
471static int iTCO_wdt_release (struct inode *inode, struct file *file) 467static int iTCO_wdt_release(struct inode *inode, struct file *file)
472{ 468{
473 /* 469 /*
474 * Shut off the timer. 470 * Shut off the timer.
@@ -476,7 +472,8 @@ static int iTCO_wdt_release (struct inode *inode, struct file *file)
476 if (expect_release == 42) { 472 if (expect_release == 42) {
477 iTCO_wdt_stop(); 473 iTCO_wdt_stop();
478 } else { 474 } else {
479 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); 475 printk(KERN_CRIT PFX
476 "Unexpected close, not stopping watchdog!\n");
480 iTCO_wdt_keepalive(); 477 iTCO_wdt_keepalive();
481 } 478 }
482 clear_bit(0, &is_active); 479 clear_bit(0, &is_active);
@@ -484,22 +481,23 @@ static int iTCO_wdt_release (struct inode *inode, struct file *file)
484 return 0; 481 return 0;
485} 482}
486 483
487static ssize_t iTCO_wdt_write (struct file *file, const char __user *data, 484static ssize_t iTCO_wdt_write(struct file *file, const char __user *data,
488 size_t len, loff_t * ppos) 485 size_t len, loff_t *ppos)
489{ 486{
490 /* See if we got the magic character 'V' and reload the timer */ 487 /* See if we got the magic character 'V' and reload the timer */
491 if (len) { 488 if (len) {
492 if (!nowayout) { 489 if (!nowayout) {
493 size_t i; 490 size_t i;
494 491
495 /* note: just in case someone wrote the magic character 492 /* note: just in case someone wrote the magic
496 * five months ago... */ 493 character five months ago... */
497 expect_release = 0; 494 expect_release = 0;
498 495
499 /* scan to see whether or not we got the magic character */ 496 /* scan to see whether or not we got the
497 magic character */
500 for (i = 0; i != len; i++) { 498 for (i = 0; i != len; i++) {
501 char c; 499 char c;
502 if (get_user(c, data+i)) 500 if (get_user(c, data + i))
503 return -EFAULT; 501 return -EFAULT;
504 if (c == 'V') 502 if (c == 'V')
505 expect_release = 42; 503 expect_release = 42;
@@ -512,8 +510,8 @@ static ssize_t iTCO_wdt_write (struct file *file, const char __user *data,
512 return len; 510 return len;
513} 511}
514 512
515static int iTCO_wdt_ioctl (struct inode *inode, struct file *file, 513static long iTCO_wdt_ioctl(struct file *file, unsigned int cmd,
516 unsigned int cmd, unsigned long arg) 514 unsigned long arg)
517{ 515{
518 int new_options, retval = -EINVAL; 516 int new_options, retval = -EINVAL;
519 int new_heartbeat; 517 int new_heartbeat;
@@ -528,64 +526,52 @@ static int iTCO_wdt_ioctl (struct inode *inode, struct file *file,
528 }; 526 };
529 527
530 switch (cmd) { 528 switch (cmd) {
531 case WDIOC_GETSUPPORT: 529 case WDIOC_GETSUPPORT:
532 return copy_to_user(argp, &ident, 530 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
533 sizeof (ident)) ? -EFAULT : 0; 531 case WDIOC_GETSTATUS:
534 532 case WDIOC_GETBOOTSTATUS:
535 case WDIOC_GETSTATUS: 533 return put_user(0, p);
536 case WDIOC_GETBOOTSTATUS: 534
537 return put_user(0, p); 535 case WDIOC_SETOPTIONS:
538 536 {
539 case WDIOC_KEEPALIVE: 537 if (get_user(new_options, p))
540 iTCO_wdt_keepalive(); 538 return -EFAULT;
541 return 0; 539
542 540 if (new_options & WDIOS_DISABLECARD) {
543 case WDIOC_SETOPTIONS: 541 iTCO_wdt_stop();
544 { 542 retval = 0;
545 if (get_user(new_options, p))
546 return -EFAULT;
547
548 if (new_options & WDIOS_DISABLECARD) {
549 iTCO_wdt_stop();
550 retval = 0;
551 }
552
553 if (new_options & WDIOS_ENABLECARD) {
554 iTCO_wdt_keepalive();
555 iTCO_wdt_start();
556 retval = 0;
557 }
558
559 return retval;
560 } 543 }
561 544 if (new_options & WDIOS_ENABLECARD) {
562 case WDIOC_SETTIMEOUT:
563 {
564 if (get_user(new_heartbeat, p))
565 return -EFAULT;
566
567 if (iTCO_wdt_set_heartbeat(new_heartbeat))
568 return -EINVAL;
569
570 iTCO_wdt_keepalive(); 545 iTCO_wdt_keepalive();
571 /* Fall */ 546 iTCO_wdt_start();
572 } 547 retval = 0;
573
574 case WDIOC_GETTIMEOUT:
575 return put_user(heartbeat, p);
576
577 case WDIOC_GETTIMELEFT:
578 {
579 int time_left;
580
581 if (iTCO_wdt_get_timeleft(&time_left))
582 return -EINVAL;
583
584 return put_user(time_left, p);
585 } 548 }
549 return retval;
550 }
551 case WDIOC_KEEPALIVE:
552 iTCO_wdt_keepalive();
553 return 0;
586 554
587 default: 555 case WDIOC_SETTIMEOUT:
588 return -ENOTTY; 556 {
557 if (get_user(new_heartbeat, p))
558 return -EFAULT;
559 if (iTCO_wdt_set_heartbeat(new_heartbeat))
560 return -EINVAL;
561 iTCO_wdt_keepalive();
562 /* Fall */
563 }
564 case WDIOC_GETTIMEOUT:
565 return put_user(heartbeat, p);
566 case WDIOC_GETTIMELEFT:
567 {
568 int time_left;
569 if (iTCO_wdt_get_timeleft(&time_left))
570 return -EINVAL;
571 return put_user(time_left, p);
572 }
573 default:
574 return -ENOTTY;
589 } 575 }
590} 576}
591 577
@@ -594,12 +580,12 @@ static int iTCO_wdt_ioctl (struct inode *inode, struct file *file,
594 */ 580 */
595 581
596static const struct file_operations iTCO_wdt_fops = { 582static const struct file_operations iTCO_wdt_fops = {
597 .owner = THIS_MODULE, 583 .owner = THIS_MODULE,
598 .llseek = no_llseek, 584 .llseek = no_llseek,
599 .write = iTCO_wdt_write, 585 .write = iTCO_wdt_write,
600 .ioctl = iTCO_wdt_ioctl, 586 .unlocked_ioctl = iTCO_wdt_ioctl,
601 .open = iTCO_wdt_open, 587 .open = iTCO_wdt_open,
602 .release = iTCO_wdt_release, 588 .release = iTCO_wdt_release,
603}; 589};
604 590
605static struct miscdevice iTCO_wdt_miscdev = { 591static struct miscdevice iTCO_wdt_miscdev = {
@@ -612,7 +598,8 @@ static struct miscdevice iTCO_wdt_miscdev = {
612 * Init & exit routines 598 * Init & exit routines
613 */ 599 */
614 600
615static int __devinit iTCO_wdt_init(struct pci_dev *pdev, const struct pci_device_id *ent, struct platform_device *dev) 601static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
602 const struct pci_device_id *ent, struct platform_device *dev)
616{ 603{
617 int ret; 604 int ret;
618 u32 base_address; 605 u32 base_address;
@@ -632,17 +619,19 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, const struct pci_device
632 pci_dev_put(pdev); 619 pci_dev_put(pdev);
633 return -ENODEV; 620 return -ENODEV;
634 } 621 }
635 iTCO_wdt_private.iTCO_version = iTCO_chipset_info[ent->driver_data].iTCO_version; 622 iTCO_wdt_private.iTCO_version =
623 iTCO_chipset_info[ent->driver_data].iTCO_version;
636 iTCO_wdt_private.ACPIBASE = base_address; 624 iTCO_wdt_private.ACPIBASE = base_address;
637 iTCO_wdt_private.pdev = pdev; 625 iTCO_wdt_private.pdev = pdev;
638 626
639 /* Get the Memory-Mapped GCS register, we need it for the NO_REBOOT flag (TCO v2) */ 627 /* Get the Memory-Mapped GCS register, we need it for the
640 /* To get access to it you have to read RCBA from PCI Config space 0xf0 628 NO_REBOOT flag (TCO v2). To get access to it you have to
641 and use it as base. GCS = RCBA + ICH6_GCS(0x3410). */ 629 read RCBA from PCI Config space 0xf0 and use it as base.
630 GCS = RCBA + ICH6_GCS(0x3410). */
642 if (iTCO_wdt_private.iTCO_version == 2) { 631 if (iTCO_wdt_private.iTCO_version == 2) {
643 pci_read_config_dword(pdev, 0xf0, &base_address); 632 pci_read_config_dword(pdev, 0xf0, &base_address);
644 RCBA = base_address & 0xffffc000; 633 RCBA = base_address & 0xffffc000;
645 iTCO_wdt_private.gcs = ioremap((RCBA + 0x3410),4); 634 iTCO_wdt_private.gcs = ioremap((RCBA + 0x3410), 4);
646 } 635 }
647 636
648 /* Check chipset's NO_REBOOT bit */ 637 /* Check chipset's NO_REBOOT bit */
@@ -657,8 +646,8 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, const struct pci_device
657 646
658 /* Set the TCO_EN bit in SMI_EN register */ 647 /* Set the TCO_EN bit in SMI_EN register */
659 if (!request_region(SMI_EN, 4, "iTCO_wdt")) { 648 if (!request_region(SMI_EN, 4, "iTCO_wdt")) {
660 printk(KERN_ERR PFX "I/O address 0x%04lx already in use\n", 649 printk(KERN_ERR PFX
661 SMI_EN ); 650 "I/O address 0x%04lx already in use\n", SMI_EN);
662 ret = -EIO; 651 ret = -EIO;
663 goto out; 652 goto out;
664 } 653 }
@@ -667,18 +656,20 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, const struct pci_device
667 outl(val32, SMI_EN); 656 outl(val32, SMI_EN);
668 release_region(SMI_EN, 4); 657 release_region(SMI_EN, 4);
669 658
670 /* The TCO I/O registers reside in a 32-byte range pointed to by the TCOBASE value */ 659 /* The TCO I/O registers reside in a 32-byte range pointed to
671 if (!request_region (TCOBASE, 0x20, "iTCO_wdt")) { 660 by the TCOBASE value */
672 printk (KERN_ERR PFX "I/O address 0x%04lx already in use\n", 661 if (!request_region(TCOBASE, 0x20, "iTCO_wdt")) {
662 printk(KERN_ERR PFX "I/O address 0x%04lx already in use\n",
673 TCOBASE); 663 TCOBASE);
674 ret = -EIO; 664 ret = -EIO;
675 goto out; 665 goto out;
676 } 666 }
677 667
678 printk(KERN_INFO PFX "Found a %s TCO device (Version=%d, TCOBASE=0x%04lx)\n", 668 printk(KERN_INFO PFX
679 iTCO_chipset_info[ent->driver_data].name, 669 "Found a %s TCO device (Version=%d, TCOBASE=0x%04lx)\n",
680 iTCO_chipset_info[ent->driver_data].iTCO_version, 670 iTCO_chipset_info[ent->driver_data].name,
681 TCOBASE); 671 iTCO_chipset_info[ent->driver_data].iTCO_version,
672 TCOBASE);
682 673
683 /* Clear out the (probably old) status */ 674 /* Clear out the (probably old) status */
684 outb(0, TCO1_STS); 675 outb(0, TCO1_STS);
@@ -687,27 +678,29 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, const struct pci_device
687 /* Make sure the watchdog is not running */ 678 /* Make sure the watchdog is not running */
688 iTCO_wdt_stop(); 679 iTCO_wdt_stop();
689 680
690 /* Check that the heartbeat value is within it's range ; if not reset to the default */ 681 /* Check that the heartbeat value is within it's range;
682 if not reset to the default */
691 if (iTCO_wdt_set_heartbeat(heartbeat)) { 683 if (iTCO_wdt_set_heartbeat(heartbeat)) {
692 iTCO_wdt_set_heartbeat(WATCHDOG_HEARTBEAT); 684 iTCO_wdt_set_heartbeat(WATCHDOG_HEARTBEAT);
693 printk(KERN_INFO PFX "heartbeat value must be 2<heartbeat<39 (TCO v1) or 613 (TCO v2), using %d\n", 685 printk(KERN_INFO PFX "heartbeat value must be 2 < heartbeat < 39 (TCO v1) or 613 (TCO v2), using %d\n",
694 heartbeat); 686 heartbeat);
695 } 687 }
696 688
697 ret = misc_register(&iTCO_wdt_miscdev); 689 ret = misc_register(&iTCO_wdt_miscdev);
698 if (ret != 0) { 690 if (ret != 0) {
699 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 691 printk(KERN_ERR PFX
700 WATCHDOG_MINOR, ret); 692 "cannot register miscdev on minor=%d (err=%d)\n",
693 WATCHDOG_MINOR, ret);
701 goto unreg_region; 694 goto unreg_region;
702 } 695 }
703 696
704 printk (KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n", 697 printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n",
705 heartbeat, nowayout); 698 heartbeat, nowayout);
706 699
707 return 0; 700 return 0;
708 701
709unreg_region: 702unreg_region:
710 release_region (TCOBASE, 0x20); 703 release_region(TCOBASE, 0x20);
711out: 704out:
712 if (iTCO_wdt_private.iTCO_version == 2) 705 if (iTCO_wdt_private.iTCO_version == 2)
713 iounmap(iTCO_wdt_private.gcs); 706 iounmap(iTCO_wdt_private.gcs);
@@ -796,7 +789,8 @@ static int __init iTCO_wdt_init_module(void)
796 if (err) 789 if (err)
797 return err; 790 return err;
798 791
799 iTCO_wdt_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0); 792 iTCO_wdt_platform_device = platform_device_register_simple(DRV_NAME,
793 -1, NULL, 0);
800 if (IS_ERR(iTCO_wdt_platform_device)) { 794 if (IS_ERR(iTCO_wdt_platform_device)) {
801 err = PTR_ERR(iTCO_wdt_platform_device); 795 err = PTR_ERR(iTCO_wdt_platform_device);
802 goto unreg_platform_driver; 796 goto unreg_platform_driver;
diff --git a/drivers/watchdog/ib700wdt.c b/drivers/watchdog/ib700wdt.c
index 4b89f401691a..05a28106e8eb 100644
--- a/drivers/watchdog/ib700wdt.c
+++ b/drivers/watchdog/ib700wdt.c
@@ -41,9 +41,9 @@
41#include <linux/spinlock.h> 41#include <linux/spinlock.h>
42#include <linux/moduleparam.h> 42#include <linux/moduleparam.h>
43#include <linux/platform_device.h> 43#include <linux/platform_device.h>
44#include <linux/io.h>
45#include <linux/uaccess.h>
44 46
45#include <asm/io.h>
46#include <asm/uaccess.h>
47#include <asm/system.h> 47#include <asm/system.h>
48 48
49static struct platform_device *ibwdt_platform_device; 49static struct platform_device *ibwdt_platform_device;
@@ -120,15 +120,16 @@ static int wd_margin = WD_TIMO;
120 120
121static int nowayout = WATCHDOG_NOWAYOUT; 121static int nowayout = WATCHDOG_NOWAYOUT;
122module_param(nowayout, int, 0); 122module_param(nowayout, int, 0);
123MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 123MODULE_PARM_DESC(nowayout,
124 "Watchdog cannot be stopped once started (default="
125 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
124 126
125 127
126/* 128/*
127 * Watchdog Operations 129 * Watchdog Operations
128 */ 130 */
129 131
130static void 132static void ibwdt_ping(void)
131ibwdt_ping(void)
132{ 133{
133 spin_lock(&ibwdt_lock); 134 spin_lock(&ibwdt_lock);
134 135
@@ -138,16 +139,14 @@ ibwdt_ping(void)
138 spin_unlock(&ibwdt_lock); 139 spin_unlock(&ibwdt_lock);
139} 140}
140 141
141static void 142static void ibwdt_disable(void)
142ibwdt_disable(void)
143{ 143{
144 spin_lock(&ibwdt_lock); 144 spin_lock(&ibwdt_lock);
145 outb_p(0, WDT_STOP); 145 outb_p(0, WDT_STOP);
146 spin_unlock(&ibwdt_lock); 146 spin_unlock(&ibwdt_lock);
147} 147}
148 148
149static int 149static int ibwdt_set_heartbeat(int t)
150ibwdt_set_heartbeat(int t)
151{ 150{
152 int i; 151 int i;
153 152
@@ -165,8 +164,8 @@ ibwdt_set_heartbeat(int t)
165 * /dev/watchdog handling 164 * /dev/watchdog handling
166 */ 165 */
167 166
168static ssize_t 167static ssize_t ibwdt_write(struct file *file, const char __user *buf,
169ibwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) 168 size_t count, loff_t *ppos)
170{ 169{
171 if (count) { 170 if (count) {
172 if (!nowayout) { 171 if (!nowayout) {
@@ -188,77 +187,71 @@ ibwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppo
188 return count; 187 return count;
189} 188}
190 189
191static int 190static long ibwdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
192ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
193 unsigned long arg)
194{ 191{
195 int new_margin; 192 int new_margin;
196 void __user *argp = (void __user *)arg; 193 void __user *argp = (void __user *)arg;
197 int __user *p = argp; 194 int __user *p = argp;
198 195
199 static struct watchdog_info ident = { 196 static struct watchdog_info ident = {
200 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, 197 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT
198 | WDIOF_MAGICCLOSE,
201 .firmware_version = 1, 199 .firmware_version = 1,
202 .identity = "IB700 WDT", 200 .identity = "IB700 WDT",
203 }; 201 };
204 202
205 switch (cmd) { 203 switch (cmd) {
206 case WDIOC_GETSUPPORT: 204 case WDIOC_GETSUPPORT:
207 if (copy_to_user(argp, &ident, sizeof(ident))) 205 if (copy_to_user(argp, &ident, sizeof(ident)))
208 return -EFAULT; 206 return -EFAULT;
209 break; 207 break;
210 208
211 case WDIOC_GETSTATUS: 209 case WDIOC_GETSTATUS:
212 case WDIOC_GETBOOTSTATUS: 210 case WDIOC_GETBOOTSTATUS:
213 return put_user(0, p); 211 return put_user(0, p);
214
215 case WDIOC_KEEPALIVE:
216 ibwdt_ping();
217 break;
218
219 case WDIOC_SETTIMEOUT:
220 if (get_user(new_margin, p))
221 return -EFAULT;
222 if (ibwdt_set_heartbeat(new_margin))
223 return -EINVAL;
224 ibwdt_ping();
225 /* Fall */
226
227 case WDIOC_GETTIMEOUT:
228 return put_user(wd_times[wd_margin], p);
229 212
230 case WDIOC_SETOPTIONS: 213 case WDIOC_SETOPTIONS:
231 { 214 {
232 int options, retval = -EINVAL; 215 int options, retval = -EINVAL;
233 216
234 if (get_user(options, p)) 217 if (get_user(options, p))
235 return -EFAULT; 218 return -EFAULT;
236 219
237 if (options & WDIOS_DISABLECARD) { 220 if (options & WDIOS_DISABLECARD) {
238 ibwdt_disable(); 221 ibwdt_disable();
239 retval = 0; 222 retval = 0;
240 } 223 }
224 if (options & WDIOS_ENABLECARD) {
225 ibwdt_ping();
226 retval = 0;
227 }
228 return retval;
229 }
230 case WDIOC_KEEPALIVE:
231 ibwdt_ping();
232 break;
241 233
242 if (options & WDIOS_ENABLECARD) { 234 case WDIOC_SETTIMEOUT:
243 ibwdt_ping(); 235 if (get_user(new_margin, p))
244 retval = 0; 236 return -EFAULT;
245 } 237 if (ibwdt_set_heartbeat(new_margin))
238 return -EINVAL;
239 ibwdt_ping();
240 /* Fall */
246 241
247 return retval; 242 case WDIOC_GETTIMEOUT:
248 } 243 return put_user(wd_times[wd_margin], p);
249 244
250 default: 245 default:
251 return -ENOTTY; 246 return -ENOTTY;
252 } 247 }
253 return 0; 248 return 0;
254} 249}
255 250
256static int 251static int ibwdt_open(struct inode *inode, struct file *file)
257ibwdt_open(struct inode *inode, struct file *file)
258{ 252{
259 if (test_and_set_bit(0, &ibwdt_is_open)) { 253 if (test_and_set_bit(0, &ibwdt_is_open))
260 return -EBUSY; 254 return -EBUSY;
261 }
262 if (nowayout) 255 if (nowayout)
263 __module_get(THIS_MODULE); 256 __module_get(THIS_MODULE);
264 257
@@ -267,13 +260,13 @@ ibwdt_open(struct inode *inode, struct file *file)
267 return nonseekable_open(inode, file); 260 return nonseekable_open(inode, file);
268} 261}
269 262
270static int 263static int ibwdt_close(struct inode *inode, struct file *file)
271ibwdt_close(struct inode *inode, struct file *file)
272{ 264{
273 if (expect_close == 42) { 265 if (expect_close == 42) {
274 ibwdt_disable(); 266 ibwdt_disable();
275 } else { 267 } else {
276 printk(KERN_CRIT PFX "WDT device closed unexpectedly. WDT will not stop!\n"); 268 printk(KERN_CRIT PFX
269 "WDT device closed unexpectedly. WDT will not stop!\n");
277 ibwdt_ping(); 270 ibwdt_ping();
278 } 271 }
279 clear_bit(0, &ibwdt_is_open); 272 clear_bit(0, &ibwdt_is_open);
@@ -289,7 +282,7 @@ static const struct file_operations ibwdt_fops = {
289 .owner = THIS_MODULE, 282 .owner = THIS_MODULE,
290 .llseek = no_llseek, 283 .llseek = no_llseek,
291 .write = ibwdt_write, 284 .write = ibwdt_write,
292 .ioctl = ibwdt_ioctl, 285 .unlocked_ioctl = ibwdt_ioctl,
293 .open = ibwdt_open, 286 .open = ibwdt_open,
294 .release = ibwdt_close, 287 .release = ibwdt_close,
295}; 288};
@@ -310,21 +303,23 @@ static int __devinit ibwdt_probe(struct platform_device *dev)
310 303
311#if WDT_START != WDT_STOP 304#if WDT_START != WDT_STOP
312 if (!request_region(WDT_STOP, 1, "IB700 WDT")) { 305 if (!request_region(WDT_STOP, 1, "IB700 WDT")) {
313 printk (KERN_ERR PFX "STOP method I/O %X is not available.\n", WDT_STOP); 306 printk(KERN_ERR PFX "STOP method I/O %X is not available.\n",
307 WDT_STOP);
314 res = -EIO; 308 res = -EIO;
315 goto out_nostopreg; 309 goto out_nostopreg;
316 } 310 }
317#endif 311#endif
318 312
319 if (!request_region(WDT_START, 1, "IB700 WDT")) { 313 if (!request_region(WDT_START, 1, "IB700 WDT")) {
320 printk (KERN_ERR PFX "START method I/O %X is not available.\n", WDT_START); 314 printk(KERN_ERR PFX "START method I/O %X is not available.\n",
315 WDT_START);
321 res = -EIO; 316 res = -EIO;
322 goto out_nostartreg; 317 goto out_nostartreg;
323 } 318 }
324 319
325 res = misc_register(&ibwdt_miscdev); 320 res = misc_register(&ibwdt_miscdev);
326 if (res) { 321 if (res) {
327 printk (KERN_ERR PFX "failed to register misc device\n"); 322 printk(KERN_ERR PFX "failed to register misc device\n");
328 goto out_nomisc; 323 goto out_nomisc;
329 } 324 }
330 return 0; 325 return 0;
@@ -342,9 +337,9 @@ out_nostopreg:
342static int __devexit ibwdt_remove(struct platform_device *dev) 337static int __devexit ibwdt_remove(struct platform_device *dev)
343{ 338{
344 misc_deregister(&ibwdt_miscdev); 339 misc_deregister(&ibwdt_miscdev);
345 release_region(WDT_START,1); 340 release_region(WDT_START, 1);
346#if WDT_START != WDT_STOP 341#if WDT_START != WDT_STOP
347 release_region(WDT_STOP,1); 342 release_region(WDT_STOP, 1);
348#endif 343#endif
349 return 0; 344 return 0;
350} 345}
@@ -369,13 +364,15 @@ static int __init ibwdt_init(void)
369{ 364{
370 int err; 365 int err;
371 366
372 printk(KERN_INFO PFX "WDT driver for IB700 single board computer initialising.\n"); 367 printk(KERN_INFO PFX
368 "WDT driver for IB700 single board computer initialising.\n");
373 369
374 err = platform_driver_register(&ibwdt_driver); 370 err = platform_driver_register(&ibwdt_driver);
375 if (err) 371 if (err)
376 return err; 372 return err;
377 373
378 ibwdt_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0); 374 ibwdt_platform_device = platform_device_register_simple(DRV_NAME,
375 -1, NULL, 0);
379 if (IS_ERR(ibwdt_platform_device)) { 376 if (IS_ERR(ibwdt_platform_device)) {
380 err = PTR_ERR(ibwdt_platform_device); 377 err = PTR_ERR(ibwdt_platform_device);
381 goto unreg_platform_driver; 378 goto unreg_platform_driver;
diff --git a/drivers/watchdog/ibmasr.c b/drivers/watchdog/ibmasr.c
index 94155f6136c2..b82405cfb4cd 100644
--- a/drivers/watchdog/ibmasr.c
+++ b/drivers/watchdog/ibmasr.c
@@ -19,9 +19,8 @@
19#include <linux/miscdevice.h> 19#include <linux/miscdevice.h>
20#include <linux/watchdog.h> 20#include <linux/watchdog.h>
21#include <linux/dmi.h> 21#include <linux/dmi.h>
22 22#include <linux/io.h>
23#include <asm/io.h> 23#include <linux/uaccess.h>
24#include <asm/uaccess.h>
25 24
26 25
27enum { 26enum {
@@ -70,10 +69,13 @@ static char asr_expect_close;
70static unsigned int asr_type, asr_base, asr_length; 69static unsigned int asr_type, asr_base, asr_length;
71static unsigned int asr_read_addr, asr_write_addr; 70static unsigned int asr_read_addr, asr_write_addr;
72static unsigned char asr_toggle_mask, asr_disable_mask; 71static unsigned char asr_toggle_mask, asr_disable_mask;
72static spinlock_t asr_lock;
73 73
74static void asr_toggle(void) 74static void __asr_toggle(void)
75{ 75{
76 unsigned char reg = inb(asr_read_addr); 76 unsigned char reg;
77
78 reg = inb(asr_read_addr);
77 79
78 outb(reg & ~asr_toggle_mask, asr_write_addr); 80 outb(reg & ~asr_toggle_mask, asr_write_addr);
79 reg = inb(asr_read_addr); 81 reg = inb(asr_read_addr);
@@ -83,12 +85,21 @@ static void asr_toggle(void)
83 85
84 outb(reg & ~asr_toggle_mask, asr_write_addr); 86 outb(reg & ~asr_toggle_mask, asr_write_addr);
85 reg = inb(asr_read_addr); 87 reg = inb(asr_read_addr);
88 spin_unlock(&asr_lock);
89}
90
91static void asr_toggle(void)
92{
93 spin_lock(&asr_lock);
94 __asr_toggle();
95 spin_unlock(&asr_lock);
86} 96}
87 97
88static void asr_enable(void) 98static void asr_enable(void)
89{ 99{
90 unsigned char reg; 100 unsigned char reg;
91 101
102 spin_lock(&asr_lock);
92 if (asr_type == ASMTYPE_TOPAZ) { 103 if (asr_type == ASMTYPE_TOPAZ) {
93 /* asr_write_addr == asr_read_addr */ 104 /* asr_write_addr == asr_read_addr */
94 reg = inb(asr_read_addr); 105 reg = inb(asr_read_addr);
@@ -99,17 +110,21 @@ static void asr_enable(void)
99 * First make sure the hardware timer is reset by toggling 110 * First make sure the hardware timer is reset by toggling
100 * ASR hardware timer line. 111 * ASR hardware timer line.
101 */ 112 */
102 asr_toggle(); 113 __asr_toggle();
103 114
104 reg = inb(asr_read_addr); 115 reg = inb(asr_read_addr);
105 outb(reg & ~asr_disable_mask, asr_write_addr); 116 outb(reg & ~asr_disable_mask, asr_write_addr);
106 } 117 }
107 reg = inb(asr_read_addr); 118 reg = inb(asr_read_addr);
119 spin_unlock(&asr_lock);
108} 120}
109 121
110static void asr_disable(void) 122static void asr_disable(void)
111{ 123{
112 unsigned char reg = inb(asr_read_addr); 124 unsigned char reg;
125
126 spin_lock(&asr_lock);
127 reg = inb(asr_read_addr);
113 128
114 if (asr_type == ASMTYPE_TOPAZ) 129 if (asr_type == ASMTYPE_TOPAZ)
115 /* asr_write_addr == asr_read_addr */ 130 /* asr_write_addr == asr_read_addr */
@@ -122,6 +137,7 @@ static void asr_disable(void)
122 outb(reg | asr_disable_mask, asr_write_addr); 137 outb(reg | asr_disable_mask, asr_write_addr);
123 } 138 }
124 reg = inb(asr_read_addr); 139 reg = inb(asr_read_addr);
140 spin_unlock(&asr_lock);
125} 141}
126 142
127static int __init asr_get_base_address(void) 143static int __init asr_get_base_address(void)
@@ -133,7 +149,8 @@ static int __init asr_get_base_address(void)
133 149
134 switch (asr_type) { 150 switch (asr_type) {
135 case ASMTYPE_TOPAZ: 151 case ASMTYPE_TOPAZ:
136 /* SELECT SuperIO CHIP FOR QUERYING (WRITE 0x07 TO BOTH 0x2E and 0x2F) */ 152 /* SELECT SuperIO CHIP FOR QUERYING
153 (WRITE 0x07 TO BOTH 0x2E and 0x2F) */
137 outb(0x07, 0x2e); 154 outb(0x07, 0x2e);
138 outb(0x07, 0x2f); 155 outb(0x07, 0x2f);
139 156
@@ -154,14 +171,26 @@ static int __init asr_get_base_address(void)
154 171
155 case ASMTYPE_JASPER: 172 case ASMTYPE_JASPER:
156 type = "Jaspers "; 173 type = "Jaspers ";
157 174#if 0
158 /* FIXME: need to use pci_config_lock here, but it's not exported */ 175 u32 r;
176 /* Suggested fix */
177 pdev = pci_get_bus_and_slot(0, DEVFN(0x1f, 0));
178 if (pdev == NULL)
179 return -ENODEV;
180 pci_read_config_dword(pdev, 0x58, &r);
181 asr_base = r & 0xFFFE;
182 pci_dev_put(pdev);
183#else
184 /* FIXME: need to use pci_config_lock here,
185 but it's not exported */
159 186
160/* spin_lock_irqsave(&pci_config_lock, flags);*/ 187/* spin_lock_irqsave(&pci_config_lock, flags);*/
161 188
162 /* Select the SuperIO chip in the PCI I/O port register */ 189 /* Select the SuperIO chip in the PCI I/O port register */
163 outl(0x8000f858, 0xcf8); 190 outl(0x8000f858, 0xcf8);
164 191
192 /* BUS 0, Slot 1F, fnc 0, offset 58 */
193
165 /* 194 /*
166 * Read the base address for the SuperIO chip. 195 * Read the base address for the SuperIO chip.
167 * Only the lower 16 bits are valid, but the address is word 196 * Only the lower 16 bits are valid, but the address is word
@@ -170,7 +199,7 @@ static int __init asr_get_base_address(void)
170 asr_base = inl(0xcfc) & 0xfffe; 199 asr_base = inl(0xcfc) & 0xfffe;
171 200
172/* spin_unlock_irqrestore(&pci_config_lock, flags);*/ 201/* spin_unlock_irqrestore(&pci_config_lock, flags);*/
173 202#endif
174 asr_read_addr = asr_write_addr = 203 asr_read_addr = asr_write_addr =
175 asr_base + JASPER_ASR_REG_OFFSET; 204 asr_base + JASPER_ASR_REG_OFFSET;
176 asr_toggle_mask = JASPER_ASR_TOGGLE_MASK; 205 asr_toggle_mask = JASPER_ASR_TOGGLE_MASK;
@@ -241,66 +270,57 @@ static ssize_t asr_write(struct file *file, const char __user *buf,
241 return count; 270 return count;
242} 271}
243 272
244static int asr_ioctl(struct inode *inode, struct file *file, 273static long asr_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
245 unsigned int cmd, unsigned long arg)
246{ 274{
247 static const struct watchdog_info ident = { 275 static const struct watchdog_info ident = {
248 .options = WDIOF_KEEPALIVEPING | 276 .options = WDIOF_KEEPALIVEPING |
249 WDIOF_MAGICCLOSE, 277 WDIOF_MAGICCLOSE,
250 .identity = "IBM ASR" 278 .identity = "IBM ASR",
251 }; 279 };
252 void __user *argp = (void __user *)arg; 280 void __user *argp = (void __user *)arg;
253 int __user *p = argp; 281 int __user *p = argp;
254 int heartbeat; 282 int heartbeat;
255 283
256 switch (cmd) { 284 switch (cmd) {
257 case WDIOC_GETSUPPORT: 285 case WDIOC_GETSUPPORT:
258 return copy_to_user(argp, &ident, sizeof(ident)) ? 286 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
259 -EFAULT : 0; 287 case WDIOC_GETSTATUS:
260 288 case WDIOC_GETBOOTSTATUS:
261 case WDIOC_GETSTATUS: 289 return put_user(0, p);
262 case WDIOC_GETBOOTSTATUS: 290 case WDIOC_SETOPTIONS:
263 return put_user(0, p); 291 {
264 292 int new_options, retval = -EINVAL;
265 case WDIOC_KEEPALIVE: 293 if (get_user(new_options, p))
294 return -EFAULT;
295 if (new_options & WDIOS_DISABLECARD) {
296 asr_disable();
297 retval = 0;
298 }
299 if (new_options & WDIOS_ENABLECARD) {
300 asr_enable();
266 asr_toggle(); 301 asr_toggle();
267 return 0; 302 retval = 0;
268
269 /*
270 * The hardware has a fixed timeout value, so no WDIOC_SETTIMEOUT
271 * and WDIOC_GETTIMEOUT always returns 256.
272 */
273 case WDIOC_GETTIMEOUT:
274 heartbeat = 256;
275 return put_user(heartbeat, p);
276
277 case WDIOC_SETOPTIONS: {
278 int new_options, retval = -EINVAL;
279
280 if (get_user(new_options, p))
281 return -EFAULT;
282
283 if (new_options & WDIOS_DISABLECARD) {
284 asr_disable();
285 retval = 0;
286 }
287
288 if (new_options & WDIOS_ENABLECARD) {
289 asr_enable();
290 asr_toggle();
291 retval = 0;
292 }
293
294 return retval;
295 } 303 }
304 return retval;
305 }
306 case WDIOC_KEEPALIVE:
307 asr_toggle();
308 return 0;
309 /*
310 * The hardware has a fixed timeout value, so no WDIOC_SETTIMEOUT
311 * and WDIOC_GETTIMEOUT always returns 256.
312 */
313 case WDIOC_GETTIMEOUT:
314 heartbeat = 256;
315 return put_user(heartbeat, p);
316 default:
317 return -ENOTTY;
296 } 318 }
297
298 return -ENOTTY;
299} 319}
300 320
301static int asr_open(struct inode *inode, struct file *file) 321static int asr_open(struct inode *inode, struct file *file)
302{ 322{
303 if(test_and_set_bit(0, &asr_is_open)) 323 if (test_and_set_bit(0, &asr_is_open))
304 return -EBUSY; 324 return -EBUSY;
305 325
306 asr_toggle(); 326 asr_toggle();
@@ -314,7 +334,8 @@ static int asr_release(struct inode *inode, struct file *file)
314 if (asr_expect_close == 42) 334 if (asr_expect_close == 42)
315 asr_disable(); 335 asr_disable();
316 else { 336 else {
317 printk(KERN_CRIT PFX "unexpected close, not stopping watchdog!\n"); 337 printk(KERN_CRIT PFX
338 "unexpected close, not stopping watchdog!\n");
318 asr_toggle(); 339 asr_toggle();
319 } 340 }
320 clear_bit(0, &asr_is_open); 341 clear_bit(0, &asr_is_open);
@@ -323,12 +344,12 @@ static int asr_release(struct inode *inode, struct file *file)
323} 344}
324 345
325static const struct file_operations asr_fops = { 346static const struct file_operations asr_fops = {
326 .owner = THIS_MODULE, 347 .owner = THIS_MODULE,
327 .llseek = no_llseek, 348 .llseek = no_llseek,
328 .write = asr_write, 349 .write = asr_write,
329 .ioctl = asr_ioctl, 350 .unlocked_ioctl = asr_ioctl,
330 .open = asr_open, 351 .open = asr_open,
331 .release = asr_release, 352 .release = asr_release,
332}; 353};
333 354
334static struct miscdevice asr_miscdev = { 355static struct miscdevice asr_miscdev = {
@@ -367,6 +388,8 @@ static int __init ibmasr_init(void)
367 if (!asr_type) 388 if (!asr_type)
368 return -ENODEV; 389 return -ENODEV;
369 390
391 spin_lock_init(&asr_lock);
392
370 rc = asr_get_base_address(); 393 rc = asr_get_base_address();
371 if (rc) 394 if (rc)
372 return rc; 395 return rc;
@@ -395,7 +418,9 @@ module_init(ibmasr_init);
395module_exit(ibmasr_exit); 418module_exit(ibmasr_exit);
396 419
397module_param(nowayout, int, 0); 420module_param(nowayout, int, 0);
398MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 421MODULE_PARM_DESC(nowayout,
422 "Watchdog cannot be stopped once started (default="
423 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
399 424
400MODULE_DESCRIPTION("IBM Automatic Server Restart driver"); 425MODULE_DESCRIPTION("IBM Automatic Server Restart driver");
401MODULE_AUTHOR("Andrey Panin"); 426MODULE_AUTHOR("Andrey Panin");
diff --git a/drivers/watchdog/indydog.c b/drivers/watchdog/indydog.c
index 788245bdaa7f..73c9e7992feb 100644
--- a/drivers/watchdog/indydog.c
+++ b/drivers/watchdog/indydog.c
@@ -1,7 +1,8 @@
1/* 1/*
2 * IndyDog 0.3 A Hardware Watchdog Device for SGI IP22 2 * IndyDog 0.3 A Hardware Watchdog Device for SGI IP22
3 * 3 *
4 * (c) Copyright 2002 Guido Guenther <agx@sigxcpu.org>, All Rights Reserved. 4 * (c) Copyright 2002 Guido Guenther <agx@sigxcpu.org>,
5 * All Rights Reserved.
5 * 6 *
6 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License 8 * modify it under the terms of the GNU General Public License
@@ -22,32 +23,42 @@
22#include <linux/notifier.h> 23#include <linux/notifier.h>
23#include <linux/reboot.h> 24#include <linux/reboot.h>
24#include <linux/init.h> 25#include <linux/init.h>
25#include <asm/uaccess.h> 26#include <linux/uaccess.h>
26#include <asm/sgi/mc.h> 27#include <asm/sgi/mc.h>
27 28
28#define PFX "indydog: " 29#define PFX "indydog: "
29static int indydog_alive; 30static unsigned long indydog_alive;
31static spinlock_t indydog_lock;
30 32
31#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ 33#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */
32 34
33static int nowayout = WATCHDOG_NOWAYOUT; 35static int nowayout = WATCHDOG_NOWAYOUT;
34module_param(nowayout, int, 0); 36module_param(nowayout, int, 0);
35MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 37MODULE_PARM_DESC(nowayout,
38 "Watchdog cannot be stopped once started (default="
39 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
36 40
37static void indydog_start(void) 41static void indydog_start(void)
38{ 42{
39 u32 mc_ctrl0 = sgimc->cpuctrl0; 43 u32 mc_ctrl0;
40 44
45 spin_lock(&indydog_lock);
46 mc_ctrl0 = sgimc->cpuctrl0;
41 mc_ctrl0 = sgimc->cpuctrl0 | SGIMC_CCTRL0_WDOG; 47 mc_ctrl0 = sgimc->cpuctrl0 | SGIMC_CCTRL0_WDOG;
42 sgimc->cpuctrl0 = mc_ctrl0; 48 sgimc->cpuctrl0 = mc_ctrl0;
49 spin_unlock(&indydog_lock);
43} 50}
44 51
45static void indydog_stop(void) 52static void indydog_stop(void)
46{ 53{
47 u32 mc_ctrl0 = sgimc->cpuctrl0; 54 u32 mc_ctrl0;
48 55
56 spin_lock(&indydog_lock);
57
58 mc_ctrl0 = sgimc->cpuctrl0;
49 mc_ctrl0 &= ~SGIMC_CCTRL0_WDOG; 59 mc_ctrl0 &= ~SGIMC_CCTRL0_WDOG;
50 sgimc->cpuctrl0 = mc_ctrl0; 60 sgimc->cpuctrl0 = mc_ctrl0;
61 spin_unlock(&indydog_lock);
51 62
52 printk(KERN_INFO PFX "Stopped watchdog timer.\n"); 63 printk(KERN_INFO PFX "Stopped watchdog timer.\n");
53} 64}
@@ -62,7 +73,7 @@ static void indydog_ping(void)
62 */ 73 */
63static int indydog_open(struct inode *inode, struct file *file) 74static int indydog_open(struct inode *inode, struct file *file)
64{ 75{
65 if (indydog_alive) 76 if (test_and_set_bit(0, &indydog_alive))
66 return -EBUSY; 77 return -EBUSY;
67 78
68 if (nowayout) 79 if (nowayout)
@@ -84,23 +95,21 @@ static int indydog_release(struct inode *inode, struct file *file)
84 * Lock it in if it's a module and we defined ...NOWAYOUT */ 95 * Lock it in if it's a module and we defined ...NOWAYOUT */
85 if (!nowayout) 96 if (!nowayout)
86 indydog_stop(); /* Turn the WDT off */ 97 indydog_stop(); /* Turn the WDT off */
87 98 clear_bit(0, &indydog_alive);
88 indydog_alive = 0;
89
90 return 0; 99 return 0;
91} 100}
92 101
93static ssize_t indydog_write(struct file *file, const char *data, size_t len, loff_t *ppos) 102static ssize_t indydog_write(struct file *file, const char *data,
103 size_t len, loff_t *ppos)
94{ 104{
95 /* Refresh the timer. */ 105 /* Refresh the timer. */
96 if (len) { 106 if (len)
97 indydog_ping(); 107 indydog_ping();
98 }
99 return len; 108 return len;
100} 109}
101 110
102static int indydog_ioctl(struct inode *inode, struct file *file, 111static long indydog_ioctl(struct file *file, unsigned int cmd,
103 unsigned int cmd, unsigned long arg) 112 unsigned long arg)
104{ 113{
105 int options, retval = -EINVAL; 114 int options, retval = -EINVAL;
106 static struct watchdog_info ident = { 115 static struct watchdog_info ident = {
@@ -111,42 +120,40 @@ static int indydog_ioctl(struct inode *inode, struct file *file,
111 }; 120 };
112 121
113 switch (cmd) { 122 switch (cmd) {
114 default: 123 case WDIOC_GETSUPPORT:
115 return -ENOTTY; 124 if (copy_to_user((struct watchdog_info *)arg,
116 case WDIOC_GETSUPPORT: 125 &ident, sizeof(ident)))
117 if (copy_to_user((struct watchdog_info *)arg, 126 return -EFAULT;
118 &ident, sizeof(ident))) 127 return 0;
119 return -EFAULT; 128 case WDIOC_GETSTATUS:
120 return 0; 129 case WDIOC_GETBOOTSTATUS:
121 case WDIOC_GETSTATUS: 130 return put_user(0, (int *)arg);
122 case WDIOC_GETBOOTSTATUS: 131 case WDIOC_SETOPTIONS:
123 return put_user(0,(int *)arg); 132 {
124 case WDIOC_KEEPALIVE: 133 if (get_user(options, (int *)arg))
125 indydog_ping(); 134 return -EFAULT;
126 return 0; 135 if (options & WDIOS_DISABLECARD) {
127 case WDIOC_GETTIMEOUT: 136 indydog_stop();
128 return put_user(WATCHDOG_TIMEOUT,(int *)arg); 137 retval = 0;
129 case WDIOC_SETOPTIONS:
130 {
131 if (get_user(options, (int *)arg))
132 return -EFAULT;
133
134 if (options & WDIOS_DISABLECARD) {
135 indydog_stop();
136 retval = 0;
137 }
138
139 if (options & WDIOS_ENABLECARD) {
140 indydog_start();
141 retval = 0;
142 }
143
144 return retval;
145 } 138 }
139 if (options & WDIOS_ENABLECARD) {
140 indydog_start();
141 retval = 0;
142 }
143 return retval;
144 }
145 case WDIOC_KEEPALIVE:
146 indydog_ping();
147 return 0;
148 case WDIOC_GETTIMEOUT:
149 return put_user(WATCHDOG_TIMEOUT, (int *)arg);
150 default:
151 return -ENOTTY;
146 } 152 }
147} 153}
148 154
149static int indydog_notify_sys(struct notifier_block *this, unsigned long code, void *unused) 155static int indydog_notify_sys(struct notifier_block *this,
156 unsigned long code, void *unused)
150{ 157{
151 if (code == SYS_DOWN || code == SYS_HALT) 158 if (code == SYS_DOWN || code == SYS_HALT)
152 indydog_stop(); /* Turn the WDT off */ 159 indydog_stop(); /* Turn the WDT off */
@@ -158,7 +165,7 @@ static const struct file_operations indydog_fops = {
158 .owner = THIS_MODULE, 165 .owner = THIS_MODULE,
159 .llseek = no_llseek, 166 .llseek = no_llseek,
160 .write = indydog_write, 167 .write = indydog_write,
161 .ioctl = indydog_ioctl, 168 .unlocked_ioctl = indydog_ioctl,
162 .open = indydog_open, 169 .open = indydog_open,
163 .release = indydog_release, 170 .release = indydog_release,
164}; 171};
@@ -180,17 +187,20 @@ static int __init watchdog_init(void)
180{ 187{
181 int ret; 188 int ret;
182 189
190 spin_lock_init(&indydog_lock);
191
183 ret = register_reboot_notifier(&indydog_notifier); 192 ret = register_reboot_notifier(&indydog_notifier);
184 if (ret) { 193 if (ret) {
185 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 194 printk(KERN_ERR PFX
186 ret); 195 "cannot register reboot notifier (err=%d)\n", ret);
187 return ret; 196 return ret;
188 } 197 }
189 198
190 ret = misc_register(&indydog_miscdev); 199 ret = misc_register(&indydog_miscdev);
191 if (ret) { 200 if (ret) {
192 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 201 printk(KERN_ERR PFX
193 WATCHDOG_MINOR, ret); 202 "cannot register miscdev on minor=%d (err=%d)\n",
203 WATCHDOG_MINOR, ret);
194 unregister_reboot_notifier(&indydog_notifier); 204 unregister_reboot_notifier(&indydog_notifier);
195 return ret; 205 return ret;
196 } 206 }
diff --git a/drivers/watchdog/iop_wdt.c b/drivers/watchdog/iop_wdt.c
index 1946dd06d815..96eb2cbe5874 100644
--- a/drivers/watchdog/iop_wdt.c
+++ b/drivers/watchdog/iop_wdt.c
@@ -37,6 +37,7 @@
37static int nowayout = WATCHDOG_NOWAYOUT; 37static int nowayout = WATCHDOG_NOWAYOUT;
38static unsigned long wdt_status; 38static unsigned long wdt_status;
39static unsigned long boot_status; 39static unsigned long boot_status;
40static spinlock_t wdt_lock;
40 41
41#define WDT_IN_USE 0 42#define WDT_IN_USE 0
42#define WDT_OK_TO_CLOSE 1 43#define WDT_OK_TO_CLOSE 1
@@ -68,8 +69,10 @@ static void wdt_enable(void)
68 /* Arm and enable the Timer to starting counting down from 0xFFFF.FFFF 69 /* Arm and enable the Timer to starting counting down from 0xFFFF.FFFF
69 * Takes approx. 10.7s to timeout 70 * Takes approx. 10.7s to timeout
70 */ 71 */
72 spin_lock(&wdt_lock);
71 write_wdtcr(IOP_WDTCR_EN_ARM); 73 write_wdtcr(IOP_WDTCR_EN_ARM);
72 write_wdtcr(IOP_WDTCR_EN); 74 write_wdtcr(IOP_WDTCR_EN);
75 spin_unlock(&wdt_lock);
73} 76}
74 77
75/* returns 0 if the timer was successfully disabled */ 78/* returns 0 if the timer was successfully disabled */
@@ -77,9 +80,11 @@ static int wdt_disable(void)
77{ 80{
78 /* Stop Counting */ 81 /* Stop Counting */
79 if (wdt_supports_disable()) { 82 if (wdt_supports_disable()) {
83 spin_lock(&wdt_lock);
80 write_wdtcr(IOP_WDTCR_DIS_ARM); 84 write_wdtcr(IOP_WDTCR_DIS_ARM);
81 write_wdtcr(IOP_WDTCR_DIS); 85 write_wdtcr(IOP_WDTCR_DIS);
82 clear_bit(WDT_ENABLED, &wdt_status); 86 clear_bit(WDT_ENABLED, &wdt_status);
87 spin_unlock(&wdt_lock);
83 printk(KERN_INFO "WATCHDOG: Disabled\n"); 88 printk(KERN_INFO "WATCHDOG: Disabled\n");
84 return 0; 89 return 0;
85 } else 90 } else
@@ -92,16 +97,12 @@ static int iop_wdt_open(struct inode *inode, struct file *file)
92 return -EBUSY; 97 return -EBUSY;
93 98
94 clear_bit(WDT_OK_TO_CLOSE, &wdt_status); 99 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
95
96 wdt_enable(); 100 wdt_enable();
97
98 set_bit(WDT_ENABLED, &wdt_status); 101 set_bit(WDT_ENABLED, &wdt_status);
99
100 return nonseekable_open(inode, file); 102 return nonseekable_open(inode, file);
101} 103}
102 104
103static ssize_t 105static ssize_t iop_wdt_write(struct file *file, const char *data, size_t len,
104iop_wdt_write(struct file *file, const char *data, size_t len,
105 loff_t *ppos) 106 loff_t *ppos)
106{ 107{
107 if (len) { 108 if (len) {
@@ -121,46 +122,35 @@ iop_wdt_write(struct file *file, const char *data, size_t len,
121 } 122 }
122 wdt_enable(); 123 wdt_enable();
123 } 124 }
124
125 return len; 125 return len;
126} 126}
127 127
128static struct watchdog_info ident = { 128static const struct watchdog_info ident = {
129 .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, 129 .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
130 .identity = "iop watchdog", 130 .identity = "iop watchdog",
131}; 131};
132 132
133static int 133static long iop_wdt_ioctl(struct file *file,
134iop_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 134 unsigned int cmd, unsigned long arg)
135 unsigned long arg)
136{ 135{
137 int options; 136 int options;
138 int ret = -ENOTTY; 137 int ret = -ENOTTY;
138 int __user *argp = (int __user *)arg;
139 139
140 switch (cmd) { 140 switch (cmd) {
141 case WDIOC_GETSUPPORT: 141 case WDIOC_GETSUPPORT:
142 if (copy_to_user 142 if (copy_to_user(argp, &ident, sizeof ident))
143 ((struct watchdog_info *)arg, &ident, sizeof ident))
144 ret = -EFAULT; 143 ret = -EFAULT;
145 else 144 else
146 ret = 0; 145 ret = 0;
147 break; 146 break;
148 147
149 case WDIOC_GETSTATUS: 148 case WDIOC_GETSTATUS:
150 ret = put_user(0, (int *)arg); 149 ret = put_user(0, argp);
151 break; 150 break;
152 151
153 case WDIOC_GETBOOTSTATUS: 152 case WDIOC_GETBOOTSTATUS:
154 ret = put_user(boot_status, (int *)arg); 153 ret = put_user(boot_status, argp);
155 break;
156
157 case WDIOC_GETTIMEOUT:
158 ret = put_user(iop_watchdog_timeout(), (int *)arg);
159 break;
160
161 case WDIOC_KEEPALIVE:
162 wdt_enable();
163 ret = 0;
164 break; 154 break;
165 155
166 case WDIOC_SETOPTIONS: 156 case WDIOC_SETOPTIONS:
@@ -177,14 +167,21 @@ iop_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
177 } else 167 } else
178 ret = 0; 168 ret = 0;
179 } 169 }
180
181 if (options & WDIOS_ENABLECARD) { 170 if (options & WDIOS_ENABLECARD) {
182 wdt_enable(); 171 wdt_enable();
183 ret = 0; 172 ret = 0;
184 } 173 }
185 break; 174 break;
186 }
187 175
176 case WDIOC_KEEPALIVE:
177 wdt_enable();
178 ret = 0;
179 break;
180
181 case WDIOC_GETTIMEOUT:
182 ret = put_user(iop_watchdog_timeout(), argp);
183 break;
184 }
188 return ret; 185 return ret;
189} 186}
190 187
@@ -214,7 +211,7 @@ static const struct file_operations iop_wdt_fops = {
214 .owner = THIS_MODULE, 211 .owner = THIS_MODULE,
215 .llseek = no_llseek, 212 .llseek = no_llseek,
216 .write = iop_wdt_write, 213 .write = iop_wdt_write,
217 .ioctl = iop_wdt_ioctl, 214 .unlocked_ioctl = iop_wdt_ioctl,
218 .open = iop_wdt_open, 215 .open = iop_wdt_open,
219 .release = iop_wdt_release, 216 .release = iop_wdt_release,
220}; 217};
@@ -229,10 +226,8 @@ static int __init iop_wdt_init(void)
229{ 226{
230 int ret; 227 int ret;
231 228
232 ret = misc_register(&iop_wdt_miscdev); 229 spin_lock_init(&wdt_lock);
233 if (ret == 0) 230
234 printk("iop watchdog timer: timeout %lu sec\n",
235 iop_watchdog_timeout());
236 231
237 /* check if the reset was caused by the watchdog timer */ 232 /* check if the reset was caused by the watchdog timer */
238 boot_status = (read_rcsr() & IOP_RCSR_WDT) ? WDIOF_CARDRESET : 0; 233 boot_status = (read_rcsr() & IOP_RCSR_WDT) ? WDIOF_CARDRESET : 0;
@@ -242,6 +237,13 @@ static int __init iop_wdt_init(void)
242 */ 237 */
243 write_wdtsr(IOP13XX_WDTCR_IB_RESET); 238 write_wdtsr(IOP13XX_WDTCR_IB_RESET);
244 239
240 /* Register after we have the device set up so we cannot race
241 with an open */
242 ret = misc_register(&iop_wdt_miscdev);
243 if (ret == 0)
244 printk(KERN_INFO "iop watchdog timer: timeout %lu sec\n",
245 iop_watchdog_timeout());
246
245 return ret; 247 return ret;
246} 248}
247 249
diff --git a/drivers/watchdog/it8712f_wdt.c b/drivers/watchdog/it8712f_wdt.c
index 51bfd5721833..2270ee07c01b 100644
--- a/drivers/watchdog/it8712f_wdt.c
+++ b/drivers/watchdog/it8712f_wdt.c
@@ -221,7 +221,7 @@ static ssize_t it8712f_wdt_write(struct file *file, const char __user *data,
221 expect_close = 0; 221 expect_close = 0;
222 for (i = 0; i < len; ++i) { 222 for (i = 0; i < len; ++i) {
223 char c; 223 char c;
224 if (get_user(c, data+i)) 224 if (get_user(c, data + i))
225 return -EFAULT; 225 return -EFAULT;
226 if (c == 'V') 226 if (c == 'V')
227 expect_close = 42; 227 expect_close = 42;
@@ -244,8 +244,6 @@ static long it8712f_wdt_ioctl(struct file *file, unsigned int cmd,
244 int value; 244 int value;
245 245
246 switch (cmd) { 246 switch (cmd) {
247 default:
248 return -ENOTTY;
249 case WDIOC_GETSUPPORT: 247 case WDIOC_GETSUPPORT:
250 if (copy_to_user(argp, &ident, sizeof(ident))) 248 if (copy_to_user(argp, &ident, sizeof(ident)))
251 return -EFAULT; 249 return -EFAULT;
@@ -284,6 +282,8 @@ static long it8712f_wdt_ioctl(struct file *file, unsigned int cmd,
284 if (put_user(margin, p)) 282 if (put_user(margin, p))
285 return -EFAULT; 283 return -EFAULT;
286 return 0; 284 return 0;
285 default:
286 return -ENOTTY;
287 } 287 }
288} 288}
289 289
diff --git a/drivers/watchdog/ixp2000_wdt.c b/drivers/watchdog/ixp2000_wdt.c
index 4226dae7d260..4f4b35a20d84 100644
--- a/drivers/watchdog/ixp2000_wdt.c
+++ b/drivers/watchdog/ixp2000_wdt.c
@@ -25,42 +25,44 @@
25#include <linux/watchdog.h> 25#include <linux/watchdog.h>
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/bitops.h> 27#include <linux/bitops.h>
28 28#include <linux/uaccess.h>
29#include <mach/hardware.h> 29#include <mach/hardware.h>
30#include <asm/uaccess.h>
31 30
32static int nowayout = WATCHDOG_NOWAYOUT; 31static int nowayout = WATCHDOG_NOWAYOUT;
33static unsigned int heartbeat = 60; /* (secs) Default is 1 minute */ 32static unsigned int heartbeat = 60; /* (secs) Default is 1 minute */
34static unsigned long wdt_status; 33static unsigned long wdt_status;
34static spinlock_t wdt_lock;
35 35
36#define WDT_IN_USE 0 36#define WDT_IN_USE 0
37#define WDT_OK_TO_CLOSE 1 37#define WDT_OK_TO_CLOSE 1
38 38
39static unsigned long wdt_tick_rate; 39static unsigned long wdt_tick_rate;
40 40
41static void 41static void wdt_enable(void)
42wdt_enable(void)
43{ 42{
43 spin_lock(&wdt_lock);
44 ixp2000_reg_write(IXP2000_RESET0, *(IXP2000_RESET0) | WDT_RESET_ENABLE); 44 ixp2000_reg_write(IXP2000_RESET0, *(IXP2000_RESET0) | WDT_RESET_ENABLE);
45 ixp2000_reg_write(IXP2000_TWDE, WDT_ENABLE); 45 ixp2000_reg_write(IXP2000_TWDE, WDT_ENABLE);
46 ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate); 46 ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate);
47 ixp2000_reg_write(IXP2000_T4_CTL, TIMER_DIVIDER_256 | TIMER_ENABLE); 47 ixp2000_reg_write(IXP2000_T4_CTL, TIMER_DIVIDER_256 | TIMER_ENABLE);
48 spin_unlock(&wdt_lock);
48} 49}
49 50
50static void 51static void wdt_disable(void)
51wdt_disable(void)
52{ 52{
53 spin_lock(&wdt_lock);
53 ixp2000_reg_write(IXP2000_T4_CTL, 0); 54 ixp2000_reg_write(IXP2000_T4_CTL, 0);
55 spin_unlock(&wdt_lock);
54} 56}
55 57
56static void 58static void wdt_keepalive(void)
57wdt_keepalive(void)
58{ 59{
60 spin_lock(&wdt_lock);
59 ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate); 61 ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate);
62 spin_unlock(&wdt_lock);
60} 63}
61 64
62static int 65static int ixp2000_wdt_open(struct inode *inode, struct file *file)
63ixp2000_wdt_open(struct inode *inode, struct file *file)
64{ 66{
65 if (test_and_set_bit(WDT_IN_USE, &wdt_status)) 67 if (test_and_set_bit(WDT_IN_USE, &wdt_status))
66 return -EBUSY; 68 return -EBUSY;
@@ -72,8 +74,8 @@ ixp2000_wdt_open(struct inode *inode, struct file *file)
72 return nonseekable_open(inode, file); 74 return nonseekable_open(inode, file);
73} 75}
74 76
75static ssize_t 77static ssize_t ixp2000_wdt_write(struct file *file, const char *data,
76ixp2000_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) 78 size_t len, loff_t *ppos)
77{ 79{
78 if (len) { 80 if (len) {
79 if (!nowayout) { 81 if (!nowayout) {
@@ -103,9 +105,8 @@ static struct watchdog_info ident = {
103 .identity = "IXP2000 Watchdog", 105 .identity = "IXP2000 Watchdog",
104}; 106};
105 107
106static int 108static long ixp2000_wdt_ioctl(struct file *file, unsigned int cmd,
107ixp2000_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 109 unsigned long arg)
108 unsigned long arg)
109{ 110{
110 int ret = -ENOTTY; 111 int ret = -ENOTTY;
111 int time; 112 int time;
@@ -124,6 +125,11 @@ ixp2000_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
124 ret = put_user(0, (int *)arg); 125 ret = put_user(0, (int *)arg);
125 break; 126 break;
126 127
128 case WDIOC_KEEPALIVE:
129 wdt_enable();
130 ret = 0;
131 break;
132
127 case WDIOC_SETTIMEOUT: 133 case WDIOC_SETTIMEOUT:
128 ret = get_user(time, (int *)arg); 134 ret = get_user(time, (int *)arg);
129 if (ret) 135 if (ret)
@@ -141,26 +147,18 @@ ixp2000_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
141 case WDIOC_GETTIMEOUT: 147 case WDIOC_GETTIMEOUT:
142 ret = put_user(heartbeat, (int *)arg); 148 ret = put_user(heartbeat, (int *)arg);
143 break; 149 break;
144
145 case WDIOC_KEEPALIVE:
146 wdt_enable();
147 ret = 0;
148 break;
149 } 150 }
150 151
151 return ret; 152 return ret;
152} 153}
153 154
154static int 155static int ixp2000_wdt_release(struct inode *inode, struct file *file)
155ixp2000_wdt_release(struct inode *inode, struct file *file)
156{ 156{
157 if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) { 157 if (test_bit(WDT_OK_TO_CLOSE, &wdt_status))
158 wdt_disable(); 158 wdt_disable();
159 } else { 159 else
160 printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - " 160 printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - "
161 "timer will not stop\n"); 161 "timer will not stop\n");
162 }
163
164 clear_bit(WDT_IN_USE, &wdt_status); 162 clear_bit(WDT_IN_USE, &wdt_status);
165 clear_bit(WDT_OK_TO_CLOSE, &wdt_status); 163 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
166 164
@@ -168,18 +166,16 @@ ixp2000_wdt_release(struct inode *inode, struct file *file)
168} 166}
169 167
170 168
171static const struct file_operations ixp2000_wdt_fops = 169static const struct file_operations ixp2000_wdt_fops = {
172{
173 .owner = THIS_MODULE, 170 .owner = THIS_MODULE,
174 .llseek = no_llseek, 171 .llseek = no_llseek,
175 .write = ixp2000_wdt_write, 172 .write = ixp2000_wdt_write,
176 .ioctl = ixp2000_wdt_ioctl, 173 .unlocked_ioctl = ixp2000_wdt_ioctl,
177 .open = ixp2000_wdt_open, 174 .open = ixp2000_wdt_open,
178 .release = ixp2000_wdt_release, 175 .release = ixp2000_wdt_release,
179}; 176};
180 177
181static struct miscdevice ixp2000_wdt_miscdev = 178static struct miscdevice ixp2000_wdt_miscdev = {
182{
183 .minor = WATCHDOG_MINOR, 179 .minor = WATCHDOG_MINOR,
184 .name = "watchdog", 180 .name = "watchdog",
185 .fops = &ixp2000_wdt_fops, 181 .fops = &ixp2000_wdt_fops,
@@ -191,9 +187,8 @@ static int __init ixp2000_wdt_init(void)
191 printk(KERN_INFO "Unable to use IXP2000 watchdog due to IXP2800 erratum #25.\n"); 187 printk(KERN_INFO "Unable to use IXP2000 watchdog due to IXP2800 erratum #25.\n");
192 return -EIO; 188 return -EIO;
193 } 189 }
194
195 wdt_tick_rate = (*IXP2000_T1_CLD * HZ) / 256; 190 wdt_tick_rate = (*IXP2000_T1_CLD * HZ) / 256;
196 191 spin_lock_init(&wdt_lock);
197 return misc_register(&ixp2000_wdt_miscdev); 192 return misc_register(&ixp2000_wdt_miscdev);
198} 193}
199 194
diff --git a/drivers/watchdog/ixp4xx_wdt.c b/drivers/watchdog/ixp4xx_wdt.c
index 2313fad0dbb1..41264a5f1731 100644
--- a/drivers/watchdog/ixp4xx_wdt.c
+++ b/drivers/watchdog/ixp4xx_wdt.c
@@ -22,48 +22,47 @@
22#include <linux/watchdog.h> 22#include <linux/watchdog.h>
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/bitops.h> 24#include <linux/bitops.h>
25 25#include <linux/uaccess.h>
26#include <mach/hardware.h> 26#include <mach/hardware.h>
27#include <asm/uaccess.h>
28 27
29static int nowayout = WATCHDOG_NOWAYOUT; 28static int nowayout = WATCHDOG_NOWAYOUT;
30static int heartbeat = 60; /* (secs) Default is 1 minute */ 29static int heartbeat = 60; /* (secs) Default is 1 minute */
31static unsigned long wdt_status; 30static unsigned long wdt_status;
32static unsigned long boot_status; 31static unsigned long boot_status;
32static spin_lock_t wdt_lock;
33 33
34#define WDT_TICK_RATE (IXP4XX_PERIPHERAL_BUS_CLOCK * 1000000UL) 34#define WDT_TICK_RATE (IXP4XX_PERIPHERAL_BUS_CLOCK * 1000000UL)
35 35
36#define WDT_IN_USE 0 36#define WDT_IN_USE 0
37#define WDT_OK_TO_CLOSE 1 37#define WDT_OK_TO_CLOSE 1
38 38
39static void 39static void wdt_enable(void)
40wdt_enable(void)
41{ 40{
41 spin_lock(&wdt_lock);
42 *IXP4XX_OSWK = IXP4XX_WDT_KEY; 42 *IXP4XX_OSWK = IXP4XX_WDT_KEY;
43 *IXP4XX_OSWE = 0; 43 *IXP4XX_OSWE = 0;
44 *IXP4XX_OSWT = WDT_TICK_RATE * heartbeat; 44 *IXP4XX_OSWT = WDT_TICK_RATE * heartbeat;
45 *IXP4XX_OSWE = IXP4XX_WDT_COUNT_ENABLE | IXP4XX_WDT_RESET_ENABLE; 45 *IXP4XX_OSWE = IXP4XX_WDT_COUNT_ENABLE | IXP4XX_WDT_RESET_ENABLE;
46 *IXP4XX_OSWK = 0; 46 *IXP4XX_OSWK = 0;
47 spin_unlock(&wdt_lock);
47} 48}
48 49
49static void 50static void wdt_disable(void)
50wdt_disable(void)
51{ 51{
52 spin_lock(&wdt_lock);
52 *IXP4XX_OSWK = IXP4XX_WDT_KEY; 53 *IXP4XX_OSWK = IXP4XX_WDT_KEY;
53 *IXP4XX_OSWE = 0; 54 *IXP4XX_OSWE = 0;
54 *IXP4XX_OSWK = 0; 55 *IXP4XX_OSWK = 0;
56 spin_unlock(&wdt_lock);
55} 57}
56 58
57static int 59static int ixp4xx_wdt_open(struct inode *inode, struct file *file)
58ixp4xx_wdt_open(struct inode *inode, struct file *file)
59{ 60{
60 if (test_and_set_bit(WDT_IN_USE, &wdt_status)) 61 if (test_and_set_bit(WDT_IN_USE, &wdt_status))
61 return -EBUSY; 62 return -EBUSY;
62 63
63 clear_bit(WDT_OK_TO_CLOSE, &wdt_status); 64 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
64
65 wdt_enable(); 65 wdt_enable();
66
67 return nonseekable_open(inode, file); 66 return nonseekable_open(inode, file);
68} 67}
69 68
@@ -87,7 +86,6 @@ ixp4xx_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos)
87 } 86 }
88 wdt_enable(); 87 wdt_enable();
89 } 88 }
90
91 return len; 89 return len;
92} 90}
93 91
@@ -98,9 +96,8 @@ static struct watchdog_info ident = {
98}; 96};
99 97
100 98
101static int 99static long ixp4xx_wdt_ioctl(struct file *file, unsigned int cmd,
102ixp4xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 100 unsigned long arg)
103 unsigned long arg)
104{ 101{
105 int ret = -ENOTTY; 102 int ret = -ENOTTY;
106 int time; 103 int time;
@@ -119,6 +116,11 @@ ixp4xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
119 ret = put_user(boot_status, (int *)arg); 116 ret = put_user(boot_status, (int *)arg);
120 break; 117 break;
121 118
119 case WDIOC_KEEPALIVE:
120 wdt_enable();
121 ret = 0;
122 break;
123
122 case WDIOC_SETTIMEOUT: 124 case WDIOC_SETTIMEOUT:
123 ret = get_user(time, (int *)arg); 125 ret = get_user(time, (int *)arg);
124 if (ret) 126 if (ret)
@@ -136,25 +138,17 @@ ixp4xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
136 case WDIOC_GETTIMEOUT: 138 case WDIOC_GETTIMEOUT:
137 ret = put_user(heartbeat, (int *)arg); 139 ret = put_user(heartbeat, (int *)arg);
138 break; 140 break;
139
140 case WDIOC_KEEPALIVE:
141 wdt_enable();
142 ret = 0;
143 break;
144 } 141 }
145 return ret; 142 return ret;
146} 143}
147 144
148static int 145static int ixp4xx_wdt_release(struct inode *inode, struct file *file)
149ixp4xx_wdt_release(struct inode *inode, struct file *file)
150{ 146{
151 if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) { 147 if (test_bit(WDT_OK_TO_CLOSE, &wdt_status))
152 wdt_disable(); 148 wdt_disable();
153 } else { 149 else
154 printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - " 150 printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - "
155 "timer will not stop\n"); 151 "timer will not stop\n");
156 }
157
158 clear_bit(WDT_IN_USE, &wdt_status); 152 clear_bit(WDT_IN_USE, &wdt_status);
159 clear_bit(WDT_OK_TO_CLOSE, &wdt_status); 153 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
160 154
@@ -162,18 +156,16 @@ ixp4xx_wdt_release(struct inode *inode, struct file *file)
162} 156}
163 157
164 158
165static const struct file_operations ixp4xx_wdt_fops = 159static const struct file_operations ixp4xx_wdt_fops = {
166{
167 .owner = THIS_MODULE, 160 .owner = THIS_MODULE,
168 .llseek = no_llseek, 161 .llseek = no_llseek,
169 .write = ixp4xx_wdt_write, 162 .write = ixp4xx_wdt_write,
170 .ioctl = ixp4xx_wdt_ioctl, 163 .unlocked_ioctl = ixp4xx_wdt_ioctl,
171 .open = ixp4xx_wdt_open, 164 .open = ixp4xx_wdt_open,
172 .release = ixp4xx_wdt_release, 165 .release = ixp4xx_wdt_release,
173}; 166};
174 167
175static struct miscdevice ixp4xx_wdt_miscdev = 168static struct miscdevice ixp4xx_wdt_miscdev = {
176{
177 .minor = WATCHDOG_MINOR, 169 .minor = WATCHDOG_MINOR,
178 .name = "watchdog", 170 .name = "watchdog",
179 .fops = &ixp4xx_wdt_fops, 171 .fops = &ixp4xx_wdt_fops,
@@ -186,19 +178,18 @@ static int __init ixp4xx_wdt_init(void)
186 178
187 asm("mrc p15, 0, %0, cr0, cr0, 0;" : "=r"(processor_id) :); 179 asm("mrc p15, 0, %0, cr0, cr0, 0;" : "=r"(processor_id) :);
188 if (!(processor_id & 0xf) && !cpu_is_ixp46x()) { 180 if (!(processor_id & 0xf) && !cpu_is_ixp46x()) {
189 printk("IXP4XXX Watchdog: Rev. A0 IXP42x CPU detected - " 181 printk(KERN_ERR "IXP4XXX Watchdog: Rev. A0 IXP42x CPU detected"
190 "watchdog disabled\n"); 182 " - watchdog disabled\n");
191 183
192 return -ENODEV; 184 return -ENODEV;
193 } 185 }
194 186 spin_lock_init(&wdt_lock);
195 ret = misc_register(&ixp4xx_wdt_miscdev);
196 if (ret == 0)
197 printk("IXP4xx Watchdog Timer: heartbeat %d sec\n", heartbeat);
198
199 boot_status = (*IXP4XX_OSST & IXP4XX_OSST_TIMER_WARM_RESET) ? 187 boot_status = (*IXP4XX_OSST & IXP4XX_OSST_TIMER_WARM_RESET) ?
200 WDIOF_CARDRESET : 0; 188 WDIOF_CARDRESET : 0;
201 189 ret = misc_register(&ixp4xx_wdt_miscdev);
190 if (ret == 0)
191 printk(KERN_INFO "IXP4xx Watchdog Timer: heartbeat %d sec\n",
192 heartbeat);
202 return ret; 193 return ret;
203} 194}
204 195
diff --git a/drivers/watchdog/ks8695_wdt.c b/drivers/watchdog/ks8695_wdt.c
index d21a6407fe21..0b798fdaa378 100644
--- a/drivers/watchdog/ks8695_wdt.c
+++ b/drivers/watchdog/ks8695_wdt.c
@@ -19,11 +19,10 @@
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/types.h> 20#include <linux/types.h>
21#include <linux/watchdog.h> 21#include <linux/watchdog.h>
22#include <asm/io.h> 22#include <linux/io.h>
23#include <asm/uaccess.h> 23#include <linux/uaccess.h>
24#include <mach/regs-timer.h> 24#include <mach/regs-timer.h>
25 25
26
27#define WDT_DEFAULT_TIME 5 /* seconds */ 26#define WDT_DEFAULT_TIME 5 /* seconds */
28#define WDT_MAX_TIME 171 /* seconds */ 27#define WDT_MAX_TIME 171 /* seconds */
29 28
@@ -31,38 +30,44 @@ static int wdt_time = WDT_DEFAULT_TIME;
31static int nowayout = WATCHDOG_NOWAYOUT; 30static int nowayout = WATCHDOG_NOWAYOUT;
32 31
33module_param(wdt_time, int, 0); 32module_param(wdt_time, int, 0);
34MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="__MODULE_STRING(WDT_DEFAULT_TIME) ")"); 33MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="
34 __MODULE_STRING(WDT_DEFAULT_TIME) ")");
35 35
36#ifdef CONFIG_WATCHDOG_NOWAYOUT 36#ifdef CONFIG_WATCHDOG_NOWAYOUT
37module_param(nowayout, int, 0); 37module_param(nowayout, int, 0);
38MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 38MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
39 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
39#endif 40#endif
40 41
41 42
42static unsigned long ks8695wdt_busy; 43static unsigned long ks8695wdt_busy;
44static spinlock_t ks8695_lock;
43 45
44/* ......................................................................... */ 46/* ......................................................................... */
45 47
46/* 48/*
47 * Disable the watchdog. 49 * Disable the watchdog.
48 */ 50 */
49static void inline ks8695_wdt_stop(void) 51static inline void ks8695_wdt_stop(void)
50{ 52{
51 unsigned long tmcon; 53 unsigned long tmcon;
52 54
55 spin_lock(&ks8695_lock);
53 /* disable timer0 */ 56 /* disable timer0 */
54 tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON); 57 tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON);
55 __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); 58 __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON);
59 spin_unlock(&ks8695_lock);
56} 60}
57 61
58/* 62/*
59 * Enable and reset the watchdog. 63 * Enable and reset the watchdog.
60 */ 64 */
61static void inline ks8695_wdt_start(void) 65static inline void ks8695_wdt_start(void)
62{ 66{
63 unsigned long tmcon; 67 unsigned long tmcon;
64 unsigned long tval = wdt_time * CLOCK_TICK_RATE; 68 unsigned long tval = wdt_time * CLOCK_TICK_RATE;
65 69
70 spin_lock(&ks8695_lock);
66 /* disable timer0 */ 71 /* disable timer0 */
67 tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON); 72 tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON);
68 __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); 73 __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON);
@@ -73,19 +78,22 @@ static void inline ks8695_wdt_start(void)
73 /* re-enable timer0 */ 78 /* re-enable timer0 */
74 tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON); 79 tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON);
75 __raw_writel(tmcon | TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); 80 __raw_writel(tmcon | TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON);
81 spin_unlock(&ks8695_lock);
76} 82}
77 83
78/* 84/*
79 * Reload the watchdog timer. (ie, pat the watchdog) 85 * Reload the watchdog timer. (ie, pat the watchdog)
80 */ 86 */
81static void inline ks8695_wdt_reload(void) 87static inline void ks8695_wdt_reload(void)
82{ 88{
83 unsigned long tmcon; 89 unsigned long tmcon;
84 90
91 spin_lock(&ks8695_lock);
85 /* disable, then re-enable timer0 */ 92 /* disable, then re-enable timer0 */
86 tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON); 93 tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON);
87 __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); 94 __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON);
88 __raw_writel(tmcon | TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); 95 __raw_writel(tmcon | TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON);
96 spin_unlock(&ks8695_lock);
89} 97}
90 98
91/* 99/*
@@ -102,7 +110,8 @@ static int ks8695_wdt_settimeout(int new_time)
102 if ((new_time <= 0) || (new_time > WDT_MAX_TIME)) 110 if ((new_time <= 0) || (new_time > WDT_MAX_TIME))
103 return -EINVAL; 111 return -EINVAL;
104 112
105 /* Set new watchdog time. It will be used when ks8695_wdt_start() is called. */ 113 /* Set new watchdog time. It will be used when
114 ks8695_wdt_start() is called. */
106 wdt_time = new_time; 115 wdt_time = new_time;
107 return 0; 116 return 0;
108} 117}
@@ -128,9 +137,9 @@ static int ks8695_wdt_open(struct inode *inode, struct file *file)
128 */ 137 */
129static int ks8695_wdt_close(struct inode *inode, struct file *file) 138static int ks8695_wdt_close(struct inode *inode, struct file *file)
130{ 139{
140 /* Disable the watchdog when file is closed */
131 if (!nowayout) 141 if (!nowayout)
132 ks8695_wdt_stop(); /* Disable the watchdog when file is closed */ 142 ks8695_wdt_stop();
133
134 clear_bit(0, &ks8695wdt_busy); 143 clear_bit(0, &ks8695wdt_busy);
135 return 0; 144 return 0;
136} 145}
@@ -143,60 +152,52 @@ static struct watchdog_info ks8695_wdt_info = {
143/* 152/*
144 * Handle commands from user-space. 153 * Handle commands from user-space.
145 */ 154 */
146static int ks8695_wdt_ioctl(struct inode *inode, struct file *file, 155static long ks8695_wdt_ioctl(struct file *file, unsigned int cmd,
147 unsigned int cmd, unsigned long arg) 156 unsigned long arg)
148{ 157{
149 void __user *argp = (void __user *)arg; 158 void __user *argp = (void __user *)arg;
150 int __user *p = argp; 159 int __user *p = argp;
151 int new_value; 160 int new_value;
152 161
153 switch(cmd) { 162 switch (cmd) {
154 case WDIOC_KEEPALIVE: 163 case WDIOC_GETSUPPORT:
155 ks8695_wdt_reload(); /* pat the watchdog */ 164 return copy_to_user(argp, &ks8695_wdt_info,
156 return 0; 165 sizeof(ks8695_wdt_info)) ? -EFAULT : 0;
157 166 case WDIOC_GETSTATUS:
158 case WDIOC_GETSUPPORT: 167 case WDIOC_GETBOOTSTATUS:
159 return copy_to_user(argp, &ks8695_wdt_info, sizeof(ks8695_wdt_info)) ? -EFAULT : 0; 168 return put_user(0, p);
160 169 case WDIOC_SETOPTIONS:
161 case WDIOC_SETTIMEOUT: 170 if (get_user(new_value, p))
162 if (get_user(new_value, p)) 171 return -EFAULT;
163 return -EFAULT; 172 if (new_value & WDIOS_DISABLECARD)
164 173 ks8695_wdt_stop();
165 if (ks8695_wdt_settimeout(new_value)) 174 if (new_value & WDIOS_ENABLECARD)
166 return -EINVAL;
167
168 /* Enable new time value */
169 ks8695_wdt_start(); 175 ks8695_wdt_start();
170 176 return 0;
171 /* Return current value */ 177 case WDIOC_KEEPALIVE:
172 return put_user(wdt_time, p); 178 ks8695_wdt_reload(); /* pat the watchdog */
173 179 return 0;
174 case WDIOC_GETTIMEOUT: 180 case WDIOC_SETTIMEOUT:
175 return put_user(wdt_time, p); 181 if (get_user(new_value, p))
176 182 return -EFAULT;
177 case WDIOC_GETSTATUS: 183 if (ks8695_wdt_settimeout(new_value))
178 case WDIOC_GETBOOTSTATUS: 184 return -EINVAL;
179 return put_user(0, p); 185 /* Enable new time value */
180 186 ks8695_wdt_start();
181 case WDIOC_SETOPTIONS: 187 /* Return current value */
182 if (get_user(new_value, p)) 188 return put_user(wdt_time, p);
183 return -EFAULT; 189 case WDIOC_GETTIMEOUT:
184 190 return put_user(wdt_time, p);
185 if (new_value & WDIOS_DISABLECARD) 191 default:
186 ks8695_wdt_stop(); 192 return -ENOTTY;
187 if (new_value & WDIOS_ENABLECARD)
188 ks8695_wdt_start();
189 return 0;
190
191 default:
192 return -ENOTTY;
193 } 193 }
194} 194}
195 195
196/* 196/*
197 * Pat the watchdog whenever device is written to. 197 * Pat the watchdog whenever device is written to.
198 */ 198 */
199static ssize_t ks8695_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) 199static ssize_t ks8695_wdt_write(struct file *file, const char *data,
200 size_t len, loff_t *ppos)
200{ 201{
201 ks8695_wdt_reload(); /* pat the watchdog */ 202 ks8695_wdt_reload(); /* pat the watchdog */
202 return len; 203 return len;
@@ -207,7 +208,7 @@ static ssize_t ks8695_wdt_write(struct file *file, const char *data, size_t len,
207static const struct file_operations ks8695wdt_fops = { 208static const struct file_operations ks8695wdt_fops = {
208 .owner = THIS_MODULE, 209 .owner = THIS_MODULE,
209 .llseek = no_llseek, 210 .llseek = no_llseek,
210 .ioctl = ks8695_wdt_ioctl, 211 .unlocked_ioctl = ks8695_wdt_ioctl,
211 .open = ks8695_wdt_open, 212 .open = ks8695_wdt_open,
212 .release = ks8695_wdt_close, 213 .release = ks8695_wdt_close,
213 .write = ks8695_wdt_write, 214 .write = ks8695_wdt_write,
@@ -231,7 +232,8 @@ static int __init ks8695wdt_probe(struct platform_device *pdev)
231 if (res) 232 if (res)
232 return res; 233 return res;
233 234
234 printk("KS8695 Watchdog Timer enabled (%d seconds%s)\n", wdt_time, nowayout ? ", nowayout" : ""); 235 printk(KERN_INFO "KS8695 Watchdog Timer enabled (%d seconds%s)\n",
236 wdt_time, nowayout ? ", nowayout" : "");
235 return 0; 237 return 0;
236} 238}
237 239
@@ -285,12 +287,14 @@ static struct platform_driver ks8695wdt_driver = {
285 287
286static int __init ks8695_wdt_init(void) 288static int __init ks8695_wdt_init(void)
287{ 289{
288 /* Check that the heartbeat value is within range; if not reset to the default */ 290 spin_lock_init(&ks8695_lock);
291 /* Check that the heartbeat value is within range;
292 if not reset to the default */
289 if (ks8695_wdt_settimeout(wdt_time)) { 293 if (ks8695_wdt_settimeout(wdt_time)) {
290 ks8695_wdt_settimeout(WDT_DEFAULT_TIME); 294 ks8695_wdt_settimeout(WDT_DEFAULT_TIME);
291 pr_info("ks8695_wdt: wdt_time value must be 1 <= wdt_time <= %i, using %d\n", wdt_time, WDT_MAX_TIME); 295 pr_info("ks8695_wdt: wdt_time value must be 1 <= wdt_time <= %i, using %d\n",
296 wdt_time, WDT_MAX_TIME);
292 } 297 }
293
294 return platform_driver_register(&ks8695wdt_driver); 298 return platform_driver_register(&ks8695wdt_driver);
295} 299}
296 300
diff --git a/drivers/watchdog/machzwd.c b/drivers/watchdog/machzwd.c
index 6905135a776c..2dfc27559bf7 100644
--- a/drivers/watchdog/machzwd.c
+++ b/drivers/watchdog/machzwd.c
@@ -40,9 +40,9 @@
40#include <linux/notifier.h> 40#include <linux/notifier.h>
41#include <linux/reboot.h> 41#include <linux/reboot.h>
42#include <linux/init.h> 42#include <linux/init.h>
43#include <linux/io.h>
44#include <linux/uaccess.h>
43 45
44#include <asm/io.h>
45#include <asm/uaccess.h>
46#include <asm/system.h> 46#include <asm/system.h>
47 47
48/* ports */ 48/* ports */
@@ -95,7 +95,9 @@ 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=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 98MODULE_PARM_DESC(nowayout,
99 "Watchdog cannot be stopped once started (default="
100 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
99 101
100#define PFX "machzwd" 102#define PFX "machzwd"
101 103
@@ -114,7 +116,7 @@ static struct watchdog_info zf_info = {
114 * 3 = GEN_SCI 116 * 3 = GEN_SCI
115 * defaults to GEN_RESET (0) 117 * defaults to GEN_RESET (0)
116 */ 118 */
117static int action = 0; 119static int action;
118module_param(action, int, 0); 120module_param(action, int, 0);
119MODULE_PARM_DESC(action, "after watchdog resets, generate: 0 = RESET(*) 1 = SMI 2 = NMI 3 = SCI"); 121MODULE_PARM_DESC(action, "after watchdog resets, generate: 0 = RESET(*) 1 = SMI 2 = NMI 3 = SCI");
120 122
@@ -123,10 +125,9 @@ static void zf_ping(unsigned long data);
123static int zf_action = GEN_RESET; 125static int zf_action = GEN_RESET;
124static unsigned long zf_is_open; 126static unsigned long zf_is_open;
125static char zf_expect_close; 127static char zf_expect_close;
126static DEFINE_SPINLOCK(zf_lock);
127static DEFINE_SPINLOCK(zf_port_lock); 128static DEFINE_SPINLOCK(zf_port_lock);
128static DEFINE_TIMER(zf_timer, zf_ping, 0, 0); 129static DEFINE_TIMER(zf_timer, zf_ping, 0, 0);
129static unsigned long next_heartbeat = 0; 130static unsigned long next_heartbeat;
130 131
131 132
132/* timeout for user land heart beat (10 seconds) */ 133/* timeout for user land heart beat (10 seconds) */
@@ -171,13 +172,13 @@ static inline void zf_set_control(unsigned short new)
171 172
172static inline void zf_set_timer(unsigned short new, unsigned char n) 173static inline void zf_set_timer(unsigned short new, unsigned char n)
173{ 174{
174 switch(n){ 175 switch (n) {
175 case WD1: 176 case WD1:
176 zf_writew(COUNTER_1, new); 177 zf_writew(COUNTER_1, new);
177 case WD2: 178 case WD2:
178 zf_writeb(COUNTER_2, new > 0xff ? 0xff : new); 179 zf_writeb(COUNTER_2, new > 0xff ? 0xff : new);
179 default: 180 default:
180 return; 181 return;
181 } 182 }
182} 183}
183 184
@@ -241,10 +242,8 @@ static void zf_ping(unsigned long data)
241 242
242 zf_writeb(COUNTER_2, 0xff); 243 zf_writeb(COUNTER_2, 0xff);
243 244
244 if(time_before(jiffies, next_heartbeat)){ 245 if (time_before(jiffies, next_heartbeat)) {
245
246 dprintk("time_before: %ld\n", next_heartbeat - jiffies); 246 dprintk("time_before: %ld\n", next_heartbeat - jiffies);
247
248 /* 247 /*
249 * reset event is activated by transition from 0 to 1 on 248 * reset event is activated by transition from 0 to 1 on
250 * RESET_WD1 bit and we assume that it is already zero... 249 * RESET_WD1 bit and we assume that it is already zero...
@@ -261,24 +260,21 @@ static void zf_ping(unsigned long data)
261 spin_unlock_irqrestore(&zf_port_lock, flags); 260 spin_unlock_irqrestore(&zf_port_lock, flags);
262 261
263 mod_timer(&zf_timer, jiffies + ZF_HW_TIMEO); 262 mod_timer(&zf_timer, jiffies + ZF_HW_TIMEO);
264 }else{ 263 } else
265 printk(KERN_CRIT PFX ": I will reset your machine\n"); 264 printk(KERN_CRIT PFX ": I will reset your machine\n");
266 }
267} 265}
268 266
269static ssize_t zf_write(struct file *file, const char __user *buf, size_t count, 267static ssize_t zf_write(struct file *file, const char __user *buf, size_t count,
270 loff_t *ppos) 268 loff_t *ppos)
271{ 269{
272 /* See if we got the magic character */ 270 /* See if we got the magic character */
273 if(count){ 271 if (count) {
274
275 /* 272 /*
276 * no need to check for close confirmation 273 * no need to check for close confirmation
277 * no way to disable watchdog ;) 274 * no way to disable watchdog ;)
278 */ 275 */
279 if (!nowayout) { 276 if (!nowayout) {
280 size_t ofs; 277 size_t ofs;
281
282 /* 278 /*
283 * note: just in case someone wrote the magic character 279 * note: just in case someone wrote the magic character
284 * five months ago... 280 * five months ago...
@@ -286,11 +282,11 @@ static ssize_t zf_write(struct file *file, const char __user *buf, size_t count,
286 zf_expect_close = 0; 282 zf_expect_close = 0;
287 283
288 /* now scan */ 284 /* now scan */
289 for (ofs = 0; ofs != count; ofs++){ 285 for (ofs = 0; ofs != count; ofs++) {
290 char c; 286 char c;
291 if (get_user(c, buf + ofs)) 287 if (get_user(c, buf + ofs))
292 return -EFAULT; 288 return -EFAULT;
293 if (c == 'V'){ 289 if (c == 'V') {
294 zf_expect_close = 42; 290 zf_expect_close = 42;
295 dprintk("zf_expect_close = 42\n"); 291 dprintk("zf_expect_close = 42\n");
296 } 292 }
@@ -303,14 +299,11 @@ static ssize_t zf_write(struct file *file, const char __user *buf, size_t count,
303 */ 299 */
304 next_heartbeat = jiffies + ZF_USER_TIMEO; 300 next_heartbeat = jiffies + ZF_USER_TIMEO;
305 dprintk("user ping at %ld\n", jiffies); 301 dprintk("user ping at %ld\n", jiffies);
306
307 } 302 }
308
309 return count; 303 return count;
310} 304}
311 305
312static int zf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 306static long zf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
313 unsigned long arg)
314{ 307{
315 void __user *argp = (void __user *)arg; 308 void __user *argp = (void __user *)arg;
316 int __user *p = argp; 309 int __user *p = argp;
@@ -319,55 +312,38 @@ static int zf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
319 if (copy_to_user(argp, &zf_info, sizeof(zf_info))) 312 if (copy_to_user(argp, &zf_info, sizeof(zf_info)))
320 return -EFAULT; 313 return -EFAULT;
321 break; 314 break;
322
323 case WDIOC_GETSTATUS: 315 case WDIOC_GETSTATUS:
324 case WDIOC_GETBOOTSTATUS: 316 case WDIOC_GETBOOTSTATUS:
325 return put_user(0, p); 317 return put_user(0, p);
326
327 case WDIOC_KEEPALIVE: 318 case WDIOC_KEEPALIVE:
328 zf_ping(0); 319 zf_ping(0);
329 break; 320 break;
330
331 default: 321 default:
332 return -ENOTTY; 322 return -ENOTTY;
333 } 323 }
334
335 return 0; 324 return 0;
336} 325}
337 326
338static int zf_open(struct inode *inode, struct file *file) 327static int zf_open(struct inode *inode, struct file *file)
339{ 328{
340 spin_lock(&zf_lock); 329 if (test_and_set_bit(0, &zf_is_open))
341 if(test_and_set_bit(0, &zf_is_open)) {
342 spin_unlock(&zf_lock);
343 return -EBUSY; 330 return -EBUSY;
344 }
345
346 if (nowayout) 331 if (nowayout)
347 __module_get(THIS_MODULE); 332 __module_get(THIS_MODULE);
348
349 spin_unlock(&zf_lock);
350
351 zf_timer_on(); 333 zf_timer_on();
352
353 return nonseekable_open(inode, file); 334 return nonseekable_open(inode, file);
354} 335}
355 336
356static int zf_close(struct inode *inode, struct file *file) 337static int zf_close(struct inode *inode, struct file *file)
357{ 338{
358 if(zf_expect_close == 42){ 339 if (zf_expect_close == 42)
359 zf_timer_off(); 340 zf_timer_off();
360 } else { 341 else {
361 del_timer(&zf_timer); 342 del_timer(&zf_timer);
362 printk(KERN_ERR PFX ": device file closed unexpectedly. Will not stop the WDT!\n"); 343 printk(KERN_ERR PFX ": device file closed unexpectedly. Will not stop the WDT!\n");
363 } 344 }
364
365 spin_lock(&zf_lock);
366 clear_bit(0, &zf_is_open); 345 clear_bit(0, &zf_is_open);
367 spin_unlock(&zf_lock);
368
369 zf_expect_close = 0; 346 zf_expect_close = 0;
370
371 return 0; 347 return 0;
372} 348}
373 349
@@ -378,23 +354,18 @@ static int zf_close(struct inode *inode, struct file *file)
378static int zf_notify_sys(struct notifier_block *this, unsigned long code, 354static int zf_notify_sys(struct notifier_block *this, unsigned long code,
379 void *unused) 355 void *unused)
380{ 356{
381 if(code == SYS_DOWN || code == SYS_HALT){ 357 if (code == SYS_DOWN || code == SYS_HALT)
382 zf_timer_off(); 358 zf_timer_off();
383 }
384
385 return NOTIFY_DONE; 359 return NOTIFY_DONE;
386} 360}
387 361
388
389
390
391static const struct file_operations zf_fops = { 362static const struct file_operations zf_fops = {
392 .owner = THIS_MODULE, 363 .owner = THIS_MODULE,
393 .llseek = no_llseek, 364 .llseek = no_llseek,
394 .write = zf_write, 365 .write = zf_write,
395 .ioctl = zf_ioctl, 366 .unlocked_ioctl = zf_ioctl,
396 .open = zf_open, 367 .open = zf_open,
397 .release = zf_close, 368 .release = zf_close,
398}; 369};
399 370
400static struct miscdevice zf_miscdev = { 371static struct miscdevice zf_miscdev = {
@@ -402,7 +373,7 @@ static struct miscdevice zf_miscdev = {
402 .name = "watchdog", 373 .name = "watchdog",
403 .fops = &zf_fops, 374 .fops = &zf_fops,
404}; 375};
405 376
406 377
407/* 378/*
408 * The device needs to learn about soft shutdowns in order to 379 * The device needs to learn about soft shutdowns in order to
@@ -423,22 +394,23 @@ static int __init zf_init(void)
423{ 394{
424 int ret; 395 int ret;
425 396
426 printk(KERN_INFO PFX ": MachZ ZF-Logic Watchdog driver initializing.\n"); 397 printk(KERN_INFO PFX
398 ": MachZ ZF-Logic Watchdog driver initializing.\n");
427 399
428 ret = zf_get_ZFL_version(); 400 ret = zf_get_ZFL_version();
429 if ((!ret) || (ret == 0xffff)) { 401 if (!ret || ret == 0xffff) {
430 printk(KERN_WARNING PFX ": no ZF-Logic found\n"); 402 printk(KERN_WARNING PFX ": no ZF-Logic found\n");
431 return -ENODEV; 403 return -ENODEV;
432 } 404 }
433 405
434 if((action <= 3) && (action >= 0)){ 406 if (action <= 3 && action >= 0)
435 zf_action = zf_action>>action; 407 zf_action = zf_action >> action;
436 } else 408 else
437 action = 0; 409 action = 0;
438 410
439 zf_show_action(action); 411 zf_show_action(action);
440 412
441 if(!request_region(ZF_IOBASE, 3, "MachZ ZFL WDT")){ 413 if (!request_region(ZF_IOBASE, 3, "MachZ ZFL WDT")) {
442 printk(KERN_ERR "cannot reserve I/O ports at %d\n", 414 printk(KERN_ERR "cannot reserve I/O ports at %d\n",
443 ZF_IOBASE); 415 ZF_IOBASE);
444 ret = -EBUSY; 416 ret = -EBUSY;
@@ -446,14 +418,14 @@ static int __init zf_init(void)
446 } 418 }
447 419
448 ret = register_reboot_notifier(&zf_notifier); 420 ret = register_reboot_notifier(&zf_notifier);
449 if(ret){ 421 if (ret) {
450 printk(KERN_ERR "can't register reboot notifier (err=%d)\n", 422 printk(KERN_ERR "can't register reboot notifier (err=%d)\n",
451 ret); 423 ret);
452 goto no_reboot; 424 goto no_reboot;
453 } 425 }
454 426
455 ret = misc_register(&zf_miscdev); 427 ret = misc_register(&zf_miscdev);
456 if (ret){ 428 if (ret) {
457 printk(KERN_ERR "can't misc_register on minor=%d\n", 429 printk(KERN_ERR "can't misc_register on minor=%d\n",
458 WATCHDOG_MINOR); 430 WATCHDOG_MINOR);
459 goto no_misc; 431 goto no_misc;
diff --git a/drivers/watchdog/mixcomwd.c b/drivers/watchdog/mixcomwd.c
index 1adf1d56027d..407b025cb104 100644
--- a/drivers/watchdog/mixcomwd.c
+++ b/drivers/watchdog/mixcomwd.c
@@ -29,7 +29,8 @@
29 * - support for one more type board 29 * - support for one more type board
30 * 30 *
31 * Version 0.5 (2001/12/14) Matt Domsch <Matt_Domsch@dell.com> 31 * Version 0.5 (2001/12/14) Matt Domsch <Matt_Domsch@dell.com>
32 * - added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT 32 * - added nowayout module option to override
33 * CONFIG_WATCHDOG_NOWAYOUT
33 * 34 *
34 * Version 0.6 (2002/04/12): Rob Radez <rob@osinvestor.com> 35 * Version 0.6 (2002/04/12): Rob Radez <rob@osinvestor.com>
35 * - make mixcomwd_opened unsigned, 36 * - make mixcomwd_opened unsigned,
@@ -53,8 +54,8 @@
53#include <linux/init.h> 54#include <linux/init.h>
54#include <linux/jiffies.h> 55#include <linux/jiffies.h>
55#include <linux/timer.h> 56#include <linux/timer.h>
56#include <asm/uaccess.h> 57#include <linux/uaccess.h>
57#include <asm/io.h> 58#include <linux/io.h>
58 59
59/* 60/*
60 * We have two types of cards that can be probed: 61 * We have two types of cards that can be probed:
@@ -108,18 +109,19 @@ static char expect_close;
108 109
109static int nowayout = WATCHDOG_NOWAYOUT; 110static int nowayout = WATCHDOG_NOWAYOUT;
110module_param(nowayout, int, 0); 111module_param(nowayout, int, 0);
111MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 112MODULE_PARM_DESC(nowayout,
113 "Watchdog cannot be stopped once started (default="
114 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
112 115
113static void mixcomwd_ping(void) 116static void mixcomwd_ping(void)
114{ 117{
115 outb_p(55,watchdog_port); 118 outb_p(55, watchdog_port);
116 return; 119 return;
117} 120}
118 121
119static void mixcomwd_timerfun(unsigned long d) 122static void mixcomwd_timerfun(unsigned long d)
120{ 123{
121 mixcomwd_ping(); 124 mixcomwd_ping();
122
123 mod_timer(&mixcomwd_timer, jiffies + 5 * HZ); 125 mod_timer(&mixcomwd_timer, jiffies + 5 * HZ);
124} 126}
125 127
@@ -129,22 +131,22 @@ static void mixcomwd_timerfun(unsigned long d)
129 131
130static int mixcomwd_open(struct inode *inode, struct file *file) 132static int mixcomwd_open(struct inode *inode, struct file *file)
131{ 133{
132 if(test_and_set_bit(0,&mixcomwd_opened)) { 134 if (test_and_set_bit(0, &mixcomwd_opened))
133 return -EBUSY; 135 return -EBUSY;
134 } 136
135 mixcomwd_ping(); 137 mixcomwd_ping();
136 138
137 if (nowayout) { 139 if (nowayout)
138 /* 140 /*
139 * fops_get() code via open() has already done 141 * fops_get() code via open() has already done
140 * a try_module_get() so it is safe to do the 142 * a try_module_get() so it is safe to do the
141 * __module_get(). 143 * __module_get().
142 */ 144 */
143 __module_get(THIS_MODULE); 145 __module_get(THIS_MODULE);
144 } else { 146 else {
145 if(mixcomwd_timer_alive) { 147 if (mixcomwd_timer_alive) {
146 del_timer(&mixcomwd_timer); 148 del_timer(&mixcomwd_timer);
147 mixcomwd_timer_alive=0; 149 mixcomwd_timer_alive = 0;
148 } 150 }
149 } 151 }
150 return nonseekable_open(inode, file); 152 return nonseekable_open(inode, file);
@@ -153,26 +155,27 @@ static int mixcomwd_open(struct inode *inode, struct file *file)
153static int mixcomwd_release(struct inode *inode, struct file *file) 155static int mixcomwd_release(struct inode *inode, struct file *file)
154{ 156{
155 if (expect_close == 42) { 157 if (expect_close == 42) {
156 if(mixcomwd_timer_alive) { 158 if (mixcomwd_timer_alive) {
157 printk(KERN_ERR PFX "release called while internal timer alive"); 159 printk(KERN_ERR PFX
160 "release called while internal timer alive");
158 return -EBUSY; 161 return -EBUSY;
159 } 162 }
160 mixcomwd_timer_alive=1; 163 mixcomwd_timer_alive = 1;
161 mod_timer(&mixcomwd_timer, jiffies + 5 * HZ); 164 mod_timer(&mixcomwd_timer, jiffies + 5 * HZ);
162 } else { 165 } else
163 printk(KERN_CRIT PFX "WDT device closed unexpectedly. WDT will not stop!\n"); 166 printk(KERN_CRIT PFX
164 } 167 "WDT device closed unexpectedly. WDT will not stop!\n");
165 168
166 clear_bit(0,&mixcomwd_opened); 169 clear_bit(0, &mixcomwd_opened);
167 expect_close=0; 170 expect_close = 0;
168 return 0; 171 return 0;
169} 172}
170 173
171 174
172static ssize_t mixcomwd_write(struct file *file, const char __user *data, size_t len, loff_t *ppos) 175static ssize_t mixcomwd_write(struct file *file, const char __user *data,
176 size_t len, loff_t *ppos)
173{ 177{
174 if(len) 178 if (len) {
175 {
176 if (!nowayout) { 179 if (!nowayout) {
177 size_t i; 180 size_t i;
178 181
@@ -192,8 +195,8 @@ static ssize_t mixcomwd_write(struct file *file, const char __user *data, size_t
192 return len; 195 return len;
193} 196}
194 197
195static int mixcomwd_ioctl(struct inode *inode, struct file *file, 198static long mixcomwd_ioctl(struct file *file,
196 unsigned int cmd, unsigned long arg) 199 unsigned int cmd, unsigned long arg)
197{ 200{
198 void __user *argp = (void __user *)arg; 201 void __user *argp = (void __user *)arg;
199 int __user *p = argp; 202 int __user *p = argp;
@@ -204,32 +207,23 @@ static int mixcomwd_ioctl(struct inode *inode, struct file *file,
204 .identity = "MixCOM watchdog", 207 .identity = "MixCOM watchdog",
205 }; 208 };
206 209
207 switch(cmd) 210 switch (cmd) {
208 { 211 case WDIOC_GETSUPPORT:
209 case WDIOC_GETSTATUS: 212 if (copy_to_user(argp, &ident, sizeof(ident)))
210 status=mixcomwd_opened; 213 return -EFAULT;
211 if (!nowayout) { 214 break;
212 status|=mixcomwd_timer_alive; 215 case WDIOC_GETSTATUS:
213 } 216 status = mixcomwd_opened;
214 if (copy_to_user(p, &status, sizeof(int))) { 217 if (!nowayout)
215 return -EFAULT; 218 status |= mixcomwd_timer_alive;
216 } 219 return put_user(status, p);
217 break; 220 case WDIOC_GETBOOTSTATUS:
218 case WDIOC_GETBOOTSTATUS: 221 return put_user(0, p);
219 if (copy_to_user(p, &status, sizeof(int))) { 222 case WDIOC_KEEPALIVE:
220 return -EFAULT; 223 mixcomwd_ping();
221 } 224 break;
222 break; 225 default:
223 case WDIOC_GETSUPPORT: 226 return -ENOTTY;
224 if (copy_to_user(argp, &ident, sizeof(ident))) {
225 return -EFAULT;
226 }
227 break;
228 case WDIOC_KEEPALIVE:
229 mixcomwd_ping();
230 break;
231 default:
232 return -ENOTTY;
233 } 227 }
234 return 0; 228 return 0;
235} 229}
@@ -238,7 +232,7 @@ static const struct file_operations mixcomwd_fops = {
238 .owner = THIS_MODULE, 232 .owner = THIS_MODULE,
239 .llseek = no_llseek, 233 .llseek = no_llseek,
240 .write = mixcomwd_write, 234 .write = mixcomwd_write,
241 .ioctl = mixcomwd_ioctl, 235 .unlocked_ioctl = mixcomwd_ioctl,
242 .open = mixcomwd_open, 236 .open = mixcomwd_open,
243 .release = mixcomwd_release, 237 .release = mixcomwd_release,
244}; 238};
@@ -253,15 +247,14 @@ static int __init checkcard(int port, int card_id)
253{ 247{
254 int id; 248 int id;
255 249
256 if (!request_region(port, 1, "MixCOM watchdog")) { 250 if (!request_region(port, 1, "MixCOM watchdog"))
257 return 0; 251 return 0;
258 }
259 252
260 id=inb_p(port); 253 id = inb_p(port);
261 if (card_id==MIXCOM_ID) 254 if (card_id == MIXCOM_ID)
262 id &= 0x3f; 255 id &= 0x3f;
263 256
264 if (id!=card_id) { 257 if (id != card_id) {
265 release_region(port, 1); 258 release_region(port, 1);
266 return 0; 259 return 0;
267 } 260 }
@@ -270,9 +263,7 @@ static int __init checkcard(int port, int card_id)
270 263
271static int __init mixcomwd_init(void) 264static int __init mixcomwd_init(void)
272{ 265{
273 int i; 266 int i, ret, found = 0;
274 int ret;
275 int found=0;
276 267
277 for (i = 0; !found && mixcomwd_io_info[i].ioport != 0; i++) { 268 for (i = 0; !found && mixcomwd_io_info[i].ioport != 0; i++) {
278 if (checkcard(mixcomwd_io_info[i].ioport, 269 if (checkcard(mixcomwd_io_info[i].ioport,
@@ -283,20 +274,22 @@ static int __init mixcomwd_init(void)
283 } 274 }
284 275
285 if (!found) { 276 if (!found) {
286 printk(KERN_ERR PFX "No card detected, or port not available.\n"); 277 printk(KERN_ERR PFX
278 "No card detected, or port not available.\n");
287 return -ENODEV; 279 return -ENODEV;
288 } 280 }
289 281
290 ret = misc_register(&mixcomwd_miscdev); 282 ret = misc_register(&mixcomwd_miscdev);
291 if (ret) 283 if (ret) {
292 { 284 printk(KERN_ERR PFX
293 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 285 "cannot register miscdev on minor=%d (err=%d)\n",
294 WATCHDOG_MINOR, ret); 286 WATCHDOG_MINOR, ret);
295 goto error_misc_register_watchdog; 287 goto error_misc_register_watchdog;
296 } 288 }
297 289
298 printk(KERN_INFO "MixCOM watchdog driver v%s, watchdog port at 0x%3x\n", 290 printk(KERN_INFO
299 VERSION, watchdog_port); 291 "MixCOM watchdog driver v%s, watchdog port at 0x%3x\n",
292 VERSION, watchdog_port);
300 293
301 return 0; 294 return 0;
302 295
@@ -309,15 +302,15 @@ error_misc_register_watchdog:
309static void __exit mixcomwd_exit(void) 302static void __exit mixcomwd_exit(void)
310{ 303{
311 if (!nowayout) { 304 if (!nowayout) {
312 if(mixcomwd_timer_alive) { 305 if (mixcomwd_timer_alive) {
313 printk(KERN_WARNING PFX "I quit now, hardware will" 306 printk(KERN_WARNING PFX "I quit now, hardware will"
314 " probably reboot!\n"); 307 " probably reboot!\n");
315 del_timer_sync(&mixcomwd_timer); 308 del_timer_sync(&mixcomwd_timer);
316 mixcomwd_timer_alive=0; 309 mixcomwd_timer_alive = 0;
317 } 310 }
318 } 311 }
319 misc_deregister(&mixcomwd_miscdev); 312 misc_deregister(&mixcomwd_miscdev);
320 release_region(watchdog_port,1); 313 release_region(watchdog_port, 1);
321} 314}
322 315
323module_init(mixcomwd_init); 316module_init(mixcomwd_init);
diff --git a/drivers/watchdog/mpc5200_wdt.c b/drivers/watchdog/mpc5200_wdt.c
index 77c1c2ae2cc2..db91892558f2 100644
--- a/drivers/watchdog/mpc5200_wdt.c
+++ b/drivers/watchdog/mpc5200_wdt.c
@@ -5,7 +5,7 @@
5#include <linux/io.h> 5#include <linux/io.h>
6#include <linux/spinlock.h> 6#include <linux/spinlock.h>
7#include <linux/of_platform.h> 7#include <linux/of_platform.h>
8#include <asm/uaccess.h> 8#include <linux/uaccess.h>
9#include <asm/mpc52xx.h> 9#include <asm/mpc52xx.h>
10 10
11 11
@@ -57,7 +57,8 @@ static int mpc5200_wdt_start(struct mpc5200_wdt *wdt)
57 /* set timeout, with maximum prescaler */ 57 /* set timeout, with maximum prescaler */
58 out_be32(&wdt->regs->count, 0x0 | wdt->count); 58 out_be32(&wdt->regs->count, 0x0 | wdt->count);
59 /* enable watchdog */ 59 /* enable watchdog */
60 out_be32(&wdt->regs->mode, GPT_MODE_CE | GPT_MODE_WDT | GPT_MODE_MS_TIMER); 60 out_be32(&wdt->regs->mode, GPT_MODE_CE | GPT_MODE_WDT |
61 GPT_MODE_MS_TIMER);
61 spin_unlock(&wdt->io_lock); 62 spin_unlock(&wdt->io_lock);
62 63
63 return 0; 64 return 0;
@@ -66,7 +67,8 @@ static int mpc5200_wdt_ping(struct mpc5200_wdt *wdt)
66{ 67{
67 spin_lock(&wdt->io_lock); 68 spin_lock(&wdt->io_lock);
68 /* writing A5 to OCPW resets the watchdog */ 69 /* writing A5 to OCPW resets the watchdog */
69 out_be32(&wdt->regs->mode, 0xA5000000 | (0xffffff & in_be32(&wdt->regs->mode))); 70 out_be32(&wdt->regs->mode, 0xA5000000 |
71 (0xffffff & in_be32(&wdt->regs->mode)));
70 spin_unlock(&wdt->io_lock); 72 spin_unlock(&wdt->io_lock);
71 return 0; 73 return 0;
72} 74}
@@ -92,8 +94,8 @@ static struct watchdog_info mpc5200_wdt_info = {
92 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 94 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
93 .identity = "mpc5200 watchdog on GPT0", 95 .identity = "mpc5200 watchdog on GPT0",
94}; 96};
95static int mpc5200_wdt_ioctl(struct inode *inode, struct file *file, 97static long mpc5200_wdt_ioctl(struct file *file, unsigned int cmd,
96 unsigned int cmd, unsigned long arg) 98 unsigned long arg)
97{ 99{
98 struct mpc5200_wdt *wdt = file->private_data; 100 struct mpc5200_wdt *wdt = file->private_data;
99 int __user *data = (int __user *)arg; 101 int __user *data = (int __user *)arg;
@@ -103,7 +105,7 @@ static int mpc5200_wdt_ioctl(struct inode *inode, struct file *file,
103 switch (cmd) { 105 switch (cmd) {
104 case WDIOC_GETSUPPORT: 106 case WDIOC_GETSUPPORT:
105 ret = copy_to_user(data, &mpc5200_wdt_info, 107 ret = copy_to_user(data, &mpc5200_wdt_info,
106 sizeof(mpc5200_wdt_info)); 108 sizeof(mpc5200_wdt_info));
107 if (ret) 109 if (ret)
108 ret = -EFAULT; 110 ret = -EFAULT;
109 break; 111 break;
@@ -135,6 +137,7 @@ static int mpc5200_wdt_ioctl(struct inode *inode, struct file *file,
135 } 137 }
136 return ret; 138 return ret;
137} 139}
140
138static int mpc5200_wdt_open(struct inode *inode, struct file *file) 141static int mpc5200_wdt_open(struct inode *inode, struct file *file)
139{ 142{
140 /* /dev/watchdog can only be opened once */ 143 /* /dev/watchdog can only be opened once */
@@ -161,13 +164,14 @@ static int mpc5200_wdt_release(struct inode *inode, struct file *file)
161static const struct file_operations mpc5200_wdt_fops = { 164static const struct file_operations mpc5200_wdt_fops = {
162 .owner = THIS_MODULE, 165 .owner = THIS_MODULE,
163 .write = mpc5200_wdt_write, 166 .write = mpc5200_wdt_write,
164 .ioctl = mpc5200_wdt_ioctl, 167 .unlocked_ioctl = mpc5200_wdt_ioctl,
165 .open = mpc5200_wdt_open, 168 .open = mpc5200_wdt_open,
166 .release = mpc5200_wdt_release, 169 .release = mpc5200_wdt_release,
167}; 170};
168 171
169/* module operations */ 172/* module operations */
170static int mpc5200_wdt_probe(struct of_device *op, const struct of_device_id *match) 173static int mpc5200_wdt_probe(struct of_device *op,
174 const struct of_device_id *match)
171{ 175{
172 struct mpc5200_wdt *wdt; 176 struct mpc5200_wdt *wdt;
173 int err; 177 int err;
@@ -215,9 +219,9 @@ static int mpc5200_wdt_probe(struct of_device *op, const struct of_device_id *ma
215 return 0; 219 return 0;
216 220
217 iounmap(wdt->regs); 221 iounmap(wdt->regs);
218 out_release: 222out_release:
219 release_mem_region(wdt->mem.start, size); 223 release_mem_region(wdt->mem.start, size);
220 out_free: 224out_free:
221 kfree(wdt); 225 kfree(wdt);
222 return err; 226 return err;
223} 227}
diff --git a/drivers/watchdog/mpc83xx_wdt.c b/drivers/watchdog/mpc83xx_wdt.c
deleted file mode 100644
index b16c5cd972eb..000000000000
--- a/drivers/watchdog/mpc83xx_wdt.c
+++ /dev/null
@@ -1,230 +0,0 @@
1/*
2 * mpc83xx_wdt.c - MPC83xx watchdog userspace interface
3 *
4 * Authors: Dave Updegraff <dave@cray.org>
5 * Kumar Gala <galak@kernel.crashing.org>
6 * Attribution: from 83xx_wst: Florian Schirmer <jolt@tuxbox.org>
7 * ..and from sc520_wdt
8 *
9 * Note: it appears that you can only actually ENABLE or DISABLE the thing
10 * once after POR. Once enabled, you cannot disable, and vice versa.
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 */
17
18#include <linux/fs.h>
19#include <linux/init.h>
20#include <linux/kernel.h>
21#include <linux/miscdevice.h>
22#include <linux/platform_device.h>
23#include <linux/module.h>
24#include <linux/watchdog.h>
25#include <asm/io.h>
26#include <asm/uaccess.h>
27
28struct mpc83xx_wdt {
29 __be32 res0;
30 __be32 swcrr; /* System watchdog control register */
31#define SWCRR_SWTC 0xFFFF0000 /* Software Watchdog Time Count. */
32#define SWCRR_SWEN 0x00000004 /* Watchdog Enable bit. */
33#define SWCRR_SWRI 0x00000002 /* Software Watchdog Reset/Interrupt Select bit.*/
34#define SWCRR_SWPR 0x00000001 /* Software Watchdog Counter Prescale bit. */
35 __be32 swcnr; /* System watchdog count register */
36 u8 res1[2];
37 __be16 swsrr; /* System watchdog service register */
38 u8 res2[0xF0];
39};
40
41static struct mpc83xx_wdt __iomem *wd_base;
42
43static u16 timeout = 0xffff;
44module_param(timeout, ushort, 0);
45MODULE_PARM_DESC(timeout, "Watchdog timeout in ticks. (0<timeout<65536, default=65535");
46
47static int reset = 1;
48module_param(reset, bool, 0);
49MODULE_PARM_DESC(reset, "Watchdog Interrupt/Reset Mode. 0 = interrupt, 1 = reset");
50
51/*
52 * We always prescale, but if someone really doesn't want to they can set this
53 * to 0
54 */
55static int prescale = 1;
56static unsigned int timeout_sec;
57
58static unsigned long wdt_is_open;
59static DEFINE_SPINLOCK(wdt_spinlock);
60
61static void mpc83xx_wdt_keepalive(void)
62{
63 /* Ping the WDT */
64 spin_lock(&wdt_spinlock);
65 out_be16(&wd_base->swsrr, 0x556c);
66 out_be16(&wd_base->swsrr, 0xaa39);
67 spin_unlock(&wdt_spinlock);
68}
69
70static ssize_t mpc83xx_wdt_write(struct file *file, const char __user *buf,
71 size_t count, loff_t *ppos)
72{
73 if (count)
74 mpc83xx_wdt_keepalive();
75 return count;
76}
77
78static int mpc83xx_wdt_open(struct inode *inode, struct file *file)
79{
80 u32 tmp = SWCRR_SWEN;
81 if (test_and_set_bit(0, &wdt_is_open))
82 return -EBUSY;
83
84 /* Once we start the watchdog we can't stop it */
85 __module_get(THIS_MODULE);
86
87 /* Good, fire up the show */
88 if (prescale)
89 tmp |= SWCRR_SWPR;
90 if (reset)
91 tmp |= SWCRR_SWRI;
92
93 tmp |= timeout << 16;
94
95 out_be32(&wd_base->swcrr, tmp);
96
97 return nonseekable_open(inode, file);
98}
99
100static int mpc83xx_wdt_release(struct inode *inode, struct file *file)
101{
102 printk(KERN_CRIT "Unexpected close, not stopping watchdog!\n");
103 mpc83xx_wdt_keepalive();
104 clear_bit(0, &wdt_is_open);
105 return 0;
106}
107
108static int mpc83xx_wdt_ioctl(struct inode *inode, struct file *file,
109 unsigned int cmd, unsigned long arg)
110{
111 void __user *argp = (void __user *)arg;
112 int __user *p = argp;
113 static struct watchdog_info ident = {
114 .options = WDIOF_KEEPALIVEPING,
115 .firmware_version = 1,
116 .identity = "MPC83xx",
117 };
118
119 switch (cmd) {
120 case WDIOC_GETSUPPORT:
121 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
122 case WDIOC_GETSTATUS:
123 case WDIOC_GETBOOTSTATUS:
124 return put_user(0, p);
125 case WDIOC_KEEPALIVE:
126 mpc83xx_wdt_keepalive();
127 return 0;
128 case WDIOC_GETTIMEOUT:
129 return put_user(timeout_sec, p);
130 default:
131 return -ENOTTY;
132 }
133}
134
135static const struct file_operations mpc83xx_wdt_fops = {
136 .owner = THIS_MODULE,
137 .llseek = no_llseek,
138 .write = mpc83xx_wdt_write,
139 .ioctl = mpc83xx_wdt_ioctl,
140 .open = mpc83xx_wdt_open,
141 .release = mpc83xx_wdt_release,
142};
143
144static struct miscdevice mpc83xx_wdt_miscdev = {
145 .minor = WATCHDOG_MINOR,
146 .name = "watchdog",
147 .fops = &mpc83xx_wdt_fops,
148};
149
150static int __devinit mpc83xx_wdt_probe(struct platform_device *dev)
151{
152 struct resource *r;
153 int ret;
154 unsigned int *freq = dev->dev.platform_data;
155
156 /* get a pointer to the register memory */
157 r = platform_get_resource(dev, IORESOURCE_MEM, 0);
158
159 if (!r) {
160 ret = -ENODEV;
161 goto err_out;
162 }
163
164 wd_base = ioremap(r->start, sizeof (struct mpc83xx_wdt));
165
166 if (wd_base == NULL) {
167 ret = -ENOMEM;
168 goto err_out;
169 }
170
171 ret = misc_register(&mpc83xx_wdt_miscdev);
172 if (ret) {
173 printk(KERN_ERR "cannot register miscdev on minor=%d "
174 "(err=%d)\n",
175 WATCHDOG_MINOR, ret);
176 goto err_unmap;
177 }
178
179 /* Calculate the timeout in seconds */
180 if (prescale)
181 timeout_sec = (timeout * 0x10000) / (*freq);
182 else
183 timeout_sec = timeout / (*freq);
184
185 printk(KERN_INFO "WDT driver for MPC83xx initialized. "
186 "mode:%s timeout=%d (%d seconds)\n",
187 reset ? "reset":"interrupt", timeout, timeout_sec);
188 return 0;
189
190err_unmap:
191 iounmap(wd_base);
192err_out:
193 return ret;
194}
195
196static int __devexit mpc83xx_wdt_remove(struct platform_device *dev)
197{
198 misc_deregister(&mpc83xx_wdt_miscdev);
199 iounmap(wd_base);
200
201 return 0;
202}
203
204static struct platform_driver mpc83xx_wdt_driver = {
205 .probe = mpc83xx_wdt_probe,
206 .remove = __devexit_p(mpc83xx_wdt_remove),
207 .driver = {
208 .name = "mpc83xx_wdt",
209 .owner = THIS_MODULE,
210 },
211};
212
213static int __init mpc83xx_wdt_init(void)
214{
215 return platform_driver_register(&mpc83xx_wdt_driver);
216}
217
218static void __exit mpc83xx_wdt_exit(void)
219{
220 platform_driver_unregister(&mpc83xx_wdt_driver);
221}
222
223module_init(mpc83xx_wdt_init);
224module_exit(mpc83xx_wdt_exit);
225
226MODULE_AUTHOR("Dave Updegraff, Kumar Gala");
227MODULE_DESCRIPTION("Driver for watchdog timer in MPC83xx uProcessor");
228MODULE_LICENSE("GPL");
229MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
230MODULE_ALIAS("platform:mpc83xx_wdt");
diff --git a/drivers/watchdog/mpc8xx_wdt.c b/drivers/watchdog/mpc8xx_wdt.c
index 85b5734403a5..1336425acf20 100644
--- a/drivers/watchdog/mpc8xx_wdt.c
+++ b/drivers/watchdog/mpc8xx_wdt.c
@@ -16,36 +16,35 @@
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/watchdog.h> 17#include <linux/watchdog.h>
18#include <asm/8xx_immap.h> 18#include <asm/8xx_immap.h>
19#include <asm/uaccess.h> 19#include <linux/uaccess.h>
20#include <asm/io.h> 20#include <linux/io.h>
21#include <syslib/m8xx_wdt.h> 21#include <syslib/m8xx_wdt.h>
22 22
23static unsigned long wdt_opened; 23static unsigned long wdt_opened;
24static int wdt_status; 24static int wdt_status;
25static spinlock_t wdt_lock;
25 26
26static void mpc8xx_wdt_handler_disable(void) 27static void mpc8xx_wdt_handler_disable(void)
27{ 28{
28 volatile uint __iomem *piscr; 29 volatile uint __iomem *piscr;
29 piscr = (uint *)&((immap_t*)IMAP_ADDR)->im_sit.sit_piscr; 30 piscr = (uint *)&((immap_t *)IMAP_ADDR)->im_sit.sit_piscr;
30 31
31 if (!m8xx_has_internal_rtc) 32 if (!m8xx_has_internal_rtc)
32 m8xx_wdt_stop_timer(); 33 m8xx_wdt_stop_timer();
33 else 34 else
34 out_be32(piscr, in_be32(piscr) & ~(PISCR_PIE | PISCR_PTE)); 35 out_be32(piscr, in_be32(piscr) & ~(PISCR_PIE | PISCR_PTE));
35
36 printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler deactivated\n"); 36 printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler deactivated\n");
37} 37}
38 38
39static void mpc8xx_wdt_handler_enable(void) 39static void mpc8xx_wdt_handler_enable(void)
40{ 40{
41 volatile uint __iomem *piscr; 41 volatile uint __iomem *piscr;
42 piscr = (uint *)&((immap_t*)IMAP_ADDR)->im_sit.sit_piscr; 42 piscr = (uint *)&((immap_t *)IMAP_ADDR)->im_sit.sit_piscr;
43 43
44 if (!m8xx_has_internal_rtc) 44 if (!m8xx_has_internal_rtc)
45 m8xx_wdt_install_timer(); 45 m8xx_wdt_install_timer();
46 else 46 else
47 out_be32(piscr, in_be32(piscr) | PISCR_PIE | PISCR_PTE); 47 out_be32(piscr, in_be32(piscr) | PISCR_PIE | PISCR_PTE);
48
49 printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler activated\n"); 48 printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler activated\n");
50} 49}
51 50
@@ -53,37 +52,34 @@ static int mpc8xx_wdt_open(struct inode *inode, struct file *file)
53{ 52{
54 if (test_and_set_bit(0, &wdt_opened)) 53 if (test_and_set_bit(0, &wdt_opened))
55 return -EBUSY; 54 return -EBUSY;
56
57 m8xx_wdt_reset(); 55 m8xx_wdt_reset();
58 mpc8xx_wdt_handler_disable(); 56 mpc8xx_wdt_handler_disable();
59
60 return nonseekable_open(inode, file); 57 return nonseekable_open(inode, file);
61} 58}
62 59
63static int mpc8xx_wdt_release(struct inode *inode, struct file *file) 60static int mpc8xx_wdt_release(struct inode *inode, struct file *file)
64{ 61{
65 m8xx_wdt_reset(); 62 m8xx_wdt_reset();
66
67#if !defined(CONFIG_WATCHDOG_NOWAYOUT) 63#if !defined(CONFIG_WATCHDOG_NOWAYOUT)
68 mpc8xx_wdt_handler_enable(); 64 mpc8xx_wdt_handler_enable();
69#endif 65#endif
70
71 clear_bit(0, &wdt_opened); 66 clear_bit(0, &wdt_opened);
72
73 return 0; 67 return 0;
74} 68}
75 69
76static ssize_t mpc8xx_wdt_write(struct file *file, const char *data, size_t len, 70static ssize_t mpc8xx_wdt_write(struct file *file, const char *data,
77 loff_t * ppos) 71 size_t len, loff_t *ppos)
78{ 72{
79 if (len) 73 if (len) {
74 spin_lock(&wdt_lock);
80 m8xx_wdt_reset(); 75 m8xx_wdt_reset();
81 76 spin_unlock(&wdt_lock);
77 }
82 return len; 78 return len;
83} 79}
84 80
85static int mpc8xx_wdt_ioctl(struct inode *inode, struct file *file, 81static long mpc8xx_wdt_ioctl(struct file *file,
86 unsigned int cmd, unsigned long arg) 82 unsigned int cmd, unsigned long arg)
87{ 83{
88 int timeout; 84 int timeout;
89 static struct watchdog_info info = { 85 static struct watchdog_info info = {
@@ -112,15 +108,19 @@ static int mpc8xx_wdt_ioctl(struct inode *inode, struct file *file,
112 return -EOPNOTSUPP; 108 return -EOPNOTSUPP;
113 109
114 case WDIOC_KEEPALIVE: 110 case WDIOC_KEEPALIVE:
111 spin_lock(&wdt_lock);
115 m8xx_wdt_reset(); 112 m8xx_wdt_reset();
116 wdt_status |= WDIOF_KEEPALIVEPING; 113 wdt_status |= WDIOF_KEEPALIVEPING;
114 spin_unlock(&wdt_lock);
117 break; 115 break;
118 116
119 case WDIOC_SETTIMEOUT: 117 case WDIOC_SETTIMEOUT:
120 return -EOPNOTSUPP; 118 return -EOPNOTSUPP;
121 119
122 case WDIOC_GETTIMEOUT: 120 case WDIOC_GETTIMEOUT:
121 spin_lock(&wdt_lock);
123 timeout = m8xx_wdt_get_timeout(); 122 timeout = m8xx_wdt_get_timeout();
123 spin_unlock(&wdt_lock);
124 if (put_user(timeout, (int *)arg)) 124 if (put_user(timeout, (int *)arg))
125 return -EFAULT; 125 return -EFAULT;
126 break; 126 break;
@@ -136,7 +136,7 @@ static const struct file_operations mpc8xx_wdt_fops = {
136 .owner = THIS_MODULE, 136 .owner = THIS_MODULE,
137 .llseek = no_llseek, 137 .llseek = no_llseek,
138 .write = mpc8xx_wdt_write, 138 .write = mpc8xx_wdt_write,
139 .ioctl = mpc8xx_wdt_ioctl, 139 .unlocked_ioctl = mpc8xx_wdt_ioctl,
140 .open = mpc8xx_wdt_open, 140 .open = mpc8xx_wdt_open,
141 .release = mpc8xx_wdt_release, 141 .release = mpc8xx_wdt_release,
142}; 142};
@@ -149,6 +149,7 @@ static struct miscdevice mpc8xx_wdt_miscdev = {
149 149
150static int __init mpc8xx_wdt_init(void) 150static int __init mpc8xx_wdt_init(void)
151{ 151{
152 spin_lock_init(&wdt_lock);
152 return misc_register(&mpc8xx_wdt_miscdev); 153 return misc_register(&mpc8xx_wdt_miscdev);
153} 154}
154 155
diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c
new file mode 100644
index 000000000000..f2094960e662
--- /dev/null
+++ b/drivers/watchdog/mpc8xxx_wdt.c
@@ -0,0 +1,316 @@
1/*
2 * mpc8xxx_wdt.c - MPC8xx/MPC83xx/MPC86xx watchdog userspace interface
3 *
4 * Authors: Dave Updegraff <dave@cray.org>
5 * Kumar Gala <galak@kernel.crashing.org>
6 * Attribution: from 83xx_wst: Florian Schirmer <jolt@tuxbox.org>
7 * ..and from sc520_wdt
8 * Copyright (c) 2008 MontaVista Software, Inc.
9 * Anton Vorontsov <avorontsov@ru.mvista.com>
10 *
11 * Note: it appears that you can only actually ENABLE or DISABLE the thing
12 * once after POR. Once enabled, you cannot disable, and vice versa.
13 *
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; either version 2 of the License, or (at your
17 * option) any later version.
18 */
19
20#include <linux/fs.h>
21#include <linux/init.h>
22#include <linux/kernel.h>
23#include <linux/timer.h>
24#include <linux/miscdevice.h>
25#include <linux/of_platform.h>
26#include <linux/module.h>
27#include <linux/watchdog.h>
28#include <linux/io.h>
29#include <linux/uaccess.h>
30#include <sysdev/fsl_soc.h>
31
32struct mpc8xxx_wdt {
33 __be32 res0;
34 __be32 swcrr; /* System watchdog control register */
35#define SWCRR_SWTC 0xFFFF0000 /* Software Watchdog Time Count. */
36#define SWCRR_SWEN 0x00000004 /* Watchdog Enable bit. */
37#define SWCRR_SWRI 0x00000002 /* Software Watchdog Reset/Interrupt Select bit.*/
38#define SWCRR_SWPR 0x00000001 /* Software Watchdog Counter Prescale bit. */
39 __be32 swcnr; /* System watchdog count register */
40 u8 res1[2];
41 __be16 swsrr; /* System watchdog service register */
42 u8 res2[0xF0];
43};
44
45struct mpc8xxx_wdt_type {
46 int prescaler;
47 bool hw_enabled;
48};
49
50static struct mpc8xxx_wdt __iomem *wd_base;
51
52static u16 timeout = 0xffff;
53module_param(timeout, ushort, 0);
54MODULE_PARM_DESC(timeout,
55 "Watchdog timeout in ticks. (0<timeout<65536, default=65535");
56
57static int reset = 1;
58module_param(reset, bool, 0);
59MODULE_PARM_DESC(reset,
60 "Watchdog Interrupt/Reset Mode. 0 = interrupt, 1 = reset");
61
62static int nowayout = WATCHDOG_NOWAYOUT;
63module_param(nowayout, int, 0);
64MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
65 "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
66
67/*
68 * We always prescale, but if someone really doesn't want to they can set this
69 * to 0
70 */
71static int prescale = 1;
72static unsigned int timeout_sec;
73
74static unsigned long wdt_is_open;
75static DEFINE_SPINLOCK(wdt_spinlock);
76
77static void mpc8xxx_wdt_keepalive(void)
78{
79 /* Ping the WDT */
80 spin_lock(&wdt_spinlock);
81 out_be16(&wd_base->swsrr, 0x556c);
82 out_be16(&wd_base->swsrr, 0xaa39);
83 spin_unlock(&wdt_spinlock);
84}
85
86static void mpc8xxx_wdt_timer_ping(unsigned long arg);
87static DEFINE_TIMER(wdt_timer, mpc8xxx_wdt_timer_ping, 0, 0);
88
89static void mpc8xxx_wdt_timer_ping(unsigned long arg)
90{
91 mpc8xxx_wdt_keepalive();
92 /* We're pinging it twice faster than needed, just to be sure. */
93 mod_timer(&wdt_timer, jiffies + HZ * timeout_sec / 2);
94}
95
96static void mpc8xxx_wdt_pr_warn(const char *msg)
97{
98 pr_crit("mpc8xxx_wdt: %s, expect the %s soon!\n", msg,
99 reset ? "reset" : "machine check exception");
100}
101
102static ssize_t mpc8xxx_wdt_write(struct file *file, const char __user *buf,
103 size_t count, loff_t *ppos)
104{
105 if (count)
106 mpc8xxx_wdt_keepalive();
107 return count;
108}
109
110static int mpc8xxx_wdt_open(struct inode *inode, struct file *file)
111{
112 u32 tmp = SWCRR_SWEN;
113 if (test_and_set_bit(0, &wdt_is_open))
114 return -EBUSY;
115
116 /* Once we start the watchdog we can't stop it */
117 if (nowayout)
118 __module_get(THIS_MODULE);
119
120 /* Good, fire up the show */
121 if (prescale)
122 tmp |= SWCRR_SWPR;
123 if (reset)
124 tmp |= SWCRR_SWRI;
125
126 tmp |= timeout << 16;
127
128 out_be32(&wd_base->swcrr, tmp);
129
130 del_timer_sync(&wdt_timer);
131
132 return nonseekable_open(inode, file);
133}
134
135static int mpc8xxx_wdt_release(struct inode *inode, struct file *file)
136{
137 if (!nowayout)
138 mpc8xxx_wdt_timer_ping(0);
139 else
140 mpc8xxx_wdt_pr_warn("watchdog closed");
141 clear_bit(0, &wdt_is_open);
142 return 0;
143}
144
145static long mpc8xxx_wdt_ioctl(struct file *file, unsigned int cmd,
146 unsigned long arg)
147{
148 void __user *argp = (void __user *)arg;
149 int __user *p = argp;
150 static struct watchdog_info ident = {
151 .options = WDIOF_KEEPALIVEPING,
152 .firmware_version = 1,
153 .identity = "MPC8xxx",
154 };
155
156 switch (cmd) {
157 case WDIOC_GETSUPPORT:
158 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
159 case WDIOC_GETSTATUS:
160 case WDIOC_GETBOOTSTATUS:
161 return put_user(0, p);
162 case WDIOC_KEEPALIVE:
163 mpc8xxx_wdt_keepalive();
164 return 0;
165 case WDIOC_GETTIMEOUT:
166 return put_user(timeout_sec, p);
167 default:
168 return -ENOTTY;
169 }
170}
171
172static const struct file_operations mpc8xxx_wdt_fops = {
173 .owner = THIS_MODULE,
174 .llseek = no_llseek,
175 .write = mpc8xxx_wdt_write,
176 .unlocked_ioctl = mpc8xxx_wdt_ioctl,
177 .open = mpc8xxx_wdt_open,
178 .release = mpc8xxx_wdt_release,
179};
180
181static struct miscdevice mpc8xxx_wdt_miscdev = {
182 .minor = WATCHDOG_MINOR,
183 .name = "watchdog",
184 .fops = &mpc8xxx_wdt_fops,
185};
186
187static int __devinit mpc8xxx_wdt_probe(struct of_device *ofdev,
188 const struct of_device_id *match)
189{
190 int ret;
191 struct device_node *np = ofdev->node;
192 struct mpc8xxx_wdt_type *wdt_type = match->data;
193 u32 freq = fsl_get_sys_freq();
194 bool enabled;
195
196 if (!freq || freq == -1)
197 return -EINVAL;
198
199 wd_base = of_iomap(np, 0);
200 if (!wd_base)
201 return -ENOMEM;
202
203 enabled = in_be32(&wd_base->swcrr) & SWCRR_SWEN;
204 if (!enabled && wdt_type->hw_enabled) {
205 pr_info("mpc8xxx_wdt: could not be enabled in software\n");
206 ret = -ENOSYS;
207 goto err_unmap;
208 }
209
210 /* Calculate the timeout in seconds */
211 if (prescale)
212 timeout_sec = (timeout * wdt_type->prescaler) / freq;
213 else
214 timeout_sec = timeout / freq;
215
216 pr_info("WDT driver for MPC8xxx initialized. mode:%s timeout=%d "
217 "(%d seconds)\n", reset ? "reset" : "interrupt", timeout,
218 timeout_sec);
219
220 /*
221 * If the watchdog was previously enabled or we're running on
222 * MPC8xxx, we should ping the wdt from the kernel until the
223 * userspace handles it.
224 */
225 if (enabled)
226 mpc8xxx_wdt_timer_ping(0);
227 return 0;
228err_unmap:
229 iounmap(wd_base);
230 wd_base = NULL;
231 return ret;
232}
233
234static int __devexit mpc8xxx_wdt_remove(struct of_device *ofdev)
235{
236 mpc8xxx_wdt_pr_warn("watchdog removed");
237 del_timer_sync(&wdt_timer);
238 misc_deregister(&mpc8xxx_wdt_miscdev);
239 iounmap(wd_base);
240
241 return 0;
242}
243
244static const struct of_device_id mpc8xxx_wdt_match[] = {
245 {
246 .compatible = "mpc83xx_wdt",
247 .data = &(struct mpc8xxx_wdt_type) {
248 .prescaler = 0x10000,
249 },
250 },
251 {
252 .compatible = "fsl,mpc8610-wdt",
253 .data = &(struct mpc8xxx_wdt_type) {
254 .prescaler = 0x10000,
255 .hw_enabled = true,
256 },
257 },
258 {
259 .compatible = "fsl,mpc823-wdt",
260 .data = &(struct mpc8xxx_wdt_type) {
261 .prescaler = 0x800,
262 },
263 },
264 {},
265};
266MODULE_DEVICE_TABLE(of, mpc8xxx_wdt_match);
267
268static struct of_platform_driver mpc8xxx_wdt_driver = {
269 .match_table = mpc8xxx_wdt_match,
270 .probe = mpc8xxx_wdt_probe,
271 .remove = __devexit_p(mpc8xxx_wdt_remove),
272 .driver = {
273 .name = "mpc8xxx_wdt",
274 .owner = THIS_MODULE,
275 },
276};
277
278/*
279 * We do wdt initialization in two steps: arch_initcall probes the wdt
280 * very early to start pinging the watchdog (misc devices are not yet
281 * available), and later module_init() just registers the misc device.
282 */
283static int __init mpc8xxx_wdt_init_late(void)
284{
285 int ret;
286
287 if (!wd_base)
288 return -ENODEV;
289
290 ret = misc_register(&mpc8xxx_wdt_miscdev);
291 if (ret) {
292 pr_err("cannot register miscdev on minor=%d (err=%d)\n",
293 WATCHDOG_MINOR, ret);
294 return ret;
295 }
296 return 0;
297}
298module_init(mpc8xxx_wdt_init_late);
299
300static int __init mpc8xxx_wdt_init(void)
301{
302 return of_register_platform_driver(&mpc8xxx_wdt_driver);
303}
304arch_initcall(mpc8xxx_wdt_init);
305
306static void __exit mpc8xxx_wdt_exit(void)
307{
308 of_unregister_platform_driver(&mpc8xxx_wdt_driver);
309}
310module_exit(mpc8xxx_wdt_exit);
311
312MODULE_AUTHOR("Dave Updegraff, Kumar Gala");
313MODULE_DESCRIPTION("Driver for watchdog timer in MPC8xx/MPC83xx/MPC86xx "
314 "uProcessors");
315MODULE_LICENSE("GPL");
316MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 009573b81496..2a9bfa81f9d6 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -29,9 +29,9 @@
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/interrupt.h> 30#include <linux/interrupt.h>
31#include <linux/platform_device.h> 31#include <linux/platform_device.h>
32#include <linux/uaccess.h>
32 33
33#include <asm/hardware/arm_twd.h> 34#include <asm/hardware/arm_twd.h>
34#include <asm/uaccess.h>
35 35
36struct mpcore_wdt { 36struct mpcore_wdt {
37 unsigned long timer_alive; 37 unsigned long timer_alive;
@@ -43,17 +43,20 @@ struct mpcore_wdt {
43}; 43};
44 44
45static struct platform_device *mpcore_wdt_dev; 45static struct platform_device *mpcore_wdt_dev;
46
47extern unsigned int mpcore_timer_rate; 46extern unsigned int mpcore_timer_rate;
48 47
49#define TIMER_MARGIN 60 48#define TIMER_MARGIN 60
50static int mpcore_margin = TIMER_MARGIN; 49static int mpcore_margin = TIMER_MARGIN;
51module_param(mpcore_margin, int, 0); 50module_param(mpcore_margin, int, 0);
52MODULE_PARM_DESC(mpcore_margin, "MPcore timer margin in seconds. (0<mpcore_margin<65536, default=" __MODULE_STRING(TIMER_MARGIN) ")"); 51MODULE_PARM_DESC(mpcore_margin,
52 "MPcore timer margin in seconds. (0 < mpcore_margin < 65536, default="
53 __MODULE_STRING(TIMER_MARGIN) ")");
53 54
54static int nowayout = WATCHDOG_NOWAYOUT; 55static int nowayout = WATCHDOG_NOWAYOUT;
55module_param(nowayout, int, 0); 56module_param(nowayout, int, 0);
56MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 57MODULE_PARM_DESC(nowayout,
58 "Watchdog cannot be stopped once started (default="
59 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
57 60
58#define ONLY_TESTING 0 61#define ONLY_TESTING 0
59static int mpcore_noboot = ONLY_TESTING; 62static int mpcore_noboot = ONLY_TESTING;
@@ -70,14 +73,12 @@ static irqreturn_t mpcore_wdt_fire(int irq, void *arg)
70 73
71 /* Check it really was our interrupt */ 74 /* Check it really was our interrupt */
72 if (readl(wdt->base + TWD_WDOG_INTSTAT)) { 75 if (readl(wdt->base + TWD_WDOG_INTSTAT)) {
73 dev_printk(KERN_CRIT, wdt->dev, "Triggered - Reboot ignored.\n"); 76 dev_printk(KERN_CRIT, wdt->dev,
74 77 "Triggered - Reboot ignored.\n");
75 /* Clear the interrupt on the watchdog */ 78 /* Clear the interrupt on the watchdog */
76 writel(1, wdt->base + TWD_WDOG_INTSTAT); 79 writel(1, wdt->base + TWD_WDOG_INTSTAT);
77
78 return IRQ_HANDLED; 80 return IRQ_HANDLED;
79 } 81 }
80
81 return IRQ_NONE; 82 return IRQ_NONE;
82} 83}
83 84
@@ -96,22 +97,26 @@ static void mpcore_wdt_keepalive(struct mpcore_wdt *wdt)
96 count = (mpcore_timer_rate / 256) * mpcore_margin; 97 count = (mpcore_timer_rate / 256) * mpcore_margin;
97 98
98 /* Reload the counter */ 99 /* Reload the counter */
100 spin_lock(&wdt_lock);
99 writel(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD); 101 writel(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD);
100
101 wdt->perturb = wdt->perturb ? 0 : 1; 102 wdt->perturb = wdt->perturb ? 0 : 1;
103 spin_unlock(&wdt_lock);
102} 104}
103 105
104static void mpcore_wdt_stop(struct mpcore_wdt *wdt) 106static void mpcore_wdt_stop(struct mpcore_wdt *wdt)
105{ 107{
108 spin_lock(&wdt_lock);
106 writel(0x12345678, wdt->base + TWD_WDOG_DISABLE); 109 writel(0x12345678, wdt->base + TWD_WDOG_DISABLE);
107 writel(0x87654321, wdt->base + TWD_WDOG_DISABLE); 110 writel(0x87654321, wdt->base + TWD_WDOG_DISABLE);
108 writel(0x0, wdt->base + TWD_WDOG_CONTROL); 111 writel(0x0, wdt->base + TWD_WDOG_CONTROL);
112 spin_unlock(&wdt_lock);
109} 113}
110 114
111static void mpcore_wdt_start(struct mpcore_wdt *wdt) 115static void mpcore_wdt_start(struct mpcore_wdt *wdt)
112{ 116{
113 dev_printk(KERN_INFO, wdt->dev, "enabling watchdog.\n"); 117 dev_printk(KERN_INFO, wdt->dev, "enabling watchdog.\n");
114 118
119 spin_lock(&wdt_lock);
115 /* This loads the count register but does NOT start the count yet */ 120 /* This loads the count register but does NOT start the count yet */
116 mpcore_wdt_keepalive(wdt); 121 mpcore_wdt_keepalive(wdt);
117 122
@@ -122,6 +127,7 @@ static void mpcore_wdt_start(struct mpcore_wdt *wdt)
122 /* Enable watchdog - prescale=256, watchdog mode=1, enable=1 */ 127 /* Enable watchdog - prescale=256, watchdog mode=1, enable=1 */
123 writel(0x0000FF09, wdt->base + TWD_WDOG_CONTROL); 128 writel(0x0000FF09, wdt->base + TWD_WDOG_CONTROL);
124 } 129 }
130 spin_unlock(&wdt_lock);
125} 131}
126 132
127static int mpcore_wdt_set_heartbeat(int t) 133static int mpcore_wdt_set_heartbeat(int t)
@@ -164,10 +170,11 @@ static int mpcore_wdt_release(struct inode *inode, struct file *file)
164 * Shut off the timer. 170 * Shut off the timer.
165 * Lock it in if it's a module and we set nowayout 171 * Lock it in if it's a module and we set nowayout
166 */ 172 */
167 if (wdt->expect_close == 42) { 173 if (wdt->expect_close == 42)
168 mpcore_wdt_stop(wdt); 174 mpcore_wdt_stop(wdt);
169 } else { 175 else {
170 dev_printk(KERN_CRIT, wdt->dev, "unexpected close, not stopping watchdog!\n"); 176 dev_printk(KERN_CRIT, wdt->dev,
177 "unexpected close, not stopping watchdog!\n");
171 mpcore_wdt_keepalive(wdt); 178 mpcore_wdt_keepalive(wdt);
172 } 179 }
173 clear_bit(0, &wdt->timer_alive); 180 clear_bit(0, &wdt->timer_alive);
@@ -175,7 +182,8 @@ static int mpcore_wdt_release(struct inode *inode, struct file *file)
175 return 0; 182 return 0;
176} 183}
177 184
178static ssize_t mpcore_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) 185static ssize_t mpcore_wdt_write(struct file *file, const char *data,
186 size_t len, loff_t *ppos)
179{ 187{
180 struct mpcore_wdt *wdt = file->private_data; 188 struct mpcore_wdt *wdt = file->private_data;
181 189
@@ -210,8 +218,8 @@ static struct watchdog_info ident = {
210 .identity = "MPcore Watchdog", 218 .identity = "MPcore Watchdog",
211}; 219};
212 220
213static int mpcore_wdt_ioctl(struct inode *inode, struct file *file, 221static long mpcore_wdt_ioctl(struct file *file, unsigned int cmd,
214 unsigned int cmd, unsigned long arg) 222 unsigned long arg)
215{ 223{
216 struct mpcore_wdt *wdt = file->private_data; 224 struct mpcore_wdt *wdt = file->private_data;
217 int ret; 225 int ret;
@@ -235,6 +243,12 @@ static int mpcore_wdt_ioctl(struct inode *inode, struct file *file,
235 ret = 0; 243 ret = 0;
236 break; 244 break;
237 245
246 case WDIOC_GETSTATUS:
247 case WDIOC_GETBOOTSTATUS:
248 uarg.i = 0;
249 ret = 0;
250 break;
251
238 case WDIOC_SETOPTIONS: 252 case WDIOC_SETOPTIONS:
239 ret = -EINVAL; 253 ret = -EINVAL;
240 if (uarg.i & WDIOS_DISABLECARD) { 254 if (uarg.i & WDIOS_DISABLECARD) {
@@ -247,12 +261,6 @@ static int mpcore_wdt_ioctl(struct inode *inode, struct file *file,
247 } 261 }
248 break; 262 break;
249 263
250 case WDIOC_GETSTATUS:
251 case WDIOC_GETBOOTSTATUS:
252 uarg.i = 0;
253 ret = 0;
254 break;
255
256 case WDIOC_KEEPALIVE: 264 case WDIOC_KEEPALIVE:
257 mpcore_wdt_keepalive(wdt); 265 mpcore_wdt_keepalive(wdt);
258 ret = 0; 266 ret = 0;
@@ -301,7 +309,7 @@ static const struct file_operations mpcore_wdt_fops = {
301 .owner = THIS_MODULE, 309 .owner = THIS_MODULE,
302 .llseek = no_llseek, 310 .llseek = no_llseek,
303 .write = mpcore_wdt_write, 311 .write = mpcore_wdt_write,
304 .ioctl = mpcore_wdt_ioctl, 312 .unlocked_ioctl = mpcore_wdt_ioctl,
305 .open = mpcore_wdt_open, 313 .open = mpcore_wdt_open,
306 .release = mpcore_wdt_release, 314 .release = mpcore_wdt_release,
307}; 315};
@@ -349,14 +357,17 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev)
349 mpcore_wdt_miscdev.parent = &dev->dev; 357 mpcore_wdt_miscdev.parent = &dev->dev;
350 ret = misc_register(&mpcore_wdt_miscdev); 358 ret = misc_register(&mpcore_wdt_miscdev);
351 if (ret) { 359 if (ret) {
352 dev_printk(KERN_ERR, _dev, "cannot register miscdev on minor=%d (err=%d)\n", 360 dev_printk(KERN_ERR, _dev,
353 WATCHDOG_MINOR, ret); 361 "cannot register miscdev on minor=%d (err=%d)\n",
362 WATCHDOG_MINOR, ret);
354 goto err_misc; 363 goto err_misc;
355 } 364 }
356 365
357 ret = request_irq(wdt->irq, mpcore_wdt_fire, IRQF_DISABLED, "mpcore_wdt", wdt); 366 ret = request_irq(wdt->irq, mpcore_wdt_fire, IRQF_DISABLED,
367 "mpcore_wdt", wdt);
358 if (ret) { 368 if (ret) {
359 dev_printk(KERN_ERR, _dev, "cannot register IRQ%d for watchdog\n", wdt->irq); 369 dev_printk(KERN_ERR, _dev,
370 "cannot register IRQ%d for watchdog\n", wdt->irq);
360 goto err_irq; 371 goto err_irq;
361 } 372 }
362 373
@@ -366,13 +377,13 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev)
366 377
367 return 0; 378 return 0;
368 379
369 err_irq: 380err_irq:
370 misc_deregister(&mpcore_wdt_miscdev); 381 misc_deregister(&mpcore_wdt_miscdev);
371 err_misc: 382err_misc:
372 iounmap(wdt->base); 383 iounmap(wdt->base);
373 err_free: 384err_free:
374 kfree(wdt); 385 kfree(wdt);
375 err_out: 386err_out:
376 return ret; 387 return ret;
377} 388}
378 389
@@ -415,7 +426,7 @@ static int __init mpcore_wdt_init(void)
415 */ 426 */
416 if (mpcore_wdt_set_heartbeat(mpcore_margin)) { 427 if (mpcore_wdt_set_heartbeat(mpcore_margin)) {
417 mpcore_wdt_set_heartbeat(TIMER_MARGIN); 428 mpcore_wdt_set_heartbeat(TIMER_MARGIN);
418 printk(KERN_INFO "mpcore_margin value must be 0<mpcore_margin<65536, using %d\n", 429 printk(KERN_INFO "mpcore_margin value must be 0 < mpcore_margin < 65536, using %d\n",
419 TIMER_MARGIN); 430 TIMER_MARGIN);
420 } 431 }
421 432
diff --git a/drivers/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c
index a8e67383784e..b4b7b0a4c119 100644
--- a/drivers/watchdog/mtx-1_wdt.c
+++ b/drivers/watchdog/mtx-1_wdt.c
@@ -1,7 +1,8 @@
1/* 1/*
2 * Driver for the MTX-1 Watchdog. 2 * Driver for the MTX-1 Watchdog.
3 * 3 *
4 * (C) Copyright 2005 4G Systems <info@4g-systems.biz>, All Rights Reserved. 4 * (C) Copyright 2005 4G Systems <info@4g-systems.biz>,
5 * All Rights Reserved.
5 * http://www.4g-systems.biz 6 * http://www.4g-systems.biz
6 * 7 *
7 * (C) Copyright 2007 OpenWrt.org, Florian Fainelli <florian@openwrt.org> 8 * (C) Copyright 2007 OpenWrt.org, Florian Fainelli <florian@openwrt.org>
@@ -46,12 +47,11 @@
46#include <linux/jiffies.h> 47#include <linux/jiffies.h>
47#include <linux/watchdog.h> 48#include <linux/watchdog.h>
48#include <linux/platform_device.h> 49#include <linux/platform_device.h>
49 50#include <linux/io.h>
50#include <asm/io.h> 51#include <linux/uaccess.h>
51#include <asm/uaccess.h> 52#include <linux/gpio.h>
52 53
53#include <asm/mach-au1x00/au1000.h> 54#include <asm/mach-au1x00/au1000.h>
54#include <asm/gpio.h>
55 55
56#define MTX1_WDT_INTERVAL (5 * HZ) 56#define MTX1_WDT_INTERVAL (5 * HZ)
57 57
@@ -59,6 +59,7 @@ static int ticks = 100 * HZ;
59 59
60static struct { 60static struct {
61 struct completion stop; 61 struct completion stop;
62 spinlock_t lock;
62 int running; 63 int running;
63 struct timer_list timer; 64 struct timer_list timer;
64 int queue; 65 int queue;
@@ -71,6 +72,7 @@ static void mtx1_wdt_trigger(unsigned long unused)
71{ 72{
72 u32 tmp; 73 u32 tmp;
73 74
75 spin_lock(&mtx1_wdt_device.lock);
74 if (mtx1_wdt_device.running) 76 if (mtx1_wdt_device.running)
75 ticks--; 77 ticks--;
76 /* 78 /*
@@ -79,13 +81,13 @@ static void mtx1_wdt_trigger(unsigned long unused)
79 tmp = au_readl(GPIO2_DIR); 81 tmp = au_readl(GPIO2_DIR);
80 tmp = (tmp & ~(1 << mtx1_wdt_device.gpio)) | 82 tmp = (tmp & ~(1 << mtx1_wdt_device.gpio)) |
81 ((~tmp) & (1 << mtx1_wdt_device.gpio)); 83 ((~tmp) & (1 << mtx1_wdt_device.gpio));
82 au_writel (tmp, GPIO2_DIR); 84 au_writel(tmp, GPIO2_DIR);
83 85
84 if (mtx1_wdt_device.queue && ticks) 86 if (mtx1_wdt_device.queue && ticks)
85 mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL); 87 mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL);
86 else { 88 else
87 complete(&mtx1_wdt_device.stop); 89 complete(&mtx1_wdt_device.stop);
88 } 90 spin_unlock(&mtx1_wdt_device.lock);
89} 91}
90 92
91static void mtx1_wdt_reset(void) 93static void mtx1_wdt_reset(void)
@@ -96,23 +98,25 @@ static void mtx1_wdt_reset(void)
96 98
97static void mtx1_wdt_start(void) 99static void mtx1_wdt_start(void)
98{ 100{
101 spin_lock_irqsave(&mtx1_wdt_device.lock, flags);
99 if (!mtx1_wdt_device.queue) { 102 if (!mtx1_wdt_device.queue) {
100 mtx1_wdt_device.queue = 1; 103 mtx1_wdt_device.queue = 1;
101 gpio_set_value(mtx1_wdt_device.gpio, 1); 104 gpio_set_value(mtx1_wdt_device.gpio, 1);
102 mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL); 105 mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL);
103 } 106 }
104 mtx1_wdt_device.running++; 107 mtx1_wdt_device.running++;
108 spin_unlock_irqrestore(&mtx1_wdt_device.lock, flags);
105} 109}
106 110
107static int mtx1_wdt_stop(void) 111static int mtx1_wdt_stop(void)
108{ 112{
113 spin_lock_irqsave(&mtx1_wdt_device.lock, flags);
109 if (mtx1_wdt_device.queue) { 114 if (mtx1_wdt_device.queue) {
110 mtx1_wdt_device.queue = 0; 115 mtx1_wdt_device.queue = 0;
111 gpio_set_value(mtx1_wdt_device.gpio, 0); 116 gpio_set_value(mtx1_wdt_device.gpio, 0);
112 } 117 }
113
114 ticks = mtx1_wdt_device.default_ticks; 118 ticks = mtx1_wdt_device.default_ticks;
115 119 spin_unlock_irqrestore(&mtx1_wdt_device.lock, flags);
116 return 0; 120 return 0;
117} 121}
118 122
@@ -122,7 +126,6 @@ static int mtx1_wdt_open(struct inode *inode, struct file *file)
122{ 126{
123 if (test_and_set_bit(0, &mtx1_wdt_device.inuse)) 127 if (test_and_set_bit(0, &mtx1_wdt_device.inuse))
124 return -EBUSY; 128 return -EBUSY;
125
126 return nonseekable_open(inode, file); 129 return nonseekable_open(inode, file);
127} 130}
128 131
@@ -133,54 +136,51 @@ static int mtx1_wdt_release(struct inode *inode, struct file *file)
133 return 0; 136 return 0;
134} 137}
135 138
136static int mtx1_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) 139static long mtx1_wdt_ioctl(struct file *file, unsigned int cmd,
140 unsigned long arg)
137{ 141{
138 void __user *argp = (void __user *)arg; 142 void __user *argp = (void __user *)arg;
143 int __user *p = (int __user *)argp;
139 unsigned int value; 144 unsigned int value;
140 static struct watchdog_info ident = 145 static const struct watchdog_info ident = {
141 {
142 .options = WDIOF_CARDRESET, 146 .options = WDIOF_CARDRESET,
143 .identity = "MTX-1 WDT", 147 .identity = "MTX-1 WDT",
144 }; 148 };
145 149
146 switch(cmd) { 150 switch (cmd) {
147 case WDIOC_KEEPALIVE: 151 case WDIOC_GETSUPPORT:
148 mtx1_wdt_reset(); 152 if (copy_to_user(argp, &ident, sizeof(ident)))
149 break; 153 return -EFAULT;
150 case WDIOC_GETSTATUS: 154 break;
151 case WDIOC_GETBOOTSTATUS: 155 case WDIOC_GETSTATUS:
152 if ( copy_to_user(argp, &value, sizeof(int)) ) 156 case WDIOC_GETBOOTSTATUS:
153 return -EFAULT; 157 put_user(0, p);
154 break; 158 break;
155 case WDIOC_GETSUPPORT: 159 case WDIOC_SETOPTIONS:
156 if ( copy_to_user(argp, &ident, sizeof(ident)) ) 160 if (get_user(value, p))
157 return -EFAULT; 161 return -EFAULT;
158 break; 162 if (value & WDIOS_ENABLECARD)
159 case WDIOC_SETOPTIONS: 163 mtx1_wdt_start();
160 if ( copy_from_user(&value, argp, sizeof(int)) ) 164 else if (value & WDIOS_DISABLECARD)
161 return -EFAULT; 165 mtx1_wdt_stop();
162 switch(value) { 166 else
163 case WDIOS_ENABLECARD: 167 return -EINVAL;
164 mtx1_wdt_start(); 168 return 0;
165 break; 169 case WDIOC_KEEPALIVE:
166 case WDIOS_DISABLECARD: 170 mtx1_wdt_reset();
167 return mtx1_wdt_stop(); 171 break;
168 default: 172 default:
169 return -EINVAL; 173 return -ENOTTY;
170 }
171 break;
172 default:
173 return -ENOTTY;
174 } 174 }
175 return 0; 175 return 0;
176} 176}
177 177
178 178
179static ssize_t mtx1_wdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos) 179static ssize_t mtx1_wdt_write(struct file *file, const char *buf,
180 size_t count, loff_t *ppos)
180{ 181{
181 if (!count) 182 if (!count)
182 return -EIO; 183 return -EIO;
183
184 mtx1_wdt_reset(); 184 mtx1_wdt_reset();
185 return count; 185 return count;
186} 186}
@@ -188,17 +188,17 @@ static ssize_t mtx1_wdt_write(struct file *file, const char *buf, size_t count,
188static const struct file_operations mtx1_wdt_fops = { 188static const struct file_operations mtx1_wdt_fops = {
189 .owner = THIS_MODULE, 189 .owner = THIS_MODULE,
190 .llseek = no_llseek, 190 .llseek = no_llseek,
191 .ioctl = mtx1_wdt_ioctl, 191 .unlocked_ioctl = mtx1_wdt_ioctl,
192 .open = mtx1_wdt_open, 192 .open = mtx1_wdt_open,
193 .write = mtx1_wdt_write, 193 .write = mtx1_wdt_write,
194 .release = mtx1_wdt_release 194 .release = mtx1_wdt_release,
195}; 195};
196 196
197 197
198static struct miscdevice mtx1_wdt_misc = { 198static struct miscdevice mtx1_wdt_misc = {
199 .minor = WATCHDOG_MINOR, 199 .minor = WATCHDOG_MINOR,
200 .name = "watchdog", 200 .name = "watchdog",
201 .fops = &mtx1_wdt_fops 201 .fops = &mtx1_wdt_fops,
202}; 202};
203 203
204 204
@@ -208,29 +208,26 @@ static int mtx1_wdt_probe(struct platform_device *pdev)
208 208
209 mtx1_wdt_device.gpio = pdev->resource[0].start; 209 mtx1_wdt_device.gpio = pdev->resource[0].start;
210 210
211 if ((ret = misc_register(&mtx1_wdt_misc)) < 0) { 211 spin_lock_init(&mtx1_wdt_device.lock);
212 printk(KERN_ERR " mtx-1_wdt : failed to register\n");
213 return ret;
214 }
215
216 init_completion(&mtx1_wdt_device.stop); 212 init_completion(&mtx1_wdt_device.stop);
217 mtx1_wdt_device.queue = 0; 213 mtx1_wdt_device.queue = 0;
218
219 clear_bit(0, &mtx1_wdt_device.inuse); 214 clear_bit(0, &mtx1_wdt_device.inuse);
220
221 setup_timer(&mtx1_wdt_device.timer, mtx1_wdt_trigger, 0L); 215 setup_timer(&mtx1_wdt_device.timer, mtx1_wdt_trigger, 0L);
222
223 mtx1_wdt_device.default_ticks = ticks; 216 mtx1_wdt_device.default_ticks = ticks;
224 217
218 ret = misc_register(&mtx1_wdt_misc);
219 if (ret < 0) {
220 printk(KERN_ERR " mtx-1_wdt : failed to register\n");
221 return ret;
222 }
225 mtx1_wdt_start(); 223 mtx1_wdt_start();
226
227 printk(KERN_INFO "MTX-1 Watchdog driver\n"); 224 printk(KERN_INFO "MTX-1 Watchdog driver\n");
228
229 return 0; 225 return 0;
230} 226}
231 227
232static int mtx1_wdt_remove(struct platform_device *pdev) 228static int mtx1_wdt_remove(struct platform_device *pdev)
233{ 229{
230 /* FIXME: do we need to lock this test ? */
234 if (mtx1_wdt_device.queue) { 231 if (mtx1_wdt_device.queue) {
235 mtx1_wdt_device.queue = 0; 232 mtx1_wdt_device.queue = 0;
236 wait_for_completion(&mtx1_wdt_device.stop); 233 wait_for_completion(&mtx1_wdt_device.stop);
diff --git a/drivers/watchdog/mv64x60_wdt.c b/drivers/watchdog/mv64x60_wdt.c
index b59ca3273967..acf589dc057c 100644
--- a/drivers/watchdog/mv64x60_wdt.c
+++ b/drivers/watchdog/mv64x60_wdt.c
@@ -8,7 +8,7 @@
8 * and services the watchdog. 8 * and services the watchdog.
9 * 9 *
10 * Derived from mpc8xx_wdt.c, with the following copyright. 10 * Derived from mpc8xx_wdt.c, with the following copyright.
11 * 11 *
12 * 2002 (c) Florian Schirmer <jolt@tuxbox.org> This file is licensed under 12 * 2002 (c) Florian Schirmer <jolt@tuxbox.org> This file is licensed under
13 * the terms of the GNU General Public License version 2. This program 13 * the terms of the GNU General Public License version 2. This program
14 * is licensed "as is" without any warranty of any kind, whether express 14 * is licensed "as is" without any warranty of any kind, whether express
@@ -22,10 +22,9 @@
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/watchdog.h> 23#include <linux/watchdog.h>
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25
26#include <linux/mv643xx.h> 25#include <linux/mv643xx.h>
27#include <asm/uaccess.h> 26#include <linux/uaccess.h>
28#include <asm/io.h> 27#include <linux/io.h>
29 28
30#define MV64x60_WDT_WDC_OFFSET 0 29#define MV64x60_WDT_WDC_OFFSET 0
31 30
@@ -61,7 +60,9 @@ static DEFINE_SPINLOCK(mv64x60_wdt_spinlock);
61 60
62static int nowayout = WATCHDOG_NOWAYOUT; 61static int nowayout = WATCHDOG_NOWAYOUT;
63module_param(nowayout, int, 0); 62module_param(nowayout, int, 0);
64MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 63MODULE_PARM_DESC(nowayout,
64 "Watchdog cannot be stopped once started (default="
65 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
65 66
66static int mv64x60_wdt_toggle_wdc(int enabled_predicate, int field_shift) 67static int mv64x60_wdt_toggle_wdc(int enabled_predicate, int field_shift)
67{ 68{
@@ -150,7 +151,7 @@ static int mv64x60_wdt_release(struct inode *inode, struct file *file)
150} 151}
151 152
152static ssize_t mv64x60_wdt_write(struct file *file, const char __user *data, 153static ssize_t mv64x60_wdt_write(struct file *file, const char __user *data,
153 size_t len, loff_t * ppos) 154 size_t len, loff_t *ppos)
154{ 155{
155 if (len) { 156 if (len) {
156 if (!nowayout) { 157 if (!nowayout) {
@@ -160,7 +161,7 @@ static ssize_t mv64x60_wdt_write(struct file *file, const char __user *data,
160 161
161 for (i = 0; i != len; i++) { 162 for (i = 0; i != len; i++) {
162 char c; 163 char c;
163 if(get_user(c, data + i)) 164 if (get_user(c, data + i))
164 return -EFAULT; 165 return -EFAULT;
165 if (c == 'V') 166 if (c == 'V')
166 expect_close = 42; 167 expect_close = 42;
@@ -172,8 +173,8 @@ static ssize_t mv64x60_wdt_write(struct file *file, const char __user *data,
172 return len; 173 return len;
173} 174}
174 175
175static int mv64x60_wdt_ioctl(struct inode *inode, struct file *file, 176static long mv64x60_wdt_ioctl(struct file *file,
176 unsigned int cmd, unsigned long arg) 177 unsigned int cmd, unsigned long arg)
177{ 178{
178 int timeout; 179 int timeout;
179 int options; 180 int options;
@@ -240,7 +241,7 @@ static const struct file_operations mv64x60_wdt_fops = {
240 .owner = THIS_MODULE, 241 .owner = THIS_MODULE,
241 .llseek = no_llseek, 242 .llseek = no_llseek,
242 .write = mv64x60_wdt_write, 243 .write = mv64x60_wdt_write,
243 .ioctl = mv64x60_wdt_ioctl, 244 .unlocked_ioctl = mv64x60_wdt_ioctl,
244 .open = mv64x60_wdt_open, 245 .open = mv64x60_wdt_open,
245 .release = mv64x60_wdt_release, 246 .release = mv64x60_wdt_release,
246}; 247};
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index 74a10d50607b..3a11dadfd8e7 100644
--- a/drivers/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -40,11 +40,9 @@
40#include <linux/moduleparam.h> 40#include <linux/moduleparam.h>
41#include <linux/clk.h> 41#include <linux/clk.h>
42#include <linux/bitops.h> 42#include <linux/bitops.h>
43 43#include <linux/io.h>
44#include <asm/io.h> 44#include <linux/uaccess.h>
45#include <asm/uaccess.h>
46#include <mach/hardware.h> 45#include <mach/hardware.h>
47
48#include <mach/prcm.h> 46#include <mach/prcm.h>
49 47
50#include "omap_wdt.h" 48#include "omap_wdt.h"
@@ -54,11 +52,12 @@ module_param(timer_margin, uint, 0);
54MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)"); 52MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)");
55 53
56static int omap_wdt_users; 54static int omap_wdt_users;
57static struct clk *armwdt_ck = NULL; 55static struct clk *armwdt_ck;
58static struct clk *mpu_wdt_ick = NULL; 56static struct clk *mpu_wdt_ick;
59static struct clk *mpu_wdt_fck = NULL; 57static struct clk *mpu_wdt_fck;
60 58
61static unsigned int wdt_trgr_pattern = 0x1234; 59static unsigned int wdt_trgr_pattern = 0x1234;
60static spinlock_t wdt_lock;
62 61
63static void omap_wdt_ping(void) 62static void omap_wdt_ping(void)
64{ 63{
@@ -174,30 +173,29 @@ static int omap_wdt_release(struct inode *inode, struct file *file)
174 return 0; 173 return 0;
175} 174}
176 175
177static ssize_t 176static ssize_t omap_wdt_write(struct file *file, const char __user *data,
178omap_wdt_write(struct file *file, const char __user *data,
179 size_t len, loff_t *ppos) 177 size_t len, loff_t *ppos)
180{ 178{
181 /* Refresh LOAD_TIME. */ 179 /* Refresh LOAD_TIME. */
182 if (len) 180 if (len) {
181 spin_lock(&wdt_lock);
183 omap_wdt_ping(); 182 omap_wdt_ping();
183 spin_unlock(&wdt_lock);
184 }
184 return len; 185 return len;
185} 186}
186 187
187static int 188static long omap_wdt_ioctl(struct file *file, unsigned int cmd,
188omap_wdt_ioctl(struct inode *inode, struct file *file, 189 unsigned long arg)
189 unsigned int cmd, unsigned long arg)
190{ 190{
191 int new_margin; 191 int new_margin;
192 static struct watchdog_info ident = { 192 static const struct watchdog_info ident = {
193 .identity = "OMAP Watchdog", 193 .identity = "OMAP Watchdog",
194 .options = WDIOF_SETTIMEOUT, 194 .options = WDIOF_SETTIMEOUT,
195 .firmware_version = 0, 195 .firmware_version = 0,
196 }; 196 };
197 197
198 switch (cmd) { 198 switch (cmd) {
199 default:
200 return -ENOTTY;
201 case WDIOC_GETSUPPORT: 199 case WDIOC_GETSUPPORT:
202 return copy_to_user((struct watchdog_info __user *)arg, &ident, 200 return copy_to_user((struct watchdog_info __user *)arg, &ident,
203 sizeof(ident)); 201 sizeof(ident));
@@ -211,28 +209,34 @@ omap_wdt_ioctl(struct inode *inode, struct file *file,
211 return put_user(omap_prcm_get_reset_sources(), 209 return put_user(omap_prcm_get_reset_sources(),
212 (int __user *)arg); 210 (int __user *)arg);
213 case WDIOC_KEEPALIVE: 211 case WDIOC_KEEPALIVE:
212 spin_lock(&wdt_lock);
214 omap_wdt_ping(); 213 omap_wdt_ping();
214 spin_unlock(&wdt_lock);
215 return 0; 215 return 0;
216 case WDIOC_SETTIMEOUT: 216 case WDIOC_SETTIMEOUT:
217 if (get_user(new_margin, (int __user *)arg)) 217 if (get_user(new_margin, (int __user *)arg))
218 return -EFAULT; 218 return -EFAULT;
219 omap_wdt_adjust_timeout(new_margin); 219 omap_wdt_adjust_timeout(new_margin);
220 220
221 spin_lock(&wdt_lock);
221 omap_wdt_disable(); 222 omap_wdt_disable();
222 omap_wdt_set_timeout(); 223 omap_wdt_set_timeout();
223 omap_wdt_enable(); 224 omap_wdt_enable();
224 225
225 omap_wdt_ping(); 226 omap_wdt_ping();
227 spin_unlock(&wdt_lock);
226 /* Fall */ 228 /* Fall */
227 case WDIOC_GETTIMEOUT: 229 case WDIOC_GETTIMEOUT:
228 return put_user(timer_margin, (int __user *)arg); 230 return put_user(timer_margin, (int __user *)arg);
231 default:
232 return -ENOTTY;
229 } 233 }
230} 234}
231 235
232static const struct file_operations omap_wdt_fops = { 236static const struct file_operations omap_wdt_fops = {
233 .owner = THIS_MODULE, 237 .owner = THIS_MODULE,
234 .write = omap_wdt_write, 238 .write = omap_wdt_write,
235 .ioctl = omap_wdt_ioctl, 239 .unlocked_ioctl = omap_wdt_ioctl,
236 .open = omap_wdt_open, 240 .open = omap_wdt_open,
237 .release = omap_wdt_release, 241 .release = omap_wdt_release,
238}; 242};
@@ -240,7 +244,7 @@ static const struct file_operations omap_wdt_fops = {
240static struct miscdevice omap_wdt_miscdev = { 244static struct miscdevice omap_wdt_miscdev = {
241 .minor = WATCHDOG_MINOR, 245 .minor = WATCHDOG_MINOR,
242 .name = "watchdog", 246 .name = "watchdog",
243 .fops = &omap_wdt_fops 247 .fops = &omap_wdt_fops,
244}; 248};
245 249
246static int __init omap_wdt_probe(struct platform_device *pdev) 250static int __init omap_wdt_probe(struct platform_device *pdev)
@@ -373,6 +377,7 @@ static struct platform_driver omap_wdt_driver = {
373 377
374static int __init omap_wdt_init(void) 378static int __init omap_wdt_init(void)
375{ 379{
380 spin_lock_init(&wdt_lock);
376 return platform_driver_register(&omap_wdt_driver); 381 return platform_driver_register(&omap_wdt_driver);
377} 382}
378 383
diff --git a/drivers/watchdog/pc87413_wdt.c b/drivers/watchdog/pc87413_wdt.c
index 15e4f8887a9e..e91ada72da1d 100644
--- a/drivers/watchdog/pc87413_wdt.c
+++ b/drivers/watchdog/pc87413_wdt.c
@@ -31,14 +31,14 @@
31#include <linux/spinlock.h> 31#include <linux/spinlock.h>
32#include <linux/moduleparam.h> 32#include <linux/moduleparam.h>
33#include <linux/version.h> 33#include <linux/version.h>
34#include <linux/io.h>
35#include <linux/uaccess.h>
34 36
35#include <asm/io.h>
36#include <asm/uaccess.h>
37#include <asm/system.h> 37#include <asm/system.h>
38 38
39/* #define DEBUG 1 */ 39/* #define DEBUG 1 */
40 40
41#define DEFAULT_TIMEOUT 1 /* 1 minute */ 41#define DEFAULT_TIMEOUT 1 /* 1 minute */
42#define MAX_TIMEOUT 255 42#define MAX_TIMEOUT 255
43 43
44#define VERSION "1.1" 44#define VERSION "1.1"
@@ -46,22 +46,22 @@
46#define PFX MODNAME ": " 46#define PFX MODNAME ": "
47#define DPFX MODNAME " - DEBUG: " 47#define DPFX MODNAME " - DEBUG: "
48 48
49#define WDT_INDEX_IO_PORT (io+0) /* I/O port base (index register) */ 49#define WDT_INDEX_IO_PORT (io+0) /* I/O port base (index register) */
50#define WDT_DATA_IO_PORT (WDT_INDEX_IO_PORT+1) 50#define WDT_DATA_IO_PORT (WDT_INDEX_IO_PORT+1)
51#define SWC_LDN 0x04 51#define SWC_LDN 0x04
52#define SIOCFG2 0x22 /* Serial IO register */ 52#define SIOCFG2 0x22 /* Serial IO register */
53#define WDCTL 0x10 /* Watchdog-Timer-Controll-Register */ 53#define WDCTL 0x10 /* Watchdog-Timer-Controll-Register */
54#define WDTO 0x11 /* Watchdog timeout register */ 54#define WDTO 0x11 /* Watchdog timeout register */
55#define WDCFG 0x12 /* Watchdog config register */ 55#define WDCFG 0x12 /* Watchdog config register */
56 56
57static int io = 0x2E; /* Address used on Portwell Boards */ 57static int io = 0x2E; /* Address used on Portwell Boards */
58 58
59static int timeout = DEFAULT_TIMEOUT; /* timeout value */ 59static int timeout = DEFAULT_TIMEOUT; /* timeout value */
60static unsigned long timer_enabled = 0; /* is the timer enabled? */ 60static unsigned long timer_enabled; /* is the timer enabled? */
61 61
62static char expect_close; /* is the close expected? */ 62static char expect_close; /* is the close expected? */
63 63
64static DEFINE_SPINLOCK(io_lock);/* to guard the watchdog from io races */ 64static DEFINE_SPINLOCK(io_lock); /* to guard us from io races */
65 65
66static int nowayout = WATCHDOG_NOWAYOUT; 66static int nowayout = WATCHDOG_NOWAYOUT;
67 67
@@ -69,7 +69,7 @@ static int nowayout = WATCHDOG_NOWAYOUT;
69 69
70/* Select pins for Watchdog output */ 70/* Select pins for Watchdog output */
71 71
72static inline void pc87413_select_wdt_out (void) 72static inline void pc87413_select_wdt_out(void)
73{ 73{
74 unsigned int cr_data = 0; 74 unsigned int cr_data = 0;
75 75
@@ -77,7 +77,7 @@ static inline void pc87413_select_wdt_out (void)
77 77
78 outb_p(SIOCFG2, WDT_INDEX_IO_PORT); 78 outb_p(SIOCFG2, WDT_INDEX_IO_PORT);
79 79
80 cr_data = inb (WDT_DATA_IO_PORT); 80 cr_data = inb(WDT_DATA_IO_PORT);
81 81
82 cr_data |= 0x80; /* Set Bit7 to 1*/ 82 cr_data |= 0x80; /* Set Bit7 to 1*/
83 outb_p(SIOCFG2, WDT_INDEX_IO_PORT); 83 outb_p(SIOCFG2, WDT_INDEX_IO_PORT);
@@ -85,8 +85,9 @@ static inline void pc87413_select_wdt_out (void)
85 outb_p(cr_data, WDT_DATA_IO_PORT); 85 outb_p(cr_data, WDT_DATA_IO_PORT);
86 86
87#ifdef DEBUG 87#ifdef DEBUG
88 printk(KERN_INFO DPFX "Select multiple pin,pin55,as WDT output:" 88 printk(KERN_INFO DPFX
89 " Bit7 to 1: %d\n", cr_data); 89 "Select multiple pin,pin55,as WDT output: Bit7 to 1: %d\n",
90 cr_data);
90#endif 91#endif
91} 92}
92 93
@@ -94,18 +95,18 @@ static inline void pc87413_select_wdt_out (void)
94 95
95static inline void pc87413_enable_swc(void) 96static inline void pc87413_enable_swc(void)
96{ 97{
97 unsigned int cr_data=0; 98 unsigned int cr_data = 0;
98 99
99 /* Step 2: Enable SWC functions */ 100 /* Step 2: Enable SWC functions */
100 101
101 outb_p(0x07, WDT_INDEX_IO_PORT); /* Point SWC_LDN (LDN=4) */ 102 outb_p(0x07, WDT_INDEX_IO_PORT); /* Point SWC_LDN (LDN=4) */
102 outb_p(SWC_LDN, WDT_DATA_IO_PORT); 103 outb_p(SWC_LDN, WDT_DATA_IO_PORT);
103 104
104 outb_p(0x30, WDT_INDEX_IO_PORT); /* Read Index 0x30 First */ 105 outb_p(0x30, WDT_INDEX_IO_PORT); /* Read Index 0x30 First */
105 cr_data = inb(WDT_DATA_IO_PORT); 106 cr_data = inb(WDT_DATA_IO_PORT);
106 cr_data |= 0x01; /* Set Bit0 to 1 */ 107 cr_data |= 0x01; /* Set Bit0 to 1 */
107 outb_p(0x30, WDT_INDEX_IO_PORT); 108 outb_p(0x30, WDT_INDEX_IO_PORT);
108 outb_p(cr_data, WDT_DATA_IO_PORT); /* Index0x30_bit0P1 */ 109 outb_p(cr_data, WDT_DATA_IO_PORT); /* Index0x30_bit0P1 */
109 110
110#ifdef DEBUG 111#ifdef DEBUG
111 printk(KERN_INFO DPFX "pc87413 - Enable SWC functions\n"); 112 printk(KERN_INFO DPFX "pc87413 - Enable SWC functions\n");
@@ -121,20 +122,19 @@ static inline unsigned int pc87413_get_swc_base(void)
121 122
122 /* Step 3: Read SWC I/O Base Address */ 123 /* Step 3: Read SWC I/O Base Address */
123 124
124 outb_p(0x60, WDT_INDEX_IO_PORT); /* Read Index 0x60 */ 125 outb_p(0x60, WDT_INDEX_IO_PORT); /* Read Index 0x60 */
125 addr_h = inb(WDT_DATA_IO_PORT); 126 addr_h = inb(WDT_DATA_IO_PORT);
126 127
127 outb_p(0x61, WDT_INDEX_IO_PORT); /* Read Index 0x61 */ 128 outb_p(0x61, WDT_INDEX_IO_PORT); /* Read Index 0x61 */
128 129
129 addr_l = inb(WDT_DATA_IO_PORT); 130 addr_l = inb(WDT_DATA_IO_PORT);
130 131
131 swc_base_addr = (addr_h << 8) + addr_l; 132 swc_base_addr = (addr_h << 8) + addr_l;
132
133#ifdef DEBUG 133#ifdef DEBUG
134 printk(KERN_INFO DPFX "Read SWC I/O Base Address: low %d, high %d," 134 printk(KERN_INFO DPFX
135 " res %d\n", addr_l, addr_h, swc_base_addr); 135 "Read SWC I/O Base Address: low %d, high %d, res %d\n",
136 addr_l, addr_h, swc_base_addr);
136#endif 137#endif
137
138 return swc_base_addr; 138 return swc_base_addr;
139} 139}
140 140
@@ -143,9 +143,7 @@ static inline unsigned int pc87413_get_swc_base(void)
143static inline void pc87413_swc_bank3(unsigned int swc_base_addr) 143static inline void pc87413_swc_bank3(unsigned int swc_base_addr)
144{ 144{
145 /* Step 4: Select Bank3 of SWC */ 145 /* Step 4: Select Bank3 of SWC */
146
147 outb_p(inb(swc_base_addr + 0x0f) | 0x03, swc_base_addr + 0x0f); 146 outb_p(inb(swc_base_addr + 0x0f) | 0x03, swc_base_addr + 0x0f);
148
149#ifdef DEBUG 147#ifdef DEBUG
150 printk(KERN_INFO DPFX "Select Bank3 of SWC\n"); 148 printk(KERN_INFO DPFX "Select Bank3 of SWC\n");
151#endif 149#endif
@@ -157,9 +155,7 @@ static inline void pc87413_programm_wdto(unsigned int swc_base_addr,
157 char pc87413_time) 155 char pc87413_time)
158{ 156{
159 /* Step 5: Programm WDTO, Twd. */ 157 /* Step 5: Programm WDTO, Twd. */
160
161 outb_p(pc87413_time, swc_base_addr + WDTO); 158 outb_p(pc87413_time, swc_base_addr + WDTO);
162
163#ifdef DEBUG 159#ifdef DEBUG
164 printk(KERN_INFO DPFX "Set WDTO to %d minutes\n", pc87413_time); 160 printk(KERN_INFO DPFX "Set WDTO to %d minutes\n", pc87413_time);
165#endif 161#endif
@@ -170,9 +166,7 @@ static inline void pc87413_programm_wdto(unsigned int swc_base_addr,
170static inline void pc87413_enable_wden(unsigned int swc_base_addr) 166static inline void pc87413_enable_wden(unsigned int swc_base_addr)
171{ 167{
172 /* Step 6: Enable WDEN */ 168 /* Step 6: Enable WDEN */
173 169 outb_p(inb(swc_base_addr + WDCTL) | 0x01, swc_base_addr + WDCTL);
174 outb_p(inb (swc_base_addr + WDCTL) | 0x01, swc_base_addr + WDCTL);
175
176#ifdef DEBUG 170#ifdef DEBUG
177 printk(KERN_INFO DPFX "Enable WDEN\n"); 171 printk(KERN_INFO DPFX "Enable WDEN\n");
178#endif 172#endif
@@ -182,9 +176,7 @@ static inline void pc87413_enable_wden(unsigned int swc_base_addr)
182static inline void pc87413_enable_sw_wd_tren(unsigned int swc_base_addr) 176static inline void pc87413_enable_sw_wd_tren(unsigned int swc_base_addr)
183{ 177{
184 /* Enable SW_WD_TREN */ 178 /* Enable SW_WD_TREN */
185 179 outb_p(inb(swc_base_addr + WDCFG) | 0x80, swc_base_addr + WDCFG);
186 outb_p(inb (swc_base_addr + WDCFG) | 0x80, swc_base_addr + WDCFG);
187
188#ifdef DEBUG 180#ifdef DEBUG
189 printk(KERN_INFO DPFX "Enable SW_WD_TREN\n"); 181 printk(KERN_INFO DPFX "Enable SW_WD_TREN\n");
190#endif 182#endif
@@ -195,9 +187,7 @@ static inline void pc87413_enable_sw_wd_tren(unsigned int swc_base_addr)
195static inline void pc87413_disable_sw_wd_tren(unsigned int swc_base_addr) 187static inline void pc87413_disable_sw_wd_tren(unsigned int swc_base_addr)
196{ 188{
197 /* Disable SW_WD_TREN */ 189 /* Disable SW_WD_TREN */
198 190 outb_p(inb(swc_base_addr + WDCFG) & 0x7f, swc_base_addr + WDCFG);
199 outb_p(inb (swc_base_addr + WDCFG) & 0x7f, swc_base_addr + WDCFG);
200
201#ifdef DEBUG 191#ifdef DEBUG
202 printk(KERN_INFO DPFX "pc87413 - Disable SW_WD_TREN\n"); 192 printk(KERN_INFO DPFX "pc87413 - Disable SW_WD_TREN\n");
203#endif 193#endif
@@ -208,9 +198,7 @@ static inline void pc87413_disable_sw_wd_tren(unsigned int swc_base_addr)
208static inline void pc87413_enable_sw_wd_trg(unsigned int swc_base_addr) 198static inline void pc87413_enable_sw_wd_trg(unsigned int swc_base_addr)
209{ 199{
210 /* Enable SW_WD_TRG */ 200 /* Enable SW_WD_TRG */
211 201 outb_p(inb(swc_base_addr + WDCTL) | 0x80, swc_base_addr + WDCTL);
212 outb_p(inb (swc_base_addr + WDCTL) | 0x80, swc_base_addr + WDCTL);
213
214#ifdef DEBUG 202#ifdef DEBUG
215 printk(KERN_INFO DPFX "pc87413 - Enable SW_WD_TRG\n"); 203 printk(KERN_INFO DPFX "pc87413 - Enable SW_WD_TRG\n");
216#endif 204#endif
@@ -221,9 +209,7 @@ static inline void pc87413_enable_sw_wd_trg(unsigned int swc_base_addr)
221static inline void pc87413_disable_sw_wd_trg(unsigned int swc_base_addr) 209static inline void pc87413_disable_sw_wd_trg(unsigned int swc_base_addr)
222{ 210{
223 /* Disable SW_WD_TRG */ 211 /* Disable SW_WD_TRG */
224 212 outb_p(inb(swc_base_addr + WDCTL) & 0x7f, swc_base_addr + WDCTL);
225 outb_p(inb (swc_base_addr + WDCTL) & 0x7f, swc_base_addr + WDCTL);
226
227#ifdef DEBUG 213#ifdef DEBUG
228 printk(KERN_INFO DPFX "Disable SW_WD_TRG\n"); 214 printk(KERN_INFO DPFX "Disable SW_WD_TRG\n");
229#endif 215#endif
@@ -314,8 +300,8 @@ static int pc87413_open(struct inode *inode, struct file *file)
314 /* Reload and activate timer */ 300 /* Reload and activate timer */
315 pc87413_refresh(); 301 pc87413_refresh();
316 302
317 printk(KERN_INFO MODNAME "Watchdog enabled. Timeout set to" 303 printk(KERN_INFO MODNAME
318 " %d minute(s).\n", timeout); 304 "Watchdog enabled. Timeout set to %d minute(s).\n", timeout);
319 305
320 return nonseekable_open(inode, file); 306 return nonseekable_open(inode, file);
321} 307}
@@ -338,17 +324,15 @@ static int pc87413_release(struct inode *inode, struct file *file)
338 324
339 if (expect_close == 42) { 325 if (expect_close == 42) {
340 pc87413_disable(); 326 pc87413_disable();
341 printk(KERN_INFO MODNAME "Watchdog disabled," 327 printk(KERN_INFO MODNAME
342 " sleeping again...\n"); 328 "Watchdog disabled, sleeping again...\n");
343 } else { 329 } else {
344 printk(KERN_CRIT MODNAME "Unexpected close, not stopping" 330 printk(KERN_CRIT MODNAME
345 " watchdog!\n"); 331 "Unexpected close, not stopping watchdog!\n");
346 pc87413_refresh(); 332 pc87413_refresh();
347 } 333 }
348
349 clear_bit(0, &timer_enabled); 334 clear_bit(0, &timer_enabled);
350 expect_close = 0; 335 expect_close = 0;
351
352 return 0; 336 return 0;
353} 337}
354 338
@@ -386,10 +370,11 @@ static ssize_t pc87413_write(struct file *file, const char __user *data,
386 /* reset expect flag */ 370 /* reset expect flag */
387 expect_close = 0; 371 expect_close = 0;
388 372
389 /* scan to see whether or not we got the magic character */ 373 /* scan to see whether or not we got the
374 magic character */
390 for (i = 0; i != len; i++) { 375 for (i = 0; i != len; i++) {
391 char c; 376 char c;
392 if (get_user(c, data+i)) 377 if (get_user(c, data + i))
393 return -EFAULT; 378 return -EFAULT;
394 if (c == 'V') 379 if (c == 'V')
395 expect_close = 42; 380 expect_close = 42;
@@ -404,7 +389,6 @@ static ssize_t pc87413_write(struct file *file, const char __user *data,
404 389
405/** 390/**
406 * pc87413_ioctl: 391 * pc87413_ioctl:
407 * @inode: inode of the device
408 * @file: file handle to the device 392 * @file: file handle to the device
409 * @cmd: watchdog command 393 * @cmd: watchdog command
410 * @arg: argument pointer 394 * @arg: argument pointer
@@ -414,8 +398,8 @@ static ssize_t pc87413_write(struct file *file, const char __user *data,
414 * querying capabilities and current status. 398 * querying capabilities and current status.
415 */ 399 */
416 400
417static int pc87413_ioctl(struct inode *inode, struct file *file, 401static long pc87413_ioctl(struct file *file, unsigned int cmd,
418 unsigned int cmd, unsigned long arg) 402 unsigned long arg)
419{ 403{
420 int new_timeout; 404 int new_timeout;
421 405
@@ -426,75 +410,58 @@ static int pc87413_ioctl(struct inode *inode, struct file *file,
426 410
427 static struct watchdog_info ident = { 411 static struct watchdog_info ident = {
428 .options = WDIOF_KEEPALIVEPING | 412 .options = WDIOF_KEEPALIVEPING |
429 WDIOF_SETTIMEOUT | 413 WDIOF_SETTIMEOUT |
430 WDIOF_MAGICCLOSE, 414 WDIOF_MAGICCLOSE,
431 .firmware_version = 1, 415 .firmware_version = 1,
432 .identity = "PC87413(HF/F) watchdog" 416 .identity = "PC87413(HF/F) watchdog",
433 }; 417 };
434 418
435 uarg.i = (int __user *)arg; 419 uarg.i = (int __user *)arg;
436 420
437 switch(cmd) { 421 switch (cmd) {
438 default: 422 case WDIOC_GETSUPPORT:
439 return -ENOTTY; 423 return copy_to_user(uarg.ident, &ident,
440 424 sizeof(ident)) ? -EFAULT : 0;
441 case WDIOC_GETSUPPORT: 425 case WDIOC_GETSTATUS:
442 return copy_to_user(uarg.ident, &ident, 426 return put_user(pc87413_status(), uarg.i);
443 sizeof(ident)) ? -EFAULT : 0; 427 case WDIOC_GETBOOTSTATUS:
444 428 return put_user(0, uarg.i);
445 case WDIOC_GETSTATUS: 429 case WDIOC_SETOPTIONS:
446 return put_user(pc87413_status(), uarg.i); 430 {
447 431 int options, retval = -EINVAL;
448 case WDIOC_GETBOOTSTATUS: 432 if (get_user(options, uarg.i))
449 return put_user(0, uarg.i); 433 return -EFAULT;
450 434 if (options & WDIOS_DISABLECARD) {
451 case WDIOC_KEEPALIVE: 435 pc87413_disable();
452 pc87413_refresh(); 436 retval = 0;
437 }
438 if (options & WDIOS_ENABLECARD) {
439 pc87413_enable();
440 retval = 0;
441 }
442 return retval;
443 }
444 case WDIOC_KEEPALIVE:
445 pc87413_refresh();
453#ifdef DEBUG 446#ifdef DEBUG
454 printk(KERN_INFO DPFX "keepalive\n"); 447 printk(KERN_INFO DPFX "keepalive\n");
455#endif 448#endif
456 return 0; 449 return 0;
457 450 case WDIOC_SETTIMEOUT:
458 case WDIOC_SETTIMEOUT: 451 if (get_user(new_timeout, uarg.i))
459 if (get_user(new_timeout, uarg.i)) 452 return -EFAULT;
460 return -EFAULT; 453 /* the API states this is given in secs */
461 454 new_timeout /= 60;
462 // the API states this is given in secs 455 if (new_timeout < 0 || new_timeout > MAX_TIMEOUT)
463 new_timeout /= 60; 456 return -EINVAL;
464 457 timeout = new_timeout;
465 if (new_timeout < 0 || new_timeout > MAX_TIMEOUT) 458 pc87413_refresh();
466 return -EINVAL; 459 /* fall through and return the new timeout... */
467 460 case WDIOC_GETTIMEOUT:
468 timeout = new_timeout; 461 new_timeout = timeout * 60;
469 pc87413_refresh(); 462 return put_user(new_timeout, uarg.i);
470 463 default:
471 // fall through and return the new timeout... 464 return -ENOTTY;
472
473 case WDIOC_GETTIMEOUT:
474
475 new_timeout = timeout * 60;
476
477 return put_user(new_timeout, uarg.i);
478
479 case WDIOC_SETOPTIONS:
480 {
481 int options, retval = -EINVAL;
482
483 if (get_user(options, uarg.i))
484 return -EFAULT;
485
486 if (options & WDIOS_DISABLECARD) {
487 pc87413_disable();
488 retval = 0;
489 }
490
491 if (options & WDIOS_ENABLECARD) {
492 pc87413_enable();
493 retval = 0;
494 }
495
496 return retval;
497 }
498 } 465 }
499} 466}
500 467
@@ -517,10 +484,8 @@ static int pc87413_notify_sys(struct notifier_block *this,
517 void *unused) 484 void *unused)
518{ 485{
519 if (code == SYS_DOWN || code == SYS_HALT) 486 if (code == SYS_DOWN || code == SYS_HALT)
520 {
521 /* Turn the card off */ 487 /* Turn the card off */
522 pc87413_disable(); 488 pc87413_disable();
523 }
524 return NOTIFY_DONE; 489 return NOTIFY_DONE;
525} 490}
526 491
@@ -530,21 +495,19 @@ static const struct file_operations pc87413_fops = {
530 .owner = THIS_MODULE, 495 .owner = THIS_MODULE,
531 .llseek = no_llseek, 496 .llseek = no_llseek,
532 .write = pc87413_write, 497 .write = pc87413_write,
533 .ioctl = pc87413_ioctl, 498 .unlocked_ioctl = pc87413_ioctl,
534 .open = pc87413_open, 499 .open = pc87413_open,
535 .release = pc87413_release, 500 .release = pc87413_release,
536}; 501};
537 502
538static struct notifier_block pc87413_notifier = 503static struct notifier_block pc87413_notifier = {
539{
540 .notifier_call = pc87413_notify_sys, 504 .notifier_call = pc87413_notify_sys,
541}; 505};
542 506
543static struct miscdevice pc87413_miscdev= 507static struct miscdevice pc87413_miscdev = {
544{
545 .minor = WATCHDOG_MINOR, 508 .minor = WATCHDOG_MINOR,
546 .name = "watchdog", 509 .name = "watchdog",
547 .fops = &pc87413_fops 510 .fops = &pc87413_fops,
548}; 511};
549 512
550/* -- Module init functions -------------------------------------*/ 513/* -- Module init functions -------------------------------------*/
@@ -561,29 +524,26 @@ static int __init pc87413_init(void)
561{ 524{
562 int ret; 525 int ret;
563 526
564 printk(KERN_INFO PFX "Version " VERSION " at io 0x%X\n", WDT_INDEX_IO_PORT); 527 printk(KERN_INFO PFX "Version " VERSION " at io 0x%X\n",
528 WDT_INDEX_IO_PORT);
565 529
566 /* request_region(io, 2, "pc87413"); */ 530 /* request_region(io, 2, "pc87413"); */
567 531
568 ret = register_reboot_notifier(&pc87413_notifier); 532 ret = register_reboot_notifier(&pc87413_notifier);
569 if (ret != 0) { 533 if (ret != 0) {
570 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 534 printk(KERN_ERR PFX
571 ret); 535 "cannot register reboot notifier (err=%d)\n", ret);
572 } 536 }
573 537
574 ret = misc_register(&pc87413_miscdev); 538 ret = misc_register(&pc87413_miscdev);
575
576 if (ret != 0) { 539 if (ret != 0) {
577 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 540 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
578 WATCHDOG_MINOR, ret); 541 WATCHDOG_MINOR, ret);
579 unregister_reboot_notifier(&pc87413_notifier); 542 unregister_reboot_notifier(&pc87413_notifier);
580 return ret; 543 return ret;
581 } 544 }
582
583 printk(KERN_INFO PFX "initialized. timeout=%d min \n", timeout); 545 printk(KERN_INFO PFX "initialized. timeout=%d min \n", timeout);
584
585 pc87413_enable(); 546 pc87413_enable();
586
587 return 0; 547 return 0;
588} 548}
589 549
@@ -600,17 +560,16 @@ static int __init pc87413_init(void)
600static void __exit pc87413_exit(void) 560static void __exit pc87413_exit(void)
601{ 561{
602 /* Stop the timer before we leave */ 562 /* Stop the timer before we leave */
603 if (!nowayout) 563 if (!nowayout) {
604 {
605 pc87413_disable(); 564 pc87413_disable();
606 printk(KERN_INFO MODNAME "Watchdog disabled.\n"); 565 printk(KERN_INFO MODNAME "Watchdog disabled.\n");
607 } 566 }
608 567
609 misc_deregister(&pc87413_miscdev); 568 misc_deregister(&pc87413_miscdev);
610 unregister_reboot_notifier(&pc87413_notifier); 569 unregister_reboot_notifier(&pc87413_notifier);
611 /* release_region(io,2); */ 570 /* release_region(io, 2); */
612 571
613 printk(MODNAME " watchdog component driver removed.\n"); 572 printk(KERN_INFO MODNAME " watchdog component driver removed.\n");
614} 573}
615 574
616module_init(pc87413_init); 575module_init(pc87413_init);
@@ -626,8 +585,12 @@ module_param(io, int, 0);
626MODULE_PARM_DESC(io, MODNAME " I/O port (default: " __MODULE_STRING(io) ")."); 585MODULE_PARM_DESC(io, MODNAME " I/O port (default: " __MODULE_STRING(io) ").");
627 586
628module_param(timeout, int, 0); 587module_param(timeout, int, 0);
629MODULE_PARM_DESC(timeout, "Watchdog timeout in minutes (default=" __MODULE_STRING(timeout) ")."); 588MODULE_PARM_DESC(timeout,
589 "Watchdog timeout in minutes (default="
590 __MODULE_STRING(timeout) ").");
630 591
631module_param(nowayout, int, 0); 592module_param(nowayout, int, 0);
632MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 593MODULE_PARM_DESC(nowayout,
594 "Watchdog cannot be stopped once started (default="
595 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
633 596
diff --git a/drivers/watchdog/pcwd.c b/drivers/watchdog/pcwd.c
index 7b41434fac8c..3b0ddc7fcf3f 100644
--- a/drivers/watchdog/pcwd.c
+++ b/drivers/watchdog/pcwd.c
@@ -40,13 +40,15 @@
40 * fairly useless proc entry. 40 * fairly useless proc entry.
41 * 990610 removed said useless proc code for the merge <alan> 41 * 990610 removed said useless proc code for the merge <alan>
42 * 000403 Removed last traces of proc code. <davej> 42 * 000403 Removed last traces of proc code. <davej>
43 * 011214 Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT <Matt_Domsch@dell.com> 43 * 011214 Added nowayout module option to override
44 * CONFIG_WATCHDOG_NOWAYOUT <Matt_Domsch@dell.com>
44 * Added timeout module option to override default 45 * Added timeout module option to override default
45 */ 46 */
46 47
47/* 48/*
48 * A bells and whistles driver is available from http://www.pcwd.de/ 49 * A bells and whistles driver is available from http://www.pcwd.de/
49 * More info available at http://www.berkprod.com/ or http://www.pcwatchdog.com/ 50 * More info available at http://www.berkprod.com/ or
51 * http://www.pcwatchdog.com/
50 */ 52 */
51 53
52#include <linux/module.h> /* For module specific items */ 54#include <linux/module.h> /* For module specific items */
@@ -65,9 +67,8 @@
65#include <linux/isa.h> /* For isa devices */ 67#include <linux/isa.h> /* For isa devices */
66#include <linux/ioport.h> /* For io-port access */ 68#include <linux/ioport.h> /* For io-port access */
67#include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ 69#include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */
68 70#include <linux/uaccess.h> /* For copy_to_user/put_user/... */
69#include <asm/uaccess.h> /* For copy_to_user/put_user/... */ 71#include <linux/io.h> /* For inb/outb/... */
70#include <asm/io.h> /* For inb/outb/... */
71 72
72/* Module and version information */ 73/* Module and version information */
73#define WATCHDOG_VERSION "1.20" 74#define WATCHDOG_VERSION "1.20"
@@ -111,14 +112,16 @@ static int pcwd_ioports[] = { 0x270, 0x350, 0x370, 0x000 };
111#define WD_REVC_WTRP 0x01 /* Watchdog Trip status */ 112#define WD_REVC_WTRP 0x01 /* Watchdog Trip status */
112#define WD_REVC_HRBT 0x02 /* Watchdog Heartbeat */ 113#define WD_REVC_HRBT 0x02 /* Watchdog Heartbeat */
113#define WD_REVC_TTRP 0x04 /* Temperature Trip status */ 114#define WD_REVC_TTRP 0x04 /* Temperature Trip status */
114#define WD_REVC_RL2A 0x08 /* Relay 2 activated by on-board processor */ 115#define WD_REVC_RL2A 0x08 /* Relay 2 activated by
116 on-board processor */
115#define WD_REVC_RL1A 0x10 /* Relay 1 active */ 117#define WD_REVC_RL1A 0x10 /* Relay 1 active */
116#define WD_REVC_R2DS 0x40 /* Relay 2 disable */ 118#define WD_REVC_R2DS 0x40 /* Relay 2 disable */
117#define WD_REVC_RLY2 0x80 /* Relay 2 activated? */ 119#define WD_REVC_RLY2 0x80 /* Relay 2 activated? */
118/* Port 2 : Control Status #2 */ 120/* Port 2 : Control Status #2 */
119#define WD_WDIS 0x10 /* Watchdog Disabled */ 121#define WD_WDIS 0x10 /* Watchdog Disabled */
120#define WD_ENTP 0x20 /* Watchdog Enable Temperature Trip */ 122#define WD_ENTP 0x20 /* Watchdog Enable Temperature Trip */
121#define WD_SSEL 0x40 /* Watchdog Switch Select (1:SW1 <-> 0:SW2) */ 123#define WD_SSEL 0x40 /* Watchdog Switch Select
124 (1:SW1 <-> 0:SW2) */
122#define WD_WCMD 0x80 /* Watchdog Command Mode */ 125#define WD_WCMD 0x80 /* Watchdog Command Mode */
123 126
124/* max. time we give an ISA watchdog card to process a command */ 127/* max. time we give an ISA watchdog card to process a command */
@@ -142,7 +145,7 @@ static int pcwd_ioports[] = { 0x270, 0x350, 0x370, 0x000 };
142#define CMD_ISA_RESET_RELAYS 0x0D 145#define CMD_ISA_RESET_RELAYS 0x0D
143 146
144/* Watchdog's Dip Switch heartbeat values */ 147/* Watchdog's Dip Switch heartbeat values */
145static const int heartbeat_tbl [] = { 148static const int heartbeat_tbl[] = {
146 20, /* OFF-OFF-OFF = 20 Sec */ 149 20, /* OFF-OFF-OFF = 20 Sec */
147 40, /* OFF-OFF-ON = 40 Sec */ 150 40, /* OFF-OFF-ON = 40 Sec */
148 60, /* OFF-ON-OFF = 1 Min */ 151 60, /* OFF-ON-OFF = 1 Min */
@@ -168,11 +171,15 @@ static int cards_found;
168static atomic_t open_allowed = ATOMIC_INIT(1); 171static atomic_t open_allowed = ATOMIC_INIT(1);
169static char expect_close; 172static char expect_close;
170static int temp_panic; 173static int temp_panic;
171static struct { /* this is private data for each ISA-PC watchdog card */ 174
175/* this is private data for each ISA-PC watchdog card */
176static struct {
172 char fw_ver_str[6]; /* The cards firmware version */ 177 char fw_ver_str[6]; /* The cards firmware version */
173 int revision; /* The card's revision */ 178 int revision; /* The card's revision */
174 int supports_temp; /* Wether or not the card has a temperature device */ 179 int supports_temp; /* Whether or not the card has
175 int command_mode; /* Wether or not the card is in command mode */ 180 a temperature device */
181 int command_mode; /* Whether or not the card is in
182 command mode */
176 int boot_status; /* The card's boot status */ 183 int boot_status; /* The card's boot status */
177 int io_addr; /* The cards I/O address */ 184 int io_addr; /* The cards I/O address */
178 spinlock_t io_lock; /* the lock for io operations */ 185 spinlock_t io_lock; /* the lock for io operations */
@@ -186,16 +193,20 @@ static struct { /* this is private data for each ISA-PC watchdog card */
186#define DEBUG 2 /* print fancy stuff too */ 193#define DEBUG 2 /* print fancy stuff too */
187static int debug = QUIET; 194static int debug = QUIET;
188module_param(debug, int, 0); 195module_param(debug, int, 0);
189MODULE_PARM_DESC(debug, "Debug level: 0=Quiet, 1=Verbose, 2=Debug (default=0)"); 196MODULE_PARM_DESC(debug,
197 "Debug level: 0=Quiet, 1=Verbose, 2=Debug (default=0)");
190 198
191#define WATCHDOG_HEARTBEAT 0 /* default heartbeat = delay-time from dip-switches */ 199/* default heartbeat = delay-time from dip-switches */
200#define WATCHDOG_HEARTBEAT 0
192static int heartbeat = WATCHDOG_HEARTBEAT; 201static int heartbeat = WATCHDOG_HEARTBEAT;
193module_param(heartbeat, int, 0); 202module_param(heartbeat, int, 0);
194MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<=heartbeat<=7200 or 0=delay-time from dip-switches, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); 203MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2 <= heartbeat <= 7200 or 0=delay-time from dip-switches, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
195 204
196static int nowayout = WATCHDOG_NOWAYOUT; 205static int nowayout = WATCHDOG_NOWAYOUT;
197module_param(nowayout, int, 0); 206module_param(nowayout, int, 0);
198MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 207MODULE_PARM_DESC(nowayout,
208 "Watchdog cannot be stopped once started (default="
209 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
199 210
200/* 211/*
201 * Internal functions 212 * Internal functions
@@ -224,7 +235,7 @@ static int send_isa_command(int cmd)
224 if (port0 == last_port0) 235 if (port0 == last_port0)
225 break; /* Data is stable */ 236 break; /* Data is stable */
226 237
227 udelay (250); 238 udelay(250);
228 } 239 }
229 240
230 if (debug >= DEBUG) 241 if (debug >= DEBUG)
@@ -236,7 +247,7 @@ static int send_isa_command(int cmd)
236 247
237static int set_command_mode(void) 248static int set_command_mode(void)
238{ 249{
239 int i, found=0, count=0; 250 int i, found = 0, count = 0;
240 251
241 /* Set the card into command mode */ 252 /* Set the card into command mode */
242 spin_lock(&pcwd_private.io_lock); 253 spin_lock(&pcwd_private.io_lock);
@@ -261,7 +272,7 @@ static int set_command_mode(void)
261 printk(KERN_DEBUG PFX "command_mode=%d\n", 272 printk(KERN_DEBUG PFX "command_mode=%d\n",
262 pcwd_private.command_mode); 273 pcwd_private.command_mode);
263 274
264 return(found); 275 return found;
265} 276}
266 277
267static void unset_command_mode(void) 278static void unset_command_mode(void)
@@ -296,7 +307,8 @@ static inline void pcwd_get_firmware(void)
296 ten = send_isa_command(CMD_ISA_VERSION_TENTH); 307 ten = send_isa_command(CMD_ISA_VERSION_TENTH);
297 hund = send_isa_command(CMD_ISA_VERSION_HUNDRETH); 308 hund = send_isa_command(CMD_ISA_VERSION_HUNDRETH);
298 minor = send_isa_command(CMD_ISA_VERSION_MINOR); 309 minor = send_isa_command(CMD_ISA_VERSION_MINOR);
299 sprintf(pcwd_private.fw_ver_str, "%c.%c%c%c", one, ten, hund, minor); 310 sprintf(pcwd_private.fw_ver_str, "%c.%c%c%c",
311 one, ten, hund, minor);
300 } 312 }
301 unset_command_mode(); 313 unset_command_mode();
302 314
@@ -305,7 +317,7 @@ static inline void pcwd_get_firmware(void)
305 317
306static inline int pcwd_get_option_switches(void) 318static inline int pcwd_get_option_switches(void)
307{ 319{
308 int option_switches=0; 320 int option_switches = 0;
309 321
310 if (set_command_mode()) { 322 if (set_command_mode()) {
311 /* Get switch settings */ 323 /* Get switch settings */
@@ -313,7 +325,7 @@ static inline int pcwd_get_option_switches(void)
313 } 325 }
314 326
315 unset_command_mode(); 327 unset_command_mode();
316 return(option_switches); 328 return option_switches;
317} 329}
318 330
319static void pcwd_show_card_info(void) 331static void pcwd_show_card_info(void)
@@ -322,7 +334,9 @@ static void pcwd_show_card_info(void)
322 334
323 /* Get some extra info from the hardware (in command/debug/diag mode) */ 335 /* Get some extra info from the hardware (in command/debug/diag mode) */
324 if (pcwd_private.revision == PCWD_REVISION_A) 336 if (pcwd_private.revision == PCWD_REVISION_A)
325 printk(KERN_INFO PFX "ISA-PC Watchdog (REV.A) detected at port 0x%04x\n", pcwd_private.io_addr); 337 printk(KERN_INFO PFX
338 "ISA-PC Watchdog (REV.A) detected at port 0x%04x\n",
339 pcwd_private.io_addr);
326 else if (pcwd_private.revision == PCWD_REVISION_C) { 340 else if (pcwd_private.revision == PCWD_REVISION_C) {
327 pcwd_get_firmware(); 341 pcwd_get_firmware();
328 printk(KERN_INFO PFX "ISA-PC Watchdog (REV.C) detected at port 0x%04x (Firmware version: %s)\n", 342 printk(KERN_INFO PFX "ISA-PC Watchdog (REV.C) detected at port 0x%04x (Firmware version: %s)\n",
@@ -347,12 +361,15 @@ static void pcwd_show_card_info(void)
347 printk(KERN_INFO PFX "Previous reboot was caused by the card\n"); 361 printk(KERN_INFO PFX "Previous reboot was caused by the card\n");
348 362
349 if (pcwd_private.boot_status & WDIOF_OVERHEAT) { 363 if (pcwd_private.boot_status & WDIOF_OVERHEAT) {
350 printk(KERN_EMERG PFX "Card senses a CPU Overheat. Panicking!\n"); 364 printk(KERN_EMERG PFX
351 printk(KERN_EMERG PFX "CPU Overheat\n"); 365 "Card senses a CPU Overheat. Panicking!\n");
366 printk(KERN_EMERG PFX
367 "CPU Overheat\n");
352 } 368 }
353 369
354 if (pcwd_private.boot_status == 0) 370 if (pcwd_private.boot_status == 0)
355 printk(KERN_INFO PFX "No previous trip detected - Cold boot or reset\n"); 371 printk(KERN_INFO PFX
372 "No previous trip detected - Cold boot or reset\n");
356} 373}
357 374
358static void pcwd_timer_ping(unsigned long data) 375static void pcwd_timer_ping(unsigned long data)
@@ -361,11 +378,12 @@ static void pcwd_timer_ping(unsigned long data)
361 378
362 /* If we got a heartbeat pulse within the WDT_INTERVAL 379 /* If we got a heartbeat pulse within the WDT_INTERVAL
363 * we agree to ping the WDT */ 380 * we agree to ping the WDT */
364 if(time_before(jiffies, pcwd_private.next_heartbeat)) { 381 if (time_before(jiffies, pcwd_private.next_heartbeat)) {
365 /* Ping the watchdog */ 382 /* Ping the watchdog */
366 spin_lock(&pcwd_private.io_lock); 383 spin_lock(&pcwd_private.io_lock);
367 if (pcwd_private.revision == PCWD_REVISION_A) { 384 if (pcwd_private.revision == PCWD_REVISION_A) {
368 /* Rev A cards are reset by setting the WD_WDRST bit in register 1 */ 385 /* Rev A cards are reset by setting the
386 WD_WDRST bit in register 1 */
369 wdrst_stat = inb_p(pcwd_private.io_addr); 387 wdrst_stat = inb_p(pcwd_private.io_addr);
370 wdrst_stat &= 0x0F; 388 wdrst_stat &= 0x0F;
371 wdrst_stat |= WD_WDRST; 389 wdrst_stat |= WD_WDRST;
@@ -381,7 +399,8 @@ static void pcwd_timer_ping(unsigned long data)
381 399
382 spin_unlock(&pcwd_private.io_lock); 400 spin_unlock(&pcwd_private.io_lock);
383 } else { 401 } else {
384 printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); 402 printk(KERN_WARNING PFX
403 "Heartbeat lost! Will not ping the watchdog\n");
385 } 404 }
386} 405}
387 406
@@ -454,7 +473,7 @@ static int pcwd_keepalive(void)
454 473
455static int pcwd_set_heartbeat(int t) 474static int pcwd_set_heartbeat(int t)
456{ 475{
457 if ((t < 2) || (t > 7200)) /* arbitrary upper limit */ 476 if (t < 2 || t > 7200) /* arbitrary upper limit */
458 return -EINVAL; 477 return -EINVAL;
459 478
460 heartbeat = t; 479 heartbeat = t;
@@ -470,7 +489,7 @@ static int pcwd_get_status(int *status)
470{ 489{
471 int control_status; 490 int control_status;
472 491
473 *status=0; 492 *status = 0;
474 spin_lock(&pcwd_private.io_lock); 493 spin_lock(&pcwd_private.io_lock);
475 if (pcwd_private.revision == PCWD_REVISION_A) 494 if (pcwd_private.revision == PCWD_REVISION_A)
476 /* Rev A cards return status information from 495 /* Rev A cards return status information from
@@ -494,9 +513,9 @@ static int pcwd_get_status(int *status)
494 if (control_status & WD_T110) { 513 if (control_status & WD_T110) {
495 *status |= WDIOF_OVERHEAT; 514 *status |= WDIOF_OVERHEAT;
496 if (temp_panic) { 515 if (temp_panic) {
497 printk(KERN_INFO PFX "Temperature overheat trip!\n"); 516 printk(KERN_INFO PFX
517 "Temperature overheat trip!\n");
498 kernel_power_off(); 518 kernel_power_off();
499 /* or should we just do a: panic(PFX "Temperature overheat trip!\n"); */
500 } 519 }
501 } 520 }
502 } else { 521 } else {
@@ -506,9 +525,9 @@ static int pcwd_get_status(int *status)
506 if (control_status & WD_REVC_TTRP) { 525 if (control_status & WD_REVC_TTRP) {
507 *status |= WDIOF_OVERHEAT; 526 *status |= WDIOF_OVERHEAT;
508 if (temp_panic) { 527 if (temp_panic) {
509 printk(KERN_INFO PFX "Temperature overheat trip!\n"); 528 printk(KERN_INFO PFX
529 "Temperature overheat trip!\n");
510 kernel_power_off(); 530 kernel_power_off();
511 /* or should we just do a: panic(PFX "Temperature overheat trip!\n"); */
512 } 531 }
513 } 532 }
514 } 533 }
@@ -524,18 +543,21 @@ static int pcwd_clear_status(void)
524 spin_lock(&pcwd_private.io_lock); 543 spin_lock(&pcwd_private.io_lock);
525 544
526 if (debug >= VERBOSE) 545 if (debug >= VERBOSE)
527 printk(KERN_INFO PFX "clearing watchdog trip status\n"); 546 printk(KERN_INFO PFX
547 "clearing watchdog trip status\n");
528 548
529 control_status = inb_p(pcwd_private.io_addr + 1); 549 control_status = inb_p(pcwd_private.io_addr + 1);
530 550
531 if (debug >= DEBUG) { 551 if (debug >= DEBUG) {
532 printk(KERN_DEBUG PFX "status was: 0x%02x\n", control_status); 552 printk(KERN_DEBUG PFX "status was: 0x%02x\n",
553 control_status);
533 printk(KERN_DEBUG PFX "sending: 0x%02x\n", 554 printk(KERN_DEBUG PFX "sending: 0x%02x\n",
534 (control_status & WD_REVC_R2DS)); 555 (control_status & WD_REVC_R2DS));
535 } 556 }
536 557
537 /* clear reset status & Keep Relay 2 disable state as it is */ 558 /* clear reset status & Keep Relay 2 disable state as it is */
538 outb_p((control_status & WD_REVC_R2DS), pcwd_private.io_addr + 1); 559 outb_p((control_status & WD_REVC_R2DS),
560 pcwd_private.io_addr + 1);
539 561
540 spin_unlock(&pcwd_private.io_lock); 562 spin_unlock(&pcwd_private.io_lock);
541 } 563 }
@@ -572,8 +594,7 @@ static int pcwd_get_temperature(int *temperature)
572 * /dev/watchdog handling 594 * /dev/watchdog handling
573 */ 595 */
574 596
575static int pcwd_ioctl(struct inode *inode, struct file *file, 597static long pcwd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
576 unsigned int cmd, unsigned long arg)
577{ 598{
578 int rv; 599 int rv;
579 int status; 600 int status;
@@ -590,12 +611,9 @@ static int pcwd_ioctl(struct inode *inode, struct file *file,
590 .identity = "PCWD", 611 .identity = "PCWD",
591 }; 612 };
592 613
593 switch(cmd) { 614 switch (cmd) {
594 default:
595 return -ENOTTY;
596
597 case WDIOC_GETSUPPORT: 615 case WDIOC_GETSUPPORT:
598 if(copy_to_user(argp, &ident, sizeof(ident))) 616 if (copy_to_user(argp, &ident, sizeof(ident)))
599 return -EFAULT; 617 return -EFAULT;
600 return 0; 618 return 0;
601 619
@@ -613,25 +631,22 @@ static int pcwd_ioctl(struct inode *inode, struct file *file,
613 return put_user(temperature, argp); 631 return put_user(temperature, argp);
614 632
615 case WDIOC_SETOPTIONS: 633 case WDIOC_SETOPTIONS:
616 if (pcwd_private.revision == PCWD_REVISION_C) 634 if (pcwd_private.revision == PCWD_REVISION_C) {
617 { 635 if (get_user(rv, argp))
618 if(copy_from_user(&rv, argp, sizeof(int)))
619 return -EFAULT; 636 return -EFAULT;
620 637
621 if (rv & WDIOS_DISABLECARD) 638 if (rv & WDIOS_DISABLECARD) {
622 { 639 status = pcwd_stop();
623 return pcwd_stop(); 640 if (status < 0)
641 return status;
624 } 642 }
625 643 if (rv & WDIOS_ENABLECARD) {
626 if (rv & WDIOS_ENABLECARD) 644 status = pcwd_start();
627 { 645 if (status < 0)
628 return pcwd_start(); 646 return status;
629 } 647 }
630
631 if (rv & WDIOS_TEMPPANIC) 648 if (rv & WDIOS_TEMPPANIC)
632 {
633 temp_panic = 1; 649 temp_panic = 1;
634 }
635 } 650 }
636 return -EINVAL; 651 return -EINVAL;
637 652
@@ -651,6 +666,9 @@ static int pcwd_ioctl(struct inode *inode, struct file *file,
651 666
652 case WDIOC_GETTIMEOUT: 667 case WDIOC_GETTIMEOUT:
653 return put_user(heartbeat, argp); 668 return put_user(heartbeat, argp);
669
670 default:
671 return -ENOTTY;
654 } 672 }
655 673
656 return 0; 674 return 0;
@@ -682,16 +700,10 @@ static ssize_t pcwd_write(struct file *file, const char __user *buf, size_t len,
682 700
683static int pcwd_open(struct inode *inode, struct file *file) 701static int pcwd_open(struct inode *inode, struct file *file)
684{ 702{
685 if (!atomic_dec_and_test(&open_allowed) ) { 703 if (test_and_set_bit(0, &open_allowed))
686 if (debug >= VERBOSE)
687 printk(KERN_ERR PFX "Attempt to open already opened device.\n");
688 atomic_inc( &open_allowed );
689 return -EBUSY; 704 return -EBUSY;
690 }
691
692 if (nowayout) 705 if (nowayout)
693 __module_get(THIS_MODULE); 706 __module_get(THIS_MODULE);
694
695 /* Activate */ 707 /* Activate */
696 pcwd_start(); 708 pcwd_start();
697 pcwd_keepalive(); 709 pcwd_keepalive();
@@ -700,14 +712,15 @@ static int pcwd_open(struct inode *inode, struct file *file)
700 712
701static int pcwd_close(struct inode *inode, struct file *file) 713static int pcwd_close(struct inode *inode, struct file *file)
702{ 714{
703 if (expect_close == 42) { 715 if (expect_close == 42)
704 pcwd_stop(); 716 pcwd_stop();
705 } else { 717 else {
706 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); 718 printk(KERN_CRIT PFX
719 "Unexpected close, not stopping watchdog!\n");
707 pcwd_keepalive(); 720 pcwd_keepalive();
708 } 721 }
709 expect_close = 0; 722 expect_close = 0;
710 atomic_inc( &open_allowed ); 723 clear_bit(0, &open_allowed);
711 return 0; 724 return 0;
712} 725}
713 726
@@ -750,7 +763,7 @@ static const struct file_operations pcwd_fops = {
750 .owner = THIS_MODULE, 763 .owner = THIS_MODULE,
751 .llseek = no_llseek, 764 .llseek = no_llseek,
752 .write = pcwd_write, 765 .write = pcwd_write,
753 .ioctl = pcwd_ioctl, 766 .unlocked_ioctl = pcwd_ioctl,
754 .open = pcwd_open, 767 .open = pcwd_open,
755 .release = pcwd_close, 768 .release = pcwd_close,
756}; 769};
@@ -788,7 +801,7 @@ static inline int get_revision(void)
788 * presumes a floating bus reads as 0xff. */ 801 * presumes a floating bus reads as 0xff. */
789 if ((inb(pcwd_private.io_addr + 2) == 0xFF) || 802 if ((inb(pcwd_private.io_addr + 2) == 0xFF) ||
790 (inb(pcwd_private.io_addr + 3) == 0xFF)) 803 (inb(pcwd_private.io_addr + 3) == 0xFF))
791 r=PCWD_REVISION_A; 804 r = PCWD_REVISION_A;
792 spin_unlock(&pcwd_private.io_lock); 805 spin_unlock(&pcwd_private.io_lock);
793 806
794 return r; 807 return r;
@@ -803,7 +816,7 @@ static inline int get_revision(void)
803 */ 816 */
804static int __devinit pcwd_isa_match(struct device *dev, unsigned int id) 817static int __devinit pcwd_isa_match(struct device *dev, unsigned int id)
805{ 818{
806 int base_addr=pcwd_ioports[id]; 819 int base_addr = pcwd_ioports[id];
807 int port0, last_port0; /* Reg 0, in case it's REV A */ 820 int port0, last_port0; /* Reg 0, in case it's REV A */
808 int port1, last_port1; /* Register 1 for REV C cards */ 821 int port1, last_port1; /* Register 1 for REV C cards */
809 int i; 822 int i;
@@ -813,7 +826,7 @@ static int __devinit pcwd_isa_match(struct device *dev, unsigned int id)
813 printk(KERN_DEBUG PFX "pcwd_isa_match id=%d\n", 826 printk(KERN_DEBUG PFX "pcwd_isa_match id=%d\n",
814 id); 827 id);
815 828
816 if (!request_region (base_addr, 4, "PCWD")) { 829 if (!request_region(base_addr, 4, "PCWD")) {
817 printk(KERN_INFO PFX "Port 0x%04x unavailable\n", base_addr); 830 printk(KERN_INFO PFX "Port 0x%04x unavailable\n", base_addr);
818 return 0; 831 return 0;
819 } 832 }
@@ -842,7 +855,7 @@ static int __devinit pcwd_isa_match(struct device *dev, unsigned int id)
842 } 855 }
843 } 856 }
844 } 857 }
845 release_region (base_addr, 4); 858 release_region(base_addr, 4);
846 859
847 return retval; 860 return retval;
848} 861}
@@ -857,7 +870,8 @@ static int __devinit pcwd_isa_probe(struct device *dev, unsigned int id)
857 870
858 cards_found++; 871 cards_found++;
859 if (cards_found == 1) 872 if (cards_found == 1)
860 printk(KERN_INFO PFX "v%s Ken Hollis (kenji@bitgate.com)\n", WD_VER); 873 printk(KERN_INFO PFX "v%s Ken Hollis (kenji@bitgate.com)\n",
874 WD_VER);
861 875
862 if (cards_found > 1) { 876 if (cards_found > 1) {
863 printk(KERN_ERR PFX "This driver only supports 1 device\n"); 877 printk(KERN_ERR PFX "This driver only supports 1 device\n");
@@ -875,10 +889,11 @@ static int __devinit pcwd_isa_probe(struct device *dev, unsigned int id)
875 /* Check card's revision */ 889 /* Check card's revision */
876 pcwd_private.revision = get_revision(); 890 pcwd_private.revision = get_revision();
877 891
878 if (!request_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4, "PCWD")) { 892 if (!request_region(pcwd_private.io_addr,
893 (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4, "PCWD")) {
879 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", 894 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n",
880 pcwd_private.io_addr); 895 pcwd_private.io_addr);
881 ret=-EIO; 896 ret = -EIO;
882 goto error_request_region; 897 goto error_request_region;
883 } 898 }
884 899
@@ -908,26 +923,30 @@ static int __devinit pcwd_isa_probe(struct device *dev, unsigned int id)
908 if (heartbeat == 0) 923 if (heartbeat == 0)
909 heartbeat = heartbeat_tbl[(pcwd_get_option_switches() & 0x07)]; 924 heartbeat = heartbeat_tbl[(pcwd_get_option_switches() & 0x07)];
910 925
911 /* Check that the heartbeat value is within it's range ; if not reset to the default */ 926 /* Check that the heartbeat value is within it's range;
927 if not reset to the default */
912 if (pcwd_set_heartbeat(heartbeat)) { 928 if (pcwd_set_heartbeat(heartbeat)) {
913 pcwd_set_heartbeat(WATCHDOG_HEARTBEAT); 929 pcwd_set_heartbeat(WATCHDOG_HEARTBEAT);
914 printk(KERN_INFO PFX "heartbeat value must be 2<=heartbeat<=7200, using %d\n", 930 printk(KERN_INFO PFX
915 WATCHDOG_HEARTBEAT); 931 "heartbeat value must be 2 <= heartbeat <= 7200, using %d\n",
932 WATCHDOG_HEARTBEAT);
916 } 933 }
917 934
918 if (pcwd_private.supports_temp) { 935 if (pcwd_private.supports_temp) {
919 ret = misc_register(&temp_miscdev); 936 ret = misc_register(&temp_miscdev);
920 if (ret) { 937 if (ret) {
921 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 938 printk(KERN_ERR PFX
922 TEMP_MINOR, ret); 939 "cannot register miscdev on minor=%d (err=%d)\n",
940 TEMP_MINOR, ret);
923 goto error_misc_register_temp; 941 goto error_misc_register_temp;
924 } 942 }
925 } 943 }
926 944
927 ret = misc_register(&pcwd_miscdev); 945 ret = misc_register(&pcwd_miscdev);
928 if (ret) { 946 if (ret) {
929 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 947 printk(KERN_ERR PFX
930 WATCHDOG_MINOR, ret); 948 "cannot register miscdev on minor=%d (err=%d)\n",
949 WATCHDOG_MINOR, ret);
931 goto error_misc_register_watchdog; 950 goto error_misc_register_watchdog;
932 } 951 }
933 952
@@ -940,7 +959,8 @@ error_misc_register_watchdog:
940 if (pcwd_private.supports_temp) 959 if (pcwd_private.supports_temp)
941 misc_deregister(&temp_miscdev); 960 misc_deregister(&temp_miscdev);
942error_misc_register_temp: 961error_misc_register_temp:
943 release_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4); 962 release_region(pcwd_private.io_addr,
963 (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4);
944error_request_region: 964error_request_region:
945 pcwd_private.io_addr = 0x0000; 965 pcwd_private.io_addr = 0x0000;
946 cards_found--; 966 cards_found--;
@@ -964,7 +984,8 @@ static int __devexit pcwd_isa_remove(struct device *dev, unsigned int id)
964 misc_deregister(&pcwd_miscdev); 984 misc_deregister(&pcwd_miscdev);
965 if (pcwd_private.supports_temp) 985 if (pcwd_private.supports_temp)
966 misc_deregister(&temp_miscdev); 986 misc_deregister(&temp_miscdev);
967 release_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4); 987 release_region(pcwd_private.io_addr,
988 (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4);
968 pcwd_private.io_addr = 0x0000; 989 pcwd_private.io_addr = 0x0000;
969 cards_found--; 990 cards_found--;
970 991
diff --git a/drivers/watchdog/pcwd_pci.c b/drivers/watchdog/pcwd_pci.c
index 61a89e959642..90eb1d4271d7 100644
--- a/drivers/watchdog/pcwd_pci.c
+++ b/drivers/watchdog/pcwd_pci.c
@@ -46,9 +46,8 @@
46#include <linux/pci.h> /* For pci functions */ 46#include <linux/pci.h> /* For pci functions */
47#include <linux/ioport.h> /* For io-port access */ 47#include <linux/ioport.h> /* For io-port access */
48#include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ 48#include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */
49 49#include <linux/uaccess.h> /* For copy_to_user/put_user/... */
50#include <asm/uaccess.h> /* For copy_to_user/put_user/... */ 50#include <linux/io.h> /* For inb/outb/... */
51#include <asm/io.h> /* For inb/outb/... */
52 51
53/* Module and version information */ 52/* Module and version information */
54#define WATCHDOG_VERSION "1.03" 53#define WATCHDOG_VERSION "1.03"
@@ -97,7 +96,7 @@
97#define CMD_GET_CLEAR_RESET_COUNT 0x84 96#define CMD_GET_CLEAR_RESET_COUNT 0x84
98 97
99/* Watchdog's Dip Switch heartbeat values */ 98/* Watchdog's Dip Switch heartbeat values */
100static const int heartbeat_tbl [] = { 99static const int heartbeat_tbl[] = {
101 5, /* OFF-OFF-OFF = 5 Sec */ 100 5, /* OFF-OFF-OFF = 5 Sec */
102 10, /* OFF-OFF-ON = 10 Sec */ 101 10, /* OFF-OFF-ON = 10 Sec */
103 30, /* OFF-ON-OFF = 30 Sec */ 102 30, /* OFF-ON-OFF = 30 Sec */
@@ -220,11 +219,10 @@ static void pcipcwd_show_card_info(void)
220 int option_switches; 219 int option_switches;
221 220
222 got_fw_rev = send_command(CMD_GET_FIRMWARE_VERSION, &fw_rev_major, &fw_rev_minor); 221 got_fw_rev = send_command(CMD_GET_FIRMWARE_VERSION, &fw_rev_major, &fw_rev_minor);
223 if (got_fw_rev) { 222 if (got_fw_rev)
224 sprintf(fw_ver_str, "%u.%02u", fw_rev_major, fw_rev_minor); 223 sprintf(fw_ver_str, "%u.%02u", fw_rev_major, fw_rev_minor);
225 } else { 224 else
226 sprintf(fw_ver_str, "<card no answer>"); 225 sprintf(fw_ver_str, "<card no answer>");
227 }
228 226
229 /* Get switch settings */ 227 /* Get switch settings */
230 option_switches = pcipcwd_get_option_switches(); 228 option_switches = pcipcwd_get_option_switches();
@@ -331,7 +329,7 @@ static int pcipcwd_get_status(int *status)
331{ 329{
332 int control_status; 330 int control_status;
333 331
334 *status=0; 332 *status = 0;
335 control_status = inb_p(pcipcwd_private.io_addr + 1); 333 control_status = inb_p(pcipcwd_private.io_addr + 1);
336 if (control_status & WD_PCI_WTRP) 334 if (control_status & WD_PCI_WTRP)
337 *status |= WDIOF_CARDRESET; 335 *status |= WDIOF_CARDRESET;
@@ -369,8 +367,8 @@ static int pcipcwd_clear_status(void)
369 outb_p((control_status & WD_PCI_R2DS) | WD_PCI_WTRP, pcipcwd_private.io_addr + 1); 367 outb_p((control_status & WD_PCI_R2DS) | WD_PCI_WTRP, pcipcwd_private.io_addr + 1);
370 368
371 /* clear reset counter */ 369 /* clear reset counter */
372 msb=0; 370 msb = 0;
373 reset_counter=0xff; 371 reset_counter = 0xff;
374 send_command(CMD_GET_CLEAR_RESET_COUNT, &msb, &reset_counter); 372 send_command(CMD_GET_CLEAR_RESET_COUNT, &msb, &reset_counter);
375 373
376 if (debug >= DEBUG) { 374 if (debug >= DEBUG) {
@@ -442,7 +440,7 @@ static ssize_t pcipcwd_write(struct file *file, const char __user *data,
442 /* scan to see whether or not we got the magic character */ 440 /* scan to see whether or not we got the magic character */
443 for (i = 0; i != len; i++) { 441 for (i = 0; i != len; i++) {
444 char c; 442 char c;
445 if(get_user(c, data+i)) 443 if (get_user(c, data + i))
446 return -EFAULT; 444 return -EFAULT;
447 if (c == 'V') 445 if (c == 'V')
448 expect_release = 42; 446 expect_release = 42;
@@ -455,8 +453,8 @@ static ssize_t pcipcwd_write(struct file *file, const char __user *data,
455 return len; 453 return len;
456} 454}
457 455
458static int pcipcwd_ioctl(struct inode *inode, struct file *file, 456static long pcipcwd_ioctl(struct file *file, unsigned int cmd,
459 unsigned int cmd, unsigned long arg) 457 unsigned long arg)
460{ 458{
461 void __user *argp = (void __user *)arg; 459 void __user *argp = (void __user *)arg;
462 int __user *p = argp; 460 int __user *p = argp;
@@ -471,92 +469,89 @@ static int pcipcwd_ioctl(struct inode *inode, struct file *file,
471 }; 469 };
472 470
473 switch (cmd) { 471 switch (cmd) {
474 case WDIOC_GETSUPPORT: 472 case WDIOC_GETSUPPORT:
475 return copy_to_user(argp, &ident, 473 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
476 sizeof (ident)) ? -EFAULT : 0; 474
475 case WDIOC_GETSTATUS:
476 {
477 int status;
478 pcipcwd_get_status(&status);
479 return put_user(status, p);
480 }
477 481
478 case WDIOC_GETSTATUS: 482 case WDIOC_GETBOOTSTATUS:
479 { 483 return put_user(pcipcwd_private.boot_status, p);
480 int status;
481 484
482 pcipcwd_get_status(&status); 485 case WDIOC_GETTEMP:
486 {
487 int temperature;
483 488
484 return put_user(status, p); 489 if (pcipcwd_get_temperature(&temperature))
485 } 490 return -EFAULT;
486 491
487 case WDIOC_GETBOOTSTATUS: 492 return put_user(temperature, p);
488 return put_user(pcipcwd_private.boot_status, p); 493 }
489 494
490 case WDIOC_GETTEMP: 495 case WDIOC_SETOPTIONS:
491 { 496 {
492 int temperature; 497 int new_options, retval = -EINVAL;
493 498
494 if (pcipcwd_get_temperature(&temperature)) 499 if (get_user(new_options, p))
495 return -EFAULT; 500 return -EFAULT;
496 501
497 return put_user(temperature, p); 502 if (new_options & WDIOS_DISABLECARD) {
503 if (pcipcwd_stop())
504 return -EIO;
505 retval = 0;
498 } 506 }
499 507
500 case WDIOC_KEEPALIVE: 508 if (new_options & WDIOS_ENABLECARD) {
501 pcipcwd_keepalive(); 509 if (pcipcwd_start())
502 return 0; 510 return -EIO;
503 511 retval = 0;
504 case WDIOC_SETOPTIONS: 512 }
505 {
506 int new_options, retval = -EINVAL;
507
508 if (get_user (new_options, p))
509 return -EFAULT;
510
511 if (new_options & WDIOS_DISABLECARD) {
512 if (pcipcwd_stop())
513 return -EIO;
514 retval = 0;
515 }
516 513
517 if (new_options & WDIOS_ENABLECARD) { 514 if (new_options & WDIOS_TEMPPANIC) {
518 if (pcipcwd_start()) 515 temp_panic = 1;
519 return -EIO; 516 retval = 0;
520 retval = 0; 517 }
521 }
522 518
523 if (new_options & WDIOS_TEMPPANIC) { 519 return retval;
524 temp_panic = 1; 520 }
525 retval = 0;
526 }
527 521
528 return retval; 522 case WDIOC_KEEPALIVE:
529 } 523 pcipcwd_keepalive();
524 return 0;
530 525
531 case WDIOC_SETTIMEOUT: 526 case WDIOC_SETTIMEOUT:
532 { 527 {
533 int new_heartbeat; 528 int new_heartbeat;
534 529
535 if (get_user(new_heartbeat, p)) 530 if (get_user(new_heartbeat, p))
536 return -EFAULT; 531 return -EFAULT;
537 532
538 if (pcipcwd_set_heartbeat(new_heartbeat)) 533 if (pcipcwd_set_heartbeat(new_heartbeat))
539 return -EINVAL; 534 return -EINVAL;
540 535
541 pcipcwd_keepalive(); 536 pcipcwd_keepalive();
542 /* Fall */ 537 /* Fall */
543 } 538 }
544 539
545 case WDIOC_GETTIMEOUT: 540 case WDIOC_GETTIMEOUT:
546 return put_user(heartbeat, p); 541 return put_user(heartbeat, p);
547 542
548 case WDIOC_GETTIMELEFT: 543 case WDIOC_GETTIMELEFT:
549 { 544 {
550 int time_left; 545 int time_left;
551 546
552 if (pcipcwd_get_timeleft(&time_left)) 547 if (pcipcwd_get_timeleft(&time_left))
553 return -EFAULT; 548 return -EFAULT;
554 549
555 return put_user(time_left, p); 550 return put_user(time_left, p);
556 } 551 }
557 552
558 default: 553 default:
559 return -ENOTTY; 554 return -ENOTTY;
560 } 555 }
561} 556}
562 557
@@ -603,7 +598,7 @@ static ssize_t pcipcwd_temp_read(struct file *file, char __user *data,
603 if (pcipcwd_get_temperature(&temperature)) 598 if (pcipcwd_get_temperature(&temperature))
604 return -EFAULT; 599 return -EFAULT;
605 600
606 if (copy_to_user (data, &temperature, 1)) 601 if (copy_to_user(data, &temperature, 1))
607 return -EFAULT; 602 return -EFAULT;
608 603
609 return 1; 604 return 1;
@@ -628,10 +623,8 @@ static int pcipcwd_temp_release(struct inode *inode, struct file *file)
628 623
629static int pcipcwd_notify_sys(struct notifier_block *this, unsigned long code, void *unused) 624static int pcipcwd_notify_sys(struct notifier_block *this, unsigned long code, void *unused)
630{ 625{
631 if (code==SYS_DOWN || code==SYS_HALT) { 626 if (code == SYS_DOWN || code == SYS_HALT)
632 /* Turn the WDT off */ 627 pcipcwd_stop(); /* Turn the WDT off */
633 pcipcwd_stop();
634 }
635 628
636 return NOTIFY_DONE; 629 return NOTIFY_DONE;
637} 630}
@@ -644,7 +637,7 @@ static const struct file_operations pcipcwd_fops = {
644 .owner = THIS_MODULE, 637 .owner = THIS_MODULE,
645 .llseek = no_llseek, 638 .llseek = no_llseek,
646 .write = pcipcwd_write, 639 .write = pcipcwd_write,
647 .ioctl = pcipcwd_ioctl, 640 .unlocked_ioctl = pcipcwd_ioctl,
648 .open = pcipcwd_open, 641 .open = pcipcwd_open,
649 .release = pcipcwd_release, 642 .release = pcipcwd_release,
650}; 643};
diff --git a/drivers/watchdog/pcwd_usb.c b/drivers/watchdog/pcwd_usb.c
index bf443d077a1e..c1685c942de6 100644
--- a/drivers/watchdog/pcwd_usb.c
+++ b/drivers/watchdog/pcwd_usb.c
@@ -40,8 +40,7 @@
40#include <linux/slab.h> /* For kmalloc, ... */ 40#include <linux/slab.h> /* For kmalloc, ... */
41#include <linux/mutex.h> /* For mutex locking */ 41#include <linux/mutex.h> /* For mutex locking */
42#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 */
43 43#include <linux/uaccess.h> /* For copy_to_user/put_user/... */
44#include <asm/uaccess.h> /* For copy_to_user/put_user/... */
45 44
46 45
47#ifdef CONFIG_USB_DEBUG 46#ifdef CONFIG_USB_DEBUG
@@ -88,7 +87,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" _
88#define USB_PCWD_PRODUCT_ID 0x1140 87#define USB_PCWD_PRODUCT_ID 0x1140
89 88
90/* table of devices that work with this driver */ 89/* table of devices that work with this driver */
91static struct usb_device_id usb_pcwd_table [] = { 90static struct usb_device_id usb_pcwd_table[] = {
92 { USB_DEVICE(USB_PCWD_VENDOR_ID, USB_PCWD_PRODUCT_ID) }, 91 { USB_DEVICE(USB_PCWD_VENDOR_ID, USB_PCWD_PRODUCT_ID) },
93 { } /* Terminating entry */ 92 { } /* Terminating entry */
94}; 93};
@@ -110,7 +109,7 @@ MODULE_DEVICE_TABLE (usb, usb_pcwd_table);
110#define CMD_DISABLE_WATCHDOG CMD_ENABLE_WATCHDOG 109#define CMD_DISABLE_WATCHDOG CMD_ENABLE_WATCHDOG
111 110
112/* Watchdog's Dip Switch heartbeat values */ 111/* Watchdog's Dip Switch heartbeat values */
113static const int heartbeat_tbl [] = { 112static const int heartbeat_tbl[] = {
114 5, /* OFF-OFF-OFF = 5 Sec */ 113 5, /* OFF-OFF-OFF = 5 Sec */
115 10, /* OFF-OFF-ON = 10 Sec */ 114 10, /* OFF-OFF-ON = 10 Sec */
116 30, /* OFF-ON-OFF = 30 Sec */ 115 30, /* OFF-ON-OFF = 30 Sec */
@@ -130,15 +129,15 @@ static char expect_release;
130 129
131/* Structure to hold all of our device specific stuff */ 130/* Structure to hold all of our device specific stuff */
132struct usb_pcwd_private { 131struct usb_pcwd_private {
133 struct usb_device * udev; /* save off the usb device pointer */ 132 struct usb_device *udev; /* save off the usb device pointer */
134 struct usb_interface * interface; /* the interface for this device */ 133 struct usb_interface *interface; /* the interface for this device */
135 134
136 unsigned int interface_number; /* the interface number used for cmd's */ 135 unsigned int interface_number; /* the interface number used for cmd's */
137 136
138 unsigned char * intr_buffer; /* the buffer to intr data */ 137 unsigned char *intr_buffer; /* the buffer to intr data */
139 dma_addr_t intr_dma; /* the dma address for the intr buffer */ 138 dma_addr_t intr_dma; /* the dma address for the intr buffer */
140 size_t intr_size; /* the size of the intr buffer */ 139 size_t intr_size; /* the size of the intr buffer */
141 struct urb * intr_urb; /* the urb used for the intr pipe */ 140 struct urb *intr_urb; /* the urb used for the intr pipe */
142 141
143 unsigned char cmd_command; /* The command that is reported back */ 142 unsigned char cmd_command; /* The command that is reported back */
144 unsigned char cmd_data_msb; /* The data MSB that is reported back */ 143 unsigned char cmd_data_msb; /* The data MSB that is reported back */
@@ -154,8 +153,8 @@ static struct usb_pcwd_private *usb_pcwd_device;
154static DEFINE_MUTEX(disconnect_mutex); 153static DEFINE_MUTEX(disconnect_mutex);
155 154
156/* local function prototypes */ 155/* local function prototypes */
157static int usb_pcwd_probe (struct usb_interface *interface, const struct usb_device_id *id); 156static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_device_id *id);
158static void usb_pcwd_disconnect (struct usb_interface *interface); 157static void usb_pcwd_disconnect(struct usb_interface *interface);
159 158
160/* usb specific object needed to register this driver with the usb subsystem */ 159/* usb specific object needed to register this driver with the usb subsystem */
161static struct usb_driver usb_pcwd_driver = { 160static struct usb_driver usb_pcwd_driver = {
@@ -195,10 +194,10 @@ static void usb_pcwd_intr_done(struct urb *urb)
195 usb_pcwd->cmd_data_lsb = data[2]; 194 usb_pcwd->cmd_data_lsb = data[2];
196 195
197 /* notify anyone waiting that the cmd has finished */ 196 /* notify anyone waiting that the cmd has finished */
198 atomic_set (&usb_pcwd->cmd_received, 1); 197 atomic_set(&usb_pcwd->cmd_received, 1);
199 198
200resubmit: 199resubmit:
201 retval = usb_submit_urb (urb, GFP_ATOMIC); 200 retval = usb_submit_urb(urb, GFP_ATOMIC);
202 if (retval) 201 if (retval)
203 printk(KERN_ERR PFX "can't resubmit intr, usb_submit_urb failed with result %d\n", 202 printk(KERN_ERR PFX "can't resubmit intr, usb_submit_urb failed with result %d\n",
204 retval); 203 retval);
@@ -224,7 +223,7 @@ static int usb_pcwd_send_command(struct usb_pcwd_private *usb_pcwd, unsigned cha
224 dbg("sending following data cmd=0x%02x msb=0x%02x lsb=0x%02x", 223 dbg("sending following data cmd=0x%02x msb=0x%02x lsb=0x%02x",
225 buf[0], buf[1], buf[2]); 224 buf[0], buf[1], buf[2]);
226 225
227 atomic_set (&usb_pcwd->cmd_received, 0); 226 atomic_set(&usb_pcwd->cmd_received, 0);
228 227
229 if (usb_control_msg(usb_pcwd->udev, usb_sndctrlpipe(usb_pcwd->udev, 0), 228 if (usb_control_msg(usb_pcwd->udev, usb_sndctrlpipe(usb_pcwd->udev, 0),
230 HID_REQ_SET_REPORT, HID_DT_REPORT, 229 HID_REQ_SET_REPORT, HID_DT_REPORT,
@@ -237,7 +236,7 @@ static int usb_pcwd_send_command(struct usb_pcwd_private *usb_pcwd, unsigned cha
237 got_response = 0; 236 got_response = 0;
238 for (count = 0; (count < USB_COMMAND_TIMEOUT) && (!got_response); count++) { 237 for (count = 0; (count < USB_COMMAND_TIMEOUT) && (!got_response); count++) {
239 mdelay(1); 238 mdelay(1);
240 if (atomic_read (&usb_pcwd->cmd_received)) 239 if (atomic_read(&usb_pcwd->cmd_received))
241 got_response = 1; 240 got_response = 1;
242 } 241 }
243 242
@@ -356,7 +355,7 @@ static ssize_t usb_pcwd_write(struct file *file, const char __user *data,
356 /* scan to see whether or not we got the magic character */ 355 /* scan to see whether or not we got the magic character */
357 for (i = 0; i != len; i++) { 356 for (i = 0; i != len; i++) {
358 char c; 357 char c;
359 if(get_user(c, data+i)) 358 if (get_user(c, data + i))
360 return -EFAULT; 359 return -EFAULT;
361 if (c == 'V') 360 if (c == 'V')
362 expect_release = 42; 361 expect_release = 42;
@@ -369,8 +368,8 @@ static ssize_t usb_pcwd_write(struct file *file, const char __user *data,
369 return len; 368 return len;
370} 369}
371 370
372static int usb_pcwd_ioctl(struct inode *inode, struct file *file, 371static long usb_pcwd_ioctl(struct file *file, unsigned int cmd,
373 unsigned int cmd, unsigned long arg) 372 unsigned long arg)
374{ 373{
375 void __user *argp = (void __user *)arg; 374 void __user *argp = (void __user *)arg;
376 int __user *p = argp; 375 int __user *p = argp;
@@ -383,77 +382,76 @@ static int usb_pcwd_ioctl(struct inode *inode, struct file *file,
383 }; 382 };
384 383
385 switch (cmd) { 384 switch (cmd) {
386 case WDIOC_GETSUPPORT: 385 case WDIOC_GETSUPPORT:
387 return copy_to_user(argp, &ident, 386 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
388 sizeof (ident)) ? -EFAULT : 0;
389 387
390 case WDIOC_GETSTATUS: 388 case WDIOC_GETSTATUS:
391 case WDIOC_GETBOOTSTATUS: 389 case WDIOC_GETBOOTSTATUS:
392 return put_user(0, p); 390 return put_user(0, p);
393 391
394 case WDIOC_GETTEMP: 392 case WDIOC_GETTEMP:
395 { 393 {
396 int temperature; 394 int temperature;
397 395
398 if (usb_pcwd_get_temperature(usb_pcwd_device, &temperature)) 396 if (usb_pcwd_get_temperature(usb_pcwd_device, &temperature))
399 return -EFAULT; 397 return -EFAULT;
400 398
401 return put_user(temperature, p); 399 return put_user(temperature, p);
402 } 400 }
403 401
404 case WDIOC_KEEPALIVE: 402 case WDIOC_SETOPTIONS:
405 usb_pcwd_keepalive(usb_pcwd_device); 403 {
406 return 0; 404 int new_options, retval = -EINVAL;
407 405
408 case WDIOC_SETOPTIONS: 406 if (get_user(new_options, p))
409 { 407 return -EFAULT;
410 int new_options, retval = -EINVAL;
411 408
412 if (get_user (new_options, p)) 409 if (new_options & WDIOS_DISABLECARD) {
413 return -EFAULT; 410 usb_pcwd_stop(usb_pcwd_device);
411 retval = 0;
412 }
414 413
415 if (new_options & WDIOS_DISABLECARD) { 414 if (new_options & WDIOS_ENABLECARD) {
416 usb_pcwd_stop(usb_pcwd_device); 415 usb_pcwd_start(usb_pcwd_device);
417 retval = 0; 416 retval = 0;
418 } 417 }
419 418
420 if (new_options & WDIOS_ENABLECARD) { 419 return retval;
421 usb_pcwd_start(usb_pcwd_device); 420 }
422 retval = 0;
423 }
424 421
425 return retval; 422 case WDIOC_KEEPALIVE:
426 } 423 usb_pcwd_keepalive(usb_pcwd_device);
424 return 0;
427 425
428 case WDIOC_SETTIMEOUT: 426 case WDIOC_SETTIMEOUT:
429 { 427 {
430 int new_heartbeat; 428 int new_heartbeat;
431 429
432 if (get_user(new_heartbeat, p)) 430 if (get_user(new_heartbeat, p))
433 return -EFAULT; 431 return -EFAULT;
434 432
435 if (usb_pcwd_set_heartbeat(usb_pcwd_device, new_heartbeat)) 433 if (usb_pcwd_set_heartbeat(usb_pcwd_device, new_heartbeat))
436 return -EINVAL; 434 return -EINVAL;
437 435
438 usb_pcwd_keepalive(usb_pcwd_device); 436 usb_pcwd_keepalive(usb_pcwd_device);
439 /* Fall */ 437 /* Fall */
440 } 438 }
441 439
442 case WDIOC_GETTIMEOUT: 440 case WDIOC_GETTIMEOUT:
443 return put_user(heartbeat, p); 441 return put_user(heartbeat, p);
444 442
445 case WDIOC_GETTIMELEFT: 443 case WDIOC_GETTIMELEFT:
446 { 444 {
447 int time_left; 445 int time_left;
448 446
449 if (usb_pcwd_get_timeleft(usb_pcwd_device, &time_left)) 447 if (usb_pcwd_get_timeleft(usb_pcwd_device, &time_left))
450 return -EFAULT; 448 return -EFAULT;
451 449
452 return put_user(time_left, p); 450 return put_user(time_left, p);
453 } 451 }
454 452
455 default: 453 default:
456 return -ENOTTY; 454 return -ENOTTY;
457 } 455 }
458} 456}
459 457
@@ -519,10 +517,8 @@ static int usb_pcwd_temperature_release(struct inode *inode, struct file *file)
519 517
520static int usb_pcwd_notify_sys(struct notifier_block *this, unsigned long code, void *unused) 518static int usb_pcwd_notify_sys(struct notifier_block *this, unsigned long code, void *unused)
521{ 519{
522 if (code==SYS_DOWN || code==SYS_HALT) { 520 if (code == SYS_DOWN || code == SYS_HALT)
523 /* Turn the WDT off */ 521 usb_pcwd_stop(usb_pcwd_device); /* Turn the WDT off */
524 usb_pcwd_stop(usb_pcwd_device);
525 }
526 522
527 return NOTIFY_DONE; 523 return NOTIFY_DONE;
528} 524}
@@ -535,7 +531,7 @@ static const struct file_operations usb_pcwd_fops = {
535 .owner = THIS_MODULE, 531 .owner = THIS_MODULE,
536 .llseek = no_llseek, 532 .llseek = no_llseek,
537 .write = usb_pcwd_write, 533 .write = usb_pcwd_write,
538 .ioctl = usb_pcwd_ioctl, 534 .unlocked_ioctl = usb_pcwd_ioctl,
539 .open = usb_pcwd_open, 535 .open = usb_pcwd_open,
540 .release = usb_pcwd_release, 536 .release = usb_pcwd_release,
541}; 537};
@@ -567,13 +563,13 @@ static struct notifier_block usb_pcwd_notifier = {
567/** 563/**
568 * usb_pcwd_delete 564 * usb_pcwd_delete
569 */ 565 */
570static inline void usb_pcwd_delete (struct usb_pcwd_private *usb_pcwd) 566static inline void usb_pcwd_delete(struct usb_pcwd_private *usb_pcwd)
571{ 567{
572 usb_free_urb(usb_pcwd->intr_urb); 568 usb_free_urb(usb_pcwd->intr_urb);
573 if (usb_pcwd->intr_buffer != NULL) 569 if (usb_pcwd->intr_buffer != NULL)
574 usb_buffer_free(usb_pcwd->udev, usb_pcwd->intr_size, 570 usb_buffer_free(usb_pcwd->udev, usb_pcwd->intr_size,
575 usb_pcwd->intr_buffer, usb_pcwd->intr_dma); 571 usb_pcwd->intr_buffer, usb_pcwd->intr_dma);
576 kfree (usb_pcwd); 572 kfree(usb_pcwd);
577} 573}
578 574
579/** 575/**
@@ -626,7 +622,7 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi
626 maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); 622 maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
627 623
628 /* allocate memory for our device and initialize it */ 624 /* allocate memory for our device and initialize it */
629 usb_pcwd = kzalloc (sizeof(struct usb_pcwd_private), GFP_KERNEL); 625 usb_pcwd = kzalloc(sizeof(struct usb_pcwd_private), GFP_KERNEL);
630 if (usb_pcwd == NULL) { 626 if (usb_pcwd == NULL) {
631 printk(KERN_ERR PFX "Out of memory\n"); 627 printk(KERN_ERR PFX "Out of memory\n");
632 goto error; 628 goto error;
@@ -641,7 +637,8 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi
641 usb_pcwd->intr_size = (le16_to_cpu(endpoint->wMaxPacketSize) > 8 ? le16_to_cpu(endpoint->wMaxPacketSize) : 8); 637 usb_pcwd->intr_size = (le16_to_cpu(endpoint->wMaxPacketSize) > 8 ? le16_to_cpu(endpoint->wMaxPacketSize) : 8);
642 638
643 /* set up the memory buffer's */ 639 /* set up the memory buffer's */
644 if (!(usb_pcwd->intr_buffer = usb_buffer_alloc(udev, usb_pcwd->intr_size, GFP_ATOMIC, &usb_pcwd->intr_dma))) { 640 usb_pcwd->intr_buffer = usb_buffer_alloc(udev, usb_pcwd->intr_size, GFP_ATOMIC, &usb_pcwd->intr_dma);
641 if (!usb_pcwd->intr_buffer) {
645 printk(KERN_ERR PFX "Out of memory\n"); 642 printk(KERN_ERR PFX "Out of memory\n");
646 goto error; 643 goto error;
647 } 644 }
@@ -675,11 +672,10 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi
675 672
676 /* Get the Firmware Version */ 673 /* Get the Firmware Version */
677 got_fw_rev = usb_pcwd_send_command(usb_pcwd, CMD_GET_FIRMWARE_VERSION, &fw_rev_major, &fw_rev_minor); 674 got_fw_rev = usb_pcwd_send_command(usb_pcwd, CMD_GET_FIRMWARE_VERSION, &fw_rev_major, &fw_rev_minor);
678 if (got_fw_rev) { 675 if (got_fw_rev)
679 sprintf(fw_ver_str, "%u.%02u", fw_rev_major, fw_rev_minor); 676 sprintf(fw_ver_str, "%u.%02u", fw_rev_major, fw_rev_minor);
680 } else { 677 else
681 sprintf(fw_ver_str, "<card no answer>"); 678 sprintf(fw_ver_str, "<card no answer>");
682 }
683 679
684 printk(KERN_INFO PFX "Found card (Firmware: %s) with temp option\n", 680 printk(KERN_INFO PFX "Found card (Firmware: %s) with temp option\n",
685 fw_ver_str); 681 fw_ver_str);
@@ -725,7 +721,7 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi
725 } 721 }
726 722
727 /* we can register the device now, as it is ready */ 723 /* we can register the device now, as it is ready */
728 usb_set_intfdata (interface, usb_pcwd); 724 usb_set_intfdata(interface, usb_pcwd);
729 725
730 printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n", 726 printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n",
731 heartbeat, nowayout); 727 heartbeat, nowayout);
@@ -759,8 +755,8 @@ static void usb_pcwd_disconnect(struct usb_interface *interface)
759 /* prevent races with open() */ 755 /* prevent races with open() */
760 mutex_lock(&disconnect_mutex); 756 mutex_lock(&disconnect_mutex);
761 757
762 usb_pcwd = usb_get_intfdata (interface); 758 usb_pcwd = usb_get_intfdata(interface);
763 usb_set_intfdata (interface, NULL); 759 usb_set_intfdata(interface, NULL);
764 760
765 mutex_lock(&usb_pcwd->mtx); 761 mutex_lock(&usb_pcwd->mtx);
766 762
@@ -820,5 +816,5 @@ static void __exit usb_pcwd_exit(void)
820} 816}
821 817
822 818
823module_init (usb_pcwd_init); 819module_init(usb_pcwd_init);
824module_exit (usb_pcwd_exit); 820module_exit(usb_pcwd_exit);
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c
index f431a0427eaa..0ed84162437b 100644
--- a/drivers/watchdog/pnx4008_wdt.c
+++ b/drivers/watchdog/pnx4008_wdt.c
@@ -28,10 +28,9 @@
28#include <linux/platform_device.h> 28#include <linux/platform_device.h>
29#include <linux/clk.h> 29#include <linux/clk.h>
30#include <linux/spinlock.h> 30#include <linux/spinlock.h>
31 31#include <linux/uaccess.h>
32#include <linux/io.h>
32#include <mach/hardware.h> 33#include <mach/hardware.h>
33#include <asm/uaccess.h>
34#include <asm/io.h>
35 34
36#define MODULE_NAME "PNX4008-WDT: " 35#define MODULE_NAME "PNX4008-WDT: "
37 36
@@ -144,9 +143,8 @@ static int pnx4008_wdt_open(struct inode *inode, struct file *file)
144 return nonseekable_open(inode, file); 143 return nonseekable_open(inode, file);
145} 144}
146 145
147static ssize_t 146static ssize_t pnx4008_wdt_write(struct file *file, const char *data,
148pnx4008_wdt_write(struct file *file, const char *data, size_t len, 147 size_t len, loff_t *ppos)
149 loff_t * ppos)
150{ 148{
151 if (len) { 149 if (len) {
152 if (!nowayout) { 150 if (!nowayout) {
@@ -169,15 +167,14 @@ pnx4008_wdt_write(struct file *file, const char *data, size_t len,
169 return len; 167 return len;
170} 168}
171 169
172static struct watchdog_info ident = { 170static const struct watchdog_info ident = {
173 .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | 171 .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE |
174 WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 172 WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
175 .identity = "PNX4008 Watchdog", 173 .identity = "PNX4008 Watchdog",
176}; 174};
177 175
178static int 176static long pnx4008_wdt_ioctl(struct inode *inode, struct file *file,
179pnx4008_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 177 unsigned int cmd, unsigned long arg)
180 unsigned long arg)
181{ 178{
182 int ret = -ENOTTY; 179 int ret = -ENOTTY;
183 int time; 180 int time;
@@ -196,6 +193,11 @@ pnx4008_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
196 ret = put_user(boot_status, (int *)arg); 193 ret = put_user(boot_status, (int *)arg);
197 break; 194 break;
198 195
196 case WDIOC_KEEPALIVE:
197 wdt_enable();
198 ret = 0;
199 break;
200
199 case WDIOC_SETTIMEOUT: 201 case WDIOC_SETTIMEOUT:
200 ret = get_user(time, (int *)arg); 202 ret = get_user(time, (int *)arg);
201 if (ret) 203 if (ret)
@@ -213,11 +215,6 @@ pnx4008_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
213 case WDIOC_GETTIMEOUT: 215 case WDIOC_GETTIMEOUT:
214 ret = put_user(heartbeat, (int *)arg); 216 ret = put_user(heartbeat, (int *)arg);
215 break; 217 break;
216
217 case WDIOC_KEEPALIVE:
218 wdt_enable();
219 ret = 0;
220 break;
221 } 218 }
222 return ret; 219 return ret;
223} 220}
@@ -238,7 +235,7 @@ static const struct file_operations pnx4008_wdt_fops = {
238 .owner = THIS_MODULE, 235 .owner = THIS_MODULE,
239 .llseek = no_llseek, 236 .llseek = no_llseek,
240 .write = pnx4008_wdt_write, 237 .write = pnx4008_wdt_write,
241 .ioctl = pnx4008_wdt_ioctl, 238 .unlocked_ioctl = pnx4008_wdt_ioctl,
242 .open = pnx4008_wdt_open, 239 .open = pnx4008_wdt_open,
243 .release = pnx4008_wdt_release, 240 .release = pnx4008_wdt_release,
244}; 241};
diff --git a/drivers/watchdog/rm9k_wdt.c b/drivers/watchdog/rm9k_wdt.c
index 5c921e471564..f1ae3729a19e 100644
--- a/drivers/watchdog/rm9k_wdt.c
+++ b/drivers/watchdog/rm9k_wdt.c
@@ -29,10 +29,10 @@
29#include <linux/notifier.h> 29#include <linux/notifier.h>
30#include <linux/miscdevice.h> 30#include <linux/miscdevice.h>
31#include <linux/watchdog.h> 31#include <linux/watchdog.h>
32#include <asm/io.h> 32#include <linux/io.h>
33#include <linux/uaccess.h>
33#include <asm/atomic.h> 34#include <asm/atomic.h>
34#include <asm/processor.h> 35#include <asm/processor.h>
35#include <asm/uaccess.h>
36#include <asm/system.h> 36#include <asm/system.h>
37#include <asm/rm9k-ocd.h> 37#include <asm/rm9k-ocd.h>
38 38
@@ -53,10 +53,12 @@ static void wdt_gpi_stop(void);
53static void wdt_gpi_set_timeout(unsigned int); 53static void wdt_gpi_set_timeout(unsigned int);
54static int wdt_gpi_open(struct inode *, struct file *); 54static int wdt_gpi_open(struct inode *, struct file *);
55static int wdt_gpi_release(struct inode *, struct file *); 55static int wdt_gpi_release(struct inode *, struct file *);
56static ssize_t wdt_gpi_write(struct file *, const char __user *, size_t, loff_t *); 56static ssize_t wdt_gpi_write(struct file *, const char __user *, size_t,
57 loff_t *);
57static long wdt_gpi_ioctl(struct file *, unsigned int, unsigned long); 58static long wdt_gpi_ioctl(struct file *, unsigned int, unsigned long);
58static int wdt_gpi_notify(struct notifier_block *, unsigned long, void *); 59static int wdt_gpi_notify(struct notifier_block *, unsigned long, void *);
59static const struct resource *wdt_gpi_get_resource(struct platform_device *, const char *, unsigned int); 60static const struct resource *wdt_gpi_get_resource(struct platform_device *,
61 const char *, unsigned int);
60static int __init wdt_gpi_probe(struct device *); 62static int __init wdt_gpi_probe(struct device *);
61static int __exit wdt_gpi_remove(struct device *); 63static int __exit wdt_gpi_remove(struct device *);
62 64
@@ -68,7 +70,7 @@ static int locked;
68 70
69 71
70/* These are set from device resources */ 72/* These are set from device resources */
71static void __iomem * wd_regs; 73static void __iomem *wd_regs;
72static unsigned int wd_irq, wd_ctr; 74static unsigned int wd_irq, wd_ctr;
73 75
74 76
@@ -216,7 +218,8 @@ static int wdt_gpi_release(struct inode *inode, struct file *file)
216 if (expect_close) { 218 if (expect_close) {
217 wdt_gpi_stop(); 219 wdt_gpi_stop();
218 free_irq(wd_irq, &miscdev); 220 free_irq(wd_irq, &miscdev);
219 printk(KERN_INFO "%s: watchdog stopped\n", wdt_gpi_name); 221 printk(KERN_INFO "%s: watchdog stopped\n",
222 wdt_gpi_name);
220 } else { 223 } else {
221 printk(KERN_CRIT "%s: unexpected close() -" 224 printk(KERN_CRIT "%s: unexpected close() -"
222 " watchdog left running\n", 225 " watchdog left running\n",
@@ -231,8 +234,8 @@ static int wdt_gpi_release(struct inode *inode, struct file *file)
231 return 0; 234 return 0;
232} 235}
233 236
234static ssize_t 237static ssize_t wdt_gpi_write(struct file *f, const char __user *d, size_t s,
235wdt_gpi_write(struct file *f, const char __user *d, size_t s, loff_t *o) 238 loff_t *o)
236{ 239{
237 char val; 240 char val;
238 241
@@ -241,8 +244,7 @@ wdt_gpi_write(struct file *f, const char __user *d, size_t s, loff_t *o)
241 return s ? 1 : 0; 244 return s ? 1 : 0;
242} 245}
243 246
244static long 247static long wdt_gpi_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
245wdt_gpi_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
246{ 248{
247 long res = -ENOTTY; 249 long res = -ENOTTY;
248 const long size = _IOC_SIZE(cmd); 250 const long size = _IOC_SIZE(cmd);
@@ -271,7 +273,8 @@ wdt_gpi_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
271 case WDIOC_GETSUPPORT: 273 case WDIOC_GETSUPPORT:
272 wdinfo.options = nowayout ? 274 wdinfo.options = nowayout ?
273 WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING : 275 WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING :
274 WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE; 276 WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
277 WDIOF_MAGICCLOSE;
275 res = __copy_to_user(argp, &wdinfo, size) ? -EFAULT : size; 278 res = __copy_to_user(argp, &wdinfo, size) ? -EFAULT : size;
276 break; 279 break;
277 280
@@ -322,8 +325,8 @@ wdt_gpi_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
322 325
323 326
324/* Shutdown notifier */ 327/* Shutdown notifier */
325static int 328static int wdt_gpi_notify(struct notifier_block *this, unsigned long code,
326wdt_gpi_notify(struct notifier_block *this, unsigned long code, void *unused) 329 void *unused)
327{ 330{
328 if (code == SYS_DOWN || code == SYS_HALT) 331 if (code == SYS_DOWN || code == SYS_HALT)
329 wdt_gpi_stop(); 332 wdt_gpi_stop();
@@ -333,9 +336,8 @@ wdt_gpi_notify(struct notifier_block *this, unsigned long code, void *unused)
333 336
334 337
335/* Init & exit procedures */ 338/* Init & exit procedures */
336static const struct resource * 339static const struct resource *wdt_gpi_get_resource(struct platform_device *pdv,
337wdt_gpi_get_resource(struct platform_device *pdv, const char *name, 340 const char *name, unsigned int type)
338 unsigned int type)
339{ 341{
340 char buf[80]; 342 char buf[80];
341 if (snprintf(buf, sizeof buf, "%s_0", name) >= sizeof buf) 343 if (snprintf(buf, sizeof buf, "%s_0", name) >= sizeof buf)
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index f1fe800658f4..3da2b90d2fe6 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -119,17 +119,6 @@ static void __s3c2410wdt_stop(void)
119{ 119{
120 unsigned long wtcon; 120 unsigned long wtcon;
121 121
122 spin_lock(&wdt_lock);
123 wtcon = readl(wdt_base + S3C2410_WTCON);
124 wtcon &= ~(S3C2410_WTCON_ENABLE | S3C2410_WTCON_RSTEN);
125 writel(wtcon, wdt_base + S3C2410_WTCON);
126 spin_unlock(&wdt_lock);
127}
128
129static void __s3c2410wdt_stop(void)
130{
131 unsigned long wtcon;
132
133 wtcon = readl(wdt_base + S3C2410_WTCON); 122 wtcon = readl(wdt_base + S3C2410_WTCON);
134 wtcon &= ~(S3C2410_WTCON_ENABLE | S3C2410_WTCON_RSTEN); 123 wtcon &= ~(S3C2410_WTCON_ENABLE | S3C2410_WTCON_RSTEN);
135 writel(wtcon, wdt_base + S3C2410_WTCON); 124 writel(wtcon, wdt_base + S3C2410_WTCON);
@@ -305,8 +294,6 @@ static long s3c2410wdt_ioctl(struct file *file, unsigned int cmd,
305 int new_margin; 294 int new_margin;
306 295
307 switch (cmd) { 296 switch (cmd) {
308 default:
309 return -ENOTTY;
310 case WDIOC_GETSUPPORT: 297 case WDIOC_GETSUPPORT:
311 return copy_to_user(argp, &s3c2410_wdt_ident, 298 return copy_to_user(argp, &s3c2410_wdt_ident,
312 sizeof(s3c2410_wdt_ident)) ? -EFAULT : 0; 299 sizeof(s3c2410_wdt_ident)) ? -EFAULT : 0;
@@ -325,6 +312,8 @@ static long s3c2410wdt_ioctl(struct file *file, unsigned int cmd,
325 return put_user(tmr_margin, p); 312 return put_user(tmr_margin, p);
326 case WDIOC_GETTIMEOUT: 313 case WDIOC_GETTIMEOUT:
327 return put_user(tmr_margin, p); 314 return put_user(tmr_margin, p);
315 default:
316 return -ENOTTY;
328 } 317 }
329} 318}
330 319
diff --git a/drivers/watchdog/sa1100_wdt.c b/drivers/watchdog/sa1100_wdt.c
index 97d9da758dcc..31a48437dc3d 100644
--- a/drivers/watchdog/sa1100_wdt.c
+++ b/drivers/watchdog/sa1100_wdt.c
@@ -26,6 +26,7 @@
26#include <linux/watchdog.h> 26#include <linux/watchdog.h>
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/bitops.h> 28#include <linux/bitops.h>
29#include <linux/uaccess.h>
29 30
30#ifdef CONFIG_ARCH_PXA 31#ifdef CONFIG_ARCH_PXA
31#include <mach/pxa-regs.h> 32#include <mach/pxa-regs.h>
@@ -33,7 +34,6 @@
33 34
34#include <mach/reset.h> 35#include <mach/reset.h>
35#include <mach/hardware.h> 36#include <mach/hardware.h>
36#include <asm/uaccess.h>
37 37
38#define OSCR_FREQ CLOCK_TICK_RATE 38#define OSCR_FREQ CLOCK_TICK_RATE
39 39
@@ -46,7 +46,7 @@ static int boot_status;
46 */ 46 */
47static int sa1100dog_open(struct inode *inode, struct file *file) 47static int sa1100dog_open(struct inode *inode, struct file *file)
48{ 48{
49 if (test_and_set_bit(1,&sa1100wdt_users)) 49 if (test_and_set_bit(1, &sa1100wdt_users))
50 return -EBUSY; 50 return -EBUSY;
51 51
52 /* Activate SA1100 Watchdog timer */ 52 /* Activate SA1100 Watchdog timer */
@@ -67,28 +67,27 @@ static int sa1100dog_open(struct inode *inode, struct file *file)
67static int sa1100dog_release(struct inode *inode, struct file *file) 67static int sa1100dog_release(struct inode *inode, struct file *file)
68{ 68{
69 printk(KERN_CRIT "WATCHDOG: Device closed - timer will not stop\n"); 69 printk(KERN_CRIT "WATCHDOG: Device closed - timer will not stop\n");
70
71 clear_bit(1, &sa1100wdt_users); 70 clear_bit(1, &sa1100wdt_users);
72
73 return 0; 71 return 0;
74} 72}
75 73
76static ssize_t sa1100dog_write(struct file *file, const char __user *data, size_t len, loff_t *ppos) 74static ssize_t sa1100dog_write(struct file *file, const char __user *data,
75 size_t len, loff_t *ppos)
77{ 76{
78 if (len) 77 if (len)
79 /* Refresh OSMR3 timer. */ 78 /* Refresh OSMR3 timer. */
80 OSMR3 = OSCR + pre_margin; 79 OSMR3 = OSCR + pre_margin;
81
82 return len; 80 return len;
83} 81}
84 82
85static struct watchdog_info ident = { 83static const struct watchdog_info ident = {
86 .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 84 .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT
85 | WDIOF_KEEPALIVEPING,
87 .identity = "SA1100/PXA255 Watchdog", 86 .identity = "SA1100/PXA255 Watchdog",
88}; 87};
89 88
90static int sa1100dog_ioctl(struct inode *inode, struct file *file, 89static long sa1100dog_ioctl(struct file *file, unsigned int cmd,
91 unsigned int cmd, unsigned long arg) 90 unsigned long arg)
92{ 91{
93 int ret = -ENOTTY; 92 int ret = -ENOTTY;
94 int time; 93 int time;
@@ -109,6 +108,11 @@ static int sa1100dog_ioctl(struct inode *inode, struct file *file,
109 ret = put_user(boot_status, p); 108 ret = put_user(boot_status, p);
110 break; 109 break;
111 110
111 case WDIOC_KEEPALIVE:
112 OSMR3 = OSCR + pre_margin;
113 ret = 0;
114 break;
115
112 case WDIOC_SETTIMEOUT: 116 case WDIOC_SETTIMEOUT:
113 ret = get_user(time, p); 117 ret = get_user(time, p);
114 if (ret) 118 if (ret)
@@ -126,27 +130,20 @@ static int sa1100dog_ioctl(struct inode *inode, struct file *file,
126 case WDIOC_GETTIMEOUT: 130 case WDIOC_GETTIMEOUT:
127 ret = put_user(pre_margin / OSCR_FREQ, p); 131 ret = put_user(pre_margin / OSCR_FREQ, p);
128 break; 132 break;
129
130 case WDIOC_KEEPALIVE:
131 OSMR3 = OSCR + pre_margin;
132 ret = 0;
133 break;
134 } 133 }
135 return ret; 134 return ret;
136} 135}
137 136
138static const struct file_operations sa1100dog_fops = 137static const struct file_operations sa1100dog_fops = {
139{
140 .owner = THIS_MODULE, 138 .owner = THIS_MODULE,
141 .llseek = no_llseek, 139 .llseek = no_llseek,
142 .write = sa1100dog_write, 140 .write = sa1100dog_write,
143 .ioctl = sa1100dog_ioctl, 141 .unlocked_ioctl = sa1100dog_ioctl,
144 .open = sa1100dog_open, 142 .open = sa1100dog_open,
145 .release = sa1100dog_release, 143 .release = sa1100dog_release,
146}; 144};
147 145
148static struct miscdevice sa1100dog_miscdev = 146static struct miscdevice sa1100dog_miscdev = {
149{
150 .minor = WATCHDOG_MINOR, 147 .minor = WATCHDOG_MINOR,
151 .name = "watchdog", 148 .name = "watchdog",
152 .fops = &sa1100dog_fops, 149 .fops = &sa1100dog_fops,
@@ -169,8 +166,9 @@ static int __init sa1100dog_init(void)
169 166
170 ret = misc_register(&sa1100dog_miscdev); 167 ret = misc_register(&sa1100dog_miscdev);
171 if (ret == 0) 168 if (ret == 0)
172 printk("SA1100/PXA2xx Watchdog Timer: timer margin %d sec\n", 169 printk(KERN_INFO
173 margin); 170 "SA1100/PXA2xx Watchdog Timer: timer margin %d sec\n",
171 margin);
174 return ret; 172 return ret;
175} 173}
176 174
diff --git a/drivers/watchdog/sb_wdog.c b/drivers/watchdog/sb_wdog.c
index b94431433695..27e526a07c9a 100644
--- a/drivers/watchdog/sb_wdog.c
+++ b/drivers/watchdog/sb_wdog.c
@@ -57,6 +57,7 @@
57#include <asm/sibyte/sb1250_int.h> 57#include <asm/sibyte/sb1250_int.h>
58#include <asm/sibyte/sb1250_scd.h> 58#include <asm/sibyte/sb1250_scd.h>
59 59
60static DEFINE_SPINLOCK(sbwd_lock);
60 61
61/* 62/*
62 * set the initial count value of a timer 63 * set the initial count value of a timer
@@ -65,8 +66,10 @@
65 */ 66 */
66void sbwdog_set(char __iomem *wdog, unsigned long t) 67void sbwdog_set(char __iomem *wdog, unsigned long t)
67{ 68{
69 spin_lock(&sbwd_lock);
68 __raw_writeb(0, wdog - 0x10); 70 __raw_writeb(0, wdog - 0x10);
69 __raw_writeq(t & 0x7fffffUL, wdog); 71 __raw_writeq(t & 0x7fffffUL, wdog);
72 spin_unlock(&sbwd_lock);
70} 73}
71 74
72/* 75/*
@@ -77,7 +80,9 @@ void sbwdog_set(char __iomem *wdog, unsigned long t)
77 */ 80 */
78void sbwdog_pet(char __iomem *wdog) 81void sbwdog_pet(char __iomem *wdog)
79{ 82{
83 spin_lock(&sbwd_lock);
80 __raw_writeb(__raw_readb(wdog) | 1, wdog); 84 __raw_writeb(__raw_readb(wdog) | 1, wdog);
85 spin_unlock(&sbwd_lock);
81} 86}
82 87
83static unsigned long sbwdog_gate; /* keeps it to one thread only */ 88static unsigned long sbwdog_gate; /* keeps it to one thread only */
@@ -86,8 +91,9 @@ static char __iomem *user_dog = (char __iomem *)(IO_BASE + (A_SCD_WDOG_CFG_1));
86static unsigned long timeout = 0x7fffffUL; /* useconds: 8.3ish secs. */ 91static unsigned long timeout = 0x7fffffUL; /* useconds: 8.3ish secs. */
87static int expect_close; 92static int expect_close;
88 93
89static struct watchdog_info ident = { 94static const struct watchdog_info ident = {
90 .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 95 .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT |
96 WDIOF_KEEPALIVEPING,
91 .identity = "SiByte Watchdog", 97 .identity = "SiByte Watchdog",
92}; 98};
93 99
@@ -97,9 +103,8 @@ static struct watchdog_info ident = {
97static int sbwdog_open(struct inode *inode, struct file *file) 103static int sbwdog_open(struct inode *inode, struct file *file)
98{ 104{
99 nonseekable_open(inode, file); 105 nonseekable_open(inode, file);
100 if (test_and_set_bit(0, &sbwdog_gate)) { 106 if (test_and_set_bit(0, &sbwdog_gate))
101 return -EBUSY; 107 return -EBUSY;
102 }
103 __module_get(THIS_MODULE); 108 __module_get(THIS_MODULE);
104 109
105 /* 110 /*
@@ -120,8 +125,9 @@ static int sbwdog_release(struct inode *inode, struct file *file)
120 __raw_writeb(0, user_dog); 125 __raw_writeb(0, user_dog);
121 module_put(THIS_MODULE); 126 module_put(THIS_MODULE);
122 } else { 127 } else {
123 printk(KERN_CRIT "%s: Unexpected close, not stopping watchdog!\n", 128 printk(KERN_CRIT
124 ident.identity); 129 "%s: Unexpected close, not stopping watchdog!\n",
130 ident.identity);
125 sbwdog_pet(user_dog); 131 sbwdog_pet(user_dog);
126 } 132 }
127 clear_bit(0, &sbwdog_gate); 133 clear_bit(0, &sbwdog_gate);
@@ -147,12 +153,10 @@ static ssize_t sbwdog_write(struct file *file, const char __user *data,
147 for (i = 0; i != len; i++) { 153 for (i = 0; i != len; i++) {
148 char c; 154 char c;
149 155
150 if (get_user(c, data + i)) { 156 if (get_user(c, data + i))
151 return -EFAULT; 157 return -EFAULT;
152 } 158 if (c == 'V')
153 if (c == 'V') {
154 expect_close = 42; 159 expect_close = 42;
155 }
156 } 160 }
157 sbwdog_pet(user_dog); 161 sbwdog_pet(user_dog);
158 } 162 }
@@ -160,8 +164,8 @@ static ssize_t sbwdog_write(struct file *file, const char __user *data,
160 return len; 164 return len;
161} 165}
162 166
163static int sbwdog_ioctl(struct inode *inode, struct file *file, 167static long sbwdog_ioctl(struct file *file, unsigned int cmd,
164 unsigned int cmd, unsigned long arg) 168 unsigned long arg)
165{ 169{
166 int ret = -ENOTTY; 170 int ret = -ENOTTY;
167 unsigned long time; 171 unsigned long time;
@@ -178,11 +182,15 @@ static int sbwdog_ioctl(struct inode *inode, struct file *file,
178 ret = put_user(0, p); 182 ret = put_user(0, p);
179 break; 183 break;
180 184
185 case WDIOC_KEEPALIVE:
186 sbwdog_pet(user_dog);
187 ret = 0;
188 break;
189
181 case WDIOC_SETTIMEOUT: 190 case WDIOC_SETTIMEOUT:
182 ret = get_user(time, p); 191 ret = get_user(time, p);
183 if (ret) { 192 if (ret)
184 break; 193 break;
185 }
186 194
187 time *= 1000000; 195 time *= 1000000;
188 if (time > 0x7fffffUL) { 196 if (time > 0x7fffffUL) {
@@ -200,11 +208,6 @@ static int sbwdog_ioctl(struct inode *inode, struct file *file,
200 */ 208 */
201 ret = put_user(__raw_readq(user_dog - 8) / 1000000, p); 209 ret = put_user(__raw_readq(user_dog - 8) / 1000000, p);
202 break; 210 break;
203
204 case WDIOC_KEEPALIVE:
205 sbwdog_pet(user_dog);
206 ret = 0;
207 break;
208 } 211 }
209 return ret; 212 return ret;
210} 213}
@@ -212,8 +215,8 @@ static int sbwdog_ioctl(struct inode *inode, struct file *file,
212/* 215/*
213 * Notifier for system down 216 * Notifier for system down
214 */ 217 */
215static int 218static int sbwdog_notify_sys(struct notifier_block *this, unsigned long code,
216sbwdog_notify_sys(struct notifier_block *this, unsigned long code, void *erf) 219 void *erf)
217{ 220{
218 if (code == SYS_DOWN || code == SYS_HALT) { 221 if (code == SYS_DOWN || code == SYS_HALT) {
219 /* 222 /*
@@ -226,18 +229,16 @@ sbwdog_notify_sys(struct notifier_block *this, unsigned long code, void *erf)
226 return NOTIFY_DONE; 229 return NOTIFY_DONE;
227} 230}
228 231
229static const struct file_operations sbwdog_fops = 232static const struct file_operations sbwdog_fops = {
230{
231 .owner = THIS_MODULE, 233 .owner = THIS_MODULE,
232 .llseek = no_llseek, 234 .llseek = no_llseek,
233 .write = sbwdog_write, 235 .write = sbwdog_write,
234 .ioctl = sbwdog_ioctl, 236 .unlocked_ioctl = sbwdog_ioctl,
235 .open = sbwdog_open, 237 .open = sbwdog_open,
236 .release = sbwdog_release, 238 .release = sbwdog_release,
237}; 239};
238 240
239static struct miscdevice sbwdog_miscdev = 241static struct miscdevice sbwdog_miscdev = {
240{
241 .minor = WATCHDOG_MINOR, 242 .minor = WATCHDOG_MINOR,
242 .name = "watchdog", 243 .name = "watchdog",
243 .fops = &sbwdog_fops, 244 .fops = &sbwdog_fops,
@@ -267,13 +268,12 @@ irqreturn_t sbwdog_interrupt(int irq, void *addr)
267 /* 268 /*
268 * if it's the second watchdog timer, it's for those users 269 * if it's the second watchdog timer, it's for those users
269 */ 270 */
270 if (wd_cfg_reg == user_dog) { 271 if (wd_cfg_reg == user_dog)
271 printk(KERN_CRIT 272 printk(KERN_CRIT
272 "%s in danger of initiating system reset in %ld.%01ld seconds\n", 273 "%s in danger of initiating system reset in %ld.%01ld seconds\n",
273 ident.identity, wd_init / 1000000, (wd_init / 100000) % 10); 274 ident.identity, wd_init / 1000000, (wd_init / 100000) % 10);
274 } else { 275 else
275 cfg |= 1; 276 cfg |= 1;
276 }
277 277
278 __raw_writeb(cfg, wd_cfg_reg); 278 __raw_writeb(cfg, wd_cfg_reg);
279 279
@@ -289,28 +289,31 @@ static int __init sbwdog_init(void)
289 */ 289 */
290 ret = register_reboot_notifier(&sbwdog_notifier); 290 ret = register_reboot_notifier(&sbwdog_notifier);
291 if (ret) { 291 if (ret) {
292 printk (KERN_ERR "%s: cannot register reboot notifier (err=%d)\n", 292 printk(KERN_ERR
293 ident.identity, ret); 293 "%s: cannot register reboot notifier (err=%d)\n",
294 ident.identity, ret);
294 return ret; 295 return ret;
295 } 296 }
296 297
297 /* 298 /*
298 * get the resources 299 * get the resources
299 */ 300 */
300 ret = misc_register(&sbwdog_miscdev);
301 if (ret == 0) {
302 printk(KERN_INFO "%s: timeout is %ld.%ld secs\n", ident.identity,
303 timeout / 1000000, (timeout / 100000) % 10);
304 }
305 301
306 ret = request_irq(1, sbwdog_interrupt, IRQF_DISABLED | IRQF_SHARED, 302 ret = request_irq(1, sbwdog_interrupt, IRQF_DISABLED | IRQF_SHARED,
307 ident.identity, (void *)user_dog); 303 ident.identity, (void *)user_dog);
308 if (ret) { 304 if (ret) {
309 printk(KERN_ERR "%s: failed to request irq 1 - %d\n", ident.identity, 305 printk(KERN_ERR "%s: failed to request irq 1 - %d\n",
310 ret); 306 ident.identity, ret);
311 misc_deregister(&sbwdog_miscdev); 307 return ret;
312 } 308 }
313 309
310 ret = misc_register(&sbwdog_miscdev);
311 if (ret == 0) {
312 printk(KERN_INFO "%s: timeout is %ld.%ld secs\n",
313 ident.identity,
314 timeout / 1000000, (timeout / 100000) % 10);
315 } else
316 free_irq(1, (void *)user_dog);
314 return ret; 317 return ret;
315} 318}
316 319
@@ -327,7 +330,7 @@ MODULE_DESCRIPTION("SiByte Watchdog");
327 330
328module_param(timeout, ulong, 0); 331module_param(timeout, ulong, 0);
329MODULE_PARM_DESC(timeout, 332MODULE_PARM_DESC(timeout,
330 "Watchdog timeout in microseconds (max/default 8388607 or 8.3ish secs)"); 333 "Watchdog timeout in microseconds (max/default 8388607 or 8.3ish secs)");
331 334
332MODULE_LICENSE("GPL"); 335MODULE_LICENSE("GPL");
333MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); 336MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
@@ -336,16 +339,15 @@ MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
336 * example code that can be put in a platform code area to utilize the 339 * example code that can be put in a platform code area to utilize the
337 * first watchdog timer for the kernels own purpose. 340 * first watchdog timer for the kernels own purpose.
338 341
339 void 342void platform_wd_setup(void)
340platform_wd_setup(void)
341{ 343{
342 int ret; 344 int ret;
343 345
344 ret = request_irq(0, sbwdog_interrupt, IRQF_DISABLED | IRQF_SHARED, 346 ret = request_irq(1, sbwdog_interrupt, IRQF_DISABLED | IRQF_SHARED,
345 "Kernel Watchdog", IOADDR(A_SCD_WDOG_CFG_0)); 347 "Kernel Watchdog", IOADDR(A_SCD_WDOG_CFG_0));
346 if (ret) { 348 if (ret) {
347 printk(KERN_CRIT "Watchdog IRQ zero(0) failed to be requested - %d\n", 349 printk(KERN_CRIT
348 ret); 350 "Watchdog IRQ zero(0) failed to be requested - %d\n", ret);
349 } 351 }
350} 352}
351 353
diff --git a/drivers/watchdog/sbc60xxwdt.c b/drivers/watchdog/sbc60xxwdt.c
index ef76f01625e7..3266daaaecf8 100644
--- a/drivers/watchdog/sbc60xxwdt.c
+++ b/drivers/watchdog/sbc60xxwdt.c
@@ -16,19 +16,23 @@
16 * 16 *
17 * 12/4 - 2000 [Initial revision] 17 * 12/4 - 2000 [Initial revision]
18 * 25/4 - 2000 Added /dev/watchdog support 18 * 25/4 - 2000 Added /dev/watchdog support
19 * 09/5 - 2001 [smj@oro.net] fixed fop_write to "return 1" on success 19 * 09/5 - 2001 [smj@oro.net] fixed fop_write to "return 1"
20 * on success
20 * 12/4 - 2002 [rob@osinvestor.com] eliminate fop_read 21 * 12/4 - 2002 [rob@osinvestor.com] eliminate fop_read
21 * fix possible wdt_is_open race 22 * fix possible wdt_is_open race
22 * add CONFIG_WATCHDOG_NOWAYOUT support 23 * add CONFIG_WATCHDOG_NOWAYOUT support
23 * remove lock_kernel/unlock_kernel pairs 24 * remove lock_kernel/unlock_kernel pairs
24 * added KERN_* to printk's 25 * added KERN_* to printk's
25 * got rid of extraneous comments 26 * got rid of extraneous comments
26 * changed watchdog_info to correctly reflect what the driver offers 27 * changed watchdog_info to correctly reflect what
27 * added WDIOC_GETSTATUS, WDIOC_GETBOOTSTATUS, WDIOC_SETTIMEOUT, 28 * the driver offers
28 * WDIOC_GETTIMEOUT, and WDIOC_SETOPTIONS ioctls 29 * added WDIOC_GETSTATUS, WDIOC_GETBOOTSTATUS,
30 * WDIOC_SETTIMEOUT, WDIOC_GETTIMEOUT, and
31 * WDIOC_SETOPTIONS ioctls
29 * 09/8 - 2003 [wim@iguana.be] cleanup of trailing spaces 32 * 09/8 - 2003 [wim@iguana.be] cleanup of trailing spaces
30 * use module_param 33 * use module_param
31 * made timeout (the emulated heartbeat) a module_param 34 * made timeout (the emulated heartbeat) a
35 * module_param
32 * made the keepalive ping an internal subroutine 36 * made the keepalive ping an internal subroutine
33 * made wdt_stop and wdt_start module params 37 * made wdt_stop and wdt_start module params
34 * added extra printk's for startup problems 38 * added extra printk's for startup problems
@@ -56,9 +60,9 @@
56#include <linux/notifier.h> 60#include <linux/notifier.h>
57#include <linux/reboot.h> 61#include <linux/reboot.h>
58#include <linux/init.h> 62#include <linux/init.h>
63#include <linux/io.h>
64#include <linux/uaccess.h>
59 65
60#include <asm/io.h>
61#include <asm/uaccess.h>
62#include <asm/system.h> 66#include <asm/system.h>
63 67
64#define OUR_NAME "sbc60xxwdt" 68#define OUR_NAME "sbc60xxwdt"
@@ -94,13 +98,18 @@ MODULE_PARM_DESC(wdt_start, "SBC60xx WDT 'start' io port (default 0x443)");
94 */ 98 */
95 99
96#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ 100#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */
97static int timeout = WATCHDOG_TIMEOUT; /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */ 101static int timeout = WATCHDOG_TIMEOUT; /* in seconds, multiplied by HZ to
102 get seconds to wait for a ping */
98module_param(timeout, int, 0); 103module_param(timeout, int, 0);
99MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); 104MODULE_PARM_DESC(timeout,
105 "Watchdog timeout in seconds. (1<=timeout<=3600, default="
106 __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
100 107
101static int nowayout = WATCHDOG_NOWAYOUT; 108static int nowayout = WATCHDOG_NOWAYOUT;
102module_param(nowayout, int, 0); 109module_param(nowayout, int, 0);
103MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 110MODULE_PARM_DESC(nowayout,
111 "Watchdog cannot be stopped once started (default="
112 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
104 113
105static void wdt_timer_ping(unsigned long); 114static void wdt_timer_ping(unsigned long);
106static DEFINE_TIMER(timer, wdt_timer_ping, 0, 0); 115static DEFINE_TIMER(timer, wdt_timer_ping, 0, 0);
@@ -117,15 +126,14 @@ static void wdt_timer_ping(unsigned long data)
117 /* If we got a heartbeat pulse within the WDT_US_INTERVAL 126 /* If we got a heartbeat pulse within the WDT_US_INTERVAL
118 * we agree to ping the WDT 127 * we agree to ping the WDT
119 */ 128 */
120 if(time_before(jiffies, next_heartbeat)) 129 if (time_before(jiffies, next_heartbeat)) {
121 {
122 /* Ping the WDT by reading from wdt_start */ 130 /* Ping the WDT by reading from wdt_start */
123 inb_p(wdt_start); 131 inb_p(wdt_start);
124 /* Re-set the timer interval */ 132 /* Re-set the timer interval */
125 mod_timer(&timer, jiffies + WDT_INTERVAL); 133 mod_timer(&timer, jiffies + WDT_INTERVAL);
126 } else { 134 } else
127 printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); 135 printk(KERN_WARNING PFX
128 } 136 "Heartbeat lost! Will not ping the watchdog\n");
129} 137}
130 138
131/* 139/*
@@ -159,40 +167,40 @@ static void wdt_keepalive(void)
159 * /dev/watchdog handling 167 * /dev/watchdog handling
160 */ 168 */
161 169
162static ssize_t fop_write(struct file * file, const char __user * buf, size_t count, loff_t * ppos) 170static ssize_t fop_write(struct file *file, const char __user *buf,
171 size_t count, loff_t *ppos)
163{ 172{
164 /* See if we got the magic character 'V' and reload the timer */ 173 /* See if we got the magic character 'V' and reload the timer */
165 if(count) 174 if (count) {
166 { 175 if (!nowayout) {
167 if (!nowayout)
168 {
169 size_t ofs; 176 size_t ofs;
170 177
171 /* note: just in case someone wrote the magic character 178 /* note: just in case someone wrote the
172 * five months ago... */ 179 magic character five months ago... */
173 wdt_expect_close = 0; 180 wdt_expect_close = 0;
174 181
175 /* scan to see whether or not we got the magic character */ 182 /* scan to see whether or not we got the
176 for(ofs = 0; ofs != count; ofs++) 183 magic character */
177 { 184 for (ofs = 0; ofs != count; ofs++) {
178 char c; 185 char c;
179 if(get_user(c, buf+ofs)) 186 if (get_user(c, buf + ofs))
180 return -EFAULT; 187 return -EFAULT;
181 if(c == 'V') 188 if (c == 'V')
182 wdt_expect_close = 42; 189 wdt_expect_close = 42;
183 } 190 }
184 } 191 }
185 192
186 /* Well, anyhow someone wrote to us, we should return that favour */ 193 /* Well, anyhow someone wrote to us, we should
194 return that favour */
187 wdt_keepalive(); 195 wdt_keepalive();
188 } 196 }
189 return count; 197 return count;
190} 198}
191 199
192static int fop_open(struct inode * inode, struct file * file) 200static int fop_open(struct inode *inode, struct file *file)
193{ 201{
194 /* Just in case we're already talking to someone... */ 202 /* Just in case we're already talking to someone... */
195 if(test_and_set_bit(0, &wdt_is_open)) 203 if (test_and_set_bit(0, &wdt_is_open))
196 return -EBUSY; 204 return -EBUSY;
197 205
198 if (nowayout) 206 if (nowayout)
@@ -203,78 +211,72 @@ static int fop_open(struct inode * inode, struct file * file)
203 return nonseekable_open(inode, file); 211 return nonseekable_open(inode, file);
204} 212}
205 213
206static int fop_close(struct inode * inode, struct file * file) 214static int fop_close(struct inode *inode, struct file *file)
207{ 215{
208 if(wdt_expect_close == 42) 216 if (wdt_expect_close == 42)
209 wdt_turnoff(); 217 wdt_turnoff();
210 else { 218 else {
211 del_timer(&timer); 219 del_timer(&timer);
212 printk(KERN_CRIT PFX "device file closed unexpectedly. Will not stop the WDT!\n"); 220 printk(KERN_CRIT PFX
221 "device file closed unexpectedly. Will not stop the WDT!\n");
213 } 222 }
214 clear_bit(0, &wdt_is_open); 223 clear_bit(0, &wdt_is_open);
215 wdt_expect_close = 0; 224 wdt_expect_close = 0;
216 return 0; 225 return 0;
217} 226}
218 227
219static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 228static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
220 unsigned long arg)
221{ 229{
222 void __user *argp = (void __user *)arg; 230 void __user *argp = (void __user *)arg;
223 int __user *p = argp; 231 int __user *p = argp;
224 static struct watchdog_info ident= 232 static const struct watchdog_info ident = {
225 { 233 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
226 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, 234 WDIOF_MAGICCLOSE,
227 .firmware_version = 1, 235 .firmware_version = 1,
228 .identity = "SBC60xx", 236 .identity = "SBC60xx",
229 }; 237 };
230 238
231 switch(cmd) 239 switch (cmd) {
240 case WDIOC_GETSUPPORT:
241 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
242 case WDIOC_GETSTATUS:
243 case WDIOC_GETBOOTSTATUS:
244 return put_user(0, p);
245 case WDIOC_SETOPTIONS:
232 { 246 {
233 default: 247 int new_options, retval = -EINVAL;
234 return -ENOTTY; 248 if (get_user(new_options, p))
235 case WDIOC_GETSUPPORT: 249 return -EFAULT;
236 return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; 250 if (new_options & WDIOS_DISABLECARD) {
237 case WDIOC_GETSTATUS: 251 wdt_turnoff();
238 case WDIOC_GETBOOTSTATUS: 252 retval = 0;
239 return put_user(0, p);
240 case WDIOC_KEEPALIVE:
241 wdt_keepalive();
242 return 0;
243 case WDIOC_SETOPTIONS:
244 {
245 int new_options, retval = -EINVAL;
246
247 if(get_user(new_options, p))
248 return -EFAULT;
249
250 if(new_options & WDIOS_DISABLECARD) {
251 wdt_turnoff();
252 retval = 0;
253 }
254
255 if(new_options & WDIOS_ENABLECARD) {
256 wdt_startup();
257 retval = 0;
258 }
259
260 return retval;
261 } 253 }
262 case WDIOC_SETTIMEOUT: 254 if (new_options & WDIOS_ENABLECARD) {
263 { 255 wdt_startup();
264 int new_timeout; 256 retval = 0;
265
266 if(get_user(new_timeout, p))
267 return -EFAULT;
268
269 if(new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */
270 return -EINVAL;
271
272 timeout = new_timeout;
273 wdt_keepalive();
274 /* Fall through */
275 } 257 }
276 case WDIOC_GETTIMEOUT: 258 return retval;
277 return put_user(timeout, p); 259 }
260 case WDIOC_KEEPALIVE:
261 wdt_keepalive();
262 return 0;
263 case WDIOC_SETTIMEOUT:
264 {
265 int new_timeout;
266 if (get_user(new_timeout, p))
267 return -EFAULT;
268 /* arbitrary upper limit */
269 if (new_timeout < 1 || new_timeout > 3600)
270 return -EINVAL;
271
272 timeout = new_timeout;
273 wdt_keepalive();
274 /* Fall through */
275 }
276 case WDIOC_GETTIMEOUT:
277 return put_user(timeout, p);
278 default:
279 return -ENOTTY;
278 } 280 }
279} 281}
280 282
@@ -284,7 +286,7 @@ static const struct file_operations wdt_fops = {
284 .write = fop_write, 286 .write = fop_write,
285 .open = fop_open, 287 .open = fop_open,
286 .release = fop_close, 288 .release = fop_close,
287 .ioctl = fop_ioctl, 289 .unlocked_ioctl = fop_ioctl,
288}; 290};
289 291
290static struct miscdevice wdt_miscdev = { 292static struct miscdevice wdt_miscdev = {
@@ -300,7 +302,7 @@ static struct miscdevice wdt_miscdev = {
300static int wdt_notify_sys(struct notifier_block *this, unsigned long code, 302static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
301 void *unused) 303 void *unused)
302{ 304{
303 if(code==SYS_DOWN || code==SYS_HALT) 305 if (code == SYS_DOWN || code == SYS_HALT)
304 wdt_turnoff(); 306 wdt_turnoff();
305 return NOTIFY_DONE; 307 return NOTIFY_DONE;
306} 308}
@@ -310,8 +312,7 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
310 * turn the timebomb registers off. 312 * turn the timebomb registers off.
311 */ 313 */
312 314
313static struct notifier_block wdt_notifier= 315static struct notifier_block wdt_notifier = {
314{
315 .notifier_call = wdt_notify_sys, 316 .notifier_call = wdt_notify_sys,
316}; 317};
317 318
@@ -324,23 +325,22 @@ static void __exit sbc60xxwdt_unload(void)
324 325
325 unregister_reboot_notifier(&wdt_notifier); 326 unregister_reboot_notifier(&wdt_notifier);
326 if ((wdt_stop != 0x45) && (wdt_stop != wdt_start)) 327 if ((wdt_stop != 0x45) && (wdt_stop != wdt_start))
327 release_region(wdt_stop,1); 328 release_region(wdt_stop, 1);
328 release_region(wdt_start,1); 329 release_region(wdt_start, 1);
329} 330}
330 331
331static int __init sbc60xxwdt_init(void) 332static int __init sbc60xxwdt_init(void)
332{ 333{
333 int rc = -EBUSY; 334 int rc = -EBUSY;
334 335
335 if(timeout < 1 || timeout > 3600) /* arbitrary upper limit */ 336 if (timeout < 1 || timeout > 3600) { /* arbitrary upper limit */
336 {
337 timeout = WATCHDOG_TIMEOUT; 337 timeout = WATCHDOG_TIMEOUT;
338 printk(KERN_INFO PFX "timeout value must be 1<=x<=3600, using %d\n", 338 printk(KERN_INFO PFX
339 timeout); 339 "timeout value must be 1 <= x <= 3600, using %d\n",
340 } 340 timeout);
341 }
341 342
342 if (!request_region(wdt_start, 1, "SBC 60XX WDT")) 343 if (!request_region(wdt_start, 1, "SBC 60XX WDT")) {
343 {
344 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", 344 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n",
345 wdt_start); 345 wdt_start);
346 rc = -EIO; 346 rc = -EIO;
@@ -348,33 +348,30 @@ static int __init sbc60xxwdt_init(void)
348 } 348 }
349 349
350 /* We cannot reserve 0x45 - the kernel already has! */ 350 /* We cannot reserve 0x45 - the kernel already has! */
351 if ((wdt_stop != 0x45) && (wdt_stop != wdt_start)) 351 if (wdt_stop != 0x45 && wdt_stop != wdt_start) {
352 { 352 if (!request_region(wdt_stop, 1, "SBC 60XX WDT")) {
353 if (!request_region(wdt_stop, 1, "SBC 60XX WDT")) 353 printk(KERN_ERR PFX
354 { 354 "I/O address 0x%04x already in use\n",
355 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", 355 wdt_stop);
356 wdt_stop);
357 rc = -EIO; 356 rc = -EIO;
358 goto err_out_region1; 357 goto err_out_region1;
359 } 358 }
360 } 359 }
361 360
362 rc = register_reboot_notifier(&wdt_notifier); 361 rc = register_reboot_notifier(&wdt_notifier);
363 if (rc) 362 if (rc) {
364 { 363 printk(KERN_ERR PFX
365 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 364 "cannot register reboot notifier (err=%d)\n", rc);
366 rc);
367 goto err_out_region2; 365 goto err_out_region2;
368 } 366 }
369 367
370 rc = misc_register(&wdt_miscdev); 368 rc = misc_register(&wdt_miscdev);
371 if (rc) 369 if (rc) {
372 { 370 printk(KERN_ERR PFX
373 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 371 "cannot register miscdev on minor=%d (err=%d)\n",
374 wdt_miscdev.minor, rc); 372 wdt_miscdev.minor, rc);
375 goto err_out_reboot; 373 goto err_out_reboot;
376 } 374 }
377
378 printk(KERN_INFO PFX "WDT driver for 60XX single board computer initialised. timeout=%d sec (nowayout=%d)\n", 375 printk(KERN_INFO PFX "WDT driver for 60XX single board computer initialised. timeout=%d sec (nowayout=%d)\n",
379 timeout, nowayout); 376 timeout, nowayout);
380 377
@@ -383,10 +380,10 @@ static int __init sbc60xxwdt_init(void)
383err_out_reboot: 380err_out_reboot:
384 unregister_reboot_notifier(&wdt_notifier); 381 unregister_reboot_notifier(&wdt_notifier);
385err_out_region2: 382err_out_region2:
386 if ((wdt_stop != 0x45) && (wdt_stop != wdt_start)) 383 if (wdt_stop != 0x45 && wdt_stop != wdt_start)
387 release_region(wdt_stop,1); 384 release_region(wdt_stop, 1);
388err_out_region1: 385err_out_region1:
389 release_region(wdt_start,1); 386 release_region(wdt_start, 1);
390err_out: 387err_out:
391 return rc; 388 return rc;
392} 389}
diff --git a/drivers/watchdog/sbc7240_wdt.c b/drivers/watchdog/sbc7240_wdt.c
index 4c8cefbd8627..67ddeb1c830a 100644
--- a/drivers/watchdog/sbc7240_wdt.c
+++ b/drivers/watchdog/sbc7240_wdt.c
@@ -27,10 +27,10 @@
27#include <linux/reboot.h> 27#include <linux/reboot.h>
28#include <linux/types.h> 28#include <linux/types.h>
29#include <linux/watchdog.h> 29#include <linux/watchdog.h>
30#include <linux/io.h>
31#include <linux/uaccess.h>
30#include <asm/atomic.h> 32#include <asm/atomic.h>
31#include <asm/io.h>
32#include <asm/system.h> 33#include <asm/system.h>
33#include <asm/uaccess.h>
34 34
35#define SBC7240_PREFIX "sbc7240_wdt: " 35#define SBC7240_PREFIX "sbc7240_wdt: "
36 36
@@ -159,7 +159,7 @@ static int fop_close(struct inode *inode, struct file *file)
159 return 0; 159 return 0;
160} 160}
161 161
162static struct watchdog_info ident = { 162static const struct watchdog_info ident = {
163 .options = WDIOF_KEEPALIVEPING| 163 .options = WDIOF_KEEPALIVEPING|
164 WDIOF_SETTIMEOUT| 164 WDIOF_SETTIMEOUT|
165 WDIOF_MAGICCLOSE, 165 WDIOF_MAGICCLOSE,
@@ -168,50 +168,50 @@ static struct watchdog_info ident = {
168}; 168};
169 169
170 170
171static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 171static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
172 unsigned long arg)
173{ 172{
174 switch (cmd) { 173 switch (cmd) {
175 case WDIOC_GETSUPPORT: 174 case WDIOC_GETSUPPORT:
176 return copy_to_user 175 return copy_to_user((void __user *)arg, &ident, sizeof(ident))
177 ((void __user *)arg, &ident, sizeof(ident)) 176 ? -EFAULT : 0;
178 ? -EFAULT : 0;
179 case WDIOC_GETSTATUS: 177 case WDIOC_GETSTATUS:
180 case WDIOC_GETBOOTSTATUS: 178 case WDIOC_GETBOOTSTATUS:
181 return put_user(0, (int __user *)arg); 179 return put_user(0, (int __user *)arg);
182 case WDIOC_KEEPALIVE: 180 case WDIOC_SETOPTIONS:
183 wdt_keepalive(); 181 {
184 return 0; 182 int options;
185 case WDIOC_SETOPTIONS:{ 183 int retval = -EINVAL;
186 int options;
187 int retval = -EINVAL;
188 184
189 if (get_user(options, (int __user *)arg)) 185 if (get_user(options, (int __user *)arg))
190 return -EFAULT; 186 return -EFAULT;
191 187
192 if (options & WDIOS_DISABLECARD) { 188 if (options & WDIOS_DISABLECARD) {
193 wdt_disable(); 189 wdt_disable();
194 retval = 0; 190 retval = 0;
195 } 191 }
196
197 if (options & WDIOS_ENABLECARD) {
198 wdt_enable();
199 retval = 0;
200 }
201 192
202 return retval; 193 if (options & WDIOS_ENABLECARD) {
194 wdt_enable();
195 retval = 0;
203 } 196 }
204 case WDIOC_SETTIMEOUT:{
205 int new_timeout;
206 197
207 if (get_user(new_timeout, (int __user *)arg)) 198 return retval;
208 return -EFAULT; 199 }
200 case WDIOC_KEEPALIVE:
201 wdt_keepalive();
202 return 0;
203 case WDIOC_SETTIMEOUT:
204 {
205 int new_timeout;
209 206
210 if (wdt_set_timeout(new_timeout)) 207 if (get_user(new_timeout, (int __user *)arg))
211 return -EINVAL; 208 return -EFAULT;
212 209
213 /* Fall through */ 210 if (wdt_set_timeout(new_timeout))
214 } 211 return -EINVAL;
212
213 /* Fall through */
214 }
215 case WDIOC_GETTIMEOUT: 215 case WDIOC_GETTIMEOUT:
216 return put_user(timeout, (int __user *)arg); 216 return put_user(timeout, (int __user *)arg);
217 default: 217 default:
@@ -225,7 +225,7 @@ static const struct file_operations wdt_fops = {
225 .write = fop_write, 225 .write = fop_write,
226 .open = fop_open, 226 .open = fop_open,
227 .release = fop_close, 227 .release = fop_close,
228 .ioctl = fop_ioctl, 228 .unlocked_ioctl = fop_ioctl,
229}; 229};
230 230
231static struct miscdevice wdt_miscdev = { 231static struct miscdevice wdt_miscdev = {
diff --git a/drivers/watchdog/sbc8360.c b/drivers/watchdog/sbc8360.c
index 2ee2677f3648..fd83dd052d8c 100644
--- a/drivers/watchdog/sbc8360.c
+++ b/drivers/watchdog/sbc8360.c
@@ -48,13 +48,12 @@
48#include <linux/init.h> 48#include <linux/init.h>
49#include <linux/spinlock.h> 49#include <linux/spinlock.h>
50#include <linux/moduleparam.h> 50#include <linux/moduleparam.h>
51#include <linux/io.h>
52#include <linux/uaccess.h>
51 53
52#include <asm/io.h>
53#include <asm/uaccess.h>
54#include <asm/system.h> 54#include <asm/system.h>
55 55
56static unsigned long sbc8360_is_open; 56static unsigned long sbc8360_is_open;
57static DEFINE_SPINLOCK(sbc8360_lock);
58static char expect_close; 57static char expect_close;
59 58
60#define PFX "sbc8360: " 59#define PFX "sbc8360: "
@@ -204,7 +203,8 @@ module_param(timeout, int, 0);
204MODULE_PARM_DESC(timeout, "Index into timeout table (0-63) (default=27 (60s))"); 203MODULE_PARM_DESC(timeout, "Index into timeout table (0-63) (default=27 (60s))");
205module_param(nowayout, int, 0); 204module_param(nowayout, int, 0);
206MODULE_PARM_DESC(nowayout, 205MODULE_PARM_DESC(nowayout,
207 "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 206 "Watchdog cannot be stopped once started (default="
207 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
208 208
209/* 209/*
210 * Kernel methods. 210 * Kernel methods.
@@ -231,9 +231,16 @@ static void sbc8360_ping(void)
231 outb(wd_margin, SBC8360_BASETIME); 231 outb(wd_margin, SBC8360_BASETIME);
232} 232}
233 233
234/* stop watchdog */
235static void sbc8360_stop(void)
236{
237 /* De-activate the watchdog */
238 outb(0, SBC8360_ENABLE);
239}
240
234/* Userspace pings kernel driver, or requests clean close */ 241/* Userspace pings kernel driver, or requests clean close */
235static ssize_t sbc8360_write(struct file *file, const char __user * buf, 242static ssize_t sbc8360_write(struct file *file, const char __user *buf,
236 size_t count, loff_t * ppos) 243 size_t count, loff_t *ppos)
237{ 244{
238 if (count) { 245 if (count) {
239 if (!nowayout) { 246 if (!nowayout) {
@@ -257,16 +264,12 @@ static ssize_t sbc8360_write(struct file *file, const char __user * buf,
257 264
258static int sbc8360_open(struct inode *inode, struct file *file) 265static int sbc8360_open(struct inode *inode, struct file *file)
259{ 266{
260 spin_lock(&sbc8360_lock); 267 if (test_and_set_bit(0, &sbc8360_is_open))
261 if (test_and_set_bit(0, &sbc8360_is_open)) {
262 spin_unlock(&sbc8360_lock);
263 return -EBUSY; 268 return -EBUSY;
264 }
265 if (nowayout) 269 if (nowayout)
266 __module_get(THIS_MODULE); 270 __module_get(THIS_MODULE);
267 271
268 /* Activate and ping once to start the countdown */ 272 /* Activate and ping once to start the countdown */
269 spin_unlock(&sbc8360_lock);
270 sbc8360_activate(); 273 sbc8360_activate();
271 sbc8360_ping(); 274 sbc8360_ping();
272 return nonseekable_open(inode, file); 275 return nonseekable_open(inode, file);
@@ -274,16 +277,14 @@ static int sbc8360_open(struct inode *inode, struct file *file)
274 277
275static int sbc8360_close(struct inode *inode, struct file *file) 278static int sbc8360_close(struct inode *inode, struct file *file)
276{ 279{
277 spin_lock(&sbc8360_lock);
278 if (expect_close == 42) 280 if (expect_close == 42)
279 outb(0, SBC8360_ENABLE); 281 sbc8360_stop();
280 else 282 else
281 printk(KERN_CRIT PFX 283 printk(KERN_CRIT PFX
282 "SBC8360 device closed unexpectedly. SBC8360 will not stop!\n"); 284 "SBC8360 device closed unexpectedly. SBC8360 will not stop!\n");
283 285
284 clear_bit(0, &sbc8360_is_open); 286 clear_bit(0, &sbc8360_is_open);
285 expect_close = 0; 287 expect_close = 0;
286 spin_unlock(&sbc8360_lock);
287 return 0; 288 return 0;
288} 289}
289 290
@@ -294,10 +295,9 @@ static int sbc8360_close(struct inode *inode, struct file *file)
294static int sbc8360_notify_sys(struct notifier_block *this, unsigned long code, 295static int sbc8360_notify_sys(struct notifier_block *this, unsigned long code,
295 void *unused) 296 void *unused)
296{ 297{
297 if (code == SYS_DOWN || code == SYS_HALT) { 298 if (code == SYS_DOWN || code == SYS_HALT)
298 /* Disable the SBC8360 Watchdog */ 299 sbc8360_stop(); /* Disable the SBC8360 Watchdog */
299 outb(0, SBC8360_ENABLE); 300
300 }
301 return NOTIFY_DONE; 301 return NOTIFY_DONE;
302} 302}
303 303
@@ -382,13 +382,13 @@ static int __init sbc8360_init(void)
382 382
383 return 0; 383 return 0;
384 384
385 out_nomisc: 385out_nomisc:
386 unregister_reboot_notifier(&sbc8360_notifier); 386 unregister_reboot_notifier(&sbc8360_notifier);
387 out_noreboot: 387out_noreboot:
388 release_region(SBC8360_BASETIME, 1); 388 release_region(SBC8360_BASETIME, 1);
389 out_nobasetimereg: 389out_nobasetimereg:
390 release_region(SBC8360_ENABLE, 1); 390 release_region(SBC8360_ENABLE, 1);
391 out: 391out:
392 return res; 392 return res;
393} 393}
394 394
diff --git a/drivers/watchdog/sbc_epx_c3.c b/drivers/watchdog/sbc_epx_c3.c
index 82cbd8809a69..e5e470ca7759 100644
--- a/drivers/watchdog/sbc_epx_c3.c
+++ b/drivers/watchdog/sbc_epx_c3.c
@@ -25,8 +25,8 @@
25#include <linux/reboot.h> 25#include <linux/reboot.h>
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/ioport.h> 27#include <linux/ioport.h>
28#include <asm/uaccess.h> 28#include <linux/uaccess.h>
29#include <asm/io.h> 29#include <linux/io.h>
30 30
31#define PFX "epx_c3: " 31#define PFX "epx_c3: "
32static int epx_c3_alive; 32static int epx_c3_alive;
@@ -100,12 +100,12 @@ static ssize_t epx_c3_write(struct file *file, const char __user *data,
100 return len; 100 return len;
101} 101}
102 102
103static int epx_c3_ioctl(struct inode *inode, struct file *file, 103static long epx_c3_ioctl(struct file *file, unsigned int cmd,
104 unsigned int cmd, unsigned long arg) 104 unsigned long arg)
105{ 105{
106 int options, retval = -EINVAL; 106 int options, retval = -EINVAL;
107 int __user *argp = (void __user *)arg; 107 int __user *argp = (void __user *)arg;
108 static struct watchdog_info ident = { 108 static const struct watchdog_info ident = {
109 .options = WDIOF_KEEPALIVEPING | 109 .options = WDIOF_KEEPALIVEPING |
110 WDIOF_MAGICCLOSE, 110 WDIOF_MAGICCLOSE,
111 .firmware_version = 0, 111 .firmware_version = 0,
@@ -120,11 +120,6 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file,
120 case WDIOC_GETSTATUS: 120 case WDIOC_GETSTATUS:
121 case WDIOC_GETBOOTSTATUS: 121 case WDIOC_GETBOOTSTATUS:
122 return put_user(0, argp); 122 return put_user(0, argp);
123 case WDIOC_KEEPALIVE:
124 epx_c3_pet();
125 return 0;
126 case WDIOC_GETTIMEOUT:
127 return put_user(WATCHDOG_TIMEOUT, argp);
128 case WDIOC_SETOPTIONS: 123 case WDIOC_SETOPTIONS:
129 if (get_user(options, argp)) 124 if (get_user(options, argp))
130 return -EFAULT; 125 return -EFAULT;
@@ -140,6 +135,11 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file,
140 } 135 }
141 136
142 return retval; 137 return retval;
138 case WDIOC_KEEPALIVE:
139 epx_c3_pet();
140 return 0;
141 case WDIOC_GETTIMEOUT:
142 return put_user(WATCHDOG_TIMEOUT, argp);
143 default: 143 default:
144 return -ENOTTY; 144 return -ENOTTY;
145 } 145 }
@@ -158,7 +158,7 @@ static const struct file_operations epx_c3_fops = {
158 .owner = THIS_MODULE, 158 .owner = THIS_MODULE,
159 .llseek = no_llseek, 159 .llseek = no_llseek,
160 .write = epx_c3_write, 160 .write = epx_c3_write,
161 .ioctl = epx_c3_ioctl, 161 .unlocked_ioctl = epx_c3_ioctl,
162 .open = epx_c3_open, 162 .open = epx_c3_open,
163 .release = epx_c3_release, 163 .release = epx_c3_release,
164}; 164};
diff --git a/drivers/watchdog/sc1200wdt.c b/drivers/watchdog/sc1200wdt.c
index 621ebad56d86..23da3ccd832a 100644
--- a/drivers/watchdog/sc1200wdt.c
+++ b/drivers/watchdog/sc1200wdt.c
@@ -196,7 +196,6 @@ static long sc1200wdt_ioctl(struct file *file, unsigned int cmd,
196 }; 196 };
197 197
198 switch (cmd) { 198 switch (cmd) {
199
200 case WDIOC_GETSUPPORT: 199 case WDIOC_GETSUPPORT:
201 if (copy_to_user(argp, &ident, sizeof ident)) 200 if (copy_to_user(argp, &ident, sizeof ident))
202 return -EFAULT; 201 return -EFAULT;
@@ -208,24 +207,6 @@ static long sc1200wdt_ioctl(struct file *file, unsigned int cmd,
208 case WDIOC_GETBOOTSTATUS: 207 case WDIOC_GETBOOTSTATUS:
209 return put_user(0, p); 208 return put_user(0, p);
210 209
211 case WDIOC_KEEPALIVE:
212 sc1200wdt_write_data(WDTO, timeout);
213 return 0;
214
215 case WDIOC_SETTIMEOUT:
216 if (get_user(new_timeout, p))
217 return -EFAULT;
218 /* the API states this is given in secs */
219 new_timeout /= 60;
220 if (new_timeout < 0 || new_timeout > MAX_TIMEOUT)
221 return -EINVAL;
222 timeout = new_timeout;
223 sc1200wdt_write_data(WDTO, timeout);
224 /* fall through and return the new timeout */
225
226 case WDIOC_GETTIMEOUT:
227 return put_user(timeout * 60, p);
228
229 case WDIOC_SETOPTIONS: 210 case WDIOC_SETOPTIONS:
230 { 211 {
231 int options, retval = -EINVAL; 212 int options, retval = -EINVAL;
@@ -245,6 +226,24 @@ static long sc1200wdt_ioctl(struct file *file, unsigned int cmd,
245 226
246 return retval; 227 return retval;
247 } 228 }
229 case WDIOC_KEEPALIVE:
230 sc1200wdt_write_data(WDTO, timeout);
231 return 0;
232
233 case WDIOC_SETTIMEOUT:
234 if (get_user(new_timeout, p))
235 return -EFAULT;
236 /* the API states this is given in secs */
237 new_timeout /= 60;
238 if (new_timeout < 0 || new_timeout > MAX_TIMEOUT)
239 return -EINVAL;
240 timeout = new_timeout;
241 sc1200wdt_write_data(WDTO, timeout);
242 /* fall through and return the new timeout */
243
244 case WDIOC_GETTIMEOUT:
245 return put_user(timeout * 60, p);
246
248 default: 247 default:
249 return -ENOTTY; 248 return -ENOTTY;
250 } 249 }
@@ -280,7 +279,7 @@ static ssize_t sc1200wdt_write(struct file *file, const char __user *data,
280 for (i = 0; i != len; i++) { 279 for (i = 0; i != len; i++) {
281 char c; 280 char c;
282 281
283 if (get_user(c, data+i)) 282 if (get_user(c, data + i))
284 return -EFAULT; 283 return -EFAULT;
285 if (c == 'V') 284 if (c == 'V')
286 expect_close = 42; 285 expect_close = 42;
diff --git a/drivers/watchdog/sc520_wdt.c b/drivers/watchdog/sc520_wdt.c
index 2847324a2be2..a2b6c1067ec5 100644
--- a/drivers/watchdog/sc520_wdt.c
+++ b/drivers/watchdog/sc520_wdt.c
@@ -64,9 +64,9 @@
64#include <linux/reboot.h> 64#include <linux/reboot.h>
65#include <linux/init.h> 65#include <linux/init.h>
66#include <linux/jiffies.h> 66#include <linux/jiffies.h>
67#include <linux/io.h>
68#include <linux/uaccess.h>
67 69
68#include <asm/io.h>
69#include <asm/uaccess.h>
70#include <asm/system.h> 70#include <asm/system.h>
71 71
72#define OUR_NAME "sc520_wdt" 72#define OUR_NAME "sc520_wdt"
@@ -91,13 +91,18 @@
91 */ 91 */
92 92
93#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ 93#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */
94static int timeout = WATCHDOG_TIMEOUT; /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */ 94/* in seconds, will be multiplied by HZ to get seconds to wait for a ping */
95static int timeout = WATCHDOG_TIMEOUT;
95module_param(timeout, int, 0); 96module_param(timeout, int, 0);
96MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); 97MODULE_PARM_DESC(timeout,
98 "Watchdog timeout in seconds. (1 <= timeout <= 3600, default="
99 __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
97 100
98static int nowayout = WATCHDOG_NOWAYOUT; 101static int nowayout = WATCHDOG_NOWAYOUT;
99module_param(nowayout, int, 0); 102module_param(nowayout, int, 0);
100MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 103MODULE_PARM_DESC(nowayout,
104 "Watchdog cannot be stopped once started (default="
105 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
101 106
102/* 107/*
103 * AMD Elan SC520 - Watchdog Timer Registers 108 * AMD Elan SC520 - Watchdog Timer Registers
@@ -136,8 +141,7 @@ static void wdt_timer_ping(unsigned long data)
136 /* If we got a heartbeat pulse within the WDT_US_INTERVAL 141 /* If we got a heartbeat pulse within the WDT_US_INTERVAL
137 * we agree to ping the WDT 142 * we agree to ping the WDT
138 */ 143 */
139 if(time_before(jiffies, next_heartbeat)) 144 if (time_before(jiffies, next_heartbeat)) {
140 {
141 /* Ping the WDT */ 145 /* Ping the WDT */
142 spin_lock(&wdt_spinlock); 146 spin_lock(&wdt_spinlock);
143 writew(0xAAAA, wdtmrctl); 147 writew(0xAAAA, wdtmrctl);
@@ -146,9 +150,9 @@ static void wdt_timer_ping(unsigned long data)
146 150
147 /* Re-set the timer interval */ 151 /* Re-set the timer interval */
148 mod_timer(&timer, jiffies + WDT_INTERVAL); 152 mod_timer(&timer, jiffies + WDT_INTERVAL);
149 } else { 153 } else
150 printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); 154 printk(KERN_WARNING PFX
151 } 155 "Heartbeat lost! Will not ping the watchdog\n");
152} 156}
153 157
154/* 158/*
@@ -162,7 +166,7 @@ static void wdt_config(int writeval)
162 166
163 /* buy some time (ping) */ 167 /* buy some time (ping) */
164 spin_lock_irqsave(&wdt_spinlock, flags); 168 spin_lock_irqsave(&wdt_spinlock, flags);
165 dummy=readw(wdtmrctl); /* ensure write synchronization */ 169 dummy = readw(wdtmrctl); /* ensure write synchronization */
166 writew(0xAAAA, wdtmrctl); 170 writew(0xAAAA, wdtmrctl);
167 writew(0x5555, wdtmrctl); 171 writew(0x5555, wdtmrctl);
168 /* unlock WDT = make WDT configuration register writable one time */ 172 /* unlock WDT = make WDT configuration register writable one time */
@@ -219,10 +223,11 @@ static int wdt_set_heartbeat(int t)
219 * /dev/watchdog handling 223 * /dev/watchdog handling
220 */ 224 */
221 225
222static ssize_t fop_write(struct file * file, const char __user * buf, size_t count, loff_t * ppos) 226static ssize_t fop_write(struct file *file, const char __user *buf,
227 size_t count, loff_t *ppos)
223{ 228{
224 /* See if we got the magic character 'V' and reload the timer */ 229 /* See if we got the magic character 'V' and reload the timer */
225 if(count) { 230 if (count) {
226 if (!nowayout) { 231 if (!nowayout) {
227 size_t ofs; 232 size_t ofs;
228 233
@@ -231,25 +236,26 @@ static ssize_t fop_write(struct file * file, const char __user * buf, size_t cou
231 wdt_expect_close = 0; 236 wdt_expect_close = 0;
232 237
233 /* now scan */ 238 /* now scan */
234 for(ofs = 0; ofs != count; ofs++) { 239 for (ofs = 0; ofs != count; ofs++) {
235 char c; 240 char c;
236 if (get_user(c, buf + ofs)) 241 if (get_user(c, buf + ofs))
237 return -EFAULT; 242 return -EFAULT;
238 if(c == 'V') 243 if (c == 'V')
239 wdt_expect_close = 42; 244 wdt_expect_close = 42;
240 } 245 }
241 } 246 }
242 247
243 /* Well, anyhow someone wrote to us, we should return that favour */ 248 /* Well, anyhow someone wrote to us, we should
249 return that favour */
244 wdt_keepalive(); 250 wdt_keepalive();
245 } 251 }
246 return count; 252 return count;
247} 253}
248 254
249static int fop_open(struct inode * inode, struct file * file) 255static int fop_open(struct inode *inode, struct file *file)
250{ 256{
251 /* Just in case we're already talking to someone... */ 257 /* Just in case we're already talking to someone... */
252 if(test_and_set_bit(0, &wdt_is_open)) 258 if (test_and_set_bit(0, &wdt_is_open))
253 return -EBUSY; 259 return -EBUSY;
254 if (nowayout) 260 if (nowayout)
255 __module_get(THIS_MODULE); 261 __module_get(THIS_MODULE);
@@ -259,12 +265,13 @@ static int fop_open(struct inode * inode, struct file * file)
259 return nonseekable_open(inode, file); 265 return nonseekable_open(inode, file);
260} 266}
261 267
262static int fop_close(struct inode * inode, struct file * file) 268static int fop_close(struct inode *inode, struct file *file)
263{ 269{
264 if(wdt_expect_close == 42) { 270 if (wdt_expect_close == 42)
265 wdt_turnoff(); 271 wdt_turnoff();
266 } else { 272 else {
267 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); 273 printk(KERN_CRIT PFX
274 "Unexpected close, not stopping watchdog!\n");
268 wdt_keepalive(); 275 wdt_keepalive();
269 } 276 }
270 clear_bit(0, &wdt_is_open); 277 clear_bit(0, &wdt_is_open);
@@ -272,63 +279,62 @@ static int fop_close(struct inode * inode, struct file * file)
272 return 0; 279 return 0;
273} 280}
274 281
275static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 282static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
276 unsigned long arg)
277{ 283{
278 void __user *argp = (void __user *)arg; 284 void __user *argp = (void __user *)arg;
279 int __user *p = argp; 285 int __user *p = argp;
280 static struct watchdog_info ident = { 286 static const struct watchdog_info ident = {
281 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, 287 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT
288 | WDIOF_MAGICCLOSE,
282 .firmware_version = 1, 289 .firmware_version = 1,
283 .identity = "SC520", 290 .identity = "SC520",
284 }; 291 };
285 292
286 switch(cmd) 293 switch (cmd) {
294 case WDIOC_GETSUPPORT:
295 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
296 case WDIOC_GETSTATUS:
297 case WDIOC_GETBOOTSTATUS:
298 return put_user(0, p);
299 case WDIOC_SETOPTIONS:
287 { 300 {
288 default: 301 int new_options, retval = -EINVAL;
289 return -ENOTTY;
290 case WDIOC_GETSUPPORT:
291 return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
292 case WDIOC_GETSTATUS:
293 case WDIOC_GETBOOTSTATUS:
294 return put_user(0, p);
295 case WDIOC_KEEPALIVE:
296 wdt_keepalive();
297 return 0;
298 case WDIOC_SETOPTIONS:
299 {
300 int new_options, retval = -EINVAL;
301
302 if(get_user(new_options, p))
303 return -EFAULT;
304
305 if(new_options & WDIOS_DISABLECARD) {
306 wdt_turnoff();
307 retval = 0;
308 }
309 302
310 if(new_options & WDIOS_ENABLECARD) { 303 if (get_user(new_options, p))
311 wdt_startup(); 304 return -EFAULT;
312 retval = 0;
313 }
314 305
315 return retval; 306 if (new_options & WDIOS_DISABLECARD) {
307 wdt_turnoff();
308 retval = 0;
316 } 309 }
317 case WDIOC_SETTIMEOUT:
318 {
319 int new_timeout;
320 310
321 if(get_user(new_timeout, p)) 311 if (new_options & WDIOS_ENABLECARD) {
322 return -EFAULT; 312 wdt_startup();
313 retval = 0;
314 }
323 315
324 if(wdt_set_heartbeat(new_timeout)) 316 return retval;
325 return -EINVAL; 317 }
318 case WDIOC_KEEPALIVE:
319 wdt_keepalive();
320 return 0;
321 case WDIOC_SETTIMEOUT:
322 {
323 int new_timeout;
326 324
327 wdt_keepalive(); 325 if (get_user(new_timeout, p))
328 /* Fall through */ 326 return -EFAULT;
329 } 327
330 case WDIOC_GETTIMEOUT: 328 if (wdt_set_heartbeat(new_timeout))
331 return put_user(timeout, p); 329 return -EINVAL;
330
331 wdt_keepalive();
332 /* Fall through */
333 }
334 case WDIOC_GETTIMEOUT:
335 return put_user(timeout, p);
336 default:
337 return -ENOTTY;
332 } 338 }
333} 339}
334 340
@@ -338,7 +344,7 @@ static const struct file_operations wdt_fops = {
338 .write = fop_write, 344 .write = fop_write,
339 .open = fop_open, 345 .open = fop_open,
340 .release = fop_close, 346 .release = fop_close,
341 .ioctl = fop_ioctl, 347 .unlocked_ioctl = fop_ioctl,
342}; 348};
343 349
344static struct miscdevice wdt_miscdev = { 350static struct miscdevice wdt_miscdev = {
@@ -354,7 +360,7 @@ static struct miscdevice wdt_miscdev = {
354static int wdt_notify_sys(struct notifier_block *this, unsigned long code, 360static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
355 void *unused) 361 void *unused)
356{ 362{
357 if(code==SYS_DOWN || code==SYS_HALT) 363 if (code == SYS_DOWN || code == SYS_HALT)
358 wdt_turnoff(); 364 wdt_turnoff();
359 return NOTIFY_DONE; 365 return NOTIFY_DONE;
360} 366}
@@ -383,11 +389,13 @@ static int __init sc520_wdt_init(void)
383{ 389{
384 int rc = -EBUSY; 390 int rc = -EBUSY;
385 391
386 /* Check that the timeout value is within it's range ; if not reset to the default */ 392 /* Check that the timeout value is within it's range ;
393 if not reset to the default */
387 if (wdt_set_heartbeat(timeout)) { 394 if (wdt_set_heartbeat(timeout)) {
388 wdt_set_heartbeat(WATCHDOG_TIMEOUT); 395 wdt_set_heartbeat(WATCHDOG_TIMEOUT);
389 printk(KERN_INFO PFX "timeout value must be 1<=timeout<=3600, using %d\n", 396 printk(KERN_INFO PFX
390 WATCHDOG_TIMEOUT); 397 "timeout value must be 1 <= timeout <= 3600, using %d\n",
398 WATCHDOG_TIMEOUT);
391 } 399 }
392 400
393 wdtmrctl = ioremap((unsigned long)(MMCR_BASE + OFFS_WDTMRCTL), 2); 401 wdtmrctl = ioremap((unsigned long)(MMCR_BASE + OFFS_WDTMRCTL), 2);
@@ -399,20 +407,22 @@ static int __init sc520_wdt_init(void)
399 407
400 rc = register_reboot_notifier(&wdt_notifier); 408 rc = register_reboot_notifier(&wdt_notifier);
401 if (rc) { 409 if (rc) {
402 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 410 printk(KERN_ERR PFX
403 rc); 411 "cannot register reboot notifier (err=%d)\n", rc);
404 goto err_out_ioremap; 412 goto err_out_ioremap;
405 } 413 }
406 414
407 rc = misc_register(&wdt_miscdev); 415 rc = misc_register(&wdt_miscdev);
408 if (rc) { 416 if (rc) {
409 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 417 printk(KERN_ERR PFX
410 WATCHDOG_MINOR, rc); 418 "cannot register miscdev on minor=%d (err=%d)\n",
419 WATCHDOG_MINOR, rc);
411 goto err_out_notifier; 420 goto err_out_notifier;
412 } 421 }
413 422
414 printk(KERN_INFO PFX "WDT driver for SC520 initialised. timeout=%d sec (nowayout=%d)\n", 423 printk(KERN_INFO PFX
415 timeout,nowayout); 424 "WDT driver for SC520 initialised. timeout=%d sec (nowayout=%d)\n",
425 timeout, nowayout);
416 426
417 return 0; 427 return 0;
418 428
diff --git a/drivers/watchdog/scx200_wdt.c b/drivers/watchdog/scx200_wdt.c
index d55882bca319..9e19a10a5bb9 100644
--- a/drivers/watchdog/scx200_wdt.c
+++ b/drivers/watchdog/scx200_wdt.c
@@ -27,9 +27,8 @@
27#include <linux/fs.h> 27#include <linux/fs.h>
28#include <linux/ioport.h> 28#include <linux/ioport.h>
29#include <linux/scx200.h> 29#include <linux/scx200.h>
30 30#include <linux/uaccess.h>
31#include <asm/uaccess.h> 31#include <linux/io.h>
32#include <asm/io.h>
33 32
34#define NAME "scx200_wdt" 33#define NAME "scx200_wdt"
35 34
@@ -47,8 +46,9 @@ module_param(nowayout, int, 0);
47MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close"); 46MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close");
48 47
49static u16 wdto_restart; 48static u16 wdto_restart;
50static struct semaphore open_semaphore;
51static char expect_close; 49static char expect_close;
50static unsigned long open_lock;
51static DEFINE_SPINLOCK(scx_lock);
52 52
53/* Bits of the WDCNFG register */ 53/* Bits of the WDCNFG register */
54#define W_ENABLE 0x00fa /* Enable watchdog */ 54#define W_ENABLE 0x00fa /* Enable watchdog */
@@ -59,7 +59,9 @@ static char expect_close;
59 59
60static void scx200_wdt_ping(void) 60static void scx200_wdt_ping(void)
61{ 61{
62 spin_lock(&scx_lock);
62 outw(wdto_restart, scx200_cb_base + SCx200_WDT_WDTO); 63 outw(wdto_restart, scx200_cb_base + SCx200_WDT_WDTO);
64 spin_unlock(&scx_lock);
63} 65}
64 66
65static void scx200_wdt_update_margin(void) 67static void scx200_wdt_update_margin(void)
@@ -73,9 +75,11 @@ static void scx200_wdt_enable(void)
73 printk(KERN_DEBUG NAME ": enabling watchdog timer, wdto_restart = %d\n", 75 printk(KERN_DEBUG NAME ": enabling watchdog timer, wdto_restart = %d\n",
74 wdto_restart); 76 wdto_restart);
75 77
78 spin_lock(&scx_lock);
76 outw(0, scx200_cb_base + SCx200_WDT_WDTO); 79 outw(0, scx200_cb_base + SCx200_WDT_WDTO);
77 outb(SCx200_WDT_WDSTS_WDOVF, scx200_cb_base + SCx200_WDT_WDSTS); 80 outb(SCx200_WDT_WDSTS_WDOVF, scx200_cb_base + SCx200_WDT_WDSTS);
78 outw(W_ENABLE, scx200_cb_base + SCx200_WDT_WDCNFG); 81 outw(W_ENABLE, scx200_cb_base + SCx200_WDT_WDCNFG);
82 spin_unlock(&scx_lock);
79 83
80 scx200_wdt_ping(); 84 scx200_wdt_ping();
81} 85}
@@ -84,15 +88,17 @@ static void scx200_wdt_disable(void)
84{ 88{
85 printk(KERN_DEBUG NAME ": disabling watchdog timer\n"); 89 printk(KERN_DEBUG NAME ": disabling watchdog timer\n");
86 90
91 spin_lock(&scx_lock);
87 outw(0, scx200_cb_base + SCx200_WDT_WDTO); 92 outw(0, scx200_cb_base + SCx200_WDT_WDTO);
88 outb(SCx200_WDT_WDSTS_WDOVF, scx200_cb_base + SCx200_WDT_WDSTS); 93 outb(SCx200_WDT_WDSTS_WDOVF, scx200_cb_base + SCx200_WDT_WDSTS);
89 outw(W_DISABLE, scx200_cb_base + SCx200_WDT_WDCNFG); 94 outw(W_DISABLE, scx200_cb_base + SCx200_WDT_WDCNFG);
95 spin_unlock(&scx_lock);
90} 96}
91 97
92static int scx200_wdt_open(struct inode *inode, struct file *file) 98static int scx200_wdt_open(struct inode *inode, struct file *file)
93{ 99{
94 /* only allow one at a time */ 100 /* only allow one at a time */
95 if (down_trylock(&open_semaphore)) 101 if (test_and_set_bit(0, &open_lock))
96 return -EBUSY; 102 return -EBUSY;
97 scx200_wdt_enable(); 103 scx200_wdt_enable();
98 104
@@ -101,13 +107,12 @@ static int scx200_wdt_open(struct inode *inode, struct file *file)
101 107
102static int scx200_wdt_release(struct inode *inode, struct file *file) 108static int scx200_wdt_release(struct inode *inode, struct file *file)
103{ 109{
104 if (expect_close != 42) { 110 if (expect_close != 42)
105 printk(KERN_WARNING NAME ": watchdog device closed unexpectedly, will not disable the watchdog timer\n"); 111 printk(KERN_WARNING NAME ": watchdog device closed unexpectedly, will not disable the watchdog timer\n");
106 } else if (!nowayout) { 112 else if (!nowayout)
107 scx200_wdt_disable(); 113 scx200_wdt_disable();
108 }
109 expect_close = 0; 114 expect_close = 0;
110 up(&open_semaphore); 115 clear_bit(0, &open_lock);
111 116
112 return 0; 117 return 0;
113} 118}
@@ -122,8 +127,7 @@ static int scx200_wdt_notify_sys(struct notifier_block *this,
122 return NOTIFY_DONE; 127 return NOTIFY_DONE;
123} 128}
124 129
125static struct notifier_block scx200_wdt_notifier = 130static struct notifier_block scx200_wdt_notifier = {
126{
127 .notifier_call = scx200_wdt_notify_sys, 131 .notifier_call = scx200_wdt_notify_sys,
128}; 132};
129 133
@@ -131,8 +135,7 @@ static ssize_t scx200_wdt_write(struct file *file, const char __user *data,
131 size_t len, loff_t *ppos) 135 size_t len, loff_t *ppos)
132{ 136{
133 /* check for a magic close character */ 137 /* check for a magic close character */
134 if (len) 138 if (len) {
135 {
136 size_t i; 139 size_t i;
137 140
138 scx200_wdt_ping(); 141 scx200_wdt_ping();
@@ -140,7 +143,7 @@ static ssize_t scx200_wdt_write(struct file *file, const char __user *data,
140 expect_close = 0; 143 expect_close = 0;
141 for (i = 0; i < len; ++i) { 144 for (i = 0; i < len; ++i) {
142 char c; 145 char c;
143 if (get_user(c, data+i)) 146 if (get_user(c, data + i))
144 return -EFAULT; 147 return -EFAULT;
145 if (c == 'V') 148 if (c == 'V')
146 expect_close = 42; 149 expect_close = 42;
@@ -152,23 +155,21 @@ static ssize_t scx200_wdt_write(struct file *file, const char __user *data,
152 return 0; 155 return 0;
153} 156}
154 157
155static int scx200_wdt_ioctl(struct inode *inode, struct file *file, 158static long scx200_wdt_ioctl(struct file *file, unsigned int cmd,
156 unsigned int cmd, unsigned long arg) 159 unsigned long arg)
157{ 160{
158 void __user *argp = (void __user *)arg; 161 void __user *argp = (void __user *)arg;
159 int __user *p = argp; 162 int __user *p = argp;
160 static struct watchdog_info ident = { 163 static const struct watchdog_info ident = {
161 .identity = "NatSemi SCx200 Watchdog", 164 .identity = "NatSemi SCx200 Watchdog",
162 .firmware_version = 1, 165 .firmware_version = 1,
163 .options = (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING), 166 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
164 }; 167 };
165 int new_margin; 168 int new_margin;
166 169
167 switch (cmd) { 170 switch (cmd) {
168 default:
169 return -ENOTTY;
170 case WDIOC_GETSUPPORT: 171 case WDIOC_GETSUPPORT:
171 if(copy_to_user(argp, &ident, sizeof(ident))) 172 if (copy_to_user(argp, &ident, sizeof(ident)))
172 return -EFAULT; 173 return -EFAULT;
173 return 0; 174 return 0;
174 case WDIOC_GETSTATUS: 175 case WDIOC_GETSTATUS:
@@ -191,22 +192,24 @@ static int scx200_wdt_ioctl(struct inode *inode, struct file *file,
191 if (put_user(margin, p)) 192 if (put_user(margin, p))
192 return -EFAULT; 193 return -EFAULT;
193 return 0; 194 return 0;
195 default:
196 return -ENOTTY;
194 } 197 }
195} 198}
196 199
197static const struct file_operations scx200_wdt_fops = { 200static const struct file_operations scx200_wdt_fops = {
198 .owner = THIS_MODULE, 201 .owner = THIS_MODULE,
199 .llseek = no_llseek, 202 .llseek = no_llseek,
200 .write = scx200_wdt_write, 203 .write = scx200_wdt_write,
201 .ioctl = scx200_wdt_ioctl, 204 .unlocked_ioctl = scx200_wdt_ioctl,
202 .open = scx200_wdt_open, 205 .open = scx200_wdt_open,
203 .release = scx200_wdt_release, 206 .release = scx200_wdt_release,
204}; 207};
205 208
206static struct miscdevice scx200_wdt_miscdev = { 209static struct miscdevice scx200_wdt_miscdev = {
207 .minor = WATCHDOG_MINOR, 210 .minor = WATCHDOG_MINOR,
208 .name = "watchdog", 211 .name = "watchdog",
209 .fops = &scx200_wdt_fops, 212 .fops = &scx200_wdt_fops,
210}; 213};
211 214
212static int __init scx200_wdt_init(void) 215static int __init scx200_wdt_init(void)
@@ -229,8 +232,6 @@ static int __init scx200_wdt_init(void)
229 scx200_wdt_update_margin(); 232 scx200_wdt_update_margin();
230 scx200_wdt_disable(); 233 scx200_wdt_disable();
231 234
232 sema_init(&open_semaphore, 1);
233
234 r = register_reboot_notifier(&scx200_wdt_notifier); 235 r = register_reboot_notifier(&scx200_wdt_notifier);
235 if (r) { 236 if (r) {
236 printk(KERN_ERR NAME ": unable to register reboot notifier"); 237 printk(KERN_ERR NAME ": unable to register reboot notifier");
@@ -263,7 +264,7 @@ module_exit(scx200_wdt_cleanup);
263 264
264/* 265/*
265 Local variables: 266 Local variables:
266 compile-command: "make -k -C ../.. SUBDIRS=drivers/char modules" 267 compile-command: "make -k -C ../.. SUBDIRS=drivers/char modules"
267 c-basic-offset: 8 268 c-basic-offset: 8
268 End: 269 End:
269*/ 270*/
diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c
index 1277f7e9cc54..824125adf90a 100644
--- a/drivers/watchdog/shwdt.c
+++ b/drivers/watchdog/shwdt.c
@@ -28,9 +28,9 @@
28#include <linux/ioport.h> 28#include <linux/ioport.h>
29#include <linux/fs.h> 29#include <linux/fs.h>
30#include <linux/mm.h> 30#include <linux/mm.h>
31#include <asm/io.h> 31#include <linux/io.h>
32#include <asm/uaccess.h> 32#include <linux/uaccess.h>
33#include <asm/watchdog.h> 33#include <linux/watchdog.h>
34 34
35#define PFX "shwdt: " 35#define PFX "shwdt: "
36 36
@@ -72,6 +72,7 @@ static struct watchdog_info sh_wdt_info;
72static char shwdt_expect_close; 72static char shwdt_expect_close;
73static DEFINE_TIMER(timer, sh_wdt_ping, 0, 0); 73static DEFINE_TIMER(timer, sh_wdt_ping, 0, 0);
74static unsigned long next_heartbeat; 74static unsigned long next_heartbeat;
75static DEFINE_SPINLOCK(shwdt_lock);
75 76
76#define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */ 77#define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */
77static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ 78static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */
@@ -86,6 +87,9 @@ static int nowayout = WATCHDOG_NOWAYOUT;
86static void sh_wdt_start(void) 87static void sh_wdt_start(void)
87{ 88{
88 __u8 csr; 89 __u8 csr;
90 unsigned long flags;
91
92 spin_lock_irqsave(&wdt_lock, flags);
89 93
90 next_heartbeat = jiffies + (heartbeat * HZ); 94 next_heartbeat = jiffies + (heartbeat * HZ);
91 mod_timer(&timer, next_ping_period(clock_division_ratio)); 95 mod_timer(&timer, next_ping_period(clock_division_ratio));
@@ -123,6 +127,7 @@ static void sh_wdt_start(void)
123 csr &= ~RSTCSR_RSTS; 127 csr &= ~RSTCSR_RSTS;
124 sh_wdt_write_rstcsr(csr); 128 sh_wdt_write_rstcsr(csr);
125#endif 129#endif
130 spin_unlock_irqrestore(&wdt_lock, flags);
126} 131}
127 132
128/** 133/**
@@ -132,12 +137,16 @@ static void sh_wdt_start(void)
132static void sh_wdt_stop(void) 137static void sh_wdt_stop(void)
133{ 138{
134 __u8 csr; 139 __u8 csr;
140 unsigned long flags;
141
142 spin_lock_irqsave(&wdt_lock, flags);
135 143
136 del_timer(&timer); 144 del_timer(&timer);
137 145
138 csr = sh_wdt_read_csr(); 146 csr = sh_wdt_read_csr();
139 csr &= ~WTCSR_TME; 147 csr &= ~WTCSR_TME;
140 sh_wdt_write_csr(csr); 148 sh_wdt_write_csr(csr);
149 spin_unlock_irqrestore(&wdt_lock, flags);
141} 150}
142 151
143/** 152/**
@@ -146,7 +155,11 @@ static void sh_wdt_stop(void)
146 */ 155 */
147static inline void sh_wdt_keepalive(void) 156static inline void sh_wdt_keepalive(void)
148{ 157{
158 unsigned long flags;
159
160 spin_lock_irqsave(&wdt_lock, flags);
149 next_heartbeat = jiffies + (heartbeat * HZ); 161 next_heartbeat = jiffies + (heartbeat * HZ);
162 spin_unlock_irqrestore(&wdt_lock, flags);
150} 163}
151 164
152/** 165/**
@@ -155,10 +168,14 @@ static inline void sh_wdt_keepalive(void)
155 */ 168 */
156static int sh_wdt_set_heartbeat(int t) 169static int sh_wdt_set_heartbeat(int t)
157{ 170{
158 if (unlikely((t < 1) || (t > 3600))) /* arbitrary upper limit */ 171 unsigned long flags;
172
173 if (unlikely(t < 1 || t > 3600)) /* arbitrary upper limit */
159 return -EINVAL; 174 return -EINVAL;
160 175
176 spin_lock_irqsave(&wdt_lock, flags);
161 heartbeat = t; 177 heartbeat = t;
178 spin_unlock_irqrestore(&wdt_lock, flags);
162 return 0; 179 return 0;
163} 180}
164 181
@@ -170,6 +187,9 @@ static int sh_wdt_set_heartbeat(int t)
170 */ 187 */
171static void sh_wdt_ping(unsigned long data) 188static void sh_wdt_ping(unsigned long data)
172{ 189{
190 unsigned long flags;
191
192 spin_lock_irqsave(&wdt_lock, flags);
173 if (time_before(jiffies, next_heartbeat)) { 193 if (time_before(jiffies, next_heartbeat)) {
174 __u8 csr; 194 __u8 csr;
175 195
@@ -183,6 +203,7 @@ static void sh_wdt_ping(unsigned long data)
183 } else 203 } else
184 printk(KERN_WARNING PFX "Heartbeat lost! Will not ping " 204 printk(KERN_WARNING PFX "Heartbeat lost! Will not ping "
185 "the watchdog\n"); 205 "the watchdog\n");
206 spin_unlock_irqrestore(&wdt_lock, flags);
186} 207}
187 208
188/** 209/**
@@ -310,7 +331,6 @@ static int sh_wdt_mmap(struct file *file, struct vm_area_struct *vma)
310 331
311/** 332/**
312 * sh_wdt_ioctl - Query Device 333 * sh_wdt_ioctl - Query Device
313 * @inode: inode of device
314 * @file: file handle of device 334 * @file: file handle of device
315 * @cmd: watchdog command 335 * @cmd: watchdog command
316 * @arg: argument 336 * @arg: argument
@@ -318,53 +338,51 @@ static int sh_wdt_mmap(struct file *file, struct vm_area_struct *vma)
318 * Query basic information from the device or ping it, as outlined by the 338 * Query basic information from the device or ping it, as outlined by the
319 * watchdog API. 339 * watchdog API.
320 */ 340 */
321static int sh_wdt_ioctl(struct inode *inode, struct file *file, 341static long sh_wdt_ioctl(struct file *file, unsigned int cmd,
322 unsigned int cmd, unsigned long arg) 342 unsigned long arg)
323{ 343{
324 int new_heartbeat; 344 int new_heartbeat;
325 int options, retval = -EINVAL; 345 int options, retval = -EINVAL;
326 346
327 switch (cmd) { 347 switch (cmd) {
328 case WDIOC_GETSUPPORT: 348 case WDIOC_GETSUPPORT:
329 return copy_to_user((struct watchdog_info *)arg, 349 return copy_to_user((struct watchdog_info *)arg,
330 &sh_wdt_info, 350 &sh_wdt_info, sizeof(sh_wdt_info)) ? -EFAULT : 0;
331 sizeof(sh_wdt_info)) ? -EFAULT : 0; 351 case WDIOC_GETSTATUS:
332 case WDIOC_GETSTATUS: 352 case WDIOC_GETBOOTSTATUS:
333 case WDIOC_GETBOOTSTATUS: 353 return put_user(0, (int *)arg);
334 return put_user(0, (int *)arg); 354 case WDIOC_SETOPTIONS:
335 case WDIOC_KEEPALIVE: 355 if (get_user(options, (int *)arg))
336 sh_wdt_keepalive(); 356 return -EFAULT;
337 return 0; 357
338 case WDIOC_SETTIMEOUT: 358 if (options & WDIOS_DISABLECARD) {
339 if (get_user(new_heartbeat, (int *)arg)) 359 sh_wdt_stop();
340 return -EFAULT; 360 retval = 0;
341 361 }
342 if (sh_wdt_set_heartbeat(new_heartbeat))
343 return -EINVAL;
344
345 sh_wdt_keepalive();
346 /* Fall */
347 case WDIOC_GETTIMEOUT:
348 return put_user(heartbeat, (int *)arg);
349 case WDIOC_SETOPTIONS:
350 if (get_user(options, (int *)arg))
351 return -EFAULT;
352
353 if (options & WDIOS_DISABLECARD) {
354 sh_wdt_stop();
355 retval = 0;
356 }
357 362
358 if (options & WDIOS_ENABLECARD) { 363 if (options & WDIOS_ENABLECARD) {
359 sh_wdt_start(); 364 sh_wdt_start();
360 retval = 0; 365 retval = 0;
361 } 366 }
362 367
363 return retval; 368 return retval;
364 default: 369 case WDIOC_KEEPALIVE:
365 return -ENOTTY; 370 sh_wdt_keepalive();
366 } 371 return 0;
372 case WDIOC_SETTIMEOUT:
373 if (get_user(new_heartbeat, (int *)arg))
374 return -EFAULT;
375
376 if (sh_wdt_set_heartbeat(new_heartbeat))
377 return -EINVAL;
367 378
379 sh_wdt_keepalive();
380 /* Fall */
381 case WDIOC_GETTIMEOUT:
382 return put_user(heartbeat, (int *)arg);
383 default:
384 return -ENOTTY;
385 }
368 return 0; 386 return 0;
369} 387}
370 388
@@ -390,13 +408,13 @@ static const struct file_operations sh_wdt_fops = {
390 .owner = THIS_MODULE, 408 .owner = THIS_MODULE,
391 .llseek = no_llseek, 409 .llseek = no_llseek,
392 .write = sh_wdt_write, 410 .write = sh_wdt_write,
393 .ioctl = sh_wdt_ioctl, 411 .unlocked_ioctl = sh_wdt_ioctl,
394 .open = sh_wdt_open, 412 .open = sh_wdt_open,
395 .release = sh_wdt_close, 413 .release = sh_wdt_close,
396 .mmap = sh_wdt_mmap, 414 .mmap = sh_wdt_mmap,
397}; 415};
398 416
399static struct watchdog_info sh_wdt_info = { 417static const struct watchdog_info sh_wdt_info = {
400 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | 418 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
401 WDIOF_MAGICCLOSE, 419 WDIOF_MAGICCLOSE,
402 .firmware_version = 1, 420 .firmware_version = 1,
@@ -422,30 +440,33 @@ static int __init sh_wdt_init(void)
422{ 440{
423 int rc; 441 int rc;
424 442
425 if ((clock_division_ratio < 0x5) || (clock_division_ratio > 0x7)) { 443 if (clock_division_ratio < 0x5 || clock_division_ratio > 0x7) {
426 clock_division_ratio = WTCSR_CKS_4096; 444 clock_division_ratio = WTCSR_CKS_4096;
427 printk(KERN_INFO PFX "clock_division_ratio value must " 445 printk(KERN_INFO PFX
428 "be 0x5<=x<=0x7, using %d\n", clock_division_ratio); 446 "clock_division_ratio value must be 0x5<=x<=0x7, using %d\n",
447 clock_division_ratio);
429 } 448 }
430 449
431 rc = sh_wdt_set_heartbeat(heartbeat); 450 rc = sh_wdt_set_heartbeat(heartbeat);
432 if (unlikely(rc)) { 451 if (unlikely(rc)) {
433 heartbeat = WATCHDOG_HEARTBEAT; 452 heartbeat = WATCHDOG_HEARTBEAT;
434 printk(KERN_INFO PFX "heartbeat value must " 453 printk(KERN_INFO PFX
435 "be 1<=x<=3600, using %d\n", heartbeat); 454 "heartbeat value must be 1<=x<=3600, using %d\n",
455 heartbeat);
436 } 456 }
437 457
438 rc = register_reboot_notifier(&sh_wdt_notifier); 458 rc = register_reboot_notifier(&sh_wdt_notifier);
439 if (unlikely(rc)) { 459 if (unlikely(rc)) {
440 printk(KERN_ERR PFX "Can't register reboot notifier (err=%d)\n", 460 printk(KERN_ERR PFX
441 rc); 461 "Can't register reboot notifier (err=%d)\n", rc);
442 return rc; 462 return rc;
443 } 463 }
444 464
445 rc = misc_register(&sh_wdt_miscdev); 465 rc = misc_register(&sh_wdt_miscdev);
446 if (unlikely(rc)) { 466 if (unlikely(rc)) {
447 printk(KERN_ERR PFX "Can't register miscdev on " 467 printk(KERN_ERR PFX
448 "minor=%d (err=%d)\n", sh_wdt_miscdev.minor, rc); 468 "Can't register miscdev on minor=%d (err=%d)\n",
469 sh_wdt_miscdev.minor, rc);
449 unregister_reboot_notifier(&sh_wdt_notifier); 470 unregister_reboot_notifier(&sh_wdt_notifier);
450 return rc; 471 return rc;
451 } 472 }
@@ -476,10 +497,14 @@ module_param(clock_division_ratio, int, 0);
476MODULE_PARM_DESC(clock_division_ratio, "Clock division ratio. Valid ranges are from 0x5 (1.31ms) to 0x7 (5.25ms). (default=" __MODULE_STRING(clock_division_ratio) ")"); 497MODULE_PARM_DESC(clock_division_ratio, "Clock division ratio. Valid ranges are from 0x5 (1.31ms) to 0x7 (5.25ms). (default=" __MODULE_STRING(clock_division_ratio) ")");
477 498
478module_param(heartbeat, int, 0); 499module_param(heartbeat, int, 0);
479MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (1<=heartbeat<=3600, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); 500MODULE_PARM_DESC(heartbeat,
501 "Watchdog heartbeat in seconds. (1 <= heartbeat <= 3600, default="
502 __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
480 503
481module_param(nowayout, int, 0); 504module_param(nowayout, int, 0);
482MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 505MODULE_PARM_DESC(nowayout,
506 "Watchdog cannot be stopped once started (default="
507 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
483 508
484module_init(sh_wdt_init); 509module_init(sh_wdt_init);
485module_exit(sh_wdt_exit); 510module_exit(sh_wdt_exit);
diff --git a/drivers/watchdog/smsc37b787_wdt.c b/drivers/watchdog/smsc37b787_wdt.c
index 5d2b5ba61414..988ff1d5b4be 100644
--- a/drivers/watchdog/smsc37b787_wdt.c
+++ b/drivers/watchdog/smsc37b787_wdt.c
@@ -18,7 +18,7 @@
18 * History: 18 * History:
19 * 2003 - Created version 1.0 for Linux 2.4.x. 19 * 2003 - Created version 1.0 for Linux 2.4.x.
20 * 2006 - Ported to Linux 2.6, added nowayout and MAGICCLOSE 20 * 2006 - Ported to Linux 2.6, added nowayout and MAGICCLOSE
21 * features. Released version 1.1 21 * features. Released version 1.1
22 * 22 *
23 * Theory of operation: 23 * Theory of operation:
24 * 24 *
@@ -55,9 +55,9 @@
55#include <linux/reboot.h> 55#include <linux/reboot.h>
56#include <linux/init.h> 56#include <linux/init.h>
57#include <linux/spinlock.h> 57#include <linux/spinlock.h>
58#include <linux/io.h>
59#include <linux/uaccess.h>
58 60
59#include <asm/io.h>
60#include <asm/uaccess.h>
61#include <asm/system.h> 61#include <asm/system.h>
62 62
63/* enable support for minutes as units? */ 63/* enable support for minutes as units? */
@@ -71,15 +71,15 @@
71#define UNIT_MINUTE 1 71#define UNIT_MINUTE 1
72 72
73#define MODNAME "smsc37b787_wdt: " 73#define MODNAME "smsc37b787_wdt: "
74#define VERSION "1.1" 74#define VERSION "1.1"
75 75
76#define IOPORT 0x3F0 76#define IOPORT 0x3F0
77#define IOPORT_SIZE 2 77#define IOPORT_SIZE 2
78#define IODEV_NO 8 78#define IODEV_NO 8
79 79
80static int unit = UNIT_SECOND; /* timer's unit */ 80static int unit = UNIT_SECOND; /* timer's unit */
81static int timeout = 60; /* timeout value: default is 60 "units" */ 81static int timeout = 60; /* timeout value: default is 60 "units" */
82static unsigned long timer_enabled = 0; /* is the timer enabled? */ 82static unsigned long timer_enabled; /* is the timer enabled? */
83 83
84static char expect_close; /* is the close expected? */ 84static char expect_close; /* is the close expected? */
85 85
@@ -93,114 +93,121 @@ static int nowayout = WATCHDOG_NOWAYOUT;
93 93
94static inline void open_io_config(void) 94static inline void open_io_config(void)
95{ 95{
96 outb(0x55, IOPORT); 96 outb(0x55, IOPORT);
97 mdelay(1); 97 mdelay(1);
98 outb(0x55, IOPORT); 98 outb(0x55, IOPORT);
99} 99}
100 100
101/* lock the IO chip */ 101/* lock the IO chip */
102static inline void close_io_config(void) 102static inline void close_io_config(void)
103{ 103{
104 outb(0xAA, IOPORT); 104 outb(0xAA, IOPORT);
105} 105}
106 106
107/* select the IO device */ 107/* select the IO device */
108static inline void select_io_device(unsigned char devno) 108static inline void select_io_device(unsigned char devno)
109{ 109{
110 outb(0x07, IOPORT); 110 outb(0x07, IOPORT);
111 outb(devno, IOPORT+1); 111 outb(devno, IOPORT+1);
112} 112}
113 113
114/* write to the control register */ 114/* write to the control register */
115static inline void write_io_cr(unsigned char reg, unsigned char data) 115static inline void write_io_cr(unsigned char reg, unsigned char data)
116{ 116{
117 outb(reg, IOPORT); 117 outb(reg, IOPORT);
118 outb(data, IOPORT+1); 118 outb(data, IOPORT+1);
119} 119}
120 120
121/* read from the control register */ 121/* read from the control register */
122static inline char read_io_cr(unsigned char reg) 122static inline char read_io_cr(unsigned char reg)
123{ 123{
124 outb(reg, IOPORT); 124 outb(reg, IOPORT);
125 return inb(IOPORT+1); 125 return inb(IOPORT+1);
126} 126}
127 127
128/* -- Medium level functions ------------------------------------*/ 128/* -- Medium level functions ------------------------------------*/
129 129
130static inline void gpio_bit12(unsigned char reg) 130static inline void gpio_bit12(unsigned char reg)
131{ 131{
132 // -- General Purpose I/O Bit 1.2 -- 132 /* -- General Purpose I/O Bit 1.2 --
133 // Bit 0, In/Out: 0 = Output, 1 = Input 133 * Bit 0, In/Out: 0 = Output, 1 = Input
134 // Bit 1, Polarity: 0 = No Invert, 1 = Invert 134 * Bit 1, Polarity: 0 = No Invert, 1 = Invert
135 // Bit 2, Group Enable Intr.: 0 = Disable, 1 = Enable 135 * Bit 2, Group Enable Intr.: 0 = Disable, 1 = Enable
136 // Bit 3/4, Function select: 00 = GPI/O, 01 = WDT, 10 = P17, 136 * Bit 3/4, Function select: 00 = GPI/O, 01 = WDT, 10 = P17,
137 // 11 = Either Edge Triggered Intr. 2 137 * 11 = Either Edge Triggered Intr. 2
138 // Bit 5/6 (Reserved) 138 * Bit 5/6 (Reserved)
139 // Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain 139 * Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain
140 write_io_cr(0xE2, reg); 140 */
141 write_io_cr(0xE2, reg);
141} 142}
142 143
143static inline void gpio_bit13(unsigned char reg) 144static inline void gpio_bit13(unsigned char reg)
144{ 145{
145 // -- General Purpose I/O Bit 1.3 -- 146 /* -- General Purpose I/O Bit 1.3 --
146 // Bit 0, In/Out: 0 = Output, 1 = Input 147 * Bit 0, In/Out: 0 = Output, 1 = Input
147 // Bit 1, Polarity: 0 = No Invert, 1 = Invert 148 * Bit 1, Polarity: 0 = No Invert, 1 = Invert
148 // Bit 2, Group Enable Intr.: 0 = Disable, 1 = Enable 149 * Bit 2, Group Enable Intr.: 0 = Disable, 1 = Enable
149 // Bit 3, Function select: 0 = GPI/O, 1 = LED 150 * Bit 3, Function select: 0 = GPI/O, 1 = LED
150 // Bit 4-6 (Reserved) 151 * Bit 4-6 (Reserved)
151 // Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain 152 * Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain
152 write_io_cr(0xE3, reg); 153 */
154 write_io_cr(0xE3, reg);
153} 155}
154 156
155static inline void wdt_timer_units(unsigned char new_units) 157static inline void wdt_timer_units(unsigned char new_units)
156{ 158{
157 // -- Watchdog timer units -- 159 /* -- Watchdog timer units --
158 // Bit 0-6 (Reserved) 160 * Bit 0-6 (Reserved)
159 // Bit 7, WDT Time-out Value Units Select 161 * Bit 7, WDT Time-out Value Units Select
160 // (0 = Minutes, 1 = Seconds) 162 * (0 = Minutes, 1 = Seconds)
161 write_io_cr(0xF1, new_units); 163 */
164 write_io_cr(0xF1, new_units);
162} 165}
163 166
164static inline void wdt_timeout_value(unsigned char new_timeout) 167static inline void wdt_timeout_value(unsigned char new_timeout)
165{ 168{
166 // -- Watchdog Timer Time-out Value -- 169 /* -- Watchdog Timer Time-out Value --
167 // Bit 0-7 Binary coded units (0=Disabled, 1..255) 170 * Bit 0-7 Binary coded units (0=Disabled, 1..255)
168 write_io_cr(0xF2, new_timeout); 171 */
172 write_io_cr(0xF2, new_timeout);
169} 173}
170 174
171static inline void wdt_timer_conf(unsigned char conf) 175static inline void wdt_timer_conf(unsigned char conf)
172{ 176{
173 // -- Watchdog timer configuration -- 177 /* -- Watchdog timer configuration --
174 // Bit 0 Joystick enable: 0* = No Reset, 1 = Reset WDT upon Gameport I/O 178 * Bit 0 Joystick enable: 0* = No Reset, 1 = Reset WDT upon
175 // Bit 1 Keyboard enable: 0* = No Reset, 1 = Reset WDT upon KBD Intr. 179 * Gameport I/O
176 // Bit 2 Mouse enable: 0* = No Reset, 1 = Reset WDT upon Mouse Intr. 180 * Bit 1 Keyboard enable: 0* = No Reset, 1 = Reset WDT upon KBD Intr.
177 // Bit 3 Reset the timer 181 * Bit 2 Mouse enable: 0* = No Reset, 1 = Reset WDT upon Mouse Intr
178 // (Wrong in SMsC documentation? Given as: PowerLED Timout Enabled) 182 * Bit 3 Reset the timer
179 // Bit 4-7 WDT Interrupt Mapping: (0000* = Disabled, 183 * (Wrong in SMsC documentation? Given as: PowerLED Timout
180 // 0001=IRQ1, 0010=(Invalid), 0011=IRQ3 to 1111=IRQ15) 184 * Enabled)
181 write_io_cr(0xF3, conf); 185 * Bit 4-7 WDT Interrupt Mapping: (0000* = Disabled,
186 * 0001=IRQ1, 0010=(Invalid), 0011=IRQ3 to 1111=IRQ15)
187 */
188 write_io_cr(0xF3, conf);
182} 189}
183 190
184static inline void wdt_timer_ctrl(unsigned char reg) 191static inline void wdt_timer_ctrl(unsigned char reg)
185{ 192{
186 // -- Watchdog timer control -- 193 /* -- Watchdog timer control --
187 // Bit 0 Status Bit: 0 = Timer counting, 1 = Timeout occured 194 * Bit 0 Status Bit: 0 = Timer counting, 1 = Timeout occured
188 // Bit 1 Power LED Toggle: 0 = Disable Toggle, 1 = Toggle at 1 Hz 195 * Bit 1 Power LED Toggle: 0 = Disable Toggle, 1 = Toggle at 1 Hz
189 // Bit 2 Force Timeout: 1 = Forces WD timeout event (self-cleaning) 196 * Bit 2 Force Timeout: 1 = Forces WD timeout event (self-cleaning)
190 // Bit 3 P20 Force Timeout enabled: 197 * Bit 3 P20 Force Timeout enabled:
191 // 0 = P20 activity does not generate the WD timeout event 198 * 0 = P20 activity does not generate the WD timeout event
192 // 1 = P20 Allows rising edge of P20, from the keyboard 199 * 1 = P20 Allows rising edge of P20, from the keyboard
193 // controller, to force the WD timeout event. 200 * controller, to force the WD timeout event.
194 // Bit 4 (Reserved) 201 * Bit 4 (Reserved)
195 // -- Soft power management -- 202 * -- Soft power management --
196 // Bit 5 Stop Counter: 1 = Stop software power down counter 203 * Bit 5 Stop Counter: 1 = Stop software power down counter
197 // set via register 0xB8, (self-cleaning) 204 * set via register 0xB8, (self-cleaning)
198 // (Upon read: 0 = Counter running, 1 = Counter stopped) 205 * (Upon read: 0 = Counter running, 1 = Counter stopped)
199 // Bit 6 Restart Counter: 1 = Restart software power down counter 206 * Bit 6 Restart Counter: 1 = Restart software power down counter
200 // set via register 0xB8, (self-cleaning) 207 * set via register 0xB8, (self-cleaning)
201 // Bit 7 SPOFF: 1 = Force software power down (self-cleaning) 208 * Bit 7 SPOFF: 1 = Force software power down (self-cleaning)
202 209 */
203 write_io_cr(0xF4, reg); 210 write_io_cr(0xF4, reg);
204} 211}
205 212
206/* -- Higher level functions ------------------------------------*/ 213/* -- Higher level functions ------------------------------------*/
@@ -209,33 +216,34 @@ static inline void wdt_timer_ctrl(unsigned char reg)
209 216
210static void wb_smsc_wdt_initialize(void) 217static void wb_smsc_wdt_initialize(void)
211{ 218{
212 unsigned char old; 219 unsigned char old;
213 220
214 spin_lock(&io_lock); 221 spin_lock(&io_lock);
215 open_io_config(); 222 open_io_config();
216 select_io_device(IODEV_NO); 223 select_io_device(IODEV_NO);
217 224
218 // enable the watchdog 225 /* enable the watchdog */
219 gpio_bit13(0x08); // Select pin 80 = LED not GPIO 226 gpio_bit13(0x08); /* Select pin 80 = LED not GPIO */
220 gpio_bit12(0x0A); // Set pin 79 = WDT not GPIO/Output/Polarity=Invert 227 gpio_bit12(0x0A); /* Set pin 79 = WDT not
228 GPIO/Output/Polarity=Invert */
229 /* disable the timeout */
230 wdt_timeout_value(0);
221 231
222 // disable the timeout 232 /* reset control register */
223 wdt_timeout_value(0); 233 wdt_timer_ctrl(0x00);
224 234
225 // reset control register 235 /* reset configuration register */
226 wdt_timer_ctrl(0x00);
227
228 // reset configuration register
229 wdt_timer_conf(0x00); 236 wdt_timer_conf(0x00);
230 237
231 // read old (timer units) register 238 /* read old (timer units) register */
232 old = read_io_cr(0xF1) & 0x7F; 239 old = read_io_cr(0xF1) & 0x7F;
233 if (unit == UNIT_SECOND) old |= 0x80; // set to seconds 240 if (unit == UNIT_SECOND)
241 old |= 0x80; /* set to seconds */
234 242
235 // set the watchdog timer units 243 /* set the watchdog timer units */
236 wdt_timer_units(old); 244 wdt_timer_units(old);
237 245
238 close_io_config(); 246 close_io_config();
239 spin_unlock(&io_lock); 247 spin_unlock(&io_lock);
240} 248}
241 249
@@ -244,23 +252,23 @@ static void wb_smsc_wdt_initialize(void)
244static void wb_smsc_wdt_shutdown(void) 252static void wb_smsc_wdt_shutdown(void)
245{ 253{
246 spin_lock(&io_lock); 254 spin_lock(&io_lock);
247 open_io_config(); 255 open_io_config();
248 select_io_device(IODEV_NO); 256 select_io_device(IODEV_NO);
249 257
250 // disable the watchdog 258 /* disable the watchdog */
251 gpio_bit13(0x09); 259 gpio_bit13(0x09);
252 gpio_bit12(0x09); 260 gpio_bit12(0x09);
253 261
254 // reset watchdog config register 262 /* reset watchdog config register */
255 wdt_timer_conf(0x00); 263 wdt_timer_conf(0x00);
256 264
257 // reset watchdog control register 265 /* reset watchdog control register */
258 wdt_timer_ctrl(0x00); 266 wdt_timer_ctrl(0x00);
259 267
260 // disable timeout 268 /* disable timeout */
261 wdt_timeout_value(0x00); 269 wdt_timeout_value(0x00);
262 270
263 close_io_config(); 271 close_io_config();
264 spin_unlock(&io_lock); 272 spin_unlock(&io_lock);
265} 273}
266 274
@@ -269,16 +277,16 @@ static void wb_smsc_wdt_shutdown(void)
269static void wb_smsc_wdt_set_timeout(unsigned char new_timeout) 277static void wb_smsc_wdt_set_timeout(unsigned char new_timeout)
270{ 278{
271 spin_lock(&io_lock); 279 spin_lock(&io_lock);
272 open_io_config(); 280 open_io_config();
273 select_io_device(IODEV_NO); 281 select_io_device(IODEV_NO);
274 282
275 // set Power LED to blink, if we enable the timeout 283 /* set Power LED to blink, if we enable the timeout */
276 wdt_timer_ctrl((new_timeout == 0) ? 0x00 : 0x02); 284 wdt_timer_ctrl((new_timeout == 0) ? 0x00 : 0x02);
277 285
278 // set timeout value 286 /* set timeout value */
279 wdt_timeout_value(new_timeout); 287 wdt_timeout_value(new_timeout);
280 288
281 close_io_config(); 289 close_io_config();
282 spin_unlock(&io_lock); 290 spin_unlock(&io_lock);
283} 291}
284 292
@@ -286,32 +294,32 @@ static void wb_smsc_wdt_set_timeout(unsigned char new_timeout)
286 294
287static unsigned char wb_smsc_wdt_get_timeout(void) 295static unsigned char wb_smsc_wdt_get_timeout(void)
288{ 296{
289 unsigned char set_timeout; 297 unsigned char set_timeout;
290 298
291 spin_lock(&io_lock); 299 spin_lock(&io_lock);
292 open_io_config(); 300 open_io_config();
293 select_io_device(IODEV_NO); 301 select_io_device(IODEV_NO);
294 set_timeout = read_io_cr(0xF2); 302 set_timeout = read_io_cr(0xF2);
295 close_io_config(); 303 close_io_config();
296 spin_unlock(&io_lock); 304 spin_unlock(&io_lock);
297 305
298 return set_timeout; 306 return set_timeout;
299} 307}
300 308
301/* disable watchdog */ 309/* disable watchdog */
302 310
303static void wb_smsc_wdt_disable(void) 311static void wb_smsc_wdt_disable(void)
304{ 312{
305 // set the timeout to 0 to disable the watchdog 313 /* set the timeout to 0 to disable the watchdog */
306 wb_smsc_wdt_set_timeout(0); 314 wb_smsc_wdt_set_timeout(0);
307} 315}
308 316
309/* enable watchdog by setting the current timeout */ 317/* enable watchdog by setting the current timeout */
310 318
311static void wb_smsc_wdt_enable(void) 319static void wb_smsc_wdt_enable(void)
312{ 320{
313 // set the current timeout... 321 /* set the current timeout... */
314 wb_smsc_wdt_set_timeout(timeout); 322 wb_smsc_wdt_set_timeout(timeout);
315} 323}
316 324
317/* reset the timer */ 325/* reset the timer */
@@ -319,14 +327,14 @@ static void wb_smsc_wdt_enable(void)
319static void wb_smsc_wdt_reset_timer(void) 327static void wb_smsc_wdt_reset_timer(void)
320{ 328{
321 spin_lock(&io_lock); 329 spin_lock(&io_lock);
322 open_io_config(); 330 open_io_config();
323 select_io_device(IODEV_NO); 331 select_io_device(IODEV_NO);
324 332
325 // reset the timer 333 /* reset the timer */
326 wdt_timeout_value(timeout); 334 wdt_timeout_value(timeout);
327 wdt_timer_conf(0x08); 335 wdt_timer_conf(0x08);
328 336
329 close_io_config(); 337 close_io_config();
330 spin_unlock(&io_lock); 338 spin_unlock(&io_lock);
331} 339}
332 340
@@ -355,7 +363,9 @@ static int wb_smsc_wdt_open(struct inode *inode, struct file *file)
355 /* Reload and activate timer */ 363 /* Reload and activate timer */
356 wb_smsc_wdt_enable(); 364 wb_smsc_wdt_enable();
357 365
358 printk(KERN_INFO MODNAME "Watchdog enabled. Timeout set to %d %s.\n", timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)"); 366 printk(KERN_INFO MODNAME
367 "Watchdog enabled. Timeout set to %d %s.\n",
368 timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)");
359 369
360 return nonseekable_open(inode, file); 370 return nonseekable_open(inode, file);
361} 371}
@@ -367,10 +377,12 @@ static int wb_smsc_wdt_release(struct inode *inode, struct file *file)
367 /* Shut off the timer. */ 377 /* Shut off the timer. */
368 378
369 if (expect_close == 42) { 379 if (expect_close == 42) {
370 wb_smsc_wdt_disable(); 380 wb_smsc_wdt_disable();
371 printk(KERN_INFO MODNAME "Watchdog disabled, sleeping again...\n"); 381 printk(KERN_INFO MODNAME
382 "Watchdog disabled, sleeping again...\n");
372 } else { 383 } else {
373 printk(KERN_CRIT MODNAME "Unexpected close, not stopping watchdog!\n"); 384 printk(KERN_CRIT MODNAME
385 "Unexpected close, not stopping watchdog!\n");
374 wb_smsc_wdt_reset_timer(); 386 wb_smsc_wdt_reset_timer();
375 } 387 }
376 388
@@ -392,10 +404,11 @@ static ssize_t wb_smsc_wdt_write(struct file *file, const char __user *data,
392 /* reset expect flag */ 404 /* reset expect flag */
393 expect_close = 0; 405 expect_close = 0;
394 406
395 /* scan to see whether or not we got the magic character */ 407 /* scan to see whether or not we got the
408 magic character */
396 for (i = 0; i != len; i++) { 409 for (i = 0; i != len; i++) {
397 char c; 410 char c;
398 if (get_user(c, data+i)) 411 if (get_user(c, data + i))
399 return -EFAULT; 412 return -EFAULT;
400 if (c == 'V') 413 if (c == 'V')
401 expect_close = 42; 414 expect_close = 42;
@@ -410,8 +423,8 @@ static ssize_t wb_smsc_wdt_write(struct file *file, const char __user *data,
410 423
411/* ioctl => control interface */ 424/* ioctl => control interface */
412 425
413static int wb_smsc_wdt_ioctl(struct inode *inode, struct file *file, 426static long wb_smsc_wdt_ioctl(struct file *file,
414 unsigned int cmd, unsigned long arg) 427 unsigned int cmd, unsigned long arg)
415{ 428{
416 int new_timeout; 429 int new_timeout;
417 430
@@ -420,89 +433,73 @@ static int wb_smsc_wdt_ioctl(struct inode *inode, struct file *file,
420 int __user *i; 433 int __user *i;
421 } uarg; 434 } uarg;
422 435
423 static struct watchdog_info ident = { 436 static const struct watchdog_info ident = {
424 .options = WDIOF_KEEPALIVEPING | 437 .options = WDIOF_KEEPALIVEPING |
425 WDIOF_SETTIMEOUT | 438 WDIOF_SETTIMEOUT |
426 WDIOF_MAGICCLOSE, 439 WDIOF_MAGICCLOSE,
427 .firmware_version = 0, 440 .firmware_version = 0,
428 .identity = "SMsC 37B787 Watchdog" 441 .identity = "SMsC 37B787 Watchdog",
429 }; 442 };
430 443
431 uarg.i = (int __user *)arg; 444 uarg.i = (int __user *)arg;
432 445
433 switch (cmd) { 446 switch (cmd) {
434 default: 447 case WDIOC_GETSUPPORT:
435 return -ENOTTY; 448 return copy_to_user(uarg.ident, &ident, sizeof(ident))
436 449 ? -EFAULT : 0;
437 case WDIOC_GETSUPPORT: 450 case WDIOC_GETSTATUS:
438 return copy_to_user(uarg.ident, &ident, 451 return put_user(wb_smsc_wdt_status(), uarg.i);
439 sizeof(ident)) ? -EFAULT : 0; 452 case WDIOC_GETBOOTSTATUS:
440 453 return put_user(0, uarg.i);
441 case WDIOC_GETSTATUS: 454 case WDIOC_SETOPTIONS:
442 return put_user(wb_smsc_wdt_status(), uarg.i); 455 {
443 456 int options, retval = -EINVAL;
444 case WDIOC_GETBOOTSTATUS:
445 return put_user(0, uarg.i);
446
447 case WDIOC_KEEPALIVE:
448 wb_smsc_wdt_reset_timer();
449 return 0;
450
451 case WDIOC_SETTIMEOUT:
452 if (get_user(new_timeout, uarg.i))
453 return -EFAULT;
454
455 // the API states this is given in secs
456 if (unit == UNIT_MINUTE)
457 new_timeout /= 60;
458
459 if (new_timeout < 0 || new_timeout > MAX_TIMEOUT)
460 return -EINVAL;
461
462 timeout = new_timeout;
463 wb_smsc_wdt_set_timeout(timeout);
464
465 // fall through and return the new timeout...
466
467 case WDIOC_GETTIMEOUT:
468
469 new_timeout = timeout;
470
471 if (unit == UNIT_MINUTE)
472 new_timeout *= 60;
473
474 return put_user(new_timeout, uarg.i);
475
476 case WDIOC_SETOPTIONS:
477 {
478 int options, retval = -EINVAL;
479
480 if (get_user(options, uarg.i))
481 return -EFAULT;
482
483 if (options & WDIOS_DISABLECARD) {
484 wb_smsc_wdt_disable();
485 retval = 0;
486 }
487 457
488 if (options & WDIOS_ENABLECARD) { 458 if (get_user(options, uarg.i))
489 wb_smsc_wdt_enable(); 459 return -EFAULT;
490 retval = 0;
491 }
492 460
493 return retval; 461 if (options & WDIOS_DISABLECARD) {
462 wb_smsc_wdt_disable();
463 retval = 0;
464 }
465 if (options & WDIOS_ENABLECARD) {
466 wb_smsc_wdt_enable();
467 retval = 0;
494 } 468 }
469 return retval;
470 }
471 case WDIOC_KEEPALIVE:
472 wb_smsc_wdt_reset_timer();
473 return 0;
474 case WDIOC_SETTIMEOUT:
475 if (get_user(new_timeout, uarg.i))
476 return -EFAULT;
477 /* the API states this is given in secs */
478 if (unit == UNIT_MINUTE)
479 new_timeout /= 60;
480 if (new_timeout < 0 || new_timeout > MAX_TIMEOUT)
481 return -EINVAL;
482 timeout = new_timeout;
483 wb_smsc_wdt_set_timeout(timeout);
484 /* fall through and return the new timeout... */
485 case WDIOC_GETTIMEOUT:
486 new_timeout = timeout;
487 if (unit == UNIT_MINUTE)
488 new_timeout *= 60;
489 return put_user(new_timeout, uarg.i);
490 default:
491 return -ENOTTY;
495 } 492 }
496} 493}
497 494
498/* -- Notifier funtions -----------------------------------------*/ 495/* -- Notifier funtions -----------------------------------------*/
499 496
500static int wb_smsc_wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) 497static int wb_smsc_wdt_notify_sys(struct notifier_block *this,
498 unsigned long code, void *unused)
501{ 499{
502 if (code == SYS_DOWN || code == SYS_HALT) 500 if (code == SYS_DOWN || code == SYS_HALT) {
503 { 501 /* set timeout to 0, to avoid possible race-condition */
504 // set timeout to 0, to avoid possible race-condition 502 timeout = 0;
505 timeout = 0;
506 wb_smsc_wdt_disable(); 503 wb_smsc_wdt_disable();
507 } 504 }
508 return NOTIFY_DONE; 505 return NOTIFY_DONE;
@@ -510,23 +507,20 @@ static int wb_smsc_wdt_notify_sys(struct notifier_block *this, unsigned long cod
510 507
511/* -- Module's structures ---------------------------------------*/ 508/* -- Module's structures ---------------------------------------*/
512 509
513static const struct file_operations wb_smsc_wdt_fops = 510static const struct file_operations wb_smsc_wdt_fops = {
514{ 511 .owner = THIS_MODULE,
515 .owner = THIS_MODULE,
516 .llseek = no_llseek, 512 .llseek = no_llseek,
517 .write = wb_smsc_wdt_write, 513 .write = wb_smsc_wdt_write,
518 .ioctl = wb_smsc_wdt_ioctl, 514 .unlocked_ioctl = wb_smsc_wdt_ioctl,
519 .open = wb_smsc_wdt_open, 515 .open = wb_smsc_wdt_open,
520 .release = wb_smsc_wdt_release, 516 .release = wb_smsc_wdt_release,
521}; 517};
522 518
523static struct notifier_block wb_smsc_wdt_notifier = 519static struct notifier_block wb_smsc_wdt_notifier = {
524{
525 .notifier_call = wb_smsc_wdt_notify_sys, 520 .notifier_call = wb_smsc_wdt_notify_sys,
526}; 521};
527 522
528static struct miscdevice wb_smsc_wdt_miscdev = 523static struct miscdevice wb_smsc_wdt_miscdev = {
529{
530 .minor = WATCHDOG_MINOR, 524 .minor = WATCHDOG_MINOR,
531 .name = "watchdog", 525 .name = "watchdog",
532 .fops = &wb_smsc_wdt_fops, 526 .fops = &wb_smsc_wdt_fops,
@@ -540,39 +534,44 @@ static int __init wb_smsc_wdt_init(void)
540{ 534{
541 int ret; 535 int ret;
542 536
543 printk("SMsC 37B787 watchdog component driver " VERSION " initialising...\n"); 537 printk(KERN_INFO "SMsC 37B787 watchdog component driver "
538 VERSION " initialising...\n");
544 539
545 if (!request_region(IOPORT, IOPORT_SIZE, "SMsC 37B787 watchdog")) { 540 if (!request_region(IOPORT, IOPORT_SIZE, "SMsC 37B787 watchdog")) {
546 printk(KERN_ERR MODNAME "Unable to register IO port %#x\n", IOPORT); 541 printk(KERN_ERR MODNAME "Unable to register IO port %#x\n",
542 IOPORT);
547 ret = -EBUSY; 543 ret = -EBUSY;
548 goto out_pnp; 544 goto out_pnp;
549 } 545 }
550 546
551 // set new maximum, if it's too big 547 /* set new maximum, if it's too big */
552 if (timeout > MAX_TIMEOUT) 548 if (timeout > MAX_TIMEOUT)
553 timeout = MAX_TIMEOUT; 549 timeout = MAX_TIMEOUT;
554 550
555 // init the watchdog timer 551 /* init the watchdog timer */
556 wb_smsc_wdt_initialize(); 552 wb_smsc_wdt_initialize();
557 553
558 ret = register_reboot_notifier(&wb_smsc_wdt_notifier); 554 ret = register_reboot_notifier(&wb_smsc_wdt_notifier);
559 if (ret) { 555 if (ret) {
560 printk(KERN_ERR MODNAME "Unable to register reboot notifier err = %d\n", ret); 556 printk(KERN_ERR MODNAME
557 "Unable to register reboot notifier err = %d\n", ret);
561 goto out_io; 558 goto out_io;
562 } 559 }
563 560
564 ret = misc_register(&wb_smsc_wdt_miscdev); 561 ret = misc_register(&wb_smsc_wdt_miscdev);
565 if (ret) { 562 if (ret) {
566 printk(KERN_ERR MODNAME "Unable to register miscdev on minor %d\n", WATCHDOG_MINOR); 563 printk(KERN_ERR MODNAME
564 "Unable to register miscdev on minor %d\n",
565 WATCHDOG_MINOR);
567 goto out_rbt; 566 goto out_rbt;
568 } 567 }
569 568
570 // output info 569 /* output info */
571 printk(KERN_INFO MODNAME "Timeout set to %d %s.\n", timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)"); 570 printk(KERN_INFO MODNAME "Timeout set to %d %s.\n",
572 printk(KERN_INFO MODNAME "Watchdog initialized and sleeping (nowayout=%d)...\n", nowayout); 571 timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)");
573 572 printk(KERN_INFO MODNAME
574 // ret = 0 573 "Watchdog initialized and sleeping (nowayout=%d)...\n",
575 574 nowayout);
576out_clean: 575out_clean:
577 return ret; 576 return ret;
578 577
@@ -591,8 +590,7 @@ out_pnp:
591static void __exit wb_smsc_wdt_exit(void) 590static void __exit wb_smsc_wdt_exit(void)
592{ 591{
593 /* Stop the timer before we leave */ 592 /* Stop the timer before we leave */
594 if (!nowayout) 593 if (!nowayout) {
595 {
596 wb_smsc_wdt_shutdown(); 594 wb_smsc_wdt_shutdown();
597 printk(KERN_INFO MODNAME "Watchdog disabled.\n"); 595 printk(KERN_INFO MODNAME "Watchdog disabled.\n");
598 } 596 }
@@ -601,25 +599,29 @@ static void __exit wb_smsc_wdt_exit(void)
601 unregister_reboot_notifier(&wb_smsc_wdt_notifier); 599 unregister_reboot_notifier(&wb_smsc_wdt_notifier);
602 release_region(IOPORT, IOPORT_SIZE); 600 release_region(IOPORT, IOPORT_SIZE);
603 601
604 printk("SMsC 37B787 watchdog component driver removed.\n"); 602 printk(KERN_INFO "SMsC 37B787 watchdog component driver removed.\n");
605} 603}
606 604
607module_init(wb_smsc_wdt_init); 605module_init(wb_smsc_wdt_init);
608module_exit(wb_smsc_wdt_exit); 606module_exit(wb_smsc_wdt_exit);
609 607
610MODULE_AUTHOR("Sven Anders <anders@anduras.de>"); 608MODULE_AUTHOR("Sven Anders <anders@anduras.de>");
611MODULE_DESCRIPTION("Driver for SMsC 37B787 watchdog component (Version " VERSION ")"); 609MODULE_DESCRIPTION("Driver for SMsC 37B787 watchdog component (Version "
610 VERSION ")");
612MODULE_LICENSE("GPL"); 611MODULE_LICENSE("GPL");
613 612
614MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); 613MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
615 614
616#ifdef SMSC_SUPPORT_MINUTES 615#ifdef SMSC_SUPPORT_MINUTES
617module_param(unit, int, 0); 616module_param(unit, int, 0);
618MODULE_PARM_DESC(unit, "set unit to use, 0=seconds or 1=minutes, default is 0"); 617MODULE_PARM_DESC(unit,
618 "set unit to use, 0=seconds or 1=minutes, default is 0");
619#endif 619#endif
620 620
621module_param(timeout, int, 0); 621module_param(timeout, int, 0);
622MODULE_PARM_DESC(timeout, "range is 1-255 units, default is 60"); 622MODULE_PARM_DESC(timeout, "range is 1-255 units, default is 60");
623 623
624module_param(nowayout, int, 0); 624module_param(nowayout, int, 0);
625MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 625MODULE_PARM_DESC(nowayout,
626 "Watchdog cannot be stopped once started (default="
627 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
diff --git a/drivers/watchdog/softdog.c b/drivers/watchdog/softdog.c
index 9c3694909243..c650464c5c63 100644
--- a/drivers/watchdog/softdog.c
+++ b/drivers/watchdog/softdog.c
@@ -47,19 +47,22 @@
47#include <linux/reboot.h> 47#include <linux/reboot.h>
48#include <linux/init.h> 48#include <linux/init.h>
49#include <linux/jiffies.h> 49#include <linux/jiffies.h>
50 50#include <linux/uaccess.h>
51#include <asm/uaccess.h>
52 51
53#define PFX "SoftDog: " 52#define PFX "SoftDog: "
54 53
55#define TIMER_MARGIN 60 /* Default is 60 seconds */ 54#define TIMER_MARGIN 60 /* Default is 60 seconds */
56static int soft_margin = TIMER_MARGIN; /* in seconds */ 55static int soft_margin = TIMER_MARGIN; /* in seconds */
57module_param(soft_margin, int, 0); 56module_param(soft_margin, int, 0);
58MODULE_PARM_DESC(soft_margin, "Watchdog soft_margin in seconds. (0<soft_margin<65536, default=" __MODULE_STRING(TIMER_MARGIN) ")"); 57MODULE_PARM_DESC(soft_margin,
58 "Watchdog soft_margin in seconds. (0 < soft_margin < 65536, default="
59 __MODULE_STRING(TIMER_MARGIN) ")");
59 60
60static int nowayout = WATCHDOG_NOWAYOUT; 61static int nowayout = WATCHDOG_NOWAYOUT;
61module_param(nowayout, int, 0); 62module_param(nowayout, int, 0);
62MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 63MODULE_PARM_DESC(nowayout,
64 "Watchdog cannot be stopped once started (default="
65 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
63 66
64#ifdef ONLY_TESTING 67#ifdef ONLY_TESTING
65static int soft_noboot = 1; 68static int soft_noboot = 1;
@@ -93,8 +96,7 @@ static void watchdog_fire(unsigned long data)
93 96
94 if (soft_noboot) 97 if (soft_noboot)
95 printk(KERN_CRIT PFX "Triggered - Reboot ignored.\n"); 98 printk(KERN_CRIT PFX "Triggered - Reboot ignored.\n");
96 else 99 else {
97 {
98 printk(KERN_CRIT PFX "Initiating system reboot.\n"); 100 printk(KERN_CRIT PFX "Initiating system reboot.\n");
99 emergency_restart(); 101 emergency_restart();
100 printk(KERN_CRIT PFX "Reboot didn't ?????\n"); 102 printk(KERN_CRIT PFX "Reboot didn't ?????\n");
@@ -153,7 +155,8 @@ static int softdog_release(struct inode *inode, struct file *file)
153 softdog_stop(); 155 softdog_stop();
154 module_put(THIS_MODULE); 156 module_put(THIS_MODULE);
155 } else { 157 } else {
156 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); 158 printk(KERN_CRIT PFX
159 "Unexpected close, not stopping watchdog!\n");
157 set_bit(0, &orphan_timer); 160 set_bit(0, &orphan_timer);
158 softdog_keepalive(); 161 softdog_keepalive();
159 } 162 }
@@ -162,12 +165,13 @@ static int softdog_release(struct inode *inode, struct file *file)
162 return 0; 165 return 0;
163} 166}
164 167
165static ssize_t softdog_write(struct file *file, const char __user *data, size_t len, loff_t *ppos) 168static ssize_t softdog_write(struct file *file, const char __user *data,
169 size_t len, loff_t *ppos)
166{ 170{
167 /* 171 /*
168 * Refresh the timer. 172 * Refresh the timer.
169 */ 173 */
170 if(len) { 174 if (len) {
171 if (!nowayout) { 175 if (!nowayout) {
172 size_t i; 176 size_t i;
173 177
@@ -188,13 +192,13 @@ static ssize_t softdog_write(struct file *file, const char __user *data, size_t
188 return len; 192 return len;
189} 193}
190 194
191static int softdog_ioctl(struct inode *inode, struct file *file, 195static long softdog_ioctl(struct file *file, unsigned int cmd,
192 unsigned int cmd, unsigned long arg) 196 unsigned long arg)
193{ 197{
194 void __user *argp = (void __user *)arg; 198 void __user *argp = (void __user *)arg;
195 int __user *p = argp; 199 int __user *p = argp;
196 int new_margin; 200 int new_margin;
197 static struct watchdog_info ident = { 201 static const struct watchdog_info ident = {
198 .options = WDIOF_SETTIMEOUT | 202 .options = WDIOF_SETTIMEOUT |
199 WDIOF_KEEPALIVEPING | 203 WDIOF_KEEPALIVEPING |
200 WDIOF_MAGICCLOSE, 204 WDIOF_MAGICCLOSE,
@@ -202,26 +206,25 @@ static int softdog_ioctl(struct inode *inode, struct file *file,
202 .identity = "Software Watchdog", 206 .identity = "Software Watchdog",
203 }; 207 };
204 switch (cmd) { 208 switch (cmd) {
205 default: 209 case WDIOC_GETSUPPORT:
206 return -ENOTTY; 210 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
207 case WDIOC_GETSUPPORT: 211 case WDIOC_GETSTATUS:
208 return copy_to_user(argp, &ident, 212 case WDIOC_GETBOOTSTATUS:
209 sizeof(ident)) ? -EFAULT : 0; 213 return put_user(0, p);
210 case WDIOC_GETSTATUS: 214 case WDIOC_KEEPALIVE:
211 case WDIOC_GETBOOTSTATUS: 215 softdog_keepalive();
212 return put_user(0, p); 216 return 0;
213 case WDIOC_KEEPALIVE: 217 case WDIOC_SETTIMEOUT:
214 softdog_keepalive(); 218 if (get_user(new_margin, p))
215 return 0; 219 return -EFAULT;
216 case WDIOC_SETTIMEOUT: 220 if (softdog_set_heartbeat(new_margin))
217 if (get_user(new_margin, p)) 221 return -EINVAL;
218 return -EFAULT; 222 softdog_keepalive();
219 if (softdog_set_heartbeat(new_margin)) 223 /* Fall */
220 return -EINVAL; 224 case WDIOC_GETTIMEOUT:
221 softdog_keepalive(); 225 return put_user(soft_margin, p);
222 /* Fall */ 226 default:
223 case WDIOC_GETTIMEOUT: 227 return -ENOTTY;
224 return put_user(soft_margin, p);
225 } 228 }
226} 229}
227 230
@@ -232,10 +235,9 @@ static int softdog_ioctl(struct inode *inode, struct file *file,
232static int softdog_notify_sys(struct notifier_block *this, unsigned long code, 235static int softdog_notify_sys(struct notifier_block *this, unsigned long code,
233 void *unused) 236 void *unused)
234{ 237{
235 if(code==SYS_DOWN || code==SYS_HALT) { 238 if (code == SYS_DOWN || code == SYS_HALT)
236 /* Turn the WDT off */ 239 /* Turn the WDT off */
237 softdog_stop(); 240 softdog_stop();
238 }
239 return NOTIFY_DONE; 241 return NOTIFY_DONE;
240} 242}
241 243
@@ -247,7 +249,7 @@ static const struct file_operations softdog_fops = {
247 .owner = THIS_MODULE, 249 .owner = THIS_MODULE,
248 .llseek = no_llseek, 250 .llseek = no_llseek,
249 .write = softdog_write, 251 .write = softdog_write,
250 .ioctl = softdog_ioctl, 252 .unlocked_ioctl = softdog_ioctl,
251 .open = softdog_open, 253 .open = softdog_open,
252 .release = softdog_release, 254 .release = softdog_release,
253}; 255};
@@ -268,24 +270,27 @@ static int __init watchdog_init(void)
268{ 270{
269 int ret; 271 int ret;
270 272
271 /* Check that the soft_margin value is within it's range ; if not reset to the default */ 273 /* Check that the soft_margin value is within it's range;
274 if not reset to the default */
272 if (softdog_set_heartbeat(soft_margin)) { 275 if (softdog_set_heartbeat(soft_margin)) {
273 softdog_set_heartbeat(TIMER_MARGIN); 276 softdog_set_heartbeat(TIMER_MARGIN);
274 printk(KERN_INFO PFX "soft_margin value must be 0<soft_margin<65536, using %d\n", 277 printk(KERN_INFO PFX
278 "soft_margin must be 0 < soft_margin < 65536, using %d\n",
275 TIMER_MARGIN); 279 TIMER_MARGIN);
276 } 280 }
277 281
278 ret = register_reboot_notifier(&softdog_notifier); 282 ret = register_reboot_notifier(&softdog_notifier);
279 if (ret) { 283 if (ret) {
280 printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 284 printk(KERN_ERR PFX
281 ret); 285 "cannot register reboot notifier (err=%d)\n", ret);
282 return ret; 286 return ret;
283 } 287 }
284 288
285 ret = misc_register(&softdog_miscdev); 289 ret = misc_register(&softdog_miscdev);
286 if (ret) { 290 if (ret) {
287 printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 291 printk(KERN_ERR PFX
288 WATCHDOG_MINOR, ret); 292 "cannot register miscdev on minor=%d (err=%d)\n",
293 WATCHDOG_MINOR, ret);
289 unregister_reboot_notifier(&softdog_notifier); 294 unregister_reboot_notifier(&softdog_notifier);
290 return ret; 295 return ret;
291 } 296 }
diff --git a/drivers/watchdog/txx9wdt.c b/drivers/watchdog/txx9wdt.c
index 57cefef27ce3..dbbc018a5f46 100644
--- a/drivers/watchdog/txx9wdt.c
+++ b/drivers/watchdog/txx9wdt.c
@@ -45,27 +45,34 @@ static unsigned long txx9wdt_alive;
45static int expect_close; 45static int expect_close;
46static struct txx9_tmr_reg __iomem *txx9wdt_reg; 46static struct txx9_tmr_reg __iomem *txx9wdt_reg;
47static struct clk *txx9_imclk; 47static struct clk *txx9_imclk;
48static DECLARE_LOCK(txx9_lock);
48 49
49static void txx9wdt_ping(void) 50static void txx9wdt_ping(void)
50{ 51{
52 spin_lock(&txx9_lock);
51 __raw_writel(TXx9_TMWTMR_TWIE | TXx9_TMWTMR_TWC, &txx9wdt_reg->wtmr); 53 __raw_writel(TXx9_TMWTMR_TWIE | TXx9_TMWTMR_TWC, &txx9wdt_reg->wtmr);
54 spin_unlock(&txx9_lock);
52} 55}
53 56
54static void txx9wdt_start(void) 57static void txx9wdt_start(void)
55{ 58{
59 spin_lock(&txx9_lock);
56 __raw_writel(WD_TIMER_CLK * timeout, &txx9wdt_reg->cpra); 60 __raw_writel(WD_TIMER_CLK * timeout, &txx9wdt_reg->cpra);
57 __raw_writel(WD_TIMER_CCD, &txx9wdt_reg->ccdr); 61 __raw_writel(WD_TIMER_CCD, &txx9wdt_reg->ccdr);
58 __raw_writel(0, &txx9wdt_reg->tisr); /* clear pending interrupt */ 62 __raw_writel(0, &txx9wdt_reg->tisr); /* clear pending interrupt */
59 __raw_writel(TXx9_TMTCR_TCE | TXx9_TMTCR_CCDE | TXx9_TMTCR_TMODE_WDOG, 63 __raw_writel(TXx9_TMTCR_TCE | TXx9_TMTCR_CCDE | TXx9_TMTCR_TMODE_WDOG,
60 &txx9wdt_reg->tcr); 64 &txx9wdt_reg->tcr);
61 __raw_writel(TXx9_TMWTMR_TWIE | TXx9_TMWTMR_TWC, &txx9wdt_reg->wtmr); 65 __raw_writel(TXx9_TMWTMR_TWIE | TXx9_TMWTMR_TWC, &txx9wdt_reg->wtmr);
66 spin_unlock(&txx9_lock);
62} 67}
63 68
64static void txx9wdt_stop(void) 69static void txx9wdt_stop(void)
65{ 70{
71 spin_lock(&txx9_lock);
66 __raw_writel(TXx9_TMWTMR_WDIS, &txx9wdt_reg->wtmr); 72 __raw_writel(TXx9_TMWTMR_WDIS, &txx9wdt_reg->wtmr);
67 __raw_writel(__raw_readl(&txx9wdt_reg->tcr) & ~TXx9_TMTCR_TCE, 73 __raw_writel(__raw_readl(&txx9wdt_reg->tcr) & ~TXx9_TMTCR_TCE,
68 &txx9wdt_reg->tcr); 74 &txx9wdt_reg->tcr);
75 spin_unlock(&txx9_lock);
69} 76}
70 77
71static int txx9wdt_open(struct inode *inode, struct file *file) 78static int txx9wdt_open(struct inode *inode, struct file *file)
@@ -120,13 +127,13 @@ static ssize_t txx9wdt_write(struct file *file, const char __user *data,
120 return len; 127 return len;
121} 128}
122 129
123static int txx9wdt_ioctl(struct inode *inode, struct file *file, 130static long txx9wdt_ioctl(struct file *file, unsigned int cmd,
124 unsigned int cmd, unsigned long arg) 131 unsigned long arg)
125{ 132{
126 void __user *argp = (void __user *)arg; 133 void __user *argp = (void __user *)arg;
127 int __user *p = argp; 134 int __user *p = argp;
128 int new_timeout; 135 int new_timeout;
129 static struct watchdog_info ident = { 136 static const struct watchdog_info ident = {
130 .options = WDIOF_SETTIMEOUT | 137 .options = WDIOF_SETTIMEOUT |
131 WDIOF_KEEPALIVEPING | 138 WDIOF_KEEPALIVEPING |
132 WDIOF_MAGICCLOSE, 139 WDIOF_MAGICCLOSE,
@@ -135,8 +142,6 @@ static int txx9wdt_ioctl(struct inode *inode, struct file *file,
135 }; 142 };
136 143
137 switch (cmd) { 144 switch (cmd) {
138 default:
139 return -ENOTTY;
140 case WDIOC_GETSUPPORT: 145 case WDIOC_GETSUPPORT:
141 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; 146 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
142 case WDIOC_GETSTATUS: 147 case WDIOC_GETSTATUS:
@@ -156,6 +161,8 @@ static int txx9wdt_ioctl(struct inode *inode, struct file *file,
156 /* Fall */ 161 /* Fall */
157 case WDIOC_GETTIMEOUT: 162 case WDIOC_GETTIMEOUT:
158 return put_user(timeout, p); 163 return put_user(timeout, p);
164 default:
165 return -ENOTTY;
159 } 166 }
160} 167}
161 168
@@ -168,22 +175,22 @@ static int txx9wdt_notify_sys(struct notifier_block *this, unsigned long code,
168} 175}
169 176
170static const struct file_operations txx9wdt_fops = { 177static const struct file_operations txx9wdt_fops = {
171 .owner = THIS_MODULE, 178 .owner = THIS_MODULE,
172 .llseek = no_llseek, 179 .llseek = no_llseek,
173 .write = txx9wdt_write, 180 .write = txx9wdt_write,
174 .ioctl = txx9wdt_ioctl, 181 .unlocked_ioctl = txx9wdt_ioctl,
175 .open = txx9wdt_open, 182 .open = txx9wdt_open,
176 .release = txx9wdt_release, 183 .release = txx9wdt_release,
177}; 184};
178 185
179static struct miscdevice txx9wdt_miscdev = { 186static struct miscdevice txx9wdt_miscdev = {
180 .minor = WATCHDOG_MINOR, 187 .minor = WATCHDOG_MINOR,
181 .name = "watchdog", 188 .name = "watchdog",
182 .fops = &txx9wdt_fops, 189 .fops = &txx9wdt_fops,
183}; 190};
184 191
185static struct notifier_block txx9wdt_notifier = { 192static struct notifier_block txx9wdt_notifier = {
186 .notifier_call = txx9wdt_notify_sys 193 .notifier_call = txx9wdt_notify_sys,
187}; 194};
188 195
189static int __init txx9wdt_probe(struct platform_device *dev) 196static int __init txx9wdt_probe(struct platform_device *dev)
diff --git a/drivers/watchdog/w83627hf_wdt.c b/drivers/watchdog/w83627hf_wdt.c
index 386492821fc2..69396adaa5c3 100644
--- a/drivers/watchdog/w83627hf_wdt.c
+++ b/drivers/watchdog/w83627hf_wdt.c
@@ -37,9 +37,9 @@
37#include <linux/reboot.h> 37#include <linux/reboot.h>
38#include <linux/init.h> 38#include <linux/init.h>
39#include <linux/spinlock.h> 39#include <linux/spinlock.h>
40#include <linux/io.h>
41#include <linux/uaccess.h>
40 42
41#include <asm/io.h>
42#include <asm/uaccess.h>
43#include <asm/system.h> 43#include <asm/system.h>
44 44
45#define WATCHDOG_NAME "w83627hf/thf/hg WDT" 45#define WATCHDOG_NAME "w83627hf/thf/hg WDT"
@@ -57,22 +57,26 @@ MODULE_PARM_DESC(wdt_io, "w83627hf/thf WDT io port (default 0x2E)");
57 57
58static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ 58static int timeout = WATCHDOG_TIMEOUT; /* in seconds */
59module_param(timeout, int, 0); 59module_param(timeout, int, 0);
60MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=255, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) "."); 60MODULE_PARM_DESC(timeout,
61 "Watchdog timeout in seconds. 1 <= timeout <= 255, default="
62 __MODULE_STRING(WATCHDOG_TIMEOUT) ".");
61 63
62static int nowayout = WATCHDOG_NOWAYOUT; 64static int nowayout = WATCHDOG_NOWAYOUT;
63module_param(nowayout, int, 0); 65module_param(nowayout, int, 0);
64MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 66MODULE_PARM_DESC(nowayout,
67 "Watchdog cannot be stopped once started (default="
68 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
65 69
66/* 70/*
67 * Kernel methods. 71 * Kernel methods.
68 */ 72 */
69 73
70#define WDT_EFER (wdt_io+0) /* Extended Function Enable Registers */ 74#define WDT_EFER (wdt_io+0) /* Extended Function Enable Registers */
71#define WDT_EFIR (wdt_io+0) /* Extended Function Index Register (same as EFER) */ 75#define WDT_EFIR (wdt_io+0) /* Extended Function Index Register
76 (same as EFER) */
72#define WDT_EFDR (WDT_EFIR+1) /* Extended Function Data Register */ 77#define WDT_EFDR (WDT_EFIR+1) /* Extended Function Data Register */
73 78
74static void 79static void w83627hf_select_wd_register(void)
75w83627hf_select_wd_register(void)
76{ 80{
77 unsigned char c; 81 unsigned char c;
78 outb_p(0x87, WDT_EFER); /* Enter extended function mode */ 82 outb_p(0x87, WDT_EFER); /* Enter extended function mode */
@@ -93,43 +97,45 @@ w83627hf_select_wd_register(void)
93 outb_p(0x01, WDT_EFDR); /* set bit 0 to activate GPIO2 */ 97 outb_p(0x01, WDT_EFDR); /* set bit 0 to activate GPIO2 */
94} 98}
95 99
96static void 100static void w83627hf_unselect_wd_register(void)
97w83627hf_unselect_wd_register(void)
98{ 101{
99 outb_p(0xAA, WDT_EFER); /* Leave extended function mode */ 102 outb_p(0xAA, WDT_EFER); /* Leave extended function mode */
100} 103}
101 104
102/* tyan motherboards seem to set F5 to 0x4C ? 105/* tyan motherboards seem to set F5 to 0x4C ?
103 * So explicitly init to appropriate value. */ 106 * So explicitly init to appropriate value. */
104static void 107
105w83627hf_init(void) 108static void w83627hf_init(void)
106{ 109{
107 unsigned char t; 110 unsigned char t;
108 111
109 w83627hf_select_wd_register(); 112 w83627hf_select_wd_register();
110 113
111 outb_p(0xF6, WDT_EFER); /* Select CRF6 */ 114 outb_p(0xF6, WDT_EFER); /* Select CRF6 */
112 t=inb_p(WDT_EFDR); /* read CRF6 */ 115 t = inb_p(WDT_EFDR); /* read CRF6 */
113 if (t != 0) { 116 if (t != 0) {
114 printk (KERN_INFO PFX "Watchdog already running. Resetting timeout to %d sec\n", timeout); 117 printk(KERN_INFO PFX
118 "Watchdog already running. Resetting timeout to %d sec\n",
119 timeout);
115 outb_p(timeout, WDT_EFDR); /* Write back to CRF6 */ 120 outb_p(timeout, WDT_EFDR); /* Write back to CRF6 */
116 } 121 }
117 122
118 outb_p(0xF5, WDT_EFER); /* Select CRF5 */ 123 outb_p(0xF5, WDT_EFER); /* Select CRF5 */
119 t=inb_p(WDT_EFDR); /* read CRF5 */ 124 t = inb_p(WDT_EFDR); /* read CRF5 */
120 t&=~0x0C; /* set second mode & disable keyboard turning off watchdog */ 125 t &= ~0x0C; /* set second mode & disable keyboard
126 turning off watchdog */
121 outb_p(t, WDT_EFDR); /* Write back to CRF5 */ 127 outb_p(t, WDT_EFDR); /* Write back to CRF5 */
122 128
123 outb_p(0xF7, WDT_EFER); /* Select CRF7 */ 129 outb_p(0xF7, WDT_EFER); /* Select CRF7 */
124 t=inb_p(WDT_EFDR); /* read CRF7 */ 130 t = inb_p(WDT_EFDR); /* read CRF7 */
125 t&=~0xC0; /* disable keyboard & mouse turning off watchdog */ 131 t &= ~0xC0; /* disable keyboard & mouse turning off
132 watchdog */
126 outb_p(t, WDT_EFDR); /* Write back to CRF7 */ 133 outb_p(t, WDT_EFDR); /* Write back to CRF7 */
127 134
128 w83627hf_unselect_wd_register(); 135 w83627hf_unselect_wd_register();
129} 136}
130 137
131static void 138static void wdt_ctrl(int timeout)
132wdt_ctrl(int timeout)
133{ 139{
134 spin_lock(&io_lock); 140 spin_lock(&io_lock);
135 141
@@ -143,32 +149,28 @@ wdt_ctrl(int timeout)
143 spin_unlock(&io_lock); 149 spin_unlock(&io_lock);
144} 150}
145 151
146static int 152static int wdt_ping(void)
147wdt_ping(void)
148{ 153{
149 wdt_ctrl(timeout); 154 wdt_ctrl(timeout);
150 return 0; 155 return 0;
151} 156}
152 157
153static int 158static int wdt_disable(void)
154wdt_disable(void)
155{ 159{
156 wdt_ctrl(0); 160 wdt_ctrl(0);
157 return 0; 161 return 0;
158} 162}
159 163
160static int 164static int wdt_set_heartbeat(int t)
161wdt_set_heartbeat(int t)
162{ 165{
163 if ((t < 1) || (t > 255)) 166 if (t < 1 || t > 255)
164 return -EINVAL; 167 return -EINVAL;
165
166 timeout = t; 168 timeout = t;
167 return 0; 169 return 0;
168} 170}
169 171
170static ssize_t 172static ssize_t wdt_write(struct file *file, const char __user *buf,
171wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) 173 size_t count, loff_t *ppos)
172{ 174{
173 if (count) { 175 if (count) {
174 if (!nowayout) { 176 if (!nowayout) {
@@ -178,7 +180,7 @@ wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
178 180
179 for (i = 0; i != count; i++) { 181 for (i = 0; i != count; i++) {
180 char c; 182 char c;
181 if (get_user(c, buf+i)) 183 if (get_user(c, buf + i))
182 return -EFAULT; 184 return -EFAULT;
183 if (c == 'V') 185 if (c == 'V')
184 expect_close = 42; 186 expect_close = 42;
@@ -189,72 +191,61 @@ wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
189 return count; 191 return count;
190} 192}
191 193
192static int 194static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
193wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
194 unsigned long arg)
195{ 195{
196 void __user *argp = (void __user *)arg; 196 void __user *argp = (void __user *)arg;
197 int __user *p = argp; 197 int __user *p = argp;
198 int new_timeout; 198 int new_timeout;
199 static struct watchdog_info ident = { 199 static struct watchdog_info ident = {
200 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, 200 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
201 WDIOF_MAGICCLOSE,
201 .firmware_version = 1, 202 .firmware_version = 1,
202 .identity = "W83627HF WDT", 203 .identity = "W83627HF WDT",
203 }; 204 };
204 205
205 switch (cmd) { 206 switch (cmd) {
206 case WDIOC_GETSUPPORT: 207 case WDIOC_GETSUPPORT:
207 if (copy_to_user(argp, &ident, sizeof(ident))) 208 if (copy_to_user(argp, &ident, sizeof(ident)))
208 return -EFAULT; 209 return -EFAULT;
209 break; 210 break;
210
211 case WDIOC_GETSTATUS: 211 case WDIOC_GETSTATUS:
212 case WDIOC_GETBOOTSTATUS: 212 case WDIOC_GETBOOTSTATUS:
213 return put_user(0, p); 213 return put_user(0, p);
214
215 case WDIOC_KEEPALIVE:
216 wdt_ping();
217 break;
218
219 case WDIOC_SETTIMEOUT:
220 if (get_user(new_timeout, p))
221 return -EFAULT;
222 if (wdt_set_heartbeat(new_timeout))
223 return -EINVAL;
224 wdt_ping();
225 /* Fall */
226
227 case WDIOC_GETTIMEOUT:
228 return put_user(timeout, p);
229
230 case WDIOC_SETOPTIONS: 214 case WDIOC_SETOPTIONS:
231 { 215 {
232 int options, retval = -EINVAL; 216 int options, retval = -EINVAL;
233
234 if (get_user(options, p))
235 return -EFAULT;
236
237 if (options & WDIOS_DISABLECARD) {
238 wdt_disable();
239 retval = 0;
240 }
241
242 if (options & WDIOS_ENABLECARD) {
243 wdt_ping();
244 retval = 0;
245 }
246 217
247 return retval; 218 if (get_user(options, p))
219 return -EFAULT;
220 if (options & WDIOS_DISABLECARD) {
221 wdt_disable();
222 retval = 0;
223 }
224 if (options & WDIOS_ENABLECARD) {
225 wdt_ping();
226 retval = 0;
227 }
228 return retval;
248 } 229 }
249 230 case WDIOC_KEEPALIVE:
231 wdt_ping();
232 break;
233 case WDIOC_SETTIMEOUT:
234 if (get_user(new_timeout, p))
235 return -EFAULT;
236 if (wdt_set_heartbeat(new_timeout))
237 return -EINVAL;
238 wdt_ping();
239 /* Fall */
240 case WDIOC_GETTIMEOUT:
241 return put_user(timeout, p);
250 default: 242 default:
251 return -ENOTTY; 243 return -ENOTTY;
252 } 244 }
253 return 0; 245 return 0;
254} 246}
255 247
256static int 248static int wdt_open(struct inode *inode, struct file *file)
257wdt_open(struct inode *inode, struct file *file)
258{ 249{
259 if (test_and_set_bit(0, &wdt_is_open)) 250 if (test_and_set_bit(0, &wdt_is_open))
260 return -EBUSY; 251 return -EBUSY;
@@ -266,13 +257,13 @@ wdt_open(struct inode *inode, struct file *file)
266 return nonseekable_open(inode, file); 257 return nonseekable_open(inode, file);
267} 258}
268 259
269static int 260static int wdt_close(struct inode *inode, struct file *file)
270wdt_close(struct inode *inode, struct file *file)
271{ 261{
272 if (expect_close == 42) { 262 if (expect_close == 42)
273 wdt_disable(); 263 wdt_disable();
274 } else { 264 else {
275 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); 265 printk(KERN_CRIT PFX
266 "Unexpected close, not stopping watchdog!\n");
276 wdt_ping(); 267 wdt_ping();
277 } 268 }
278 expect_close = 0; 269 expect_close = 0;
@@ -284,14 +275,12 @@ wdt_close(struct inode *inode, struct file *file)
284 * Notifier for system down 275 * Notifier for system down
285 */ 276 */
286 277
287static int 278static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
288wdt_notify_sys(struct notifier_block *this, unsigned long code,
289 void *unused) 279 void *unused)
290{ 280{
291 if (code == SYS_DOWN || code == SYS_HALT) { 281 if (code == SYS_DOWN || code == SYS_HALT)
292 /* Turn the WDT off */ 282 wdt_disable(); /* Turn the WDT off */
293 wdt_disable(); 283
294 }
295 return NOTIFY_DONE; 284 return NOTIFY_DONE;
296} 285}
297 286
@@ -303,7 +292,7 @@ static const struct file_operations wdt_fops = {
303 .owner = THIS_MODULE, 292 .owner = THIS_MODULE,
304 .llseek = no_llseek, 293 .llseek = no_llseek,
305 .write = wdt_write, 294 .write = wdt_write,
306 .ioctl = wdt_ioctl, 295 .unlocked_ioctl = wdt_ioctl,
307 .open = wdt_open, 296 .open = wdt_open,
308 .release = wdt_close, 297 .release = wdt_close,
309}; 298};
@@ -323,8 +312,7 @@ static struct notifier_block wdt_notifier = {
323 .notifier_call = wdt_notify_sys, 312 .notifier_call = wdt_notify_sys,
324}; 313};
325 314
326static int __init 315static int __init wdt_init(void)
327wdt_init(void)
328{ 316{
329 int ret; 317 int ret;
330 318
@@ -332,12 +320,13 @@ wdt_init(void)
332 320
333 if (wdt_set_heartbeat(timeout)) { 321 if (wdt_set_heartbeat(timeout)) {
334 wdt_set_heartbeat(WATCHDOG_TIMEOUT); 322 wdt_set_heartbeat(WATCHDOG_TIMEOUT);
335 printk (KERN_INFO PFX "timeout value must be 1<=timeout<=255, using %d\n", 323 printk(KERN_INFO PFX
336 WATCHDOG_TIMEOUT); 324 "timeout value must be 1 <= timeout <= 255, using %d\n",
325 WATCHDOG_TIMEOUT);
337 } 326 }
338 327
339 if (!request_region(wdt_io, 1, WATCHDOG_NAME)) { 328 if (!request_region(wdt_io, 1, WATCHDOG_NAME)) {
340 printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", 329 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n",
341 wdt_io); 330 wdt_io);
342 ret = -EIO; 331 ret = -EIO;
343 goto out; 332 goto out;
@@ -347,20 +336,22 @@ wdt_init(void)
347 336
348 ret = register_reboot_notifier(&wdt_notifier); 337 ret = register_reboot_notifier(&wdt_notifier);
349 if (ret != 0) { 338 if (ret != 0) {
350 printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 339 printk(KERN_ERR PFX
351 ret); 340 "cannot register reboot notifier (err=%d)\n", ret);
352 goto unreg_regions; 341 goto unreg_regions;
353 } 342 }
354 343
355 ret = misc_register(&wdt_miscdev); 344 ret = misc_register(&wdt_miscdev);
356 if (ret != 0) { 345 if (ret != 0) {
357 printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 346 printk(KERN_ERR PFX
358 WATCHDOG_MINOR, ret); 347 "cannot register miscdev on minor=%d (err=%d)\n",
348 WATCHDOG_MINOR, ret);
359 goto unreg_reboot; 349 goto unreg_reboot;
360 } 350 }
361 351
362 printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n", 352 printk(KERN_INFO PFX
363 timeout, nowayout); 353 "initialized. timeout=%d sec (nowayout=%d)\n",
354 timeout, nowayout);
364 355
365out: 356out:
366 return ret; 357 return ret;
@@ -371,12 +362,11 @@ unreg_regions:
371 goto out; 362 goto out;
372} 363}
373 364
374static void __exit 365static void __exit wdt_exit(void)
375wdt_exit(void)
376{ 366{
377 misc_deregister(&wdt_miscdev); 367 misc_deregister(&wdt_miscdev);
378 unregister_reboot_notifier(&wdt_notifier); 368 unregister_reboot_notifier(&wdt_notifier);
379 release_region(wdt_io,1); 369 release_region(wdt_io, 1);
380} 370}
381 371
382module_init(wdt_init); 372module_init(wdt_init);
diff --git a/drivers/watchdog/w83697hf_wdt.c b/drivers/watchdog/w83697hf_wdt.c
index 528b882420b6..445d30a01ed3 100644
--- a/drivers/watchdog/w83697hf_wdt.c
+++ b/drivers/watchdog/w83697hf_wdt.c
@@ -36,9 +36,9 @@
36#include <linux/reboot.h> 36#include <linux/reboot.h>
37#include <linux/init.h> 37#include <linux/init.h>
38#include <linux/spinlock.h> 38#include <linux/spinlock.h>
39#include <linux/io.h>
40#include <linux/uaccess.h>
39 41
40#include <asm/io.h>
41#include <asm/uaccess.h>
42#include <asm/system.h> 42#include <asm/system.h>
43 43
44#define WATCHDOG_NAME "w83697hf/hg WDT" 44#define WATCHDOG_NAME "w83697hf/hg WDT"
@@ -53,37 +53,43 @@ static DEFINE_SPINLOCK(io_lock);
53/* You must set this - there is no sane way to probe for this board. */ 53/* You must set this - there is no sane way to probe for this board. */
54static int wdt_io = 0x2e; 54static int wdt_io = 0x2e;
55module_param(wdt_io, int, 0); 55module_param(wdt_io, int, 0);
56MODULE_PARM_DESC(wdt_io, "w83697hf/hg WDT io port (default 0x2e, 0 = autodetect)"); 56MODULE_PARM_DESC(wdt_io,
57 "w83697hf/hg WDT io port (default 0x2e, 0 = autodetect)");
57 58
58static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ 59static int timeout = WATCHDOG_TIMEOUT; /* in seconds */
59module_param(timeout, int, 0); 60module_param(timeout, int, 0);
60MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=255 (default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); 61MODULE_PARM_DESC(timeout,
62 "Watchdog timeout in seconds. 1<= timeout <=255 (default="
63 __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
61 64
62static int nowayout = WATCHDOG_NOWAYOUT; 65static int nowayout = WATCHDOG_NOWAYOUT;
63module_param(nowayout, int, 0); 66module_param(nowayout, int, 0);
64MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 67MODULE_PARM_DESC(nowayout,
68 "Watchdog cannot be stopped once started (default="
69 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
65 70
66static int early_disable = WATCHDOG_EARLY_DISABLE; 71static int early_disable = WATCHDOG_EARLY_DISABLE;
67module_param(early_disable, int, 0); 72module_param(early_disable, int, 0);
68MODULE_PARM_DESC(early_disable, "Watchdog gets disabled at boot time (default=" __MODULE_STRING(WATCHDOG_EARLY_DISABLE) ")"); 73MODULE_PARM_DESC(early_disable,
74 "Watchdog gets disabled at boot time (default="
75 __MODULE_STRING(WATCHDOG_EARLY_DISABLE) ")");
69 76
70/* 77/*
71 * Kernel methods. 78 * Kernel methods.
72 */ 79 */
73 80
74#define W83697HF_EFER (wdt_io+0) /* Extended Function Enable Register */ 81#define W83697HF_EFER (wdt_io + 0) /* Extended Function Enable Register */
75#define W83697HF_EFIR (wdt_io+0) /* Extended Function Index Register (same as EFER) */ 82#define W83697HF_EFIR (wdt_io + 0) /* Extended Function Index Register
76#define W83697HF_EFDR (wdt_io+1) /* Extended Function Data Register */ 83 (same as EFER) */
84#define W83697HF_EFDR (wdt_io + 1) /* Extended Function Data Register */
77 85
78static inline void 86static inline void w83697hf_unlock(void)
79w83697hf_unlock(void)
80{ 87{
81 outb_p(0x87, W83697HF_EFER); /* Enter extended function mode */ 88 outb_p(0x87, W83697HF_EFER); /* Enter extended function mode */
82 outb_p(0x87, W83697HF_EFER); /* Again according to manual */ 89 outb_p(0x87, W83697HF_EFER); /* Again according to manual */
83} 90}
84 91
85static inline void 92static inline void w83697hf_lock(void)
86w83697hf_lock(void)
87{ 93{
88 outb_p(0xAA, W83697HF_EFER); /* Leave extended function mode */ 94 outb_p(0xAA, W83697HF_EFER); /* Leave extended function mode */
89} 95}
@@ -93,41 +99,36 @@ w83697hf_lock(void)
93 * w83697hf_write_timeout() must be called with the device unlocked. 99 * w83697hf_write_timeout() must be called with the device unlocked.
94 */ 100 */
95 101
96static unsigned char 102static unsigned char w83697hf_get_reg(unsigned char reg)
97w83697hf_get_reg(unsigned char reg)
98{ 103{
99 outb_p(reg, W83697HF_EFIR); 104 outb_p(reg, W83697HF_EFIR);
100 return inb_p(W83697HF_EFDR); 105 return inb_p(W83697HF_EFDR);
101} 106}
102 107
103static void 108static void w83697hf_set_reg(unsigned char reg, unsigned char data)
104w83697hf_set_reg(unsigned char reg, unsigned char data)
105{ 109{
106 outb_p(reg, W83697HF_EFIR); 110 outb_p(reg, W83697HF_EFIR);
107 outb_p(data, W83697HF_EFDR); 111 outb_p(data, W83697HF_EFDR);
108} 112}
109 113
110static void 114static void w83697hf_write_timeout(int timeout)
111w83697hf_write_timeout(int timeout)
112{ 115{
113 w83697hf_set_reg(0xF4, timeout); /* Write Timeout counter to CRF4 */ 116 /* Write Timeout counter to CRF4 */
117 w83697hf_set_reg(0xF4, timeout);
114} 118}
115 119
116static void 120static void w83697hf_select_wdt(void)
117w83697hf_select_wdt(void)
118{ 121{
119 w83697hf_unlock(); 122 w83697hf_unlock();
120 w83697hf_set_reg(0x07, 0x08); /* Switch to logic device 8 (GPIO2) */ 123 w83697hf_set_reg(0x07, 0x08); /* Switch to logic device 8 (GPIO2) */
121} 124}
122 125
123static inline void 126static inline void w83697hf_deselect_wdt(void)
124w83697hf_deselect_wdt(void)
125{ 127{
126 w83697hf_lock(); 128 w83697hf_lock();
127} 129}
128 130
129static void 131static void w83697hf_init(void)
130w83697hf_init(void)
131{ 132{
132 unsigned char bbuf; 133 unsigned char bbuf;
133 134
@@ -136,7 +137,9 @@ w83697hf_init(void)
136 bbuf = w83697hf_get_reg(0x29); 137 bbuf = w83697hf_get_reg(0x29);
137 bbuf &= ~0x60; 138 bbuf &= ~0x60;
138 bbuf |= 0x20; 139 bbuf |= 0x20;
139 w83697hf_set_reg(0x29, bbuf); /* Set pin 119 to WDTO# mode (= CR29, WDT0) */ 140
141 /* Set pin 119 to WDTO# mode (= CR29, WDT0) */
142 w83697hf_set_reg(0x29, bbuf);
140 143
141 bbuf = w83697hf_get_reg(0xF3); 144 bbuf = w83697hf_get_reg(0xF3);
142 bbuf &= ~0x04; 145 bbuf &= ~0x04;
@@ -145,8 +148,7 @@ w83697hf_init(void)
145 w83697hf_deselect_wdt(); 148 w83697hf_deselect_wdt();
146} 149}
147 150
148static void 151static void wdt_ping(void)
149wdt_ping(void)
150{ 152{
151 spin_lock(&io_lock); 153 spin_lock(&io_lock);
152 w83697hf_select_wdt(); 154 w83697hf_select_wdt();
@@ -157,8 +159,7 @@ wdt_ping(void)
157 spin_unlock(&io_lock); 159 spin_unlock(&io_lock);
158} 160}
159 161
160static void 162static void wdt_enable(void)
161wdt_enable(void)
162{ 163{
163 spin_lock(&io_lock); 164 spin_lock(&io_lock);
164 w83697hf_select_wdt(); 165 w83697hf_select_wdt();
@@ -170,8 +171,7 @@ wdt_enable(void)
170 spin_unlock(&io_lock); 171 spin_unlock(&io_lock);
171} 172}
172 173
173static void 174static void wdt_disable(void)
174wdt_disable(void)
175{ 175{
176 spin_lock(&io_lock); 176 spin_lock(&io_lock);
177 w83697hf_select_wdt(); 177 w83697hf_select_wdt();
@@ -183,8 +183,7 @@ wdt_disable(void)
183 spin_unlock(&io_lock); 183 spin_unlock(&io_lock);
184} 184}
185 185
186static unsigned char 186static unsigned char wdt_running(void)
187wdt_running(void)
188{ 187{
189 unsigned char t; 188 unsigned char t;
190 189
@@ -199,18 +198,17 @@ wdt_running(void)
199 return t; 198 return t;
200} 199}
201 200
202static int 201static int wdt_set_heartbeat(int t)
203wdt_set_heartbeat(int t)
204{ 202{
205 if ((t < 1) || (t > 255)) 203 if (t < 1 || t > 255)
206 return -EINVAL; 204 return -EINVAL;
207 205
208 timeout = t; 206 timeout = t;
209 return 0; 207 return 0;
210} 208}
211 209
212static ssize_t 210static ssize_t wdt_write(struct file *file, const char __user *buf,
213wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) 211 size_t count, loff_t *ppos)
214{ 212{
215 if (count) { 213 if (count) {
216 if (!nowayout) { 214 if (!nowayout) {
@@ -220,7 +218,7 @@ wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
220 218
221 for (i = 0; i != count; i++) { 219 for (i = 0; i != count; i++) {
222 char c; 220 char c;
223 if (get_user(c, buf+i)) 221 if (get_user(c, buf + i))
224 return -EFAULT; 222 return -EFAULT;
225 if (c == 'V') 223 if (c == 'V')
226 expect_close = 42; 224 expect_close = 42;
@@ -231,15 +229,14 @@ wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
231 return count; 229 return count;
232} 230}
233 231
234static int 232static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
235wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
236 unsigned long arg)
237{ 233{
238 void __user *argp = (void __user *)arg; 234 void __user *argp = (void __user *)arg;
239 int __user *p = argp; 235 int __user *p = argp;
240 int new_timeout; 236 int new_timeout;
241 static struct watchdog_info ident = { 237 static const struct watchdog_info ident = {
242 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, 238 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT
239 | WDIOF_MAGICCLOSE,
243 .firmware_version = 1, 240 .firmware_version = 1,
244 .identity = "W83697HF WDT", 241 .identity = "W83697HF WDT",
245 }; 242 };
@@ -254,21 +251,6 @@ wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
254 case WDIOC_GETBOOTSTATUS: 251 case WDIOC_GETBOOTSTATUS:
255 return put_user(0, p); 252 return put_user(0, p);
256 253
257 case WDIOC_KEEPALIVE:
258 wdt_ping();
259 break;
260
261 case WDIOC_SETTIMEOUT:
262 if (get_user(new_timeout, p))
263 return -EFAULT;
264 if (wdt_set_heartbeat(new_timeout))
265 return -EINVAL;
266 wdt_ping();
267 /* Fall */
268
269 case WDIOC_GETTIMEOUT:
270 return put_user(timeout, p);
271
272 case WDIOC_SETOPTIONS: 254 case WDIOC_SETOPTIONS:
273 { 255 {
274 int options, retval = -EINVAL; 256 int options, retval = -EINVAL;
@@ -289,14 +271,28 @@ wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
289 return retval; 271 return retval;
290 } 272 }
291 273
274 case WDIOC_KEEPALIVE:
275 wdt_ping();
276 break;
277
278 case WDIOC_SETTIMEOUT:
279 if (get_user(new_timeout, p))
280 return -EFAULT;
281 if (wdt_set_heartbeat(new_timeout))
282 return -EINVAL;
283 wdt_ping();
284 /* Fall */
285
286 case WDIOC_GETTIMEOUT:
287 return put_user(timeout, p);
288
292 default: 289 default:
293 return -ENOTTY; 290 return -ENOTTY;
294 } 291 }
295 return 0; 292 return 0;
296} 293}
297 294
298static int 295static int wdt_open(struct inode *inode, struct file *file)
299wdt_open(struct inode *inode, struct file *file)
300{ 296{
301 if (test_and_set_bit(0, &wdt_is_open)) 297 if (test_and_set_bit(0, &wdt_is_open))
302 return -EBUSY; 298 return -EBUSY;
@@ -308,13 +304,13 @@ wdt_open(struct inode *inode, struct file *file)
308 return nonseekable_open(inode, file); 304 return nonseekable_open(inode, file);
309} 305}
310 306
311static int 307static int wdt_close(struct inode *inode, struct file *file)
312wdt_close(struct inode *inode, struct file *file)
313{ 308{
314 if (expect_close == 42) { 309 if (expect_close == 42)
315 wdt_disable(); 310 wdt_disable();
316 } else { 311 else {
317 printk (KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); 312 printk(KERN_CRIT PFX
313 "Unexpected close, not stopping watchdog!\n");
318 wdt_ping(); 314 wdt_ping();
319 } 315 }
320 expect_close = 0; 316 expect_close = 0;
@@ -326,14 +322,12 @@ wdt_close(struct inode *inode, struct file *file)
326 * Notifier for system down 322 * Notifier for system down
327 */ 323 */
328 324
329static int 325static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
330wdt_notify_sys(struct notifier_block *this, unsigned long code,
331 void *unused) 326 void *unused)
332{ 327{
333 if (code == SYS_DOWN || code == SYS_HALT) { 328 if (code == SYS_DOWN || code == SYS_HALT)
334 /* Turn the WDT off */ 329 wdt_disable(); /* Turn the WDT off */
335 wdt_disable(); 330
336 }
337 return NOTIFY_DONE; 331 return NOTIFY_DONE;
338} 332}
339 333
@@ -345,7 +339,7 @@ static const struct file_operations wdt_fops = {
345 .owner = THIS_MODULE, 339 .owner = THIS_MODULE,
346 .llseek = no_llseek, 340 .llseek = no_llseek,
347 .write = wdt_write, 341 .write = wdt_write,
348 .ioctl = wdt_ioctl, 342 .unlocked_ioctl = wdt_ioctl,
349 .open = wdt_open, 343 .open = wdt_open,
350 .release = wdt_close, 344 .release = wdt_close,
351}; 345};
@@ -365,36 +359,38 @@ static struct notifier_block wdt_notifier = {
365 .notifier_call = wdt_notify_sys, 359 .notifier_call = wdt_notify_sys,
366}; 360};
367 361
368static int 362static int w83697hf_check_wdt(void)
369w83697hf_check_wdt(void)
370{ 363{
371 if (!request_region(wdt_io, 2, WATCHDOG_NAME)) { 364 if (!request_region(wdt_io, 2, WATCHDOG_NAME)) {
372 printk (KERN_ERR PFX "I/O address 0x%x already in use\n", wdt_io); 365 printk(KERN_ERR PFX
366 "I/O address 0x%x already in use\n", wdt_io);
373 return -EIO; 367 return -EIO;
374 } 368 }
375 369
376 printk (KERN_DEBUG PFX "Looking for watchdog at address 0x%x\n", wdt_io); 370 printk(KERN_DEBUG PFX
371 "Looking for watchdog at address 0x%x\n", wdt_io);
377 w83697hf_unlock(); 372 w83697hf_unlock();
378 if (w83697hf_get_reg(0x20) == 0x60) { 373 if (w83697hf_get_reg(0x20) == 0x60) {
379 printk (KERN_INFO PFX "watchdog found at address 0x%x\n", wdt_io); 374 printk(KERN_INFO PFX
375 "watchdog found at address 0x%x\n", wdt_io);
380 w83697hf_lock(); 376 w83697hf_lock();
381 return 0; 377 return 0;
382 } 378 }
383 w83697hf_lock(); /* Reprotect in case it was a compatible device */ 379 /* Reprotect in case it was a compatible device */
380 w83697hf_lock();
384 381
385 printk (KERN_INFO PFX "watchdog not found at address 0x%x\n", wdt_io); 382 printk(KERN_INFO PFX "watchdog not found at address 0x%x\n", wdt_io);
386 release_region(wdt_io, 2); 383 release_region(wdt_io, 2);
387 return -EIO; 384 return -EIO;
388} 385}
389 386
390static int w83697hf_ioports[] = { 0x2e, 0x4e, 0x00 }; 387static int w83697hf_ioports[] = { 0x2e, 0x4e, 0x00 };
391 388
392static int __init 389static int __init wdt_init(void)
393wdt_init(void)
394{ 390{
395 int ret, i, found = 0; 391 int ret, i, found = 0;
396 392
397 printk (KERN_INFO PFX "WDT driver for W83697HF/HG initializing\n"); 393 printk(KERN_INFO PFX "WDT driver for W83697HF/HG initializing\n");
398 394
399 if (wdt_io == 0) { 395 if (wdt_io == 0) {
400 /* we will autodetect the W83697HF/HG watchdog */ 396 /* we will autodetect the W83697HF/HG watchdog */
@@ -409,7 +405,7 @@ wdt_init(void)
409 } 405 }
410 406
411 if (!found) { 407 if (!found) {
412 printk (KERN_ERR PFX "No W83697HF/HG could be found\n"); 408 printk(KERN_ERR PFX "No W83697HF/HG could be found\n");
413 ret = -EIO; 409 ret = -EIO;
414 goto out; 410 goto out;
415 } 411 }
@@ -417,31 +413,33 @@ wdt_init(void)
417 w83697hf_init(); 413 w83697hf_init();
418 if (early_disable) { 414 if (early_disable) {
419 if (wdt_running()) 415 if (wdt_running())
420 printk (KERN_WARNING PFX "Stopping previously enabled watchdog until userland kicks in\n"); 416 printk(KERN_WARNING PFX "Stopping previously enabled watchdog until userland kicks in\n");
421 wdt_disable(); 417 wdt_disable();
422 } 418 }
423 419
424 if (wdt_set_heartbeat(timeout)) { 420 if (wdt_set_heartbeat(timeout)) {
425 wdt_set_heartbeat(WATCHDOG_TIMEOUT); 421 wdt_set_heartbeat(WATCHDOG_TIMEOUT);
426 printk (KERN_INFO PFX "timeout value must be 1<=timeout<=255, using %d\n", 422 printk(KERN_INFO PFX
427 WATCHDOG_TIMEOUT); 423 "timeout value must be 1 <= timeout <= 255, using %d\n",
424 WATCHDOG_TIMEOUT);
428 } 425 }
429 426
430 ret = register_reboot_notifier(&wdt_notifier); 427 ret = register_reboot_notifier(&wdt_notifier);
431 if (ret != 0) { 428 if (ret != 0) {
432 printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 429 printk(KERN_ERR PFX
433 ret); 430 "cannot register reboot notifier (err=%d)\n", ret);
434 goto unreg_regions; 431 goto unreg_regions;
435 } 432 }
436 433
437 ret = misc_register(&wdt_miscdev); 434 ret = misc_register(&wdt_miscdev);
438 if (ret != 0) { 435 if (ret != 0) {
439 printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 436 printk(KERN_ERR PFX
440 WATCHDOG_MINOR, ret); 437 "cannot register miscdev on minor=%d (err=%d)\n",
438 WATCHDOG_MINOR, ret);
441 goto unreg_reboot; 439 goto unreg_reboot;
442 } 440 }
443 441
444 printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n", 442 printk(KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n",
445 timeout, nowayout); 443 timeout, nowayout);
446 444
447out: 445out:
@@ -453,8 +451,7 @@ unreg_regions:
453 goto out; 451 goto out;
454} 452}
455 453
456static void __exit 454static void __exit wdt_exit(void)
457wdt_exit(void)
458{ 455{
459 misc_deregister(&wdt_miscdev); 456 misc_deregister(&wdt_miscdev);
460 unregister_reboot_notifier(&wdt_notifier); 457 unregister_reboot_notifier(&wdt_notifier);
diff --git a/drivers/watchdog/w83877f_wdt.c b/drivers/watchdog/w83877f_wdt.c
index f510a3a595e6..24587d2060c4 100644
--- a/drivers/watchdog/w83877f_wdt.c
+++ b/drivers/watchdog/w83877f_wdt.c
@@ -23,13 +23,16 @@
23 * Added KERN_* tags to printks 23 * Added KERN_* tags to printks
24 * add CONFIG_WATCHDOG_NOWAYOUT support 24 * add CONFIG_WATCHDOG_NOWAYOUT support
25 * fix possible wdt_is_open race 25 * fix possible wdt_is_open race
26 * changed watchdog_info to correctly reflect what the driver offers 26 * changed watchdog_info to correctly reflect what
27 * added WDIOC_GETSTATUS, WDIOC_GETBOOTSTATUS, WDIOC_SETTIMEOUT, 27 * the driver offers
28 * added WDIOC_GETSTATUS, WDIOC_GETBOOTSTATUS,
29 * WDIOC_SETTIMEOUT,
28 * WDIOC_GETTIMEOUT, and WDIOC_SETOPTIONS ioctls 30 * WDIOC_GETTIMEOUT, and WDIOC_SETOPTIONS ioctls
29 * 09/8 - 2003 [wim@iguana.be] cleanup of trailing spaces 31 * 09/8 - 2003 [wim@iguana.be] cleanup of trailing spaces
30 * added extra printk's for startup problems 32 * added extra printk's for startup problems
31 * use module_param 33 * use module_param
32 * made timeout (the emulated heartbeat) a module_param 34 * made timeout (the emulated heartbeat) a
35 * module_param
33 * made the keepalive ping an internal subroutine 36 * made the keepalive ping an internal subroutine
34 * 37 *
35 * This WDT driver is different from most other Linux WDT 38 * This WDT driver is different from most other Linux WDT
@@ -51,8 +54,8 @@
51#include <linux/notifier.h> 54#include <linux/notifier.h>
52#include <linux/reboot.h> 55#include <linux/reboot.h>
53#include <linux/init.h> 56#include <linux/init.h>
54#include <asm/io.h> 57#include <linux/io.h>
55#include <asm/uaccess.h> 58#include <linux/uaccess.h>
56#include <asm/system.h> 59#include <asm/system.h>
57 60
58#define OUR_NAME "w83877f_wdt" 61#define OUR_NAME "w83877f_wdt"
@@ -80,14 +83,19 @@
80 */ 83 */
81 84
82#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ 85#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */
83static int timeout = WATCHDOG_TIMEOUT; /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */ 86/* in seconds, will be multiplied by HZ to get seconds to wait for a ping */
87static int timeout = WATCHDOG_TIMEOUT;
84module_param(timeout, int, 0); 88module_param(timeout, int, 0);
85MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); 89MODULE_PARM_DESC(timeout,
90 "Watchdog timeout in seconds. (1<=timeout<=3600, default="
91 __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
86 92
87 93
88static int nowayout = WATCHDOG_NOWAYOUT; 94static int nowayout = WATCHDOG_NOWAYOUT;
89module_param(nowayout, int, 0); 95module_param(nowayout, int, 0);
90MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 96MODULE_PARM_DESC(nowayout,
97 "Watchdog cannot be stopped once started (default="
98 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
91 99
92static void wdt_timer_ping(unsigned long); 100static void wdt_timer_ping(unsigned long);
93static DEFINE_TIMER(timer, wdt_timer_ping, 0, 0); 101static DEFINE_TIMER(timer, wdt_timer_ping, 0, 0);
@@ -105,8 +113,7 @@ static void wdt_timer_ping(unsigned long data)
105 /* If we got a heartbeat pulse within the WDT_US_INTERVAL 113 /* If we got a heartbeat pulse within the WDT_US_INTERVAL
106 * we agree to ping the WDT 114 * we agree to ping the WDT
107 */ 115 */
108 if(time_before(jiffies, next_heartbeat)) 116 if (time_before(jiffies, next_heartbeat)) {
109 {
110 /* Ping the WDT */ 117 /* Ping the WDT */
111 spin_lock(&wdt_spinlock); 118 spin_lock(&wdt_spinlock);
112 119
@@ -118,9 +125,9 @@ static void wdt_timer_ping(unsigned long data)
118 125
119 spin_unlock(&wdt_spinlock); 126 spin_unlock(&wdt_spinlock);
120 127
121 } else { 128 } else
122 printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); 129 printk(KERN_WARNING PFX
123 } 130 "Heartbeat lost! Will not ping the watchdog\n");
124} 131}
125 132
126/* 133/*
@@ -181,22 +188,21 @@ static void wdt_keepalive(void)
181 * /dev/watchdog handling 188 * /dev/watchdog handling
182 */ 189 */
183 190
184static ssize_t fop_write(struct file * file, const char __user * buf, size_t count, loff_t * ppos) 191static ssize_t fop_write(struct file *file, const char __user *buf,
192 size_t count, loff_t *ppos)
185{ 193{
186 /* See if we got the magic character 'V' and reload the timer */ 194 /* See if we got the magic character 'V' and reload the timer */
187 if(count) 195 if (count) {
188 { 196 if (!nowayout) {
189 if (!nowayout)
190 {
191 size_t ofs; 197 size_t ofs;
192 198
193 /* note: just in case someone wrote the magic character 199 /* note: just in case someone wrote the magic
194 * five months ago... */ 200 character five months ago... */
195 wdt_expect_close = 0; 201 wdt_expect_close = 0;
196 202
197 /* scan to see whether or not we got the magic character */ 203 /* scan to see whether or not we got the
198 for(ofs = 0; ofs != count; ofs++) 204 magic character */
199 { 205 for (ofs = 0; ofs != count; ofs++) {
200 char c; 206 char c;
201 if (get_user(c, buf + ofs)) 207 if (get_user(c, buf + ofs))
202 return -EFAULT; 208 return -EFAULT;
@@ -211,10 +217,10 @@ static ssize_t fop_write(struct file * file, const char __user * buf, size_t cou
211 return count; 217 return count;
212} 218}
213 219
214static int fop_open(struct inode * inode, struct file * file) 220static int fop_open(struct inode *inode, struct file *file)
215{ 221{
216 /* Just in case we're already talking to someone... */ 222 /* Just in case we're already talking to someone... */
217 if(test_and_set_bit(0, &wdt_is_open)) 223 if (test_and_set_bit(0, &wdt_is_open))
218 return -EBUSY; 224 return -EBUSY;
219 225
220 /* Good, fire up the show */ 226 /* Good, fire up the show */
@@ -222,78 +228,78 @@ static int fop_open(struct inode * inode, struct file * file)
222 return nonseekable_open(inode, file); 228 return nonseekable_open(inode, file);
223} 229}
224 230
225static int fop_close(struct inode * inode, struct file * file) 231static int fop_close(struct inode *inode, struct file *file)
226{ 232{
227 if(wdt_expect_close == 42) 233 if (wdt_expect_close == 42)
228 wdt_turnoff(); 234 wdt_turnoff();
229 else { 235 else {
230 del_timer(&timer); 236 del_timer(&timer);
231 printk(KERN_CRIT PFX "device file closed unexpectedly. Will not stop the WDT!\n"); 237 printk(KERN_CRIT PFX
238 "device file closed unexpectedly. Will not stop the WDT!\n");
232 } 239 }
233 clear_bit(0, &wdt_is_open); 240 clear_bit(0, &wdt_is_open);
234 wdt_expect_close = 0; 241 wdt_expect_close = 0;
235 return 0; 242 return 0;
236} 243}
237 244
238static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 245static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
239 unsigned long arg)
240{ 246{
241 void __user *argp = (void __user *)arg; 247 void __user *argp = (void __user *)arg;
242 int __user *p = argp; 248 int __user *p = argp;
243 static struct watchdog_info ident= 249 static const struct watchdog_info ident = {
244 { 250 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT
245 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, 251 | WDIOF_MAGICCLOSE,
246 .firmware_version = 1, 252 .firmware_version = 1,
247 .identity = "W83877F", 253 .identity = "W83877F",
248 }; 254 };
249 255
250 switch(cmd) 256 switch (cmd) {
257 case WDIOC_GETSUPPORT:
258 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
259 case WDIOC_GETSTATUS:
260 case WDIOC_GETBOOTSTATUS:
261 return put_user(0, p);
262 case WDIOC_SETOPTIONS:
251 { 263 {
252 default: 264 int new_options, retval = -EINVAL;
253 return -ENOTTY;
254 case WDIOC_GETSUPPORT:
255 return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
256 case WDIOC_GETSTATUS:
257 case WDIOC_GETBOOTSTATUS:
258 return put_user(0, p);
259 case WDIOC_KEEPALIVE:
260 wdt_keepalive();
261 return 0;
262 case WDIOC_SETOPTIONS:
263 {
264 int new_options, retval = -EINVAL;
265
266 if(get_user(new_options, p))
267 return -EFAULT;
268
269 if(new_options & WDIOS_DISABLECARD) {
270 wdt_turnoff();
271 retval = 0;
272 }
273 265
274 if(new_options & WDIOS_ENABLECARD) { 266 if (get_user(new_options, p))
275 wdt_startup(); 267 return -EFAULT;
276 retval = 0;
277 }
278 268
279 return retval; 269 if (new_options & WDIOS_DISABLECARD) {
270 wdt_turnoff();
271 retval = 0;
280 } 272 }
281 case WDIOC_SETTIMEOUT:
282 {
283 int new_timeout;
284 273
285 if(get_user(new_timeout, p)) 274 if (new_options & WDIOS_ENABLECARD) {
286 return -EFAULT; 275 wdt_startup();
276 retval = 0;
277 }
287 278
288 if(new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */ 279 return retval;
289 return -EINVAL; 280 }
281 case WDIOC_KEEPALIVE:
282 wdt_keepalive();
283 return 0;
284 case WDIOC_SETTIMEOUT:
285 {
286 int new_timeout;
290 287
291 timeout = new_timeout; 288 if (get_user(new_timeout, p))
292 wdt_keepalive(); 289 return -EFAULT;
293 /* Fall through */ 290
294 } 291 /* arbitrary upper limit */
295 case WDIOC_GETTIMEOUT: 292 if (new_timeout < 1 || new_timeout > 3600)
296 return put_user(timeout, p); 293 return -EINVAL;
294
295 timeout = new_timeout;
296 wdt_keepalive();
297 /* Fall through */
298 }
299 case WDIOC_GETTIMEOUT:
300 return put_user(timeout, p);
301 default:
302 return -ENOTTY;
297 } 303 }
298} 304}
299 305
@@ -303,7 +309,7 @@ static const struct file_operations wdt_fops = {
303 .write = fop_write, 309 .write = fop_write,
304 .open = fop_open, 310 .open = fop_open,
305 .release = fop_close, 311 .release = fop_close,
306 .ioctl = fop_ioctl, 312 .unlocked_ioctl = fop_ioctl,
307}; 313};
308 314
309static struct miscdevice wdt_miscdev = { 315static struct miscdevice wdt_miscdev = {
@@ -319,7 +325,7 @@ static struct miscdevice wdt_miscdev = {
319static int wdt_notify_sys(struct notifier_block *this, unsigned long code, 325static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
320 void *unused) 326 void *unused)
321{ 327{
322 if(code==SYS_DOWN || code==SYS_HALT) 328 if (code == SYS_DOWN || code == SYS_HALT)
323 wdt_turnoff(); 329 wdt_turnoff();
324 return NOTIFY_DONE; 330 return NOTIFY_DONE;
325} 331}
@@ -329,8 +335,7 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
329 * turn the timebomb registers off. 335 * turn the timebomb registers off.
330 */ 336 */
331 337
332static struct notifier_block wdt_notifier= 338static struct notifier_block wdt_notifier = {
333{
334 .notifier_call = wdt_notify_sys, 339 .notifier_call = wdt_notify_sys,
335}; 340};
336 341
@@ -342,31 +347,29 @@ static void __exit w83877f_wdt_unload(void)
342 misc_deregister(&wdt_miscdev); 347 misc_deregister(&wdt_miscdev);
343 348
344 unregister_reboot_notifier(&wdt_notifier); 349 unregister_reboot_notifier(&wdt_notifier);
345 release_region(WDT_PING,1); 350 release_region(WDT_PING, 1);
346 release_region(ENABLE_W83877F_PORT,2); 351 release_region(ENABLE_W83877F_PORT, 2);
347} 352}
348 353
349static int __init w83877f_wdt_init(void) 354static int __init w83877f_wdt_init(void)
350{ 355{
351 int rc = -EBUSY; 356 int rc = -EBUSY;
352 357
353 if(timeout < 1 || timeout > 3600) /* arbitrary upper limit */ 358 if (timeout < 1 || timeout > 3600) { /* arbitrary upper limit */
354 {
355 timeout = WATCHDOG_TIMEOUT; 359 timeout = WATCHDOG_TIMEOUT;
356 printk(KERN_INFO PFX "timeout value must be 1<=x<=3600, using %d\n", 360 printk(KERN_INFO PFX
357 timeout); 361 "timeout value must be 1 <= x <= 3600, using %d\n",
362 timeout);
358 } 363 }
359 364
360 if (!request_region(ENABLE_W83877F_PORT, 2, "W83877F WDT")) 365 if (!request_region(ENABLE_W83877F_PORT, 2, "W83877F WDT")) {
361 {
362 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", 366 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n",
363 ENABLE_W83877F_PORT); 367 ENABLE_W83877F_PORT);
364 rc = -EIO; 368 rc = -EIO;
365 goto err_out; 369 goto err_out;
366 } 370 }
367 371
368 if (!request_region(WDT_PING, 1, "W8387FF WDT")) 372 if (!request_region(WDT_PING, 1, "W8387FF WDT")) {
369 {
370 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", 373 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n",
371 WDT_PING); 374 WDT_PING);
372 rc = -EIO; 375 rc = -EIO;
@@ -374,22 +377,22 @@ static int __init w83877f_wdt_init(void)
374 } 377 }
375 378
376 rc = register_reboot_notifier(&wdt_notifier); 379 rc = register_reboot_notifier(&wdt_notifier);
377 if (rc) 380 if (rc) {
378 { 381 printk(KERN_ERR PFX
379 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 382 "cannot register reboot notifier (err=%d)\n", rc);
380 rc);
381 goto err_out_region2; 383 goto err_out_region2;
382 } 384 }
383 385
384 rc = misc_register(&wdt_miscdev); 386 rc = misc_register(&wdt_miscdev);
385 if (rc) 387 if (rc) {
386 { 388 printk(KERN_ERR PFX
387 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 389 "cannot register miscdev on minor=%d (err=%d)\n",
388 wdt_miscdev.minor, rc); 390 wdt_miscdev.minor, rc);
389 goto err_out_reboot; 391 goto err_out_reboot;
390 } 392 }
391 393
392 printk(KERN_INFO PFX "WDT driver for W83877F initialised. timeout=%d sec (nowayout=%d)\n", 394 printk(KERN_INFO PFX
395 "WDT driver for W83877F initialised. timeout=%d sec (nowayout=%d)\n",
393 timeout, nowayout); 396 timeout, nowayout);
394 397
395 return 0; 398 return 0;
@@ -397,9 +400,9 @@ static int __init w83877f_wdt_init(void)
397err_out_reboot: 400err_out_reboot:
398 unregister_reboot_notifier(&wdt_notifier); 401 unregister_reboot_notifier(&wdt_notifier);
399err_out_region2: 402err_out_region2:
400 release_region(WDT_PING,1); 403 release_region(WDT_PING, 1);
401err_out_region1: 404err_out_region1:
402 release_region(ENABLE_W83877F_PORT,2); 405 release_region(ENABLE_W83877F_PORT, 2);
403err_out: 406err_out:
404 return rc; 407 return rc;
405} 408}
diff --git a/drivers/watchdog/w83977f_wdt.c b/drivers/watchdog/w83977f_wdt.c
index b209bcd7f789..2525da5080ca 100644
--- a/drivers/watchdog/w83977f_wdt.c
+++ b/drivers/watchdog/w83977f_wdt.c
@@ -26,10 +26,10 @@
26#include <linux/watchdog.h> 26#include <linux/watchdog.h>
27#include <linux/notifier.h> 27#include <linux/notifier.h>
28#include <linux/reboot.h> 28#include <linux/reboot.h>
29#include <linux/uaccess.h>
30#include <linux/io.h>
29 31
30#include <asm/io.h>
31#include <asm/system.h> 32#include <asm/system.h>
32#include <asm/uaccess.h>
33 33
34#define WATCHDOG_VERSION "1.00" 34#define WATCHDOG_VERSION "1.00"
35#define WATCHDOG_NAME "W83977F WDT" 35#define WATCHDOG_NAME "W83977F WDT"
@@ -53,13 +53,17 @@ static char expect_close;
53static DEFINE_SPINLOCK(spinlock); 53static DEFINE_SPINLOCK(spinlock);
54 54
55module_param(timeout, int, 0); 55module_param(timeout, int, 0);
56MODULE_PARM_DESC(timeout,"Watchdog timeout in seconds (15..7635), default=" __MODULE_STRING(DEFAULT_TIMEOUT) ")"); 56MODULE_PARM_DESC(timeout,
57 "Watchdog timeout in seconds (15..7635), default="
58 __MODULE_STRING(DEFAULT_TIMEOUT) ")");
57module_param(testmode, int, 0); 59module_param(testmode, int, 0);
58MODULE_PARM_DESC(testmode,"Watchdog testmode (1 = no reboot), default=0"); 60MODULE_PARM_DESC(testmode, "Watchdog testmode (1 = no reboot), default=0");
59 61
60static int nowayout = WATCHDOG_NOWAYOUT; 62static int nowayout = WATCHDOG_NOWAYOUT;
61module_param(nowayout, int, 0); 63module_param(nowayout, int, 0);
62MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 64MODULE_PARM_DESC(nowayout,
65 "Watchdog cannot be stopped once started (default="
66 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
63 67
64/* 68/*
65 * Start the watchdog 69 * Start the watchdog
@@ -72,8 +76,8 @@ static int wdt_start(void)
72 spin_lock_irqsave(&spinlock, flags); 76 spin_lock_irqsave(&spinlock, flags);
73 77
74 /* Unlock the SuperIO chip */ 78 /* Unlock the SuperIO chip */
75 outb_p(UNLOCK_DATA,IO_INDEX_PORT); 79 outb_p(UNLOCK_DATA, IO_INDEX_PORT);
76 outb_p(UNLOCK_DATA,IO_INDEX_PORT); 80 outb_p(UNLOCK_DATA, IO_INDEX_PORT);
77 81
78 /* 82 /*
79 * Select device Aux2 (device=8) to set watchdog regs F2, F3 and F4. 83 * Select device Aux2 (device=8) to set watchdog regs F2, F3 and F4.
@@ -81,50 +85,49 @@ static int wdt_start(void)
81 * F3 is set to enable watchdog LED blink at timeout. 85 * F3 is set to enable watchdog LED blink at timeout.
82 * F4 is used to just clear the TIMEOUT'ed state (bit 0). 86 * F4 is used to just clear the TIMEOUT'ed state (bit 0).
83 */ 87 */
84 outb_p(DEVICE_REGISTER,IO_INDEX_PORT); 88 outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
85 outb_p(0x08,IO_DATA_PORT); 89 outb_p(0x08, IO_DATA_PORT);
86 outb_p(0xF2,IO_INDEX_PORT); 90 outb_p(0xF2, IO_INDEX_PORT);
87 outb_p(timeoutW,IO_DATA_PORT); 91 outb_p(timeoutW, IO_DATA_PORT);
88 outb_p(0xF3,IO_INDEX_PORT); 92 outb_p(0xF3, IO_INDEX_PORT);
89 outb_p(0x08,IO_DATA_PORT); 93 outb_p(0x08, IO_DATA_PORT);
90 outb_p(0xF4,IO_INDEX_PORT); 94 outb_p(0xF4, IO_INDEX_PORT);
91 outb_p(0x00,IO_DATA_PORT); 95 outb_p(0x00, IO_DATA_PORT);
92 96
93 /* Set device Aux2 active */ 97 /* Set device Aux2 active */
94 outb_p(0x30,IO_INDEX_PORT); 98 outb_p(0x30, IO_INDEX_PORT);
95 outb_p(0x01,IO_DATA_PORT); 99 outb_p(0x01, IO_DATA_PORT);
96 100
97 /* 101 /*
98 * Select device Aux1 (dev=7) to set GP16 as the watchdog output 102 * Select device Aux1 (dev=7) to set GP16 as the watchdog output
99 * (in reg E6) and GP13 as the watchdog LED output (in reg E3). 103 * (in reg E6) and GP13 as the watchdog LED output (in reg E3).
100 * Map GP16 at pin 119. 104 * Map GP16 at pin 119.
101 * In test mode watch the bit 0 on F4 to indicate "triggered" or 105 * In test mode watch the bit 0 on F4 to indicate "triggered" or
102 * check watchdog LED on SBC. 106 * check watchdog LED on SBC.
103 */ 107 */
104 outb_p(DEVICE_REGISTER,IO_INDEX_PORT); 108 outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
105 outb_p(0x07,IO_DATA_PORT); 109 outb_p(0x07, IO_DATA_PORT);
106 if (!testmode) 110 if (!testmode) {
107 {
108 unsigned pin_map; 111 unsigned pin_map;
109 112
110 outb_p(0xE6,IO_INDEX_PORT); 113 outb_p(0xE6, IO_INDEX_PORT);
111 outb_p(0x0A,IO_DATA_PORT); 114 outb_p(0x0A, IO_DATA_PORT);
112 outb_p(0x2C,IO_INDEX_PORT); 115 outb_p(0x2C, IO_INDEX_PORT);
113 pin_map = inb_p(IO_DATA_PORT); 116 pin_map = inb_p(IO_DATA_PORT);
114 pin_map |= 0x10; 117 pin_map |= 0x10;
115 pin_map &= ~(0x20); 118 pin_map &= ~(0x20);
116 outb_p(0x2C,IO_INDEX_PORT); 119 outb_p(0x2C, IO_INDEX_PORT);
117 outb_p(pin_map,IO_DATA_PORT); 120 outb_p(pin_map, IO_DATA_PORT);
118 } 121 }
119 outb_p(0xE3,IO_INDEX_PORT); 122 outb_p(0xE3, IO_INDEX_PORT);
120 outb_p(0x08,IO_DATA_PORT); 123 outb_p(0x08, IO_DATA_PORT);
121 124
122 /* Set device Aux1 active */ 125 /* Set device Aux1 active */
123 outb_p(0x30,IO_INDEX_PORT); 126 outb_p(0x30, IO_INDEX_PORT);
124 outb_p(0x01,IO_DATA_PORT); 127 outb_p(0x01, IO_DATA_PORT);
125 128
126 /* Lock the SuperIO chip */ 129 /* Lock the SuperIO chip */
127 outb_p(LOCK_DATA,IO_INDEX_PORT); 130 outb_p(LOCK_DATA, IO_INDEX_PORT);
128 131
129 spin_unlock_irqrestore(&spinlock, flags); 132 spin_unlock_irqrestore(&spinlock, flags);
130 133
@@ -144,42 +147,41 @@ static int wdt_stop(void)
144 spin_lock_irqsave(&spinlock, flags); 147 spin_lock_irqsave(&spinlock, flags);
145 148
146 /* Unlock the SuperIO chip */ 149 /* Unlock the SuperIO chip */
147 outb_p(UNLOCK_DATA,IO_INDEX_PORT); 150 outb_p(UNLOCK_DATA, IO_INDEX_PORT);
148 outb_p(UNLOCK_DATA,IO_INDEX_PORT); 151 outb_p(UNLOCK_DATA, IO_INDEX_PORT);
149 152
150 /* 153 /*
151 * Select device Aux2 (device=8) to set watchdog regs F2, F3 and F4. 154 * Select device Aux2 (device=8) to set watchdog regs F2, F3 and F4.
152 * F2 is reset to its default value (watchdog timer disabled). 155 * F2 is reset to its default value (watchdog timer disabled).
153 * F3 is reset to its default state. 156 * F3 is reset to its default state.
154 * F4 clears the TIMEOUT'ed state (bit 0) - back to default. 157 * F4 clears the TIMEOUT'ed state (bit 0) - back to default.
155 */ 158 */
156 outb_p(DEVICE_REGISTER,IO_INDEX_PORT); 159 outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
157 outb_p(0x08,IO_DATA_PORT); 160 outb_p(0x08, IO_DATA_PORT);
158 outb_p(0xF2,IO_INDEX_PORT); 161 outb_p(0xF2, IO_INDEX_PORT);
159 outb_p(0xFF,IO_DATA_PORT); 162 outb_p(0xFF, IO_DATA_PORT);
160 outb_p(0xF3,IO_INDEX_PORT); 163 outb_p(0xF3, IO_INDEX_PORT);
161 outb_p(0x00,IO_DATA_PORT); 164 outb_p(0x00, IO_DATA_PORT);
162 outb_p(0xF4,IO_INDEX_PORT); 165 outb_p(0xF4, IO_INDEX_PORT);
163 outb_p(0x00,IO_DATA_PORT); 166 outb_p(0x00, IO_DATA_PORT);
164 outb_p(0xF2,IO_INDEX_PORT); 167 outb_p(0xF2, IO_INDEX_PORT);
165 outb_p(0x00,IO_DATA_PORT); 168 outb_p(0x00, IO_DATA_PORT);
166 169
167 /* 170 /*
168 * Select device Aux1 (dev=7) to set GP16 (in reg E6) and 171 * Select device Aux1 (dev=7) to set GP16 (in reg E6) and
169 * Gp13 (in reg E3) as inputs. 172 * Gp13 (in reg E3) as inputs.
170 */ 173 */
171 outb_p(DEVICE_REGISTER,IO_INDEX_PORT); 174 outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
172 outb_p(0x07,IO_DATA_PORT); 175 outb_p(0x07, IO_DATA_PORT);
173 if (!testmode) 176 if (!testmode) {
174 { 177 outb_p(0xE6, IO_INDEX_PORT);
175 outb_p(0xE6,IO_INDEX_PORT); 178 outb_p(0x01, IO_DATA_PORT);
176 outb_p(0x01,IO_DATA_PORT);
177 } 179 }
178 outb_p(0xE3,IO_INDEX_PORT); 180 outb_p(0xE3, IO_INDEX_PORT);
179 outb_p(0x01,IO_DATA_PORT); 181 outb_p(0x01, IO_DATA_PORT);
180 182
181 /* Lock the SuperIO chip */ 183 /* Lock the SuperIO chip */
182 outb_p(LOCK_DATA,IO_INDEX_PORT); 184 outb_p(LOCK_DATA, IO_INDEX_PORT);
183 185
184 spin_unlock_irqrestore(&spinlock, flags); 186 spin_unlock_irqrestore(&spinlock, flags);
185 187
@@ -200,17 +202,17 @@ static int wdt_keepalive(void)
200 spin_lock_irqsave(&spinlock, flags); 202 spin_lock_irqsave(&spinlock, flags);
201 203
202 /* Unlock the SuperIO chip */ 204 /* Unlock the SuperIO chip */
203 outb_p(UNLOCK_DATA,IO_INDEX_PORT); 205 outb_p(UNLOCK_DATA, IO_INDEX_PORT);
204 outb_p(UNLOCK_DATA,IO_INDEX_PORT); 206 outb_p(UNLOCK_DATA, IO_INDEX_PORT);
205 207
206 /* Select device Aux2 (device=8) to kick watchdog reg F2 */ 208 /* Select device Aux2 (device=8) to kick watchdog reg F2 */
207 outb_p(DEVICE_REGISTER,IO_INDEX_PORT); 209 outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
208 outb_p(0x08,IO_DATA_PORT); 210 outb_p(0x08, IO_DATA_PORT);
209 outb_p(0xF2,IO_INDEX_PORT); 211 outb_p(0xF2, IO_INDEX_PORT);
210 outb_p(timeoutW,IO_DATA_PORT); 212 outb_p(timeoutW, IO_DATA_PORT);
211 213
212 /* Lock the SuperIO chip */ 214 /* Lock the SuperIO chip */
213 outb_p(LOCK_DATA,IO_INDEX_PORT); 215 outb_p(LOCK_DATA, IO_INDEX_PORT);
214 216
215 spin_unlock_irqrestore(&spinlock, flags); 217 spin_unlock_irqrestore(&spinlock, flags);
216 218
@@ -227,7 +229,7 @@ static int wdt_set_timeout(int t)
227 229
228 /* 230 /*
229 * Convert seconds to watchdog counter time units, rounding up. 231 * Convert seconds to watchdog counter time units, rounding up.
230 * On PCM-5335 watchdog units are 30 seconds/step with 15 sec startup 232 * On PCM-5335 watchdog units are 30 seconds/step with 15 sec startup
231 * value. This information is supplied in the PCM-5335 manual and was 233 * value. This information is supplied in the PCM-5335 manual and was
232 * checked by me on a real board. This is a bit strange because W83977f 234 * checked by me on a real board. This is a bit strange because W83977f
233 * datasheet says counter unit is in minutes! 235 * datasheet says counter unit is in minutes!
@@ -241,7 +243,7 @@ static int wdt_set_timeout(int t)
241 return -EINVAL; 243 return -EINVAL;
242 244
243 /* 245 /*
244 * timeout is the timeout in seconds, 246 * timeout is the timeout in seconds,
245 * timeoutW is the timeout in watchdog counter units. 247 * timeoutW is the timeout in watchdog counter units.
246 */ 248 */
247 timeoutW = tmrval; 249 timeoutW = tmrval;
@@ -261,17 +263,17 @@ static int wdt_get_status(int *status)
261 spin_lock_irqsave(&spinlock, flags); 263 spin_lock_irqsave(&spinlock, flags);
262 264
263 /* Unlock the SuperIO chip */ 265 /* Unlock the SuperIO chip */
264 outb_p(UNLOCK_DATA,IO_INDEX_PORT); 266 outb_p(UNLOCK_DATA, IO_INDEX_PORT);
265 outb_p(UNLOCK_DATA,IO_INDEX_PORT); 267 outb_p(UNLOCK_DATA, IO_INDEX_PORT);
266 268
267 /* Select device Aux2 (device=8) to read watchdog reg F4 */ 269 /* Select device Aux2 (device=8) to read watchdog reg F4 */
268 outb_p(DEVICE_REGISTER,IO_INDEX_PORT); 270 outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
269 outb_p(0x08,IO_DATA_PORT); 271 outb_p(0x08, IO_DATA_PORT);
270 outb_p(0xF4,IO_INDEX_PORT); 272 outb_p(0xF4, IO_INDEX_PORT);
271 new_status = inb_p(IO_DATA_PORT); 273 new_status = inb_p(IO_DATA_PORT);
272 274
273 /* Lock the SuperIO chip */ 275 /* Lock the SuperIO chip */
274 outb_p(LOCK_DATA,IO_INDEX_PORT); 276 outb_p(LOCK_DATA, IO_INDEX_PORT);
275 277
276 spin_unlock_irqrestore(&spinlock, flags); 278 spin_unlock_irqrestore(&spinlock, flags);
277 279
@@ -290,7 +292,7 @@ static int wdt_get_status(int *status)
290static int wdt_open(struct inode *inode, struct file *file) 292static int wdt_open(struct inode *inode, struct file *file)
291{ 293{
292 /* If the watchdog is alive we don't need to start it again */ 294 /* If the watchdog is alive we don't need to start it again */
293 if( test_and_set_bit(0, &timer_alive) ) 295 if (test_and_set_bit(0, &timer_alive))
294 return -EBUSY; 296 return -EBUSY;
295 297
296 if (nowayout) 298 if (nowayout)
@@ -306,13 +308,13 @@ static int wdt_release(struct inode *inode, struct file *file)
306 * Shut off the timer. 308 * Shut off the timer.
307 * Lock it in if it's a module and we set nowayout 309 * Lock it in if it's a module and we set nowayout
308 */ 310 */
309 if (expect_close == 42) 311 if (expect_close == 42) {
310 {
311 wdt_stop(); 312 wdt_stop();
312 clear_bit(0, &timer_alive); 313 clear_bit(0, &timer_alive);
313 } else { 314 } else {
314 wdt_keepalive(); 315 wdt_keepalive();
315 printk(KERN_CRIT PFX "unexpected close, not stopping watchdog!\n"); 316 printk(KERN_CRIT PFX
317 "unexpected close, not stopping watchdog!\n");
316 } 318 }
317 expect_close = 0; 319 expect_close = 0;
318 return 0; 320 return 0;
@@ -333,24 +335,22 @@ static ssize_t wdt_write(struct file *file, const char __user *buf,
333 size_t count, loff_t *ppos) 335 size_t count, loff_t *ppos)
334{ 336{
335 /* See if we got the magic character 'V' and reload the timer */ 337 /* See if we got the magic character 'V' and reload the timer */
336 if(count) 338 if (count) {
337 { 339 if (!nowayout) {
338 if (!nowayout)
339 {
340 size_t ofs; 340 size_t ofs;
341 341
342 /* note: just in case someone wrote the magic character long ago */ 342 /* note: just in case someone wrote the
343 magic character long ago */
343 expect_close = 0; 344 expect_close = 0;
344 345
345 /* scan to see whether or not we got the magic character */ 346 /* scan to see whether or not we got the
346 for(ofs = 0; ofs != count; ofs++) 347 magic character */
347 { 348 for (ofs = 0; ofs != count; ofs++) {
348 char c; 349 char c;
349 if (get_user(c, buf + ofs)) 350 if (get_user(c, buf + ofs))
350 return -EFAULT; 351 return -EFAULT;
351 if (c == 'V') { 352 if (c == 'V')
352 expect_close = 42; 353 expect_close = 42;
353 }
354 } 354 }
355 } 355 }
356 356
@@ -377,8 +377,7 @@ static struct watchdog_info ident = {
377 .identity = WATCHDOG_NAME, 377 .identity = WATCHDOG_NAME,
378}; 378};
379 379
380static int wdt_ioctl(struct inode *inode, struct file *file, 380static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
381 unsigned int cmd, unsigned long arg)
382{ 381{
383 int status; 382 int status;
384 int new_options, retval = -EINVAL; 383 int new_options, retval = -EINVAL;
@@ -390,13 +389,10 @@ static int wdt_ioctl(struct inode *inode, struct file *file,
390 389
391 uarg.i = (int __user *)arg; 390 uarg.i = (int __user *)arg;
392 391
393 switch(cmd) 392 switch (cmd) {
394 {
395 default:
396 return -ENOTTY;
397
398 case WDIOC_GETSUPPORT: 393 case WDIOC_GETSUPPORT:
399 return copy_to_user(uarg.ident, &ident, sizeof(ident)) ? -EFAULT : 0; 394 return copy_to_user(uarg.ident, &ident,
395 sizeof(ident)) ? -EFAULT : 0;
400 396
401 case WDIOC_GETSTATUS: 397 case WDIOC_GETSTATUS:
402 wdt_get_status(&status); 398 wdt_get_status(&status);
@@ -405,12 +401,8 @@ static int wdt_ioctl(struct inode *inode, struct file *file,
405 case WDIOC_GETBOOTSTATUS: 401 case WDIOC_GETBOOTSTATUS:
406 return put_user(0, uarg.i); 402 return put_user(0, uarg.i);
407 403
408 case WDIOC_KEEPALIVE:
409 wdt_keepalive();
410 return 0;
411
412 case WDIOC_SETOPTIONS: 404 case WDIOC_SETOPTIONS:
413 if (get_user (new_options, uarg.i)) 405 if (get_user(new_options, uarg.i))
414 return -EFAULT; 406 return -EFAULT;
415 407
416 if (new_options & WDIOS_DISABLECARD) { 408 if (new_options & WDIOS_DISABLECARD) {
@@ -425,6 +417,10 @@ static int wdt_ioctl(struct inode *inode, struct file *file,
425 417
426 return retval; 418 return retval;
427 419
420 case WDIOC_KEEPALIVE:
421 wdt_keepalive();
422 return 0;
423
428 case WDIOC_SETTIMEOUT: 424 case WDIOC_SETTIMEOUT:
429 if (get_user(new_timeout, uarg.i)) 425 if (get_user(new_timeout, uarg.i))
430 return -EFAULT; 426 return -EFAULT;
@@ -438,29 +434,30 @@ static int wdt_ioctl(struct inode *inode, struct file *file,
438 case WDIOC_GETTIMEOUT: 434 case WDIOC_GETTIMEOUT:
439 return put_user(timeout, uarg.i); 435 return put_user(timeout, uarg.i);
440 436
437 default:
438 return -ENOTTY;
439
441 } 440 }
442} 441}
443 442
444static int wdt_notify_sys(struct notifier_block *this, unsigned long code, 443static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
445 void *unused) 444 void *unused)
446{ 445{
447 if (code==SYS_DOWN || code==SYS_HALT) 446 if (code == SYS_DOWN || code == SYS_HALT)
448 wdt_stop(); 447 wdt_stop();
449 return NOTIFY_DONE; 448 return NOTIFY_DONE;
450} 449}
451 450
452static const struct file_operations wdt_fops= 451static const struct file_operations wdt_fops = {
453{
454 .owner = THIS_MODULE, 452 .owner = THIS_MODULE,
455 .llseek = no_llseek, 453 .llseek = no_llseek,
456 .write = wdt_write, 454 .write = wdt_write,
457 .ioctl = wdt_ioctl, 455 .unlocked_ioctl = wdt_ioctl,
458 .open = wdt_open, 456 .open = wdt_open,
459 .release = wdt_release, 457 .release = wdt_release,
460}; 458};
461 459
462static struct miscdevice wdt_miscdev= 460static struct miscdevice wdt_miscdev = {
463{
464 .minor = WATCHDOG_MINOR, 461 .minor = WATCHDOG_MINOR,
465 .name = "watchdog", 462 .name = "watchdog",
466 .fops = &wdt_fops, 463 .fops = &wdt_fops,
@@ -474,20 +471,20 @@ static int __init w83977f_wdt_init(void)
474{ 471{
475 int rc; 472 int rc;
476 473
477 printk(KERN_INFO PFX DRIVER_VERSION); 474 printk(KERN_INFO PFX DRIVER_VERSION);
478 475
479 /* 476 /*
480 * Check that the timeout value is within it's range ; 477 * Check that the timeout value is within it's range;
481 * if not reset to the default 478 * if not reset to the default
482 */ 479 */
483 if (wdt_set_timeout(timeout)) { 480 if (wdt_set_timeout(timeout)) {
484 wdt_set_timeout(DEFAULT_TIMEOUT); 481 wdt_set_timeout(DEFAULT_TIMEOUT);
485 printk(KERN_INFO PFX "timeout value must be 15<=timeout<=7635, using %d\n", 482 printk(KERN_INFO PFX
486 DEFAULT_TIMEOUT); 483 "timeout value must be 15 <= timeout <= 7635, using %d\n",
484 DEFAULT_TIMEOUT);
487 } 485 }
488 486
489 if (!request_region(IO_INDEX_PORT, 2, WATCHDOG_NAME)) 487 if (!request_region(IO_INDEX_PORT, 2, WATCHDOG_NAME)) {
490 {
491 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", 488 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n",
492 IO_INDEX_PORT); 489 IO_INDEX_PORT);
493 rc = -EIO; 490 rc = -EIO;
@@ -495,30 +492,30 @@ static int __init w83977f_wdt_init(void)
495 } 492 }
496 493
497 rc = register_reboot_notifier(&wdt_notifier); 494 rc = register_reboot_notifier(&wdt_notifier);
498 if (rc) 495 if (rc) {
499 { 496 printk(KERN_ERR PFX
500 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 497 "cannot register reboot notifier (err=%d)\n", rc);
501 rc);
502 goto err_out_region; 498 goto err_out_region;
503 } 499 }
504 500
505 rc = misc_register(&wdt_miscdev); 501 rc = misc_register(&wdt_miscdev);
506 if (rc) 502 if (rc) {
507 { 503 printk(KERN_ERR PFX
508 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 504 "cannot register miscdev on minor=%d (err=%d)\n",
509 wdt_miscdev.minor, rc); 505 wdt_miscdev.minor, rc);
510 goto err_out_reboot; 506 goto err_out_reboot;
511 } 507 }
512 508
513 printk(KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d testmode=%d)\n", 509 printk(KERN_INFO PFX
514 timeout, nowayout, testmode); 510 "initialized. timeout=%d sec (nowayout=%d testmode=%d)\n",
511 timeout, nowayout, testmode);
515 512
516 return 0; 513 return 0;
517 514
518err_out_reboot: 515err_out_reboot:
519 unregister_reboot_notifier(&wdt_notifier); 516 unregister_reboot_notifier(&wdt_notifier);
520err_out_region: 517err_out_region:
521 release_region(IO_INDEX_PORT,2); 518 release_region(IO_INDEX_PORT, 2);
522err_out: 519err_out:
523 return rc; 520 return rc;
524} 521}
@@ -528,7 +525,7 @@ static void __exit w83977f_wdt_exit(void)
528 wdt_stop(); 525 wdt_stop();
529 misc_deregister(&wdt_miscdev); 526 misc_deregister(&wdt_miscdev);
530 unregister_reboot_notifier(&wdt_notifier); 527 unregister_reboot_notifier(&wdt_notifier);
531 release_region(IO_INDEX_PORT,2); 528 release_region(IO_INDEX_PORT, 2);
532} 529}
533 530
534module_init(w83977f_wdt_init); 531module_init(w83977f_wdt_init);
diff --git a/drivers/watchdog/wafer5823wdt.c b/drivers/watchdog/wafer5823wdt.c
index 9e368091f799..68377ae171ff 100644
--- a/drivers/watchdog/wafer5823wdt.c
+++ b/drivers/watchdog/wafer5823wdt.c
@@ -1,11 +1,11 @@
1/* 1/*
2 * ICP Wafer 5823 Single Board Computer WDT driver 2 * ICP Wafer 5823 Single Board Computer WDT driver
3 * http://www.icpamerica.com/wafer_5823.php 3 * http://www.icpamerica.com/wafer_5823.php
4 * May also work on other similar models 4 * May also work on other similar models
5 * 5 *
6 * (c) Copyright 2002 Justin Cormack <justin@street-vision.com> 6 * (c) Copyright 2002 Justin Cormack <justin@street-vision.com>
7 * 7 *
8 * Release 0.02 8 * Release 0.02
9 * 9 *
10 * Based on advantechwdt.c which is based on wdt.c. 10 * Based on advantechwdt.c which is based on wdt.c.
11 * Original copyright messages: 11 * Original copyright messages:
@@ -36,8 +36,8 @@
36#include <linux/reboot.h> 36#include <linux/reboot.h>
37#include <linux/init.h> 37#include <linux/init.h>
38#include <linux/spinlock.h> 38#include <linux/spinlock.h>
39#include <asm/io.h> 39#include <linux/io.h>
40#include <asm/uaccess.h> 40#include <linux/uaccess.h>
41 41
42#define WATCHDOG_NAME "Wafer 5823 WDT" 42#define WATCHDOG_NAME "Wafer 5823 WDT"
43#define PFX WATCHDOG_NAME ": " 43#define PFX WATCHDOG_NAME ": "
@@ -50,10 +50,10 @@ static DEFINE_SPINLOCK(wafwdt_lock);
50/* 50/*
51 * You must set these - there is no sane way to probe for this board. 51 * You must set these - there is no sane way to probe for this board.
52 * 52 *
53 * To enable, write the timeout value in seconds (1 to 255) to I/O 53 * To enable, write the timeout value in seconds (1 to 255) to I/O
54 * port WDT_START, then read the port to start the watchdog. To pat 54 * port WDT_START, then read the port to start the watchdog. To pat
55 * the dog, read port WDT_STOP to stop the timer, then read WDT_START 55 * the dog, read port WDT_STOP to stop the timer, then read WDT_START
56 * to restart it again. 56 * to restart it again.
57 */ 57 */
58 58
59static int wdt_stop = 0x843; 59static int wdt_stop = 0x843;
@@ -61,11 +61,15 @@ static int wdt_start = 0x443;
61 61
62static int timeout = WD_TIMO; /* in seconds */ 62static int timeout = WD_TIMO; /* in seconds */
63module_param(timeout, int, 0); 63module_param(timeout, int, 0);
64MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=255, default=" __MODULE_STRING(WD_TIMO) "."); 64MODULE_PARM_DESC(timeout,
65 "Watchdog timeout in seconds. 1 <= timeout <= 255, default="
66 __MODULE_STRING(WD_TIMO) ".");
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=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 70MODULE_PARM_DESC(nowayout,
71 "Watchdog cannot be stopped once started (default="
72 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
69 73
70static void wafwdt_ping(void) 74static void wafwdt_ping(void)
71{ 75{
@@ -83,14 +87,14 @@ static void wafwdt_start(void)
83 inb_p(wdt_start); 87 inb_p(wdt_start);
84} 88}
85 89
86static void 90static void wafwdt_stop(void)
87wafwdt_stop(void)
88{ 91{
89 /* stop watchdog */ 92 /* stop watchdog */
90 inb_p(wdt_stop); 93 inb_p(wdt_stop);
91} 94}
92 95
93static ssize_t wafwdt_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos) 96static ssize_t wafwdt_write(struct file *file, const char __user *buf,
97 size_t count, loff_t *ppos)
94{ 98{
95 /* See if we got the magic character 'V' and reload the timer */ 99 /* See if we got the magic character 'V' and reload the timer */
96 if (count) { 100 if (count) {
@@ -100,7 +104,8 @@ static ssize_t wafwdt_write(struct file *file, const char __user *buf, size_t co
100 /* In case it was set long ago */ 104 /* In case it was set long ago */
101 expect_close = 0; 105 expect_close = 0;
102 106
103 /* scan to see whether or not we got the magic character */ 107 /* scan to see whether or not we got the magic
108 character */
104 for (i = 0; i != count; i++) { 109 for (i = 0; i != count; i++) {
105 char c; 110 char c;
106 if (get_user(c, buf + i)) 111 if (get_user(c, buf + i))
@@ -109,27 +114,29 @@ static ssize_t wafwdt_write(struct file *file, const char __user *buf, size_t co
109 expect_close = 42; 114 expect_close = 42;
110 } 115 }
111 } 116 }
112 /* Well, anyhow someone wrote to us, we should return that favour */ 117 /* Well, anyhow someone wrote to us, we should
118 return that favour */
113 wafwdt_ping(); 119 wafwdt_ping();
114 } 120 }
115 return count; 121 return count;
116} 122}
117 123
118static int wafwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 124static long wafwdt_ioctl(struct file *file, unsigned int cmd,
119 unsigned long arg) 125 unsigned long arg)
120{ 126{
121 int new_timeout; 127 int new_timeout;
122 void __user *argp = (void __user *)arg; 128 void __user *argp = (void __user *)arg;
123 int __user *p = argp; 129 int __user *p = argp;
124 static struct watchdog_info ident = { 130 static const struct watchdog_info ident = {
125 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, 131 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
132 WDIOF_MAGICCLOSE,
126 .firmware_version = 1, 133 .firmware_version = 1,
127 .identity = "Wafer 5823 WDT", 134 .identity = "Wafer 5823 WDT",
128 }; 135 };
129 136
130 switch (cmd) { 137 switch (cmd) {
131 case WDIOC_GETSUPPORT: 138 case WDIOC_GETSUPPORT:
132 if (copy_to_user(argp, &ident, sizeof (ident))) 139 if (copy_to_user(argp, &ident, sizeof(ident)))
133 return -EFAULT; 140 return -EFAULT;
134 break; 141 break;
135 142
@@ -137,22 +144,6 @@ static int wafwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd
137 case WDIOC_GETBOOTSTATUS: 144 case WDIOC_GETBOOTSTATUS:
138 return put_user(0, p); 145 return put_user(0, p);
139 146
140 case WDIOC_KEEPALIVE:
141 wafwdt_ping();
142 break;
143
144 case WDIOC_SETTIMEOUT:
145 if (get_user(new_timeout, p))
146 return -EFAULT;
147 if ((new_timeout < 1) || (new_timeout > 255))
148 return -EINVAL;
149 timeout = new_timeout;
150 wafwdt_stop();
151 wafwdt_start();
152 /* Fall */
153 case WDIOC_GETTIMEOUT:
154 return put_user(timeout, p);
155
156 case WDIOC_SETOPTIONS: 147 case WDIOC_SETOPTIONS:
157 { 148 {
158 int options, retval = -EINVAL; 149 int options, retval = -EINVAL;
@@ -173,6 +164,22 @@ static int wafwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd
173 return retval; 164 return retval;
174 } 165 }
175 166
167 case WDIOC_KEEPALIVE:
168 wafwdt_ping();
169 break;
170
171 case WDIOC_SETTIMEOUT:
172 if (get_user(new_timeout, p))
173 return -EFAULT;
174 if ((new_timeout < 1) || (new_timeout > 255))
175 return -EINVAL;
176 timeout = new_timeout;
177 wafwdt_stop();
178 wafwdt_start();
179 /* Fall */
180 case WDIOC_GETTIMEOUT:
181 return put_user(timeout, p);
182
176 default: 183 default:
177 return -ENOTTY; 184 return -ENOTTY;
178 } 185 }
@@ -191,13 +198,13 @@ static int wafwdt_open(struct inode *inode, struct file *file)
191 return nonseekable_open(inode, file); 198 return nonseekable_open(inode, file);
192} 199}
193 200
194static int 201static int wafwdt_close(struct inode *inode, struct file *file)
195wafwdt_close(struct inode *inode, struct file *file)
196{ 202{
197 if (expect_close == 42) { 203 if (expect_close == 42)
198 wafwdt_stop(); 204 wafwdt_stop();
199 } else { 205 else {
200 printk(KERN_CRIT PFX "WDT device closed unexpectedly. WDT will not stop!\n"); 206 printk(KERN_CRIT PFX
207 "WDT device closed unexpectedly. WDT will not stop!\n");
201 wafwdt_ping(); 208 wafwdt_ping();
202 } 209 }
203 clear_bit(0, &wafwdt_is_open); 210 clear_bit(0, &wafwdt_is_open);
@@ -209,12 +216,11 @@ wafwdt_close(struct inode *inode, struct file *file)
209 * Notifier for system down 216 * Notifier for system down
210 */ 217 */
211 218
212static int wafwdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) 219static int wafwdt_notify_sys(struct notifier_block *this, unsigned long code,
220 void *unused)
213{ 221{
214 if (code == SYS_DOWN || code == SYS_HALT) { 222 if (code == SYS_DOWN || code == SYS_HALT)
215 /* Turn the WDT off */
216 wafwdt_stop(); 223 wafwdt_stop();
217 }
218 return NOTIFY_DONE; 224 return NOTIFY_DONE;
219} 225}
220 226
@@ -226,7 +232,7 @@ static const struct file_operations wafwdt_fops = {
226 .owner = THIS_MODULE, 232 .owner = THIS_MODULE,
227 .llseek = no_llseek, 233 .llseek = no_llseek,
228 .write = wafwdt_write, 234 .write = wafwdt_write,
229 .ioctl = wafwdt_ioctl, 235 .unlocked_ioctl = wafwdt_ioctl,
230 .open = wafwdt_open, 236 .open = wafwdt_open,
231 .release = wafwdt_close, 237 .release = wafwdt_close,
232}; 238};
@@ -250,25 +256,28 @@ static int __init wafwdt_init(void)
250{ 256{
251 int ret; 257 int ret;
252 258
253 printk(KERN_INFO "WDT driver for Wafer 5823 single board computer initialising.\n"); 259 printk(KERN_INFO
260 "WDT driver for Wafer 5823 single board computer initialising.\n");
254 261
255 if (timeout < 1 || timeout > 255) { 262 if (timeout < 1 || timeout > 255) {
256 timeout = WD_TIMO; 263 timeout = WD_TIMO;
257 printk (KERN_INFO PFX "timeout value must be 1<=x<=255, using %d\n", 264 printk(KERN_INFO PFX
258 timeout); 265 "timeout value must be 1 <= x <= 255, using %d\n",
266 timeout);
259 } 267 }
260 268
261 if (wdt_stop != wdt_start) { 269 if (wdt_stop != wdt_start) {
262 if(!request_region(wdt_stop, 1, "Wafer 5823 WDT")) { 270 if (!request_region(wdt_stop, 1, "Wafer 5823 WDT")) {
263 printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", 271 printk(KERN_ERR PFX
264 wdt_stop); 272 "I/O address 0x%04x already in use\n",
273 wdt_stop);
265 ret = -EIO; 274 ret = -EIO;
266 goto error; 275 goto error;
267 } 276 }
268 } 277 }
269 278
270 if(!request_region(wdt_start, 1, "Wafer 5823 WDT")) { 279 if (!request_region(wdt_start, 1, "Wafer 5823 WDT")) {
271 printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", 280 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n",
272 wdt_start); 281 wdt_start);
273 ret = -EIO; 282 ret = -EIO;
274 goto error2; 283 goto error2;
@@ -276,19 +285,20 @@ static int __init wafwdt_init(void)
276 285
277 ret = register_reboot_notifier(&wafwdt_notifier); 286 ret = register_reboot_notifier(&wafwdt_notifier);
278 if (ret != 0) { 287 if (ret != 0) {
279 printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 288 printk(KERN_ERR PFX
280 ret); 289 "cannot register reboot notifier (err=%d)\n", ret);
281 goto error3; 290 goto error3;
282 } 291 }
283 292
284 ret = misc_register(&wafwdt_miscdev); 293 ret = misc_register(&wafwdt_miscdev);
285 if (ret != 0) { 294 if (ret != 0) {
286 printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 295 printk(KERN_ERR PFX
287 WATCHDOG_MINOR, ret); 296 "cannot register miscdev on minor=%d (err=%d)\n",
297 WATCHDOG_MINOR, ret);
288 goto error4; 298 goto error4;
289 } 299 }
290 300
291 printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n", 301 printk(KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n",
292 timeout, nowayout); 302 timeout, nowayout);
293 303
294 return ret; 304 return ret;
@@ -307,7 +317,7 @@ static void __exit wafwdt_exit(void)
307{ 317{
308 misc_deregister(&wafwdt_miscdev); 318 misc_deregister(&wafwdt_miscdev);
309 unregister_reboot_notifier(&wafwdt_notifier); 319 unregister_reboot_notifier(&wafwdt_notifier);
310 if(wdt_stop != wdt_start) 320 if (wdt_stop != wdt_start)
311 release_region(wdt_stop, 1); 321 release_region(wdt_stop, 1);
312 release_region(wdt_start, 1); 322 release_region(wdt_start, 1);
313} 323}
diff --git a/drivers/watchdog/wd501p.h b/drivers/watchdog/wd501p.h
index a4504f40394d..db34853c28ae 100644
--- a/drivers/watchdog/wd501p.h
+++ b/drivers/watchdog/wd501p.h
@@ -12,7 +12,7 @@
12 * http://www.cymru.net 12 * http://www.cymru.net
13 * 13 *
14 * This driver is provided under the GNU General Public License, incorporated 14 * This driver is provided under the GNU General Public License, incorporated
15 * herein by reference. The driver is provided without warranty or 15 * herein by reference. The driver is provided without warranty or
16 * support. 16 * support.
17 * 17 *
18 * Release 0.04. 18 * Release 0.04.
diff --git a/drivers/watchdog/wdrtas.c b/drivers/watchdog/wdrtas.c
index 1d64e277567d..5d3b1a8e28b0 100644
--- a/drivers/watchdog/wdrtas.c
+++ b/drivers/watchdog/wdrtas.c
@@ -35,9 +35,9 @@
35#include <linux/reboot.h> 35#include <linux/reboot.h>
36#include <linux/types.h> 36#include <linux/types.h>
37#include <linux/watchdog.h> 37#include <linux/watchdog.h>
38#include <linux/uaccess.h>
38 39
39#include <asm/rtas.h> 40#include <asm/rtas.h>
40#include <asm/uaccess.h>
41 41
42#define WDRTAS_MAGIC_CHAR 42 42#define WDRTAS_MAGIC_CHAR 42
43#define WDRTAS_SUPPORTED_MASK (WDIOF_SETTIMEOUT | \ 43#define WDRTAS_SUPPORTED_MASK (WDIOF_SETTIMEOUT | \
@@ -56,7 +56,7 @@ static int wdrtas_nowayout = 0;
56#endif 56#endif
57 57
58static atomic_t wdrtas_miscdev_open = ATOMIC_INIT(0); 58static atomic_t wdrtas_miscdev_open = ATOMIC_INIT(0);
59static char wdrtas_expect_close = 0; 59static char wdrtas_expect_close;
60 60
61static int wdrtas_interval; 61static int wdrtas_interval;
62 62
@@ -86,8 +86,8 @@ static char wdrtas_logbuffer[WDRTAS_LOGBUFFER_LEN];
86 * RTAS function set-indicator (surveillance). The unit of interval is 86 * RTAS function set-indicator (surveillance). The unit of interval is
87 * seconds. 87 * seconds.
88 */ 88 */
89static int 89
90wdrtas_set_interval(int interval) 90static int wdrtas_set_interval(int interval)
91{ 91{
92 long result; 92 long result;
93 static int print_msg = 10; 93 static int print_msg = 10;
@@ -97,7 +97,7 @@ wdrtas_set_interval(int interval)
97 97
98 result = rtas_call(wdrtas_token_set_indicator, 3, 1, NULL, 98 result = rtas_call(wdrtas_token_set_indicator, 3, 1, NULL,
99 WDRTAS_SURVEILLANCE_IND, 0, interval); 99 WDRTAS_SURVEILLANCE_IND, 0, interval);
100 if ( (result < 0) && (print_msg) ) { 100 if (result < 0 && print_msg) {
101 printk(KERN_ERR "wdrtas: setting the watchdog to %i " 101 printk(KERN_ERR "wdrtas: setting the watchdog to %i "
102 "timeout failed: %li\n", interval, result); 102 "timeout failed: %li\n", interval, result);
103 print_msg--; 103 print_msg--;
@@ -116,16 +116,14 @@ wdrtas_set_interval(int interval)
116 * as reported by the RTAS function ibm,get-system-parameter. The unit 116 * as reported by the RTAS function ibm,get-system-parameter. The unit
117 * of the return value is seconds. 117 * of the return value is seconds.
118 */ 118 */
119static int 119static int wdrtas_get_interval(int fallback_value)
120wdrtas_get_interval(int fallback_value)
121{ 120{
122 long result; 121 long result;
123 char value[4]; 122 char value[4];
124 123
125 result = rtas_call(wdrtas_token_get_sp, 3, 1, NULL, 124 result = rtas_call(wdrtas_token_get_sp, 3, 1, NULL,
126 WDRTAS_SP_SPI, (void *)__pa(&value), 4); 125 WDRTAS_SP_SPI, (void *)__pa(&value), 4);
127 if ( (value[0] != 0) || (value[1] != 2) || (value[3] != 0) || 126 if (value[0] != 0 || value[1] != 2 || value[3] != 0 || result < 0) {
128 (result < 0) ) {
129 printk(KERN_WARNING "wdrtas: could not get sp_spi watchdog " 127 printk(KERN_WARNING "wdrtas: could not get sp_spi watchdog "
130 "timeout (%li). Continuing\n", result); 128 "timeout (%li). Continuing\n", result);
131 return fallback_value; 129 return fallback_value;
@@ -141,8 +139,7 @@ wdrtas_get_interval(int fallback_value)
141 * wdrtas_timer_start starts the watchdog by calling the RTAS function 139 * wdrtas_timer_start starts the watchdog by calling the RTAS function
142 * set-interval (surveillance) 140 * set-interval (surveillance)
143 */ 141 */
144static void 142static void wdrtas_timer_start(void)
145wdrtas_timer_start(void)
146{ 143{
147 wdrtas_set_interval(wdrtas_interval); 144 wdrtas_set_interval(wdrtas_interval);
148} 145}
@@ -153,8 +150,7 @@ wdrtas_timer_start(void)
153 * wdrtas_timer_stop stops the watchdog timer by calling the RTAS function 150 * wdrtas_timer_stop stops the watchdog timer by calling the RTAS function
154 * set-interval (surveillance) 151 * set-interval (surveillance)
155 */ 152 */
156static void 153static void wdrtas_timer_stop(void)
157wdrtas_timer_stop(void)
158{ 154{
159 wdrtas_set_interval(0); 155 wdrtas_set_interval(0);
160} 156}
@@ -165,8 +161,7 @@ wdrtas_timer_stop(void)
165 * wdrtas_log_scanned_event prints a message to the log buffer dumping 161 * wdrtas_log_scanned_event prints a message to the log buffer dumping
166 * the results of the last event-scan call 162 * the results of the last event-scan call
167 */ 163 */
168static void 164static void wdrtas_log_scanned_event(void)
169wdrtas_log_scanned_event(void)
170{ 165{
171 int i; 166 int i;
172 167
@@ -175,13 +170,13 @@ wdrtas_log_scanned_event(void)
175 "%02x %02x %02x %02x %02x %02x %02x %02x " 170 "%02x %02x %02x %02x %02x %02x %02x %02x "
176 "%02x %02x %02x %02x %02x %02x %02x %02x\n", 171 "%02x %02x %02x %02x %02x %02x %02x %02x\n",
177 (i / 16) + 1, (WDRTAS_LOGBUFFER_LEN / 16), 172 (i / 16) + 1, (WDRTAS_LOGBUFFER_LEN / 16),
178 wdrtas_logbuffer[i + 0], wdrtas_logbuffer[i + 1], 173 wdrtas_logbuffer[i + 0], wdrtas_logbuffer[i + 1],
179 wdrtas_logbuffer[i + 2], wdrtas_logbuffer[i + 3], 174 wdrtas_logbuffer[i + 2], wdrtas_logbuffer[i + 3],
180 wdrtas_logbuffer[i + 4], wdrtas_logbuffer[i + 5], 175 wdrtas_logbuffer[i + 4], wdrtas_logbuffer[i + 5],
181 wdrtas_logbuffer[i + 6], wdrtas_logbuffer[i + 7], 176 wdrtas_logbuffer[i + 6], wdrtas_logbuffer[i + 7],
182 wdrtas_logbuffer[i + 8], wdrtas_logbuffer[i + 9], 177 wdrtas_logbuffer[i + 8], wdrtas_logbuffer[i + 9],
183 wdrtas_logbuffer[i + 10], wdrtas_logbuffer[i + 11], 178 wdrtas_logbuffer[i + 10], wdrtas_logbuffer[i + 11],
184 wdrtas_logbuffer[i + 12], wdrtas_logbuffer[i + 13], 179 wdrtas_logbuffer[i + 12], wdrtas_logbuffer[i + 13],
185 wdrtas_logbuffer[i + 14], wdrtas_logbuffer[i + 15]); 180 wdrtas_logbuffer[i + 14], wdrtas_logbuffer[i + 15]);
186} 181}
187 182
@@ -192,8 +187,7 @@ wdrtas_log_scanned_event(void)
192 * RTAS function event-scan and repeats these calls as long as there are 187 * RTAS function event-scan and repeats these calls as long as there are
193 * events available. All events will be dumped. 188 * events available. All events will be dumped.
194 */ 189 */
195static void 190static void wdrtas_timer_keepalive(void)
196wdrtas_timer_keepalive(void)
197{ 191{
198 long result; 192 long result;
199 193
@@ -218,8 +212,7 @@ wdrtas_timer_keepalive(void)
218 * wdrtas_get_temperature returns the current temperature in Fahrenheit. It 212 * wdrtas_get_temperature returns the current temperature in Fahrenheit. It
219 * uses the RTAS call get-sensor-state, token 3 to do so 213 * uses the RTAS call get-sensor-state, token 3 to do so
220 */ 214 */
221static int 215static int wdrtas_get_temperature(void)
222wdrtas_get_temperature(void)
223{ 216{
224 long result; 217 long result;
225 int temperature = 0; 218 int temperature = 0;
@@ -243,8 +236,7 @@ wdrtas_get_temperature(void)
243 * returns a bitmask of defines WDIOF_... as defined in 236 * returns a bitmask of defines WDIOF_... as defined in
244 * include/linux/watchdog.h 237 * include/linux/watchdog.h
245 */ 238 */
246static int 239static int wdrtas_get_status(void)
247wdrtas_get_status(void)
248{ 240{
249 return 0; /* TODO */ 241 return 0; /* TODO */
250} 242}
@@ -255,8 +247,7 @@ wdrtas_get_status(void)
255 * returns a bitmask of defines WDIOF_... as defined in 247 * returns a bitmask of defines WDIOF_... as defined in
256 * include/linux/watchdog.h, indicating why the watchdog rebooted the system 248 * include/linux/watchdog.h, indicating why the watchdog rebooted the system
257 */ 249 */
258static int 250static int wdrtas_get_boot_status(void)
259wdrtas_get_boot_status(void)
260{ 251{
261 return 0; /* TODO */ 252 return 0; /* TODO */
262} 253}
@@ -276,8 +267,7 @@ wdrtas_get_boot_status(void)
276 * character 'V'. This character allows the watchdog device to be closed 267 * character 'V'. This character allows the watchdog device to be closed
277 * properly. 268 * properly.
278 */ 269 */
279static ssize_t 270static ssize_t wdrtas_write(struct file *file, const char __user *buf,
280wdrtas_write(struct file *file, const char __user *buf,
281 size_t len, loff_t *ppos) 271 size_t len, loff_t *ppos)
282{ 272{
283 int i; 273 int i;
@@ -306,7 +296,6 @@ out:
306 296
307/** 297/**
308 * wdrtas_ioctl - ioctl function for the watchdog device 298 * wdrtas_ioctl - ioctl function for the watchdog device
309 * @inode: inode structure
310 * @file: file structure 299 * @file: file structure
311 * @cmd: command for ioctl 300 * @cmd: command for ioctl
312 * @arg: argument pointer 301 * @arg: argument pointer
@@ -315,16 +304,16 @@ out:
315 * 304 *
316 * wdrtas_ioctl implements the watchdog API ioctls 305 * wdrtas_ioctl implements the watchdog API ioctls
317 */ 306 */
318static int 307
319wdrtas_ioctl(struct inode *inode, struct file *file, 308static long wdrtas_ioctl(struct file *file, unsigned int cmd,
320 unsigned int cmd, unsigned long arg) 309 unsigned long arg)
321{ 310{
322 int __user *argp = (void __user *)arg; 311 int __user *argp = (void __user *)arg;
323 int i; 312 int i;
324 static struct watchdog_info wdinfo = { 313 static struct watchdog_info wdinfo = {
325 .options = WDRTAS_SUPPORTED_MASK, 314 .options = WDRTAS_SUPPORTED_MASK,
326 .firmware_version = 0, 315 .firmware_version = 0,
327 .identity = "wdrtas" 316 .identity = "wdrtas",
328 }; 317 };
329 318
330 switch (cmd) { 319 switch (cmd) {
@@ -357,9 +346,9 @@ wdrtas_ioctl(struct inode *inode, struct file *file,
357 wdrtas_timer_keepalive(); 346 wdrtas_timer_keepalive();
358 wdrtas_timer_start(); 347 wdrtas_timer_start();
359 } 348 }
349 /* not implemented. Done by H8
360 if (i & WDIOS_TEMPPANIC) { 350 if (i & WDIOS_TEMPPANIC) {
361 /* not implemented. Done by H8 */ 351 } */
362 }
363 return 0; 352 return 0;
364 353
365 case WDIOC_KEEPALIVE: 354 case WDIOC_KEEPALIVE:
@@ -399,8 +388,7 @@ wdrtas_ioctl(struct inode *inode, struct file *file,
399 * 388 *
400 * function called when watchdog device is opened 389 * function called when watchdog device is opened
401 */ 390 */
402static int 391static int wdrtas_open(struct inode *inode, struct file *file)
403wdrtas_open(struct inode *inode, struct file *file)
404{ 392{
405 /* only open once */ 393 /* only open once */
406 if (atomic_inc_return(&wdrtas_miscdev_open) > 1) { 394 if (atomic_inc_return(&wdrtas_miscdev_open) > 1) {
@@ -423,8 +411,7 @@ wdrtas_open(struct inode *inode, struct file *file)
423 * 411 *
424 * close function. Always succeeds 412 * close function. Always succeeds
425 */ 413 */
426static int 414static int wdrtas_close(struct inode *inode, struct file *file)
427wdrtas_close(struct inode *inode, struct file *file)
428{ 415{
429 /* only stop watchdog, if this was announced using 'V' before */ 416 /* only stop watchdog, if this was announced using 'V' before */
430 if (wdrtas_expect_close == WDRTAS_MAGIC_CHAR) 417 if (wdrtas_expect_close == WDRTAS_MAGIC_CHAR)
@@ -453,8 +440,7 @@ wdrtas_close(struct inode *inode, struct file *file)
453 * wdrtas_temp_read gives the temperature to the users by copying this 440 * wdrtas_temp_read gives the temperature to the users by copying this
454 * value as one byte into the user space buffer. The unit is Fahrenheit... 441 * value as one byte into the user space buffer. The unit is Fahrenheit...
455 */ 442 */
456static ssize_t 443static ssize_t wdrtas_temp_read(struct file *file, char __user *buf,
457wdrtas_temp_read(struct file *file, char __user *buf,
458 size_t count, loff_t *ppos) 444 size_t count, loff_t *ppos)
459{ 445{
460 int temperature = 0; 446 int temperature = 0;
@@ -478,8 +464,7 @@ wdrtas_temp_read(struct file *file, char __user *buf,
478 * 464 *
479 * function called when temperature device is opened 465 * function called when temperature device is opened
480 */ 466 */
481static int 467static int wdrtas_temp_open(struct inode *inode, struct file *file)
482wdrtas_temp_open(struct inode *inode, struct file *file)
483{ 468{
484 return nonseekable_open(inode, file); 469 return nonseekable_open(inode, file);
485} 470}
@@ -493,8 +478,7 @@ wdrtas_temp_open(struct inode *inode, struct file *file)
493 * 478 *
494 * close function. Always succeeds 479 * close function. Always succeeds
495 */ 480 */
496static int 481static int wdrtas_temp_close(struct inode *inode, struct file *file)
497wdrtas_temp_close(struct inode *inode, struct file *file)
498{ 482{
499 return 0; 483 return 0;
500} 484}
@@ -509,10 +493,10 @@ wdrtas_temp_close(struct inode *inode, struct file *file)
509 * 493 *
510 * wdrtas_reboot stops the watchdog in case of a reboot 494 * wdrtas_reboot stops the watchdog in case of a reboot
511 */ 495 */
512static int 496static int wdrtas_reboot(struct notifier_block *this,
513wdrtas_reboot(struct notifier_block *this, unsigned long code, void *ptr) 497 unsigned long code, void *ptr)
514{ 498{
515 if ( (code==SYS_DOWN) || (code==SYS_HALT) ) 499 if (code == SYS_DOWN || code == SYS_HALT)
516 wdrtas_timer_stop(); 500 wdrtas_timer_stop();
517 501
518 return NOTIFY_DONE; 502 return NOTIFY_DONE;
@@ -524,7 +508,7 @@ static const struct file_operations wdrtas_fops = {
524 .owner = THIS_MODULE, 508 .owner = THIS_MODULE,
525 .llseek = no_llseek, 509 .llseek = no_llseek,
526 .write = wdrtas_write, 510 .write = wdrtas_write,
527 .ioctl = wdrtas_ioctl, 511 .unlocked_ioctl = wdrtas_ioctl,
528 .open = wdrtas_open, 512 .open = wdrtas_open,
529 .release = wdrtas_close, 513 .release = wdrtas_close,
530}; 514};
@@ -562,8 +546,7 @@ static struct notifier_block wdrtas_notifier = {
562 * this watchdog driver. It tolerates, if "get-sensor-state" and 546 * this watchdog driver. It tolerates, if "get-sensor-state" and
563 * "ibm,get-system-parameter" are not available. 547 * "ibm,get-system-parameter" are not available.
564 */ 548 */
565static int 549static int wdrtas_get_tokens(void)
566wdrtas_get_tokens(void)
567{ 550{
568 wdrtas_token_get_sensor_state = rtas_token("get-sensor-state"); 551 wdrtas_token_get_sensor_state = rtas_token("get-sensor-state");
569 if (wdrtas_token_get_sensor_state == RTAS_UNKNOWN_SERVICE) { 552 if (wdrtas_token_get_sensor_state == RTAS_UNKNOWN_SERVICE) {
@@ -603,8 +586,7 @@ wdrtas_get_tokens(void)
603 * wdrtas_register_devs unregisters the watchdog and temperature watchdog 586 * wdrtas_register_devs unregisters the watchdog and temperature watchdog
604 * misc devs 587 * misc devs
605 */ 588 */
606static void 589static void wdrtas_unregister_devs(void)
607wdrtas_unregister_devs(void)
608{ 590{
609 misc_deregister(&wdrtas_miscdev); 591 misc_deregister(&wdrtas_miscdev);
610 if (wdrtas_token_get_sensor_state != RTAS_UNKNOWN_SERVICE) 592 if (wdrtas_token_get_sensor_state != RTAS_UNKNOWN_SERVICE)
@@ -619,8 +601,7 @@ wdrtas_unregister_devs(void)
619 * wdrtas_register_devs registers the watchdog and temperature watchdog 601 * wdrtas_register_devs registers the watchdog and temperature watchdog
620 * misc devs 602 * misc devs
621 */ 603 */
622static int 604static int wdrtas_register_devs(void)
623wdrtas_register_devs(void)
624{ 605{
625 int result; 606 int result;
626 607
@@ -651,8 +632,7 @@ wdrtas_register_devs(void)
651 * 632 *
652 * registers the file handlers and the reboot notifier 633 * registers the file handlers and the reboot notifier
653 */ 634 */
654static int __init 635static int __init wdrtas_init(void)
655wdrtas_init(void)
656{ 636{
657 if (wdrtas_get_tokens()) 637 if (wdrtas_get_tokens())
658 return -ENODEV; 638 return -ENODEV;
@@ -680,8 +660,7 @@ wdrtas_init(void)
680 * 660 *
681 * unregisters the file handlers and the reboot notifier 661 * unregisters the file handlers and the reboot notifier
682 */ 662 */
683static void __exit 663static void __exit wdrtas_exit(void)
684wdrtas_exit(void)
685{ 664{
686 if (!wdrtas_nowayout) 665 if (!wdrtas_nowayout)
687 wdrtas_timer_stop(); 666 wdrtas_timer_stop();
diff --git a/drivers/watchdog/wdt.c b/drivers/watchdog/wdt.c
index 53a6b18bcb9a..deeebb2b13ea 100644
--- a/drivers/watchdog/wdt.c
+++ b/drivers/watchdog/wdt.c
@@ -373,8 +373,6 @@ static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
373#endif /* CONFIG_WDT_501 */ 373#endif /* CONFIG_WDT_501 */
374 374
375 switch (cmd) { 375 switch (cmd) {
376 default:
377 return -ENOTTY;
378 case WDIOC_GETSUPPORT: 376 case WDIOC_GETSUPPORT:
379 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; 377 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
380 case WDIOC_GETSTATUS: 378 case WDIOC_GETSTATUS:
@@ -394,6 +392,8 @@ static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
394 /* Fall */ 392 /* Fall */
395 case WDIOC_GETTIMEOUT: 393 case WDIOC_GETTIMEOUT:
396 return put_user(heartbeat, p); 394 return put_user(heartbeat, p);
395 default:
396 return -ENOTTY;
397 } 397 }
398} 398}
399 399
diff --git a/drivers/watchdog/wdt285.c b/drivers/watchdog/wdt285.c
index 94e2d91c9ac9..c8d7f1b2df02 100644
--- a/drivers/watchdog/wdt285.c
+++ b/drivers/watchdog/wdt285.c
@@ -26,10 +26,10 @@
26#include <linux/reboot.h> 26#include <linux/reboot.h>
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/interrupt.h> 28#include <linux/interrupt.h>
29 29#include <linux/uaccess.h>
30#include <asm/irq.h> 30#include <linux/irq.h>
31#include <asm/uaccess.h>
32#include <mach/hardware.h> 31#include <mach/hardware.h>
32
33#include <asm/mach-types.h> 33#include <asm/mach-types.h>
34#include <asm/hardware/dec21285.h> 34#include <asm/hardware/dec21285.h>
35 35
@@ -115,8 +115,8 @@ static int watchdog_release(struct inode *inode, struct file *file)
115 return 0; 115 return 0;
116} 116}
117 117
118static ssize_t 118static ssize_t watchdog_write(struct file *file, const char *data,
119watchdog_write(struct file *file, const char *data, size_t len, loff_t *ppos) 119 size_t len, loff_t *ppos)
120{ 120{
121 /* 121 /*
122 * Refresh the timer. 122 * Refresh the timer.
@@ -127,19 +127,18 @@ watchdog_write(struct file *file, const char *data, size_t len, loff_t *ppos)
127 return len; 127 return len;
128} 128}
129 129
130static struct watchdog_info ident = { 130static const struct watchdog_info ident = {
131 .options = WDIOF_SETTIMEOUT, 131 .options = WDIOF_SETTIMEOUT,
132 .identity = "Footbridge Watchdog", 132 .identity = "Footbridge Watchdog",
133}; 133};
134 134
135static int 135static long watchdog_ioctl(struct file *file, unsigned int cmd,
136watchdog_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 136 unsigned long arg)
137 unsigned long arg)
138{ 137{
139 unsigned int new_margin; 138 unsigned int new_margin;
140 int ret = -ENOTTY; 139 int ret = -ENOTTY;
141 140
142 switch(cmd) { 141 switch (cmd) {
143 case WDIOC_GETSUPPORT: 142 case WDIOC_GETSUPPORT:
144 ret = 0; 143 ret = 0;
145 if (copy_to_user((void *)arg, &ident, sizeof(ident))) 144 if (copy_to_user((void *)arg, &ident, sizeof(ident)))
@@ -148,7 +147,7 @@ watchdog_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
148 147
149 case WDIOC_GETSTATUS: 148 case WDIOC_GETSTATUS:
150 case WDIOC_GETBOOTSTATUS: 149 case WDIOC_GETBOOTSTATUS:
151 ret = put_user(0,(int *)arg); 150 ret = put_user(0, (int *)arg);
152 break; 151 break;
153 152
154 case WDIOC_KEEPALIVE: 153 case WDIOC_KEEPALIVE:
@@ -182,7 +181,7 @@ static const struct file_operations watchdog_fops = {
182 .owner = THIS_MODULE, 181 .owner = THIS_MODULE,
183 .llseek = no_llseek, 182 .llseek = no_llseek,
184 .write = watchdog_write, 183 .write = watchdog_write,
185 .ioctl = watchdog_ioctl, 184 .unlocked_ioctl = watchdog_ioctl,
186 .open = watchdog_open, 185 .open = watchdog_open,
187 .release = watchdog_release, 186 .release = watchdog_release,
188}; 187};
@@ -204,11 +203,13 @@ static int __init footbridge_watchdog_init(void)
204 if (retval < 0) 203 if (retval < 0)
205 return retval; 204 return retval;
206 205
207 printk("Footbridge Watchdog Timer: 0.01, timer margin: %d sec\n", 206 printk(KERN_INFO
208 soft_margin); 207 "Footbridge Watchdog Timer: 0.01, timer margin: %d sec\n",
208 soft_margin);
209 209
210 if (machine_is_cats()) 210 if (machine_is_cats())
211 printk("Warning: Watchdog reset may not work on this machine.\n"); 211 printk(KERN_WARN
212 "Warning: Watchdog reset may not work on this machine.\n");
212 return 0; 213 return 0;
213} 214}
214 215
@@ -223,7 +224,7 @@ MODULE_LICENSE("GPL");
223MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); 224MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
224 225
225module_param(soft_margin, int, 0); 226module_param(soft_margin, int, 0);
226MODULE_PARM_DESC(soft_margin,"Watchdog timeout in seconds"); 227MODULE_PARM_DESC(soft_margin, "Watchdog timeout in seconds");
227 228
228module_init(footbridge_watchdog_init); 229module_init(footbridge_watchdog_init);
229module_exit(footbridge_watchdog_exit); 230module_exit(footbridge_watchdog_exit);
diff --git a/drivers/watchdog/wdt977.c b/drivers/watchdog/wdt977.c
index fb4b876c9fda..60e28d49ff52 100644
--- a/drivers/watchdog/wdt977.c
+++ b/drivers/watchdog/wdt977.c
@@ -19,7 +19,8 @@
19 * 07-Jul-2003 Daniele Bellucci: Audit return code of misc_register in 19 * 07-Jul-2003 Daniele Bellucci: Audit return code of misc_register in
20 * nwwatchdog_init. 20 * nwwatchdog_init.
21 * 25-Oct-2005 Woody Suwalski: Convert addresses to #defs, add spinlocks 21 * 25-Oct-2005 Woody Suwalski: Convert addresses to #defs, add spinlocks
22 * remove limitiation to be used on Netwinders only 22 * remove limitiation to be used on
23 * Netwinders only
23 */ 24 */
24 25
25#include <linux/module.h> 26#include <linux/module.h>
@@ -33,11 +34,11 @@
33#include <linux/watchdog.h> 34#include <linux/watchdog.h>
34#include <linux/notifier.h> 35#include <linux/notifier.h>
35#include <linux/reboot.h> 36#include <linux/reboot.h>
37#include <linux/io.h>
38#include <linux/uaccess.h>
36 39
37#include <asm/io.h>
38#include <asm/system.h> 40#include <asm/system.h>
39#include <asm/mach-types.h> 41#include <asm/mach-types.h>
40#include <asm/uaccess.h>
41 42
42#define WATCHDOG_VERSION "0.04" 43#define WATCHDOG_VERSION "0.04"
43#define WATCHDOG_NAME "Wdt977" 44#define WATCHDOG_NAME "Wdt977"
@@ -45,7 +46,7 @@
45#define DRIVER_VERSION WATCHDOG_NAME " driver, v" WATCHDOG_VERSION "\n" 46#define DRIVER_VERSION WATCHDOG_NAME " driver, v" WATCHDOG_VERSION "\n"
46 47
47#define IO_INDEX_PORT 0x370 /* on some systems it can be 0x3F0 */ 48#define IO_INDEX_PORT 0x370 /* on some systems it can be 0x3F0 */
48#define IO_DATA_PORT (IO_INDEX_PORT+1) 49#define IO_DATA_PORT (IO_INDEX_PORT + 1)
49 50
50#define UNLOCK_DATA 0x87 51#define UNLOCK_DATA 0x87
51#define LOCK_DATA 0xAA 52#define LOCK_DATA 0xAA
@@ -62,13 +63,16 @@ static char expect_close;
62static DEFINE_SPINLOCK(spinlock); 63static DEFINE_SPINLOCK(spinlock);
63 64
64module_param(timeout, int, 0); 65module_param(timeout, int, 0);
65MODULE_PARM_DESC(timeout,"Watchdog timeout in seconds (60..15300), default=" __MODULE_STRING(DEFAULT_TIMEOUT) ")"); 66MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (60..15300), default="
67 __MODULE_STRING(DEFAULT_TIMEOUT) ")");
66module_param(testmode, int, 0); 68module_param(testmode, int, 0);
67MODULE_PARM_DESC(testmode,"Watchdog testmode (1 = no reboot), default=0"); 69MODULE_PARM_DESC(testmode, "Watchdog testmode (1 = no reboot), default=0");
68 70
69static int nowayout = WATCHDOG_NOWAYOUT; 71static int nowayout = WATCHDOG_NOWAYOUT;
70module_param(nowayout, int, 0); 72module_param(nowayout, int, 0);
71MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 73MODULE_PARM_DESC(nowayout,
74 "Watchdog cannot be stopped once started (default="
75 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
72 76
73/* 77/*
74 * Start the watchdog 78 * Start the watchdog
@@ -95,14 +99,16 @@ static int wdt977_start(void)
95 outb_p(0xF2, IO_INDEX_PORT); 99 outb_p(0xF2, IO_INDEX_PORT);
96 outb_p(timeoutM, IO_DATA_PORT); 100 outb_p(timeoutM, IO_DATA_PORT);
97 outb_p(0xF3, IO_INDEX_PORT); 101 outb_p(0xF3, IO_INDEX_PORT);
98 outb_p(0x00, IO_DATA_PORT); /* another setting is 0E for kbd/mouse/LED */ 102 outb_p(0x00, IO_DATA_PORT); /* another setting is 0E for
103 kbd/mouse/LED */
99 outb_p(0xF4, IO_INDEX_PORT); 104 outb_p(0xF4, IO_INDEX_PORT);
100 outb_p(0x00, IO_DATA_PORT); 105 outb_p(0x00, IO_DATA_PORT);
101 106
102 /* at last select device Aux1 (dev=7) and set GP16 as a watchdog output */ 107 /* At last select device Aux1 (dev=7) and set GP16 as a
103 /* in test mode watch the bit 1 on F4 to indicate "triggered" */ 108 * watchdog output. In test mode watch the bit 1 on F4 to
104 if (!testmode) 109 * indicate "triggered"
105 { 110 */
111 if (!testmode) {
106 outb_p(DEVICE_REGISTER, IO_INDEX_PORT); 112 outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
107 outb_p(0x07, IO_DATA_PORT); 113 outb_p(0x07, IO_DATA_PORT);
108 outb_p(0xE6, IO_INDEX_PORT); 114 outb_p(0xE6, IO_INDEX_PORT);
@@ -147,7 +153,8 @@ static int wdt977_stop(void)
147 outb_p(0xF2, IO_INDEX_PORT); 153 outb_p(0xF2, IO_INDEX_PORT);
148 outb_p(0x00, IO_DATA_PORT); 154 outb_p(0x00, IO_DATA_PORT);
149 155
150 /* at last select device Aux1 (dev=7) and set GP16 as a watchdog output */ 156 /* at last select device Aux1 (dev=7) and set
157 GP16 as a watchdog output */
151 outb_p(DEVICE_REGISTER, IO_INDEX_PORT); 158 outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
152 outb_p(0x07, IO_DATA_PORT); 159 outb_p(0x07, IO_DATA_PORT);
153 outb_p(0xE6, IO_INDEX_PORT); 160 outb_p(0xE6, IO_INDEX_PORT);
@@ -202,16 +209,18 @@ static int wdt977_set_timeout(int t)
202 tmrval = (t + 59) / 60; 209 tmrval = (t + 59) / 60;
203 210
204 if (machine_is_netwinder()) { 211 if (machine_is_netwinder()) {
205 /* we have a hw bug somewhere, so each 977 minute is actually only 30sec 212 /* we have a hw bug somewhere, so each 977 minute is actually
206 * this limits the max timeout to half of device max of 255 minutes... 213 * only 30sec. This limits the max timeout to half of device
214 * max of 255 minutes...
207 */ 215 */
208 tmrval += tmrval; 216 tmrval += tmrval;
209 } 217 }
210 218
211 if ((tmrval < 1) || (tmrval > 255)) 219 if (tmrval < 1 || tmrval > 255)
212 return -EINVAL; 220 return -EINVAL;
213 221
214 /* timeout is the timeout in seconds, timeoutM is the timeout in minutes) */ 222 /* timeout is the timeout in seconds, timeoutM is
223 the timeout in minutes) */
215 timeout = t; 224 timeout = t;
216 timeoutM = tmrval; 225 timeoutM = tmrval;
217 return 0; 226 return 0;
@@ -243,7 +252,7 @@ static int wdt977_get_status(int *status)
243 252
244 spin_unlock_irqrestore(&spinlock, flags); 253 spin_unlock_irqrestore(&spinlock, flags);
245 254
246 *status=0; 255 *status = 0;
247 if (new_status & 1) 256 if (new_status & 1)
248 *status |= WDIOF_CARDRESET; 257 *status |= WDIOF_CARDRESET;
249 258
@@ -258,7 +267,7 @@ static int wdt977_get_status(int *status)
258static int wdt977_open(struct inode *inode, struct file *file) 267static int wdt977_open(struct inode *inode, struct file *file)
259{ 268{
260 /* If the watchdog is alive we don't need to start it again */ 269 /* If the watchdog is alive we don't need to start it again */
261 if( test_and_set_bit(0,&timer_alive) ) 270 if (test_and_set_bit(0, &timer_alive))
262 return -EBUSY; 271 return -EBUSY;
263 272
264 if (nowayout) 273 if (nowayout)
@@ -274,13 +283,13 @@ static int wdt977_release(struct inode *inode, struct file *file)
274 * Shut off the timer. 283 * Shut off the timer.
275 * Lock it in if it's a module and we set nowayout 284 * Lock it in if it's a module and we set nowayout
276 */ 285 */
277 if (expect_close == 42) 286 if (expect_close == 42) {
278 {
279 wdt977_stop(); 287 wdt977_stop();
280 clear_bit(0,&timer_alive); 288 clear_bit(0, &timer_alive);
281 } else { 289 } else {
282 wdt977_keepalive(); 290 wdt977_keepalive();
283 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); 291 printk(KERN_CRIT PFX
292 "Unexpected close, not stopping watchdog!\n");
284 } 293 }
285 expect_close = 0; 294 expect_close = 0;
286 return 0; 295 return 0;
@@ -301,17 +310,14 @@ static int wdt977_release(struct inode *inode, struct file *file)
301static ssize_t wdt977_write(struct file *file, const char __user *buf, 310static ssize_t wdt977_write(struct file *file, const char __user *buf,
302 size_t count, loff_t *ppos) 311 size_t count, loff_t *ppos)
303{ 312{
304 if (count) 313 if (count) {
305 { 314 if (!nowayout) {
306 if (!nowayout)
307 {
308 size_t i; 315 size_t i;
309 316
310 /* In case it was set long ago */ 317 /* In case it was set long ago */
311 expect_close = 0; 318 expect_close = 0;
312 319
313 for (i = 0; i != count; i++) 320 for (i = 0; i != count; i++) {
314 {
315 char c; 321 char c;
316 if (get_user(c, buf + i)) 322 if (get_user(c, buf + i))
317 return -EFAULT; 323 return -EFAULT;
@@ -326,6 +332,14 @@ static ssize_t wdt977_write(struct file *file, const char __user *buf,
326 return count; 332 return count;
327} 333}
328 334
335static const struct watchdog_info ident = {
336 .options = WDIOF_SETTIMEOUT |
337 WDIOF_MAGICCLOSE |
338 WDIOF_KEEPALIVEPING,
339 .firmware_version = 1,
340 .identity = WATCHDOG_NAME,
341};
342
329/* 343/*
330 * wdt977_ioctl: 344 * wdt977_ioctl:
331 * @inode: inode of the device 345 * @inode: inode of the device
@@ -337,16 +351,8 @@ static ssize_t wdt977_write(struct file *file, const char __user *buf,
337 * according to their available features. 351 * according to their available features.
338 */ 352 */
339 353
340static struct watchdog_info ident = { 354static long wdt977_ioctl(struct file *file, unsigned int cmd,
341 .options = WDIOF_SETTIMEOUT | 355 unsigned long arg)
342 WDIOF_MAGICCLOSE |
343 WDIOF_KEEPALIVEPING,
344 .firmware_version = 1,
345 .identity = WATCHDOG_NAME,
346};
347
348static int wdt977_ioctl(struct inode *inode, struct file *file,
349 unsigned int cmd, unsigned long arg)
350{ 356{
351 int status; 357 int status;
352 int new_options, retval = -EINVAL; 358 int new_options, retval = -EINVAL;
@@ -358,11 +364,7 @@ static int wdt977_ioctl(struct inode *inode, struct file *file,
358 364
359 uarg.i = (int __user *)arg; 365 uarg.i = (int __user *)arg;
360 366
361 switch(cmd) 367 switch (cmd) {
362 {
363 default:
364 return -ENOTTY;
365
366 case WDIOC_GETSUPPORT: 368 case WDIOC_GETSUPPORT:
367 return copy_to_user(uarg.ident, &ident, 369 return copy_to_user(uarg.ident, &ident,
368 sizeof(ident)) ? -EFAULT : 0; 370 sizeof(ident)) ? -EFAULT : 0;
@@ -374,12 +376,8 @@ static int wdt977_ioctl(struct inode *inode, struct file *file,
374 case WDIOC_GETBOOTSTATUS: 376 case WDIOC_GETBOOTSTATUS:
375 return put_user(0, uarg.i); 377 return put_user(0, uarg.i);
376 378
377 case WDIOC_KEEPALIVE:
378 wdt977_keepalive();
379 return 0;
380
381 case WDIOC_SETOPTIONS: 379 case WDIOC_SETOPTIONS:
382 if (get_user (new_options, uarg.i)) 380 if (get_user(new_options, uarg.i))
383 return -EFAULT; 381 return -EFAULT;
384 382
385 if (new_options & WDIOS_DISABLECARD) { 383 if (new_options & WDIOS_DISABLECARD) {
@@ -394,6 +392,10 @@ static int wdt977_ioctl(struct inode *inode, struct file *file,
394 392
395 return retval; 393 return retval;
396 394
395 case WDIOC_KEEPALIVE:
396 wdt977_keepalive();
397 return 0;
398
397 case WDIOC_SETTIMEOUT: 399 case WDIOC_SETTIMEOUT:
398 if (get_user(new_timeout, uarg.i)) 400 if (get_user(new_timeout, uarg.i))
399 return -EFAULT; 401 return -EFAULT;
@@ -407,29 +409,30 @@ static int wdt977_ioctl(struct inode *inode, struct file *file,
407 case WDIOC_GETTIMEOUT: 409 case WDIOC_GETTIMEOUT:
408 return put_user(timeout, uarg.i); 410 return put_user(timeout, uarg.i);
409 411
412 default:
413 return -ENOTTY;
414
410 } 415 }
411} 416}
412 417
413static int wdt977_notify_sys(struct notifier_block *this, unsigned long code, 418static int wdt977_notify_sys(struct notifier_block *this, unsigned long code,
414 void *unused) 419 void *unused)
415{ 420{
416 if(code==SYS_DOWN || code==SYS_HALT) 421 if (code == SYS_DOWN || code == SYS_HALT)
417 wdt977_stop(); 422 wdt977_stop();
418 return NOTIFY_DONE; 423 return NOTIFY_DONE;
419} 424}
420 425
421static const struct file_operations wdt977_fops= 426static const struct file_operations wdt977_fops = {
422{
423 .owner = THIS_MODULE, 427 .owner = THIS_MODULE,
424 .llseek = no_llseek, 428 .llseek = no_llseek,
425 .write = wdt977_write, 429 .write = wdt977_write,
426 .ioctl = wdt977_ioctl, 430 .unlocked_ioctl = wdt977_ioctl,
427 .open = wdt977_open, 431 .open = wdt977_open,
428 .release = wdt977_release, 432 .release = wdt977_release,
429}; 433};
430 434
431static struct miscdevice wdt977_miscdev= 435static struct miscdevice wdt977_miscdev = {
432{
433 .minor = WATCHDOG_MINOR, 436 .minor = WATCHDOG_MINOR,
434 .name = "watchdog", 437 .name = "watchdog",
435 .fops = &wdt977_fops, 438 .fops = &wdt977_fops,
@@ -443,51 +446,48 @@ static int __init wd977_init(void)
443{ 446{
444 int rc; 447 int rc;
445 448
446 //if (!machine_is_netwinder())
447 // return -ENODEV;
448
449 printk(KERN_INFO PFX DRIVER_VERSION); 449 printk(KERN_INFO PFX DRIVER_VERSION);
450 450
451 /* Check that the timeout value is within it's range ; if not reset to the default */ 451 /* Check that the timeout value is within its range;
452 if (wdt977_set_timeout(timeout)) 452 if not reset to the default */
453 { 453 if (wdt977_set_timeout(timeout)) {
454 wdt977_set_timeout(DEFAULT_TIMEOUT); 454 wdt977_set_timeout(DEFAULT_TIMEOUT);
455 printk(KERN_INFO PFX "timeout value must be 60<timeout<15300, using %d\n", 455 printk(KERN_INFO PFX
456 DEFAULT_TIMEOUT); 456 "timeout value must be 60 < timeout < 15300, using %d\n",
457 DEFAULT_TIMEOUT);
457 } 458 }
458 459
459 /* on Netwinder the IOports are already reserved by 460 /* on Netwinder the IOports are already reserved by
460 * arch/arm/mach-footbridge/netwinder-hw.c 461 * arch/arm/mach-footbridge/netwinder-hw.c
461 */ 462 */
462 if (!machine_is_netwinder()) 463 if (!machine_is_netwinder()) {
463 { 464 if (!request_region(IO_INDEX_PORT, 2, WATCHDOG_NAME)) {
464 if (!request_region(IO_INDEX_PORT, 2, WATCHDOG_NAME)) 465 printk(KERN_ERR PFX
465 { 466 "I/O address 0x%04x already in use\n",
466 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", 467 IO_INDEX_PORT);
467 IO_INDEX_PORT);
468 rc = -EIO; 468 rc = -EIO;
469 goto err_out; 469 goto err_out;
470 } 470 }
471 } 471 }
472 472
473 rc = register_reboot_notifier(&wdt977_notifier); 473 rc = register_reboot_notifier(&wdt977_notifier);
474 if (rc) 474 if (rc) {
475 { 475 printk(KERN_ERR PFX
476 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 476 "cannot register reboot notifier (err=%d)\n", rc);
477 rc);
478 goto err_out_region; 477 goto err_out_region;
479 } 478 }
480 479
481 rc = misc_register(&wdt977_miscdev); 480 rc = misc_register(&wdt977_miscdev);
482 if (rc) 481 if (rc) {
483 { 482 printk(KERN_ERR PFX
484 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 483 "cannot register miscdev on minor=%d (err=%d)\n",
485 wdt977_miscdev.minor, rc); 484 wdt977_miscdev.minor, rc);
486 goto err_out_reboot; 485 goto err_out_reboot;
487 } 486 }
488 487
489 printk(KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d, testmode=%i)\n", 488 printk(KERN_INFO PFX
490 timeout, nowayout, testmode); 489 "initialized. timeout=%d sec (nowayout=%d, testmode=%i)\n",
490 timeout, nowayout, testmode);
491 491
492 return 0; 492 return 0;
493 493
@@ -495,7 +495,7 @@ err_out_reboot:
495 unregister_reboot_notifier(&wdt977_notifier); 495 unregister_reboot_notifier(&wdt977_notifier);
496err_out_region: 496err_out_region:
497 if (!machine_is_netwinder()) 497 if (!machine_is_netwinder())
498 release_region(IO_INDEX_PORT,2); 498 release_region(IO_INDEX_PORT, 2);
499err_out: 499err_out:
500 return rc; 500 return rc;
501} 501}
@@ -505,7 +505,7 @@ static void __exit wd977_exit(void)
505 wdt977_stop(); 505 wdt977_stop();
506 misc_deregister(&wdt977_miscdev); 506 misc_deregister(&wdt977_miscdev);
507 unregister_reboot_notifier(&wdt977_notifier); 507 unregister_reboot_notifier(&wdt977_notifier);
508 release_region(IO_INDEX_PORT,2); 508 release_region(IO_INDEX_PORT, 2);
509} 509}
510 510
511module_init(wd977_init); 511module_init(wd977_init);
diff --git a/drivers/watchdog/wdt_pci.c b/drivers/watchdog/wdt_pci.c
index 5d922fd6eafc..ed02bdb38c09 100644
--- a/drivers/watchdog/wdt_pci.c
+++ b/drivers/watchdog/wdt_pci.c
@@ -381,7 +381,7 @@ static ssize_t wdtpci_write(struct file *file, const char __user *buf,
381 381
382 for (i = 0; i != count; i++) { 382 for (i = 0; i != count; i++) {
383 char c; 383 char c;
384 if (get_user(c, buf+i)) 384 if (get_user(c, buf + i))
385 return -EFAULT; 385 return -EFAULT;
386 if (c == 'V') 386 if (c == 'V')
387 expect_close = 42; 387 expect_close = 42;
@@ -428,8 +428,6 @@ static long wdtpci_ioctl(struct file *file, unsigned int cmd,
428#endif /* CONFIG_WDT_501_PCI */ 428#endif /* CONFIG_WDT_501_PCI */
429 429
430 switch (cmd) { 430 switch (cmd) {
431 default:
432 return -ENOTTY;
433 case WDIOC_GETSUPPORT: 431 case WDIOC_GETSUPPORT:
434 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; 432 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
435 case WDIOC_GETSTATUS: 433 case WDIOC_GETSTATUS:
@@ -449,7 +447,9 @@ static long wdtpci_ioctl(struct file *file, unsigned int cmd,
449 /* Fall */ 447 /* Fall */
450 case WDIOC_GETTIMEOUT: 448 case WDIOC_GETTIMEOUT:
451 return put_user(heartbeat, p); 449 return put_user(heartbeat, p);
452 } 450 default:
451 return -ENOTTY;
452 }
453} 453}
454 454
455/** 455/**