aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/watchdog/acquirewdt.c119
-rw-r--r--drivers/watchdog/advantechwdt.c135
-rw-r--r--drivers/watchdog/alim1535_wdt.c186
-rw-r--r--drivers/watchdog/alim7101_wdt.c224
-rw-r--r--drivers/watchdog/at32ap700x_wdt.c7
-rw-r--r--drivers/watchdog/at91rm9200_wdt.c108
-rw-r--r--drivers/watchdog/bfin_wdt.c147
-rw-r--r--drivers/watchdog/booke_wdt.c26
-rw-r--r--drivers/watchdog/cpu5wdt.c144
-rw-r--r--drivers/watchdog/davinci_wdt.c11
-rw-r--r--drivers/watchdog/ep93xx_wdt.c17
-rw-r--r--drivers/watchdog/eurotechwdt.c57
-rw-r--r--drivers/watchdog/hpwdt.c4
-rw-r--r--drivers/watchdog/i6300esb.c342
-rw-r--r--drivers/watchdog/iTCO_vendor.h15
-rw-r--r--drivers/watchdog/iTCO_vendor_support.c53
-rw-r--r--drivers/watchdog/iTCO_wdt.c296
-rw-r--r--drivers/watchdog/ib700wdt.c103
-rw-r--r--drivers/watchdog/ibmasr.c149
-rw-r--r--drivers/watchdog/indydog.c114
-rw-r--r--drivers/watchdog/iop_wdt.c46
-rw-r--r--drivers/watchdog/ixp2000_wdt.c50
-rw-r--r--drivers/watchdog/ixp4xx_wdt.c41
-rw-r--r--drivers/watchdog/ks8695_wdt.c119
-rw-r--r--drivers/watchdog/machzwd.c108
-rw-r--r--drivers/watchdog/mixcomwd.c133
-rw-r--r--drivers/watchdog/mpc5200_wdt.c18
-rw-r--r--drivers/watchdog/mpc83xx_wdt.c19
-rw-r--r--drivers/watchdog/mpc8xx_wdt.c37
-rw-r--r--drivers/watchdog/mpcore_wdt.c53
-rw-r--r--drivers/watchdog/mtx-1_wdt.c107
-rw-r--r--drivers/watchdog/mv64x60_wdt.c20
-rw-r--r--drivers/watchdog/omap_wdt.c35
-rw-r--r--drivers/watchdog/pc87413_wdt.c211
-rw-r--r--drivers/watchdog/pcwd.c179
-rw-r--r--drivers/watchdog/pnx4008_wdt.c18
-rw-r--r--drivers/watchdog/rm9k_wdt.c21
-rw-r--r--drivers/watchdog/sa1100_wdt.c32
-rw-r--r--drivers/watchdog/sb_wdog.c78
-rw-r--r--drivers/watchdog/sbc60xxwdt.c223
-rw-r--r--drivers/watchdog/sbc7240_wdt.c16
-rw-r--r--drivers/watchdog/sbc8360.c30
-rw-r--r--drivers/watchdog/sbc_epx_c3.c12
-rw-r--r--drivers/watchdog/sc520_wdt.c163
-rw-r--r--drivers/watchdog/scx200_wdt.c59
-rw-r--r--drivers/watchdog/shwdt.c139
-rw-r--r--drivers/watchdog/smsc37b787_wdt.c442
-rw-r--r--drivers/watchdog/softdog.c87
-rw-r--r--drivers/watchdog/txx9wdt.c31
-rw-r--r--drivers/watchdog/w83627hf_wdt.c175
-rw-r--r--drivers/watchdog/w83697hf_wdt.c148
-rw-r--r--drivers/watchdog/w83877f_wdt.c199
-rw-r--r--drivers/watchdog/w83977f_wdt.c225
-rw-r--r--drivers/watchdog/wafer5823wdt.c80
-rw-r--r--drivers/watchdog/wdrtas.c103
-rw-r--r--drivers/watchdog/wdt285.c31
-rw-r--r--drivers/watchdog/wdt977.c148
57 files changed, 2963 insertions, 2930 deletions
diff --git a/drivers/watchdog/acquirewdt.c b/drivers/watchdog/acquirewdt.c
index 85269c365a10..269ada2f1fc3 100644
--- a/drivers/watchdog/acquirewdt.c
+++ b/drivers/watchdog/acquirewdt.c
@@ -58,39 +58,46 @@
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
68#include <asm/uaccess.h> /* For copy_to_user/put_user/... */ 69#include <linux/uaccess.h> /* For copy_to_user/put_user/... */
69#include <asm/io.h> /* For inb/outb/... */ 70#include <linux/io.h> /* For inb/outb/... */
70 71
71/* Module information */ 72/* Module information */
72#define DRV_NAME "acquirewdt" 73#define DRV_NAME "acquirewdt"
73#define PFX DRV_NAME ": " 74#define PFX DRV_NAME ": "
74#define WATCHDOG_NAME "Acquire WDT" 75#define WATCHDOG_NAME "Acquire WDT"
75#define WATCHDOG_HEARTBEAT 0 /* There is no way to see what the correct time-out period is */ 76/* There is no way to see what the correct time-out period is */
77#define WATCHDOG_HEARTBEAT 0
76 78
77/* internal variables */ 79/* internal variables */
78static struct platform_device *acq_platform_device; /* the watchdog platform device */ 80/* the watchdog platform device */
81static struct platform_device *acq_platform_device;
79static unsigned long acq_is_open; 82static unsigned long acq_is_open;
80static char expect_close; 83static char expect_close;
81 84
82/* module parameters */ 85/* module parameters */
83static int wdt_stop = 0x43; /* You must set this - there is no sane way to probe for this board. */ 86/* You must set this - there is no sane way to probe for this board. */
87static int wdt_stop = 0x43;
84module_param(wdt_stop, int, 0); 88module_param(wdt_stop, int, 0);
85MODULE_PARM_DESC(wdt_stop, "Acquire WDT 'stop' io port (default 0x43)"); 89MODULE_PARM_DESC(wdt_stop, "Acquire WDT 'stop' io port (default 0x43)");
86 90
87static int wdt_start = 0x443; /* You must set this - there is no sane way to probe for this board. */ 91/* You must set this - there is no sane way to probe for this board. */
92static int wdt_start = 0x443;
88module_param(wdt_start, int, 0); 93module_param(wdt_start, int, 0);
89MODULE_PARM_DESC(wdt_start, "Acquire WDT 'start' io port (default 0x443)"); 94MODULE_PARM_DESC(wdt_start, "Acquire WDT 'start' io port (default 0x443)");
90 95
91static int nowayout = WATCHDOG_NOWAYOUT; 96static int nowayout = WATCHDOG_NOWAYOUT;
92module_param(nowayout, int, 0); 97module_param(nowayout, int, 0);
93MODULE_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) ")");
94 101
95/* 102/*
96 * Watchdog Operations 103 * Watchdog Operations
@@ -112,18 +119,18 @@ static void acq_stop(void)
112 * /dev/watchdog handling 119 * /dev/watchdog handling
113 */ 120 */
114 121
115static ssize_t acq_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) 122static ssize_t acq_write(struct file *file, const char __user *buf,
123 size_t count, loff_t *ppos)
116{ 124{
117 /* See if we got the magic character 'V' and reload the timer */ 125 /* See if we got the magic character 'V' and reload the timer */
118 if(count) { 126 if (count) {
119 if (!nowayout) { 127 if (!nowayout) {
120 size_t i; 128 size_t i;
121
122 /* note: just in case someone wrote the magic character 129 /* note: just in case someone wrote the magic character
123 * five months ago... */ 130 * five months ago... */
124 expect_close = 0; 131 expect_close = 0;
125 132 /* scan to see whether or not we got the
126 /* scan to see whether or not we got the magic character */ 133 magic character */
127 for (i = 0; i != count; i++) { 134 for (i = 0; i != count; i++) {
128 char c; 135 char c;
129 if (get_user(c, buf + i)) 136 if (get_user(c, buf + i))
@@ -132,64 +139,55 @@ static ssize_t acq_write(struct file *file, const char __user *buf, size_t count
132 expect_close = 42; 139 expect_close = 42;
133 } 140 }
134 } 141 }
135 142 /* Well, anyhow someone wrote to us, we should
136 /* Well, anyhow someone wrote to us, we should return that favour */ 143 return that favour */
137 acq_keepalive(); 144 acq_keepalive();
138 } 145 }
139 return count; 146 return count;
140} 147}
141 148
142static int acq_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 149static long acq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
143 unsigned long arg)
144{ 150{
145 int options, retval = -EINVAL; 151 int options, retval = -EINVAL;
146 void __user *argp = (void __user *)arg; 152 void __user *argp = (void __user *)arg;
147 int __user *p = argp; 153 int __user *p = argp;
148 static struct watchdog_info ident = 154 static struct watchdog_info ident = {
149 {
150 .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, 155 .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
151 .firmware_version = 1, 156 .firmware_version = 1,
152 .identity = WATCHDOG_NAME, 157 .identity = WATCHDOG_NAME,
153 }; 158 };
154 159
155 switch(cmd) 160 switch (cmd) {
156 {
157 case WDIOC_GETSUPPORT: 161 case WDIOC_GETSUPPORT:
158 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; 162 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
159 163
160 case WDIOC_GETSTATUS: 164 case WDIOC_GETSTATUS:
161 case WDIOC_GETBOOTSTATUS: 165 case WDIOC_GETBOOTSTATUS:
162 return put_user(0, p); 166 return put_user(0, p);
163 167
164 case WDIOC_KEEPALIVE: 168 case WDIOC_KEEPALIVE:
165 acq_keepalive(); 169 acq_keepalive();
166 return 0; 170 return 0;
167 171
168 case WDIOC_GETTIMEOUT: 172 case WDIOC_GETTIMEOUT:
169 return put_user(WATCHDOG_HEARTBEAT, p); 173 return put_user(WATCHDOG_HEARTBEAT, p);
170 174
171 case WDIOC_SETOPTIONS: 175 case WDIOC_SETOPTIONS:
172 { 176 {
173 if (get_user(options, p)) 177 if (get_user(options, p))
174 return -EFAULT; 178 return -EFAULT;
175 179 if (options & WDIOS_DISABLECARD) {
176 if (options & WDIOS_DISABLECARD) 180 acq_stop();
177 { 181 retval = 0;
178 acq_stop(); 182 }
179 retval = 0; 183 if (options & WDIOS_ENABLECARD) {
180 } 184 acq_keepalive();
181 185 retval = 0;
182 if (options & WDIOS_ENABLECARD) 186 }
183 { 187 return retval;
184 acq_keepalive();
185 retval = 0;
186 }
187
188 return retval;
189 } 188 }
190
191 default: 189 default:
192 return -ENOTTY; 190 return -ENOTTY;
193 } 191 }
194} 192}
195 193
@@ -211,7 +209,8 @@ static int acq_close(struct inode *inode, struct file *file)
211 if (expect_close == 42) { 209 if (expect_close == 42) {
212 acq_stop(); 210 acq_stop();
213 } else { 211 } else {
214 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); 212 printk(KERN_CRIT PFX
213 "Unexpected close, not stopping watchdog!\n");
215 acq_keepalive(); 214 acq_keepalive();
216 } 215 }
217 clear_bit(0, &acq_is_open); 216 clear_bit(0, &acq_is_open);
@@ -227,7 +226,7 @@ static const struct file_operations acq_fops = {
227 .owner = THIS_MODULE, 226 .owner = THIS_MODULE,
228 .llseek = no_llseek, 227 .llseek = no_llseek,
229 .write = acq_write, 228 .write = acq_write,
230 .ioctl = acq_ioctl, 229 .unlocked_ioctl = acq_ioctl,
231 .open = acq_open, 230 .open = acq_open,
232 .release = acq_close, 231 .release = acq_close,
233}; 232};
@@ -248,32 +247,29 @@ static int __devinit acq_probe(struct platform_device *dev)
248 247
249 if (wdt_stop != wdt_start) { 248 if (wdt_stop != wdt_start) {
250 if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) { 249 if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) {
251 printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", 250 printk(KERN_ERR PFX
252 wdt_stop); 251 "I/O address 0x%04x already in use\n", wdt_stop);
253 ret = -EIO; 252 ret = -EIO;
254 goto out; 253 goto out;
255 } 254 }
256 } 255 }
257 256
258 if (!request_region(wdt_start, 1, WATCHDOG_NAME)) { 257 if (!request_region(wdt_start, 1, WATCHDOG_NAME)) {
259 printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", 258 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n",
260 wdt_start); 259 wdt_start);
261 ret = -EIO; 260 ret = -EIO;
262 goto unreg_stop; 261 goto unreg_stop;
263 } 262 }
264
265 ret = misc_register(&acq_miscdev); 263 ret = misc_register(&acq_miscdev);
266 if (ret != 0) { 264 if (ret != 0) {
267 printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 265 printk(KERN_ERR PFX
268 WATCHDOG_MINOR, ret); 266 "cannot register miscdev on minor=%d (err=%d)\n",
267 WATCHDOG_MINOR, ret);
269 goto unreg_regions; 268 goto unreg_regions;
270 } 269 }
271 270 printk(KERN_INFO PFX "initialized. (nowayout=%d)\n", nowayout);
272 printk (KERN_INFO PFX "initialized. (nowayout=%d)\n",
273 nowayout);
274 271
275 return 0; 272 return 0;
276
277unreg_regions: 273unreg_regions:
278 release_region(wdt_start, 1); 274 release_region(wdt_start, 1);
279unreg_stop: 275unreg_stop:
@@ -286,9 +282,9 @@ out:
286static int __devexit acq_remove(struct platform_device *dev) 282static int __devexit acq_remove(struct platform_device *dev)
287{ 283{
288 misc_deregister(&acq_miscdev); 284 misc_deregister(&acq_miscdev);
289 release_region(wdt_start,1); 285 release_region(wdt_start, 1);
290 if(wdt_stop != wdt_start) 286 if (wdt_stop != wdt_start)
291 release_region(wdt_stop,1); 287 release_region(wdt_stop, 1);
292 288
293 return 0; 289 return 0;
294} 290}
@@ -313,18 +309,19 @@ static int __init acq_init(void)
313{ 309{
314 int err; 310 int err;
315 311
316 printk(KERN_INFO "WDT driver for Acquire single board computer initialising.\n"); 312 printk(KERN_INFO
313 "WDT driver for Acquire single board computer initialising.\n");
317 314
318 err = platform_driver_register(&acquirewdt_driver); 315 err = platform_driver_register(&acquirewdt_driver);
319 if (err) 316 if (err)
320 return err; 317 return err;
321 318
322 acq_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0); 319 acq_platform_device = platform_device_register_simple(DRV_NAME,
320 -1, NULL, 0);
323 if (IS_ERR(acq_platform_device)) { 321 if (IS_ERR(acq_platform_device)) {
324 err = PTR_ERR(acq_platform_device); 322 err = PTR_ERR(acq_platform_device);
325 goto unreg_platform_driver; 323 goto unreg_platform_driver;
326 } 324 }
327
328 return 0; 325 return 0;
329 326
330unreg_platform_driver: 327unreg_platform_driver:
diff --git a/drivers/watchdog/advantechwdt.c b/drivers/watchdog/advantechwdt.c
index 8121cc247343..220d238ee427 100644
--- a/drivers/watchdog/advantechwdt.c
+++ b/drivers/watchdog/advantechwdt.c
@@ -72,35 +72,35 @@ MODULE_PARM_DESC(wdt_start, "Advantech WDT 'start' io port (default 0x443)");
72 72
73static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ 73static int timeout = WATCHDOG_TIMEOUT; /* in seconds */
74module_param(timeout, int, 0); 74module_param(timeout, int, 0);
75MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=63, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) "."); 75MODULE_PARM_DESC(timeout,
76 "Watchdog timeout in seconds. 1<= timeout <=63, default="
77 __MODULE_STRING(WATCHDOG_TIMEOUT) ".");
76 78
77static int nowayout = WATCHDOG_NOWAYOUT; 79static int nowayout = WATCHDOG_NOWAYOUT;
78module_param(nowayout, int, 0); 80module_param(nowayout, int, 0);
79MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 81MODULE_PARM_DESC(nowayout,
82 "Watchdog cannot be stopped once started (default="
83 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
80 84
81/* 85/*
82 * Watchdog Operations 86 * Watchdog Operations
83 */ 87 */
84 88
85static void 89static void advwdt_ping(void)
86advwdt_ping(void)
87{ 90{
88 /* Write a watchdog value */ 91 /* Write a watchdog value */
89 outb_p(timeout, wdt_start); 92 outb_p(timeout, wdt_start);
90} 93}
91 94
92static void 95static void advwdt_disable(void)
93advwdt_disable(void)
94{ 96{
95 inb_p(wdt_stop); 97 inb_p(wdt_stop);
96} 98}
97 99
98static int 100static int advwdt_set_heartbeat(int t)
99advwdt_set_heartbeat(int t)
100{ 101{
101 if ((t < 1) || (t > 63)) 102 if (t < 1 || t > 63)
102 return -EINVAL; 103 return -EINVAL;
103
104 timeout = t; 104 timeout = t;
105 return 0; 105 return 0;
106} 106}
@@ -109,8 +109,8 @@ advwdt_set_heartbeat(int t)
109 * /dev/watchdog handling 109 * /dev/watchdog handling
110 */ 110 */
111 111
112static ssize_t 112static 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) 113 size_t count, loff_t *ppos)
114{ 114{
115 if (count) { 115 if (count) {
116 if (!nowayout) { 116 if (!nowayout) {
@@ -131,9 +131,7 @@ advwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *pp
131 return count; 131 return count;
132} 132}
133 133
134static int 134static 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{ 135{
138 int new_timeout; 136 int new_timeout;
139 void __user *argp = (void __user *)arg; 137 void __user *argp = (void __user *)arg;
@@ -146,57 +144,50 @@ advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
146 144
147 switch (cmd) { 145 switch (cmd) {
148 case WDIOC_GETSUPPORT: 146 case WDIOC_GETSUPPORT:
149 if (copy_to_user(argp, &ident, sizeof(ident))) 147 if (copy_to_user(argp, &ident, sizeof(ident)))
150 return -EFAULT; 148 return -EFAULT;
151 break; 149 break;
152 150
153 case WDIOC_GETSTATUS: 151 case WDIOC_GETSTATUS:
154 case WDIOC_GETBOOTSTATUS: 152 case WDIOC_GETBOOTSTATUS:
155 return put_user(0, p); 153 return put_user(0, p);
156 154
157 case WDIOC_KEEPALIVE: 155 case WDIOC_KEEPALIVE:
158 advwdt_ping(); 156 advwdt_ping();
159 break; 157 break;
160 158
161 case WDIOC_SETTIMEOUT: 159 case WDIOC_SETTIMEOUT:
162 if (get_user(new_timeout, p)) 160 if (get_user(new_timeout, p))
163 return -EFAULT; 161 return -EFAULT;
164 if (advwdt_set_heartbeat(new_timeout)) 162 if (advwdt_set_heartbeat(new_timeout))
165 return -EINVAL; 163 return -EINVAL;
166 advwdt_ping(); 164 advwdt_ping();
167 /* Fall */ 165 /* Fall */
168
169 case WDIOC_GETTIMEOUT: 166 case WDIOC_GETTIMEOUT:
170 return put_user(timeout, p); 167 return put_user(timeout, p);
171
172 case WDIOC_SETOPTIONS: 168 case WDIOC_SETOPTIONS:
173 { 169 {
174 int options, retval = -EINVAL; 170 int options, retval = -EINVAL;
175
176 if (get_user(options, p))
177 return -EFAULT;
178 171
179 if (options & WDIOS_DISABLECARD) { 172 if (get_user(options, p))
180 advwdt_disable(); 173 return -EFAULT;
181 retval = 0; 174 if (options & WDIOS_DISABLECARD) {
182 } 175 advwdt_disable();
183 176 retval = 0;
184 if (options & WDIOS_ENABLECARD) { 177 }
185 advwdt_ping(); 178 if (options & WDIOS_ENABLECARD) {
186 retval = 0; 179 advwdt_ping();
187 } 180 retval = 0;
188 181 }
189 return retval; 182 return retval;
190 } 183 }
191
192 default: 184 default:
193 return -ENOTTY; 185 return -ENOTTY;
194 } 186 }
195 return 0; 187 return 0;
196} 188}
197 189
198static int 190static int advwdt_open(struct inode *inode, struct file *file)
199advwdt_open(struct inode *inode, struct file *file)
200{ 191{
201 if (test_and_set_bit(0, &advwdt_is_open)) 192 if (test_and_set_bit(0, &advwdt_is_open))
202 return -EBUSY; 193 return -EBUSY;
@@ -214,7 +205,8 @@ advwdt_close(struct inode *inode, struct file *file)
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,8 +285,7 @@ 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);
@@ -304,8 +295,7 @@ advwdt_remove(struct platform_device *dev)
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,8 +311,7 @@ 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
@@ -332,7 +321,8 @@ advwdt_init(void)
332 if (err) 321 if (err)
333 return err; 322 return err;
334 323
335 advwdt_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0); 324 advwdt_platform_device = platform_device_register_simple(DRV_NAME,
325 -1, NULL, 0);
336 if (IS_ERR(advwdt_platform_device)) { 326 if (IS_ERR(advwdt_platform_device)) {
337 err = PTR_ERR(advwdt_platform_device); 327 err = PTR_ERR(advwdt_platform_device);
338 goto unreg_platform_driver; 328 goto unreg_platform_driver;
@@ -345,8 +335,7 @@ unreg_platform_driver:
345 return err; 335 return err;
346} 336}
347 337
348static void __exit 338static void __exit advwdt_exit(void)
349advwdt_exit(void)
350{ 339{
351 platform_device_unregister(advwdt_platform_device); 340 platform_device_unregister(advwdt_platform_device);
352 platform_driver_unregister(&advwdt_driver); 341 platform_driver_unregister(&advwdt_driver);
diff --git a/drivers/watchdog/alim1535_wdt.c b/drivers/watchdog/alim1535_wdt.c
index 2b1fbdb2fcf7..88760cb5ec13 100644
--- a/drivers/watchdog/alim1535_wdt.c
+++ b/drivers/watchdog/alim1535_wdt.c
@@ -19,8 +19,8 @@
19#include <linux/fs.h> 19#include <linux/fs.h>
20#include <linux/pci.h> 20#include <linux/pci.h>
21 21
22#include <asm/uaccess.h> 22#include <linux/uaccess.h>
23#include <asm/io.h> 23#include <linux/io.h>
24 24
25#define WATCHDOG_NAME "ALi_M1535" 25#define WATCHDOG_NAME "ALi_M1535"
26#define PFX WATCHDOG_NAME ": " 26#define PFX WATCHDOG_NAME ": "
@@ -30,17 +30,21 @@
30static unsigned long ali_is_open; 30static unsigned long ali_is_open;
31static char ali_expect_release; 31static char ali_expect_release;
32static struct pci_dev *ali_pci; 32static struct pci_dev *ali_pci;
33static u32 ali_timeout_bits; /* stores the computed timeout */ 33static u32 ali_timeout_bits; /* stores the computed timeout */
34static DEFINE_SPINLOCK(ali_lock); /* Guards the hardware */ 34static DEFINE_SPINLOCK(ali_lock); /* Guards the hardware */
35 35
36/* module parameters */ 36/* module parameters */
37static int timeout = WATCHDOG_TIMEOUT; 37static int timeout = WATCHDOG_TIMEOUT;
38module_param(timeout, int, 0); 38module_param(timeout, int, 0);
39MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (0<timeout<18000, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); 39MODULE_PARM_DESC(timeout,
40 "Watchdog timeout in seconds. (0 < timeout < 18000, default="
41 __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
40 42
41static int nowayout = WATCHDOG_NOWAYOUT; 43static int nowayout = WATCHDOG_NOWAYOUT;
42module_param(nowayout, int, 0); 44module_param(nowayout, int, 0);
43MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 45MODULE_PARM_DESC(nowayout,
46 "Watchdog cannot be stopped once started (default="
47 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
44 48
45/* 49/*
46 * ali_start - start watchdog countdown 50 * ali_start - start watchdog countdown
@@ -103,15 +107,16 @@ static void ali_keepalive(void)
103 107
104static int ali_settimer(int t) 108static int ali_settimer(int t)
105{ 109{
106 if(t < 0) 110 if (t < 0)
107 return -EINVAL; 111 return -EINVAL;
108 else if(t < 60) 112 else if (t < 60)
109 ali_timeout_bits = t|(1<<6); 113 ali_timeout_bits = t|(1<<6);
110 else if(t < 3600) 114 else if (t < 3600)
111 ali_timeout_bits = (t/60)|(1<<7); 115 ali_timeout_bits = (t/60)|(1<<7);
112 else if(t < 18000) 116 else if (t < 18000)
113 ali_timeout_bits = (t/300)|(1<<6)|(1<<7); 117 ali_timeout_bits = (t/300)|(1<<6)|(1<<7);
114 else return -EINVAL; 118 else
119 return -EINVAL;
115 120
116 timeout = t; 121 timeout = t;
117 return 0; 122 return 0;
@@ -134,21 +139,22 @@ static int ali_settimer(int t)
134 */ 139 */
135 140
136static ssize_t ali_write(struct file *file, const char __user *data, 141static ssize_t ali_write(struct file *file, const char __user *data,
137 size_t len, loff_t * ppos) 142 size_t len, loff_t *ppos)
138{ 143{
139 /* See if we got the magic character 'V' and reload the timer */ 144 /* See if we got the magic character 'V' and reload the timer */
140 if (len) { 145 if (len) {
141 if (!nowayout) { 146 if (!nowayout) {
142 size_t i; 147 size_t i;
143 148
144 /* note: just in case someone wrote the magic character 149 /* note: just in case someone wrote the
145 * five months ago... */ 150 magic character five months ago... */
146 ali_expect_release = 0; 151 ali_expect_release = 0;
147 152
148 /* scan to see whether or not we got the magic character */ 153 /* scan to see whether or not we got
154 the magic character */
149 for (i = 0; i != len; i++) { 155 for (i = 0; i != len; i++) {
150 char c; 156 char c;
151 if(get_user(c, data+i)) 157 if (get_user(c, data+i))
152 return -EFAULT; 158 return -EFAULT;
153 if (c == 'V') 159 if (c == 'V')
154 ali_expect_release = 42; 160 ali_expect_release = 42;
@@ -163,7 +169,6 @@ static ssize_t ali_write(struct file *file, const char __user *data,
163 169
164/* 170/*
165 * ali_ioctl - handle watchdog ioctls 171 * ali_ioctl - handle watchdog ioctls
166 * @inode: VFS inode
167 * @file: VFS file pointer 172 * @file: VFS file pointer
168 * @cmd: ioctl number 173 * @cmd: ioctl number
169 * @arg: arguments to the ioctl 174 * @arg: arguments to the ioctl
@@ -172,8 +177,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 177 * we want an extension to enable irq ack monitoring and the like
173 */ 178 */
174 179
175static int ali_ioctl(struct inode *inode, struct file *file, 180static long ali_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
176 unsigned int cmd, unsigned long arg)
177{ 181{
178 void __user *argp = (void __user *)arg; 182 void __user *argp = (void __user *)arg;
179 int __user *p = argp; 183 int __user *p = argp;
@@ -186,57 +190,45 @@ static int ali_ioctl(struct inode *inode, struct file *file,
186 }; 190 };
187 191
188 switch (cmd) { 192 switch (cmd) {
189 case WDIOC_GETSUPPORT: 193 case WDIOC_GETSUPPORT:
190 return copy_to_user(argp, &ident, 194 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
191 sizeof (ident)) ? -EFAULT : 0;
192
193 case WDIOC_GETSTATUS:
194 case WDIOC_GETBOOTSTATUS:
195 return put_user(0, p);
196
197 case WDIOC_KEEPALIVE:
198 ali_keepalive();
199 return 0;
200
201 case WDIOC_SETOPTIONS:
202 {
203 int new_options, retval = -EINVAL;
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 195
218 return retval; 196 case WDIOC_GETSTATUS:
197 case WDIOC_GETBOOTSTATUS:
198 return put_user(0, p);
199 case WDIOC_KEEPALIVE:
200 ali_keepalive();
201 return 0;
202 case WDIOC_SETOPTIONS:
203 {
204 int new_options, retval = -EINVAL;
205
206 if (get_user(new_options, p))
207 return -EFAULT;
208 if (new_options & WDIOS_DISABLECARD) {
209 ali_stop();
210 retval = 0;
219 } 211 }
220 212 if (new_options & WDIOS_ENABLECARD) {
221 case WDIOC_SETTIMEOUT: 213 ali_start();
222 { 214 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 } 215 }
234 216 return retval;
235 case WDIOC_GETTIMEOUT: 217 }
236 return put_user(timeout, p); 218 case WDIOC_SETTIMEOUT:
237 219 {
238 default: 220 int new_timeout;
239 return -ENOTTY; 221 if (get_user(new_timeout, p))
222 return -EFAULT;
223 if (ali_settimer(new_timeout))
224 return -EINVAL;
225 ali_keepalive();
226 /* Fall */
227 }
228 case WDIOC_GETTIMEOUT:
229 return put_user(timeout, p);
230 default:
231 return -ENOTTY;
240 } 232 }
241} 233}
242 234
@@ -274,10 +266,11 @@ static int ali_release(struct inode *inode, struct file *file)
274 /* 266 /*
275 * Shut off the timer. 267 * Shut off the timer.
276 */ 268 */
277 if (ali_expect_release == 42) { 269 if (ali_expect_release == 42)
278 ali_stop(); 270 ali_stop();
279 } else { 271 else {
280 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); 272 printk(KERN_CRIT PFX
273 "Unexpected close, not stopping watchdog!\n");
281 ali_keepalive(); 274 ali_keepalive();
282 } 275 }
283 clear_bit(0, &ali_is_open); 276 clear_bit(0, &ali_is_open);
@@ -292,13 +285,11 @@ static int ali_release(struct inode *inode, struct file *file)
292 */ 285 */
293 286
294 287
295static int ali_notify_sys(struct notifier_block *this, unsigned long code, void *unused) 288static int ali_notify_sys(struct notifier_block *this,
289 unsigned long code, void *unused)
296{ 290{
297 if (code==SYS_DOWN || code==SYS_HALT) { 291 if (code == SYS_DOWN || code == SYS_HALT)
298 /* Turn the WDT off */ 292 ali_stop(); /* Turn the WDT off */
299 ali_stop();
300 }
301
302 return NOTIFY_DONE; 293 return NOTIFY_DONE;
303} 294}
304 295
@@ -340,10 +331,10 @@ static int __init ali_find_watchdog(void)
340 331
341 /* Check for the a 7101 PMU */ 332 /* Check for the a 7101 PMU */
342 pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x7101, NULL); 333 pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x7101, NULL);
343 if(pdev == NULL) 334 if (pdev == NULL)
344 return -ENODEV; 335 return -ENODEV;
345 336
346 if(pci_enable_device(pdev)) { 337 if (pci_enable_device(pdev)) {
347 pci_dev_put(pdev); 338 pci_dev_put(pdev);
348 return -EIO; 339 return -EIO;
349 } 340 }
@@ -355,9 +346,12 @@ static int __init ali_find_watchdog(void)
355 */ 346 */
356 pci_read_config_dword(pdev, 0xCC, &wdog); 347 pci_read_config_dword(pdev, 0xCC, &wdog);
357 348
358 wdog &= ~0x3F; /* Timer bits */ 349 /* Timer bits */
359 wdog &= ~((1<<27)|(1<<26)|(1<<25)|(1<<24)); /* Issued events */ 350 wdog &= ~0x3F;
360 wdog &= ~((1<<16)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)); /* No monitor bits */ 351 /* Issued events */
352 wdog &= ~((1<<27)|(1<<26)|(1<<25)|(1<<24));
353 /* No monitor bits */
354 wdog &= ~((1<<16)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9));
361 355
362 pci_write_config_dword(pdev, 0xCC, wdog); 356 pci_write_config_dword(pdev, 0xCC, wdog);
363 357
@@ -369,12 +363,12 @@ static int __init ali_find_watchdog(void)
369 */ 363 */
370 364
371static const struct file_operations ali_fops = { 365static const struct file_operations ali_fops = {
372 .owner = THIS_MODULE, 366 .owner = THIS_MODULE,
373 .llseek = no_llseek, 367 .llseek = no_llseek,
374 .write = ali_write, 368 .write = ali_write,
375 .ioctl = ali_ioctl, 369 .unlocked_ioctl = ali_ioctl,
376 .open = ali_open, 370 .open = ali_open,
377 .release = ali_release, 371 .release = ali_release,
378}; 372};
379 373
380static struct miscdevice ali_miscdev = { 374static struct miscdevice ali_miscdev = {
@@ -399,15 +393,16 @@ static int __init watchdog_init(void)
399 int ret; 393 int ret;
400 394
401 /* Check whether or not the hardware watchdog is there */ 395 /* Check whether or not the hardware watchdog is there */
402 if (ali_find_watchdog() != 0) { 396 if (ali_find_watchdog() != 0)
403 return -ENODEV; 397 return -ENODEV;
404 }
405 398
406 /* Check that the timeout value is within it's range ; if not reset to the default */ 399 /* Check that the timeout value is within it's range;
400 if not reset to the default */
407 if (timeout < 1 || timeout >= 18000) { 401 if (timeout < 1 || timeout >= 18000) {
408 timeout = WATCHDOG_TIMEOUT; 402 timeout = WATCHDOG_TIMEOUT;
409 printk(KERN_INFO PFX "timeout value must be 0<timeout<18000, using %d\n", 403 printk(KERN_INFO PFX
410 timeout); 404 "timeout value must be 0 < timeout < 18000, using %d\n",
405 timeout);
411 } 406 }
412 407
413 /* Calculate the watchdog's timeout */ 408 /* Calculate the watchdog's timeout */
@@ -415,15 +410,16 @@ static int __init watchdog_init(void)
415 410
416 ret = register_reboot_notifier(&ali_notifier); 411 ret = register_reboot_notifier(&ali_notifier);
417 if (ret != 0) { 412 if (ret != 0) {
418 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 413 printk(KERN_ERR PFX
419 ret); 414 "cannot register reboot notifier (err=%d)\n", ret);
420 goto out; 415 goto out;
421 } 416 }
422 417
423 ret = misc_register(&ali_miscdev); 418 ret = misc_register(&ali_miscdev);
424 if (ret != 0) { 419 if (ret != 0) {
425 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 420 printk(KERN_ERR PFX
426 WATCHDOG_MINOR, ret); 421 "cannot register miscdev on minor=%d (err=%d)\n",
422 WATCHDOG_MINOR, ret);
427 goto unreg_reboot; 423 goto unreg_reboot;
428 } 424 }
429 425
diff --git a/drivers/watchdog/alim7101_wdt.c b/drivers/watchdog/alim7101_wdt.c
index 238273c98656..c495f36c6aa9 100644
--- a/drivers/watchdog/alim7101_wdt.c
+++ b/drivers/watchdog/alim7101_wdt.c
@@ -32,8 +32,8 @@
32#include <linux/fs.h> 32#include <linux/fs.h>
33#include <linux/pci.h> 33#include <linux/pci.h>
34 34
35#include <asm/io.h> 35#include <linux/io.h>
36#include <asm/uaccess.h> 36#include <linux/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);
@@ -121,17 +129,23 @@ static void wdt_change(int writeval)
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
@@ -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_KEEPALIVE:
255 wdt_keepalive();
256 return 0;
257 case WDIOC_SETOPTIONS:
233 { 258 {
234 case WDIOC_GETSUPPORT: 259 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
254 if(new_options & WDIOS_ENABLECARD) {
255 wdt_startup();
256 retval = 0;
257 }
258 260
259 return retval; 261 if (get_user(new_options, p))
262 return -EFAULT;
263 if (new_options & WDIOS_DISABLECARD) {
264 wdt_turnoff();
265 retval = 0;
260 } 266 }
261 case WDIOC_SETTIMEOUT: 267 if (new_options & WDIOS_ENABLECARD) {
262 { 268 wdt_startup();
263 int new_timeout; 269 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 } 270 }
275 case WDIOC_GETTIMEOUT: 271 return retval;
276 return put_user(timeout, p); 272 }
277 default: 273 case WDIOC_SETTIMEOUT:
278 return -ENOTTY; 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/at32ap700x_wdt.c b/drivers/watchdog/at32ap700x_wdt.c
index ae0fca5e8749..c5dc5e912fb2 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;
@@ -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 9ff9a9565320..bb79f649dc7e 100644
--- a/drivers/watchdog/at91rm9200_wdt.c
+++ b/drivers/watchdog/at91rm9200_wdt.c
@@ -20,7 +20,7 @@
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 <asm/arch/at91_st.h> 24#include <asm/arch/at91_st.h>
25 25
26 26
@@ -31,11 +31,14 @@ static int wdt_time = WDT_DEFAULT_TIME;
31static int nowayout = WATCHDOG_NOWAYOUT; 31static int nowayout = WATCHDOG_NOWAYOUT;
32 32
33module_param(wdt_time, int, 0); 33module_param(wdt_time, int, 0);
34MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="__MODULE_STRING(WDT_DEFAULT_TIME) ")"); 34MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="
35 __MODULE_STRING(WDT_DEFAULT_TIME) ")");
35 36
36#ifdef CONFIG_WATCHDOG_NOWAYOUT 37#ifdef CONFIG_WATCHDOG_NOWAYOUT
37module_param(nowayout, int, 0); 38module_param(nowayout, int, 0);
38MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 39MODULE_PARM_DESC(nowayout,
40 "Watchdog cannot be stopped once started (default="
41 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
39#endif 42#endif
40 43
41 44
@@ -46,7 +49,7 @@ static unsigned long at91wdt_busy;
46/* 49/*
47 * Disable the watchdog. 50 * Disable the watchdog.
48 */ 51 */
49static void inline at91_wdt_stop(void) 52static inline void at91_wdt_stop(void)
50{ 53{
51 at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN); 54 at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN);
52} 55}
@@ -54,16 +57,17 @@ static void inline at91_wdt_stop(void)
54/* 57/*
55 * Enable and reset the watchdog. 58 * Enable and reset the watchdog.
56 */ 59 */
57static void inline at91_wdt_start(void) 60static inline void at91_wdt_start(void)
58{ 61{
59 at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN | AT91_ST_RSTEN | (((65536 * wdt_time) >> 8) & AT91_ST_WDV)); 62 at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN | AT91_ST_RSTEN |
63 (((65536 * wdt_time) >> 8) & AT91_ST_WDV));
60 at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); 64 at91_sys_write(AT91_ST_CR, AT91_ST_WDRST);
61} 65}
62 66
63/* 67/*
64 * Reload the watchdog timer. (ie, pat the watchdog) 68 * Reload the watchdog timer. (ie, pat the watchdog)
65 */ 69 */
66static void inline at91_wdt_reload(void) 70static inline void at91_wdt_reload(void)
67{ 71{
68 at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); 72 at91_sys_write(AT91_ST_CR, AT91_ST_WDRST);
69} 73}
@@ -89,8 +93,9 @@ static int at91_wdt_open(struct inode *inode, struct file *file)
89 */ 93 */
90static int at91_wdt_close(struct inode *inode, struct file *file) 94static int at91_wdt_close(struct inode *inode, struct file *file)
91{ 95{
96 /* Disable the watchdog when file is closed */
92 if (!nowayout) 97 if (!nowayout)
93 at91_wdt_stop(); /* Disable the watchdog when file is closed */ 98 at91_wdt_stop();
94 99
95 clear_bit(0, &at91wdt_busy); 100 clear_bit(0, &at91wdt_busy);
96 return 0; 101 return 0;
@@ -110,7 +115,8 @@ static int at91_wdt_settimeout(int new_time)
110 if ((new_time <= 0) || (new_time > WDT_MAX_TIME)) 115 if ((new_time <= 0) || (new_time > WDT_MAX_TIME))
111 return -EINVAL; 116 return -EINVAL;
112 117
113 /* Set new watchdog time. It will be used when at91_wdt_start() is called. */ 118 /* Set new watchdog time. It will be used when
119 at91_wdt_start() is called. */
114 wdt_time = new_time; 120 wdt_time = new_time;
115 return 0; 121 return 0;
116} 122}
@@ -123,60 +129,52 @@ static struct watchdog_info at91_wdt_info = {
123/* 129/*
124 * Handle commands from user-space. 130 * Handle commands from user-space.
125 */ 131 */
126static int at91_wdt_ioctl(struct inode *inode, struct file *file, 132static long at91_wdt_ioct(struct file *file,
127 unsigned int cmd, unsigned long arg) 133 unsigned int cmd, unsigned long arg)
128{ 134{
129 void __user *argp = (void __user *)arg; 135 void __user *argp = (void __user *)arg;
130 int __user *p = argp; 136 int __user *p = argp;
131 int new_value; 137 int new_value;
132 138
133 switch(cmd) { 139 switch (cmd) {
134 case WDIOC_KEEPALIVE: 140 case WDIOC_KEEPALIVE:
135 at91_wdt_reload(); /* pat the watchdog */ 141 at91_wdt_reload(); /* pat the watchdog */
136 return 0; 142 return 0;
137 143 case WDIOC_GETSUPPORT:
138 case WDIOC_GETSUPPORT: 144 return copy_to_user(argp, &at91_wdt_info,
139 return copy_to_user(argp, &at91_wdt_info, sizeof(at91_wdt_info)) ? -EFAULT : 0; 145 sizeof(at91_wdt_info)) ? -EFAULT : 0;
140 146 case WDIOC_SETTIMEOUT:
141 case WDIOC_SETTIMEOUT: 147 if (get_user(new_value, p))
142 if (get_user(new_value, p)) 148 return -EFAULT;
143 return -EFAULT; 149 if (at91_wdt_settimeout(new_value))
144 150 return -EINVAL;
145 if (at91_wdt_settimeout(new_value)) 151 /* Enable new time value */
146 return -EINVAL; 152 at91_wdt_start();
147 153 /* Return current value */
148 /* Enable new time value */ 154 return put_user(wdt_time, p);
155 case WDIOC_GETTIMEOUT:
156 return put_user(wdt_time, p);
157 case WDIOC_GETSTATUS:
158 case WDIOC_GETBOOTSTATUS:
159 return put_user(0, p);
160 case WDIOC_SETOPTIONS:
161 if (get_user(new_value, p))
162 return -EFAULT;
163 if (new_value & WDIOS_DISABLECARD)
164 at91_wdt_stop();
165 if (new_value & WDIOS_ENABLECARD)
149 at91_wdt_start(); 166 at91_wdt_start();
150 167 return 0;
151 /* Return current value */ 168 default:
152 return put_user(wdt_time, p); 169 return -ENOTTY;
153
154 case WDIOC_GETTIMEOUT:
155 return put_user(wdt_time, p);
156
157 case WDIOC_GETSTATUS:
158 case WDIOC_GETBOOTSTATUS:
159 return put_user(0, p);
160
161 case WDIOC_SETOPTIONS:
162 if (get_user(new_value, p))
163 return -EFAULT;
164
165 if (new_value & WDIOS_DISABLECARD)
166 at91_wdt_stop();
167 if (new_value & WDIOS_ENABLECARD)
168 at91_wdt_start();
169 return 0;
170
171 default:
172 return -ENOTTY;
173 } 170 }
174} 171}
175 172
176/* 173/*
177 * Pat the watchdog whenever device is written to. 174 * Pat the watchdog whenever device is written to.
178 */ 175 */
179static ssize_t at91_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) 176static ssize_t at91_wdt_write(struct file *file, const char *data,
177 size_t len, loff_t *ppos)
180{ 178{
181 at91_wdt_reload(); /* pat the watchdog */ 179 at91_wdt_reload(); /* pat the watchdog */
182 return len; 180 return len;
@@ -187,7 +185,7 @@ static ssize_t at91_wdt_write(struct file *file, const char *data, size_t len, l
187static const struct file_operations at91wdt_fops = { 185static const struct file_operations at91wdt_fops = {
188 .owner = THIS_MODULE, 186 .owner = THIS_MODULE,
189 .llseek = no_llseek, 187 .llseek = no_llseek,
190 .ioctl = at91_wdt_ioctl, 188 .unlocked_ioctl = at91_wdt_ioctl,
191 .open = at91_wdt_open, 189 .open = at91_wdt_open,
192 .release = at91_wdt_close, 190 .release = at91_wdt_close,
193 .write = at91_wdt_write, 191 .write = at91_wdt_write,
@@ -211,7 +209,8 @@ static int __init at91wdt_probe(struct platform_device *pdev)
211 if (res) 209 if (res)
212 return res; 210 return res;
213 211
214 printk("AT91 Watchdog Timer enabled (%d seconds%s)\n", wdt_time, nowayout ? ", nowayout" : ""); 212 printk(KERN_INFO "AT91 Watchdog Timer enabled (%d seconds%s)\n",
213 wdt_time, nowayout ? ", nowayout" : "");
215 return 0; 214 return 0;
216} 215}
217 216
@@ -265,7 +264,8 @@ static struct platform_driver at91wdt_driver = {
265 264
266static int __init at91_wdt_init(void) 265static int __init at91_wdt_init(void)
267{ 266{
268 /* Check that the heartbeat value is within range; if not reset to the default */ 267 /* Check that the heartbeat value is within range;
268 if not reset to the default */
269 if (at91_wdt_settimeout(wdt_time)) { 269 if (at91_wdt_settimeout(wdt_time)) {
270 at91_wdt_settimeout(WDT_DEFAULT_TIME); 270 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); 271 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..2b92818cc664 100644
--- a/drivers/watchdog/bfin_wdt.c
+++ b/drivers/watchdog/bfin_wdt.c
@@ -25,7 +25,7 @@
25#include <linux/init.h> 25#include <linux/init.h>
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <asm/blackfin.h> 27#include <asm/blackfin.h>
28#include <asm/uaccess.h> 28#include <linux/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_KEEPALIVE:
281 if (get_user(new_timeout, p)) 269 bfin_wdt_keepalive();
282 return -EFAULT; 270 return 0;
283 271 case WDIOC_SETTIMEOUT: {
284 if (bfin_wdt_set_timeout(new_timeout)) 272 int new_timeout;
285 return -EINVAL; 273
274 if (get_user(new_timeout, p))
275 return -EFAULT;
276 if (bfin_wdt_set_timeout(new_timeout))
277 return -EINVAL;
278 }
279 /* Fall */
280 case WDIOC_GETTIMEOUT:
281 return put_user(timeout, p);
282 case WDIOC_SETOPTIONS: {
283 unsigned long flags;
284 int options, ret = -EINVAL;
285
286 if (get_user(options, p))
287 return -EFAULT;
288
289 spin_lock_irqsave(&bfin_wdt_spinlock, flags);
290 if (options & WDIOS_DISABLECARD) {
291 bfin_wdt_stop();
292 ret = 0;
286 } 293 }
287 /* Fall */ 294 if (options & WDIOS_ENABLECARD) {
288 case WDIOC_GETTIMEOUT: 295 bfin_wdt_start();
289 return put_user(timeout, p); 296 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 } 297 }
298 spin_unlock_irqrestore(&bfin_wdt_spinlock, flags);
299 return ret;
300 }
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..06b7a17a60e7 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);
@@ -106,7 +105,8 @@ static int booke_wdt_ioctl(struct inode *inode, struct file *file,
106 case WDIOC_SETTIMEOUT: 105 case WDIOC_SETTIMEOUT:
107 if (get_user(booke_wdt_period, p)) 106 if (get_user(booke_wdt_period, p))
108 return -EFAULT; 107 return -EFAULT;
109 mtspr(SPRN_TCR, (mfspr(SPRN_TCR)&~WDTP(0))|WDTP(booke_wdt_period)); 108 mtspr(SPRN_TCR, (mfspr(SPRN_TCR) & ~WDTP(0)) |
109 WDTP(booke_wdt_period));
110 return 0; 110 return 0;
111 case WDIOC_GETTIMEOUT: 111 case WDIOC_GETTIMEOUT:
112 return put_user(booke_wdt_period, p); 112 return put_user(booke_wdt_period, p);
@@ -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..ec324e5e1c99 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_KEEPALIVE:
157 cpu5wdt_reset(); 164 cpu5wdt_reset();
158 break; 165 break;
159 case WDIOC_GETSTATUS: 166 case WDIOC_GETSTATUS:
160 value = inb(port + CPU5WDT_STATUS_REG); 167 value = inb(port + CPU5WDT_STATUS_REG);
161 value = (value >> 2) & 1; 168 value = (value >> 2) & 1;
162 if ( copy_to_user(argp, &value, sizeof(int)) ) 169 return put_user(value, p);
163 return -EFAULT; 170 case WDIOC_GETBOOTSTATUS:
164 break; 171 return put_user(0, p);
165 case WDIOC_GETBOOTSTATUS: 172 case WDIOC_GETSUPPORT:
166 if ( copy_to_user(argp, &value, sizeof(int)) ) 173 if (copy_to_user(argp, &ident, sizeof(ident)))
167 return -EFAULT; 174 return -EFAULT;
168 break; 175 break;
169 case WDIOC_GETSUPPORT: 176 case WDIOC_SETOPTIONS:
170 if ( copy_to_user(argp, &ident, sizeof(ident)) ) 177 if (get_user(value, p))
171 return -EFAULT; 178 return -EFAULT;
172 break; 179 if (value & WDIOS_ENABLECARD)
173 case WDIOC_SETOPTIONS: 180 cpu5wdt_start();
174 if ( copy_from_user(&value, argp, sizeof(int)) ) 181 if (value & WDIOS_DISABLECARD)
175 return -EFAULT; 182 cpu5wdt_stop();
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 1782c79eff06..926b59c41186 100644
--- a/drivers/watchdog/davinci_wdt.c
+++ b/drivers/watchdog/davinci_wdt.c
@@ -22,10 +22,10 @@
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#include <linux/uaccess.h>
26#include <linux/io.h>
25 27
26#include <asm/hardware.h> 28#include <asm/hardware.h>
27#include <asm/uaccess.h>
28#include <asm/io.h>
29 29
30#define MODULE_NAME "DAVINCI-WDT: " 30#define MODULE_NAME "DAVINCI-WDT: "
31 31
@@ -143,9 +143,8 @@ static struct watchdog_info ident = {
143 .identity = "DaVinci Watchdog", 143 .identity = "DaVinci Watchdog",
144}; 144};
145 145
146static int 146static long davinci_wdt_ioctl(struct file *file,
147davinci_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 147 unsigned int cmd, unsigned long arg)
148 unsigned long arg)
149{ 148{
150 int ret = -ENOTTY; 149 int ret = -ENOTTY;
151 150
@@ -184,7 +183,7 @@ static const struct file_operations davinci_wdt_fops = {
184 .owner = THIS_MODULE, 183 .owner = THIS_MODULE,
185 .llseek = no_llseek, 184 .llseek = no_llseek,
186 .write = davinci_wdt_write, 185 .write = davinci_wdt_write,
187 .ioctl = davinci_wdt_ioctl, 186 .unlocked_ioctl = davinci_wdt_ioctl,
188 .open = davinci_wdt_open, 187 .open = davinci_wdt_open,
189 .release = davinci_wdt_release, 188 .release = davinci_wdt_release,
190}; 189};
diff --git a/drivers/watchdog/ep93xx_wdt.c b/drivers/watchdog/ep93xx_wdt.c
index 0e4787a0bb87..cdcdd11173a7 100644
--- a/drivers/watchdog/ep93xx_wdt.c
+++ b/drivers/watchdog/ep93xx_wdt.c
@@ -28,9 +28,9 @@
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#include <linux/uaccess.h>
31 32
32#include <asm/hardware.h> 33#include <asm/hardware.h>
33#include <asm/uaccess.h>
34 34
35#define WDT_VERSION "0.3" 35#define WDT_VERSION "0.3"
36#define PFX "ep93xx_wdt: " 36#define PFX "ep93xx_wdt: "
@@ -136,9 +136,8 @@ static struct watchdog_info ident = {
136 .identity = "EP93xx Watchdog", 136 .identity = "EP93xx Watchdog",
137}; 137};
138 138
139static int 139static long ep93xx_wdt_ioctl(struct file *file,
140ep93xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 140 unsigned int cmd, unsigned long arg)
141 unsigned long arg)
142{ 141{
143 int ret = -ENOTTY; 142 int ret = -ENOTTY;
144 143
@@ -174,8 +173,8 @@ static int ep93xx_wdt_release(struct inode *inode, struct file *file)
174 if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) 173 if (test_bit(WDT_OK_TO_CLOSE, &wdt_status))
175 wdt_shutdown(); 174 wdt_shutdown();
176 else 175 else
177 printk(KERN_CRIT PFX "Device closed unexpectedly - " 176 printk(KERN_CRIT PFX
178 "timer will not stop\n"); 177 "Device closed unexpectedly - timer will not stop\n");
179 178
180 clear_bit(WDT_IN_USE, &wdt_status); 179 clear_bit(WDT_IN_USE, &wdt_status);
181 clear_bit(WDT_OK_TO_CLOSE, &wdt_status); 180 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
@@ -186,7 +185,7 @@ static int ep93xx_wdt_release(struct inode *inode, struct file *file)
186static const struct file_operations ep93xx_wdt_fops = { 185static const struct file_operations ep93xx_wdt_fops = {
187 .owner = THIS_MODULE, 186 .owner = THIS_MODULE,
188 .write = ep93xx_wdt_write, 187 .write = ep93xx_wdt_write,
189 .ioctl = ep93xx_wdt_ioctl, 188 .unlocked_ioctl = ep93xx_wdt_ioctl,
190 .open = ep93xx_wdt_open, 189 .open = ep93xx_wdt_open,
191 .release = ep93xx_wdt_release, 190 .release = ep93xx_wdt_release,
192}; 191};
@@ -243,7 +242,9 @@ module_param(nowayout, int, 0);
243MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"); 242MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started");
244 243
245module_param(timeout, int, 0); 244module_param(timeout, int, 0);
246MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); 245MODULE_PARM_DESC(timeout,
246 "Watchdog timeout in seconds. (1<=timeout<=3600, default="
247 __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
247 248
248MODULE_AUTHOR("Ray Lehtiniemi <rayl@mail.com>," 249MODULE_AUTHOR("Ray Lehtiniemi <rayl@mail.com>,"
249 "Alessandro Zummo <a.zummo@towertech.it>"); 250 "Alessandro Zummo <a.zummo@towertech.it>");
diff --git a/drivers/watchdog/eurotechwdt.c b/drivers/watchdog/eurotechwdt.c
index b14e9d1f164d..b94e6ef4c7a7 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,7 +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: 252 default:
248 return -ENOTTY; 253 return -ENOTTY;
249 254
@@ -255,7 +260,9 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file,
255 return put_user(0, p); 260 return put_user(0, p);
256 261
257 case WDIOC_KEEPALIVE: 262 case WDIOC_KEEPALIVE:
263 spin_lock(&eurwdt_lock);
258 eurwdt_ping(); 264 eurwdt_ping();
265 spin_unlock(&eurwdt_lock);
259 return 0; 266 return 0;
260 267
261 case WDIOC_SETTIMEOUT: 268 case WDIOC_SETTIMEOUT:
@@ -266,8 +273,10 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file,
266 if (time < 0 || time > 255) 273 if (time < 0 || time > 255)
267 return -EINVAL; 274 return -EINVAL;
268 275
276 spin_lock(&eurwdt_lock);
269 eurwdt_timeout = time; 277 eurwdt_timeout = time;
270 eurwdt_set_timeout(time); 278 eurwdt_set_timeout(time);
279 spin_unlock(&eurwdt_lock);
271 /* Fall */ 280 /* Fall */
272 281
273 case WDIOC_GETTIMEOUT: 282 case WDIOC_GETTIMEOUT:
@@ -276,6 +285,7 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file,
276 case WDIOC_SETOPTIONS: 285 case WDIOC_SETOPTIONS:
277 if (get_user(options, p)) 286 if (get_user(options, p))
278 return -EFAULT; 287 return -EFAULT;
288 spin_lock(&eurwdt_lock);
279 if (options & WDIOS_DISABLECARD) { 289 if (options & WDIOS_DISABLECARD) {
280 eurwdt_disable_timer(); 290 eurwdt_disable_timer();
281 retval = 0; 291 retval = 0;
@@ -285,6 +295,7 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file,
285 eurwdt_ping(); 295 eurwdt_ping();
286 retval = 0; 296 retval = 0;
287 } 297 }
298 spin_unlock(&eurwdt_lock);
288 return retval; 299 return retval;
289 } 300 }
290} 301}
@@ -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);
@@ -362,11 +374,11 @@ static int eurwdt_notify_sys(struct notifier_block *this, unsigned long code,
362 374
363 375
364static const struct file_operations eurwdt_fops = { 376static const struct file_operations eurwdt_fops = {
365 .owner = THIS_MODULE, 377 .owner = THIS_MODULE,
366 .llseek = no_llseek, 378 .llseek = no_llseek,
367 .write = eurwdt_write, 379 .write = eurwdt_write,
368 .ioctl = eurwdt_ioctl, 380 .unlocked_ioctl = eurwdt_ioctl,
369 .open = eurwdt_open, 381 .open = eurwdt_open,
370 .release = eurwdt_release, 382 .release = eurwdt_release,
371}; 383};
372 384
@@ -419,7 +431,7 @@ static int __init eurwdt_init(void)
419 int ret; 431 int ret;
420 432
421 ret = request_irq(irq, eurwdt_interrupt, IRQF_DISABLED, "eurwdt", NULL); 433 ret = request_irq(irq, eurwdt_interrupt, IRQF_DISABLED, "eurwdt", NULL);
422 if(ret) { 434 if (ret) {
423 printk(KERN_ERR "eurwdt: IRQ %d is not free.\n", irq); 435 printk(KERN_ERR "eurwdt: IRQ %d is not free.\n", irq);
424 goto out; 436 goto out;
425 } 437 }
@@ -432,10 +444,13 @@ static int __init eurwdt_init(void)
432 444
433 ret = register_reboot_notifier(&eurwdt_notifier); 445 ret = register_reboot_notifier(&eurwdt_notifier);
434 if (ret) { 446 if (ret) {
435 printk(KERN_ERR "eurwdt: can't register reboot notifier (err=%d)\n", ret); 447 printk(KERN_ERR
448 "eurwdt: can't register reboot notifier (err=%d)\n", ret);
436 goto outreg; 449 goto outreg;
437 } 450 }
438 451
452 spin_lock_init(&eurwdt_lock);
453
439 ret = misc_register(&eurwdt_miscdev); 454 ret = misc_register(&eurwdt_miscdev);
440 if (ret) { 455 if (ret) {
441 printk(KERN_ERR "eurwdt: can't misc_register on minor=%d\n", 456 printk(KERN_ERR "eurwdt: can't misc_register on minor=%d\n",
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index ccd6c530782d..d20f591e3fd7 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -39,9 +39,9 @@
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> 42#include <linux/dmi.h>
43#include <asm/desc.h> 43#include <asm/desc.h>
44#include <asm/kdebug.h> 44#include <linux/kdebug.h>
45 45
46#define PCI_BIOS32_SD_VALUE 0x5F32335F /* "_32_" */ 46#define PCI_BIOS32_SD_VALUE 0x5F32335F /* "_32_" */
47#define CRU_BIOS_SIGNATURE_VALUE 0x55524324 47#define CRU_BIOS_SIGNATURE_VALUE 0x55524324
diff --git a/drivers/watchdog/i6300esb.c b/drivers/watchdog/i6300esb.c
index ca44fd9b19bb..01a283f7a271 100644
--- a/drivers/watchdog/i6300esb.c
+++ b/drivers/watchdog/i6300esb.c
@@ -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
@@ -104,8 +109,8 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" _
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 writeb(ESB_UNLOCK1, ESB_RELOAD_REG);
108 writeb(ESB_UNLOCK2, ESB_RELOAD_REG); 113 writeb(ESB_UNLOCK2, ESB_RELOAD_REG);
109} 114}
110 115
111static void esb_timer_start(void) 116static void esb_timer_start(void)
@@ -114,8 +119,7 @@ static void esb_timer_start(void)
114 119
115 /* Enable or Enable + Lock? */ 120 /* Enable or Enable + Lock? */
116 val = 0x02 | (nowayout ? 0x01 : 0x00); 121 val = 0x02 | (nowayout ? 0x01 : 0x00);
117 122 pci_write_config_byte(esb_pci, ESB_LOCK_REG, val);
118 pci_write_config_byte(esb_pci, ESB_LOCK_REG, val);
119} 123}
120 124
121static int esb_timer_stop(void) 125static int esb_timer_stop(void)
@@ -140,7 +144,7 @@ static void esb_timer_keepalive(void)
140 spin_lock(&esb_lock); 144 spin_lock(&esb_lock);
141 esb_unlock_registers(); 145 esb_unlock_registers();
142 writew(ESB_WDT_RELOAD, ESB_RELOAD_REG); 146 writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
143 /* FIXME: Do we need to flush anything here? */ 147 /* FIXME: Do we need to flush anything here? */
144 spin_unlock(&esb_lock); 148 spin_unlock(&esb_lock);
145} 149}
146 150
@@ -167,7 +171,7 @@ static int esb_timer_set_heartbeat(int time)
167 esb_unlock_registers(); 171 esb_unlock_registers();
168 writel(val, ESB_TIMER2_REG); 172 writel(val, ESB_TIMER2_REG);
169 173
170 /* Reload */ 174 /* Reload */
171 esb_unlock_registers(); 175 esb_unlock_registers();
172 writew(ESB_WDT_RELOAD, ESB_RELOAD_REG); 176 writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
173 177
@@ -179,54 +183,55 @@ static int esb_timer_set_heartbeat(int time)
179 return 0; 183 return 0;
180} 184}
181 185
182static int esb_timer_read (void) 186static int esb_timer_read(void)
183{ 187{
184 u32 count; 188 u32 count;
185 189
186 /* This isn't documented, and doesn't take into 190 /* This isn't documented, and doesn't take into
187 * acount which stage is running, but it looks 191 * acount which stage is running, but it looks
188 * like a 20 bit count down, so we might as well report it. 192 * like a 20 bit count down, so we might as well report it.
189 */ 193 */
190 pci_read_config_dword(esb_pci, 0x64, &count); 194 pci_read_config_dword(esb_pci, 0x64, &count);
191 return (int)count; 195 return (int)count;
192} 196}
193 197
194/* 198/*
195 * /dev/watchdog handling 199 * /dev/watchdog handling
196 */ 200 */
197 201
198static int esb_open (struct inode *inode, struct file *file) 202static int esb_open(struct inode *inode, struct file *file)
199{ 203{
200 /* /dev/watchdog can only be opened once */ 204 /* /dev/watchdog can only be opened once */
201 if (test_and_set_bit(0, &timer_alive)) 205 if (test_and_set_bit(0, &timer_alive))
202 return -EBUSY; 206 return -EBUSY;
203 207
204 /* Reload and activate timer */ 208 /* Reload and activate timer */
205 esb_timer_keepalive (); 209 esb_timer_keepalive();
206 esb_timer_start (); 210 esb_timer_start();
207 211
208 return nonseekable_open(inode, file); 212 return nonseekable_open(inode, file);
209} 213}
210 214
211static int esb_release (struct inode *inode, struct file *file) 215static int esb_release(struct inode *inode, struct file *file)
212{ 216{
213 /* Shut off the timer. */ 217 /* Shut off the timer. */
214 if (esb_expect_close == 42) { 218 if (esb_expect_close == 42)
215 esb_timer_stop (); 219 esb_timer_stop();
216 } else { 220 else {
217 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); 221 printk(KERN_CRIT PFX
218 esb_timer_keepalive (); 222 "Unexpected close, not stopping watchdog!\n");
219 } 223 esb_timer_keepalive();
220 clear_bit(0, &timer_alive); 224 }
221 esb_expect_close = 0; 225 clear_bit(0, &timer_alive);
222 return 0; 226 esb_expect_close = 0;
227 return 0;
223} 228}
224 229
225static ssize_t esb_write (struct file *file, const char __user *data, 230static ssize_t esb_write(struct file *file, const char __user *data,
226 size_t len, loff_t * ppos) 231 size_t len, loff_t *ppos)
227{ 232{
228 /* See if we got the magic character 'V' and reload the timer */ 233 /* See if we got the magic character 'V' and reload the timer */
229 if (len) { 234 if (len) {
230 if (!nowayout) { 235 if (!nowayout) {
231 size_t i; 236 size_t i;
232 237
@@ -237,7 +242,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 */ 242 /* scan to see whether or not we got the magic character */
238 for (i = 0; i != len; i++) { 243 for (i = 0; i != len; i++) {
239 char c; 244 char c;
240 if(get_user(c, data+i)) 245 if (get_user(c, data+i))
241 return -EFAULT; 246 return -EFAULT;
242 if (c == 'V') 247 if (c == 'V')
243 esb_expect_close = 42; 248 esb_expect_close = 42;
@@ -245,13 +250,12 @@ static ssize_t esb_write (struct file *file, const char __user *data,
245 } 250 }
246 251
247 /* someone wrote to us, we should reload the timer */ 252 /* someone wrote to us, we should reload the timer */
248 esb_timer_keepalive (); 253 esb_timer_keepalive();
249 } 254 }
250 return len; 255 return len;
251} 256}
252 257
253static int esb_ioctl (struct inode *inode, struct file *file, 258static long esb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
254 unsigned int cmd, unsigned long arg)
255{ 259{
256 int new_options, retval = -EINVAL; 260 int new_options, retval = -EINVAL;
257 int new_heartbeat; 261 int new_heartbeat;
@@ -266,71 +270,65 @@ static int esb_ioctl (struct inode *inode, struct file *file,
266 }; 270 };
267 271
268 switch (cmd) { 272 switch (cmd) {
269 case WDIOC_GETSUPPORT: 273 case WDIOC_GETSUPPORT:
270 return copy_to_user(argp, &ident, 274 return copy_to_user(argp, &ident,
271 sizeof (ident)) ? -EFAULT : 0; 275 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
279 case WDIOC_KEEPALIVE:
280 esb_timer_keepalive ();
281 return 0;
282 276
283 case WDIOC_SETOPTIONS: 277 case WDIOC_GETSTATUS:
284 { 278 return put_user(esb_timer_read(), p);
285 if (get_user (new_options, p))
286 return -EFAULT;
287 279
288 if (new_options & WDIOS_DISABLECARD) { 280 case WDIOC_GETBOOTSTATUS:
289 esb_timer_stop (); 281 return put_user(triggered, p);
290 retval = 0;
291 }
292 282
293 if (new_options & WDIOS_ENABLECARD) { 283 case WDIOC_KEEPALIVE:
294 esb_timer_keepalive (); 284 esb_timer_keepalive();
295 esb_timer_start (); 285 return 0;
296 retval = 0;
297 }
298 286
299 return retval; 287 case WDIOC_SETOPTIONS:
300 } 288 {
289 if (get_user(new_options, p))
290 return -EFAULT;
301 291
302 case WDIOC_SETTIMEOUT: 292 if (new_options & WDIOS_DISABLECARD) {
303 { 293 esb_timer_stop();
304 if (get_user(new_heartbeat, p)) 294 retval = 0;
305 return -EFAULT; 295 }
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 296
317 default: 297 if (new_options & WDIOS_ENABLECARD) {
318 return -ENOTTY; 298 esb_timer_keepalive();
319 } 299 esb_timer_start();
300 retval = 0;
301 }
302 return retval;
303 }
304 case WDIOC_SETTIMEOUT:
305 {
306 if (get_user(new_heartbeat, p))
307 return -EFAULT;
308 if (esb_timer_set_heartbeat(new_heartbeat))
309 return -EINVAL;
310 esb_timer_keepalive();
311 /* Fall */
312 }
313 case WDIOC_GETTIMEOUT:
314 return put_user(heartbeat, p);
315 default:
316 return -ENOTTY;
317 }
320} 318}
321 319
322/* 320/*
323 * Notify system 321 * Notify system
324 */ 322 */
325 323
326static int esb_notify_sys (struct notifier_block *this, unsigned long code, void *unused) 324static int esb_notify_sys(struct notifier_block *this,
325 unsigned long code, void *unused)
327{ 326{
328 if (code==SYS_DOWN || code==SYS_HALT) { 327 if (code == SYS_DOWN || code == SYS_HALT) {
329 /* Turn the WDT off */ 328 /* Turn the WDT off */
330 esb_timer_stop (); 329 esb_timer_stop();
331 } 330 }
332 331 return NOTIFY_DONE;
333 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..09e9534ac2e4 100644
--- a/drivers/watchdog/iTCO_vendor_support.c
+++ b/drivers/watchdog/iTCO_vendor_support.c
@@ -32,7 +32,9 @@
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 34
35#include <asm/io.h> /* For inb/outb/... */ 35#include <linux/io.h> /* For inb/outb/... */
36
37#include "iTCO_vendor.h"
36 38
37/* iTCO defines */ 39/* iTCO defines */
38#define SMI_EN acpibase + 0x30 /* SMI Control and Enable Register */ 40#define SMI_EN acpibase + 0x30 /* SMI Control and Enable Register */
@@ -40,10 +42,12 @@
40#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */ 42#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */
41 43
42/* List of vendor support modes */ 44/* List of vendor support modes */
43#define SUPERMICRO_OLD_BOARD 1 /* SuperMicro Pentium 3 Era 370SSE+-OEM1/P3TSSE */ 45/* SuperMicro Pentium 3 Era 370SSE+-OEM1/P3TSSE */
44#define SUPERMICRO_NEW_BOARD 2 /* SuperMicro Pentium 4 / Xeon 4 / EMT64T Era Systems */ 46#define SUPERMICRO_OLD_BOARD 1
47/* SuperMicro Pentium 4 / Xeon 4 / EMT64T Era Systems */
48#define SUPERMICRO_NEW_BOARD 2
45 49
46static int vendorsupport = 0; 50static int vendorsupport;
47module_param(vendorsupport, int, 0); 51module_param(vendorsupport, int, 0);
48MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default=0 (none), 1=SuperMicro Pent3, 2=SuperMicro Pent4+"); 52MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default=0 (none), 1=SuperMicro Pent3, 2=SuperMicro Pent4+");
49 53
@@ -143,34 +147,35 @@ static void supermicro_old_pre_keepalive(unsigned long acpibase)
143 */ 147 */
144 148
145/* I/O Port's */ 149/* I/O Port's */
146#define SM_REGINDEX 0x2e /* SuperMicro ICH4+ Register Index */ 150#define SM_REGINDEX 0x2e /* SuperMicro ICH4+ Register Index */
147#define SM_DATAIO 0x2f /* SuperMicro ICH4+ Register Data I/O */ 151#define SM_DATAIO 0x2f /* SuperMicro ICH4+ Register Data I/O */
148 152
149/* Control Register's */ 153/* Control Register's */
150#define SM_CTLPAGESW 0x07 /* SuperMicro ICH4+ Control Page Switch */ 154#define SM_CTLPAGESW 0x07 /* SuperMicro ICH4+ Control Page Switch */
151#define SM_CTLPAGE 0x08 /* SuperMicro ICH4+ Control Page Num */ 155#define SM_CTLPAGE 0x08 /* SuperMicro ICH4+ Control Page Num */
152 156
153#define SM_WATCHENABLE 0x30 /* Watchdog enable: Bit 0: 0=off, 1=on */ 157#define SM_WATCHENABLE 0x30 /* Watchdog enable: Bit 0: 0=off, 1=on */
154 158
155#define SM_WATCHPAGE 0x87 /* Watchdog unlock control page */ 159#define SM_WATCHPAGE 0x87 /* Watchdog unlock control page */
156 160
157#define SM_ENDWATCH 0xAA /* Watchdog lock control page */ 161#define SM_ENDWATCH 0xAA /* Watchdog lock control page */
158 162
159#define SM_COUNTMODE 0xf5 /* Watchdog count mode select */ 163#define SM_COUNTMODE 0xf5 /* Watchdog count mode select */
160 /* (Bit 3: 0 = seconds, 1 = minutes */ 164 /* (Bit 3: 0 = seconds, 1 = minutes */
161 165
162#define SM_WATCHTIMER 0xf6 /* 8-bits, Watchdog timer counter (RW) */ 166#define SM_WATCHTIMER 0xf6 /* 8-bits, Watchdog timer counter (RW) */
163 167
164#define SM_RESETCONTROL 0xf7 /* Watchdog reset control */ 168#define SM_RESETCONTROL 0xf7 /* Watchdog reset control */
165 /* Bit 6: timer is reset by kbd interrupt */ 169 /* Bit 6: timer is reset by kbd interrupt */
166 /* Bit 7: timer is reset by mouse interrupt */ 170 /* Bit 7: timer is reset by mouse interrupt */
167 171
168static void supermicro_new_unlock_watchdog(void) 172static void supermicro_new_unlock_watchdog(void)
169{ 173{
170 outb(SM_WATCHPAGE, SM_REGINDEX); /* Write 0x87 to port 0x2e twice */ 174 /* Write 0x87 to port 0x2e twice */
171 outb(SM_WATCHPAGE, SM_REGINDEX); 175 outb(SM_WATCHPAGE, SM_REGINDEX);
172 176 outb(SM_WATCHPAGE, SM_REGINDEX);
173 outb(SM_CTLPAGESW, SM_REGINDEX); /* Switch to watchdog control page */ 177 /* Switch to watchdog control page */
178 outb(SM_CTLPAGESW, SM_REGINDEX);
174 outb(SM_CTLPAGE, SM_DATAIO); 179 outb(SM_CTLPAGE, SM_DATAIO);
175} 180}
176 181
@@ -192,7 +197,7 @@ static void supermicro_new_pre_start(unsigned int heartbeat)
192 outb(val, SM_DATAIO); 197 outb(val, SM_DATAIO);
193 198
194 /* Write heartbeat interval to WDOG */ 199 /* Write heartbeat interval to WDOG */
195 outb (SM_WATCHTIMER, SM_REGINDEX); 200 outb(SM_WATCHTIMER, SM_REGINDEX);
196 outb((heartbeat & 255), SM_DATAIO); 201 outb((heartbeat & 255), SM_DATAIO);
197 202
198 /* Make sure keyboard/mouse interrupts don't interfere */ 203 /* Make sure keyboard/mouse interrupts don't interfere */
@@ -277,7 +282,7 @@ EXPORT_SYMBOL(iTCO_vendor_pre_set_heartbeat);
277 282
278int iTCO_vendor_check_noreboot_on(void) 283int iTCO_vendor_check_noreboot_on(void)
279{ 284{
280 switch(vendorsupport) { 285 switch (vendorsupport) {
281 case SUPERMICRO_OLD_BOARD: 286 case SUPERMICRO_OLD_BOARD:
282 return 0; 287 return 0;
283 default: 288 default:
@@ -288,13 +293,13 @@ EXPORT_SYMBOL(iTCO_vendor_check_noreboot_on);
288 293
289static int __init iTCO_vendor_init_module(void) 294static int __init iTCO_vendor_init_module(void)
290{ 295{
291 printk (KERN_INFO PFX "vendor-support=%d\n", vendorsupport); 296 printk(KERN_INFO PFX "vendor-support=%d\n", vendorsupport);
292 return 0; 297 return 0;
293} 298}
294 299
295static void __exit iTCO_vendor_exit_module(void) 300static void __exit iTCO_vendor_exit_module(void)
296{ 301{
297 printk (KERN_INFO PFX "Module Unloaded\n"); 302 printk(KERN_INFO PFX "Module Unloaded\n");
298} 303}
299 304
300module_init(iTCO_vendor_init_module); 305module_init(iTCO_vendor_init_module);
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
index 95ba985bd341..c9ca8f691d81 100644
--- a/drivers/watchdog/iTCO_wdt.c
+++ b/drivers/watchdog/iTCO_wdt.c
@@ -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 {
@@ -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,19 +481,20 @@ 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))
@@ -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:
537 return put_user(0, p);
538
539 case WDIOC_KEEPALIVE:
540 iTCO_wdt_keepalive();
541 return 0;
542 534
543 case WDIOC_SETOPTIONS: 535 case WDIOC_KEEPALIVE:
544 { 536 iTCO_wdt_keepalive();
545 if (get_user(new_options, p)) 537 return 0;
546 return -EFAULT;
547
548 if (new_options & WDIOS_DISABLECARD) {
549 iTCO_wdt_stop();
550 retval = 0;
551 }
552 538
553 if (new_options & WDIOS_ENABLECARD) { 539 case WDIOC_SETOPTIONS:
554 iTCO_wdt_keepalive(); 540 {
555 iTCO_wdt_start(); 541 if (get_user(new_options, p))
556 retval = 0; 542 return -EFAULT;
557 }
558 543
559 return retval; 544 if (new_options & WDIOS_DISABLECARD) {
545 iTCO_wdt_stop();
546 retval = 0;
560 } 547 }
561 548 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(); 549 iTCO_wdt_keepalive();
571 /* Fall */ 550 iTCO_wdt_start();
551 retval = 0;
572 } 552 }
573 553 return retval;
574 case WDIOC_GETTIMEOUT: 554 }
575 return put_user(heartbeat, p); 555 case WDIOC_SETTIMEOUT:
576 556 {
577 case WDIOC_GETTIMELEFT: 557 if (get_user(new_heartbeat, p))
578 { 558 return -EFAULT;
579 int time_left; 559 if (iTCO_wdt_set_heartbeat(new_heartbeat))
580 560 return -EINVAL;
581 if (iTCO_wdt_get_timeleft(&time_left)) 561 iTCO_wdt_keepalive();
582 return -EINVAL; 562 /* Fall */
583 563 }
584 return put_user(time_left, p); 564 case WDIOC_GETTIMEOUT:
585 } 565 return put_user(heartbeat, p);
586 566 case WDIOC_GETTIMELEFT:
587 default: 567 {
588 return -ENOTTY; 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..805a54b02aa1 100644
--- a/drivers/watchdog/ib700wdt.c
+++ b/drivers/watchdog/ib700wdt.c
@@ -42,8 +42,8 @@
42#include <linux/moduleparam.h> 42#include <linux/moduleparam.h>
43#include <linux/platform_device.h> 43#include <linux/platform_device.h>
44 44
45#include <asm/io.h> 45#include <linux/io.h>
46#include <asm/uaccess.h> 46#include <linux/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,7 +120,9 @@ 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/*
@@ -165,8 +167,8 @@ ibwdt_set_heartbeat(int t)
165 * /dev/watchdog handling 167 * /dev/watchdog handling
166 */ 168 */
167 169
168static ssize_t 170static 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) 171 size_t count, loff_t *ppos)
170{ 172{
171 if (count) { 173 if (count) {
172 if (!nowayout) { 174 if (!nowayout) {
@@ -188,77 +190,71 @@ ibwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppo
188 return count; 190 return count;
189} 191}
190 192
191static int 193static 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{ 194{
195 int new_margin; 195 int new_margin;
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 198
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 = "IB700 WDT", 203 .identity = "IB700 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
211 case WDIOC_GETSTATUS: 212 case WDIOC_GETSTATUS:
212 case WDIOC_GETBOOTSTATUS: 213 case WDIOC_GETBOOTSTATUS:
213 return put_user(0, p); 214 return put_user(0, p);
214 215
215 case WDIOC_KEEPALIVE: 216 case WDIOC_KEEPALIVE:
216 ibwdt_ping(); 217 ibwdt_ping();
217 break; 218 break;
218 219
219 case WDIOC_SETTIMEOUT: 220 case WDIOC_SETTIMEOUT:
220 if (get_user(new_margin, p)) 221 if (get_user(new_margin, p))
221 return -EFAULT; 222 return -EFAULT;
222 if (ibwdt_set_heartbeat(new_margin)) 223 if (ibwdt_set_heartbeat(new_margin))
223 return -EINVAL; 224 return -EINVAL;
224 ibwdt_ping(); 225 ibwdt_ping();
225 /* Fall */ 226 /* Fall */
226 227
227 case WDIOC_GETTIMEOUT: 228 case WDIOC_GETTIMEOUT:
228 return put_user(wd_times[wd_margin], p); 229 return put_user(wd_times[wd_margin], p);
229 230
230 case WDIOC_SETOPTIONS: 231 case WDIOC_SETOPTIONS:
231 { 232 {
232 int options, retval = -EINVAL; 233 int options, retval = -EINVAL;
233 234
234 if (get_user(options, p)) 235 if (get_user(options, p))
235 return -EFAULT; 236 return -EFAULT;
236 237
237 if (options & WDIOS_DISABLECARD) { 238 if (options & WDIOS_DISABLECARD) {
238 ibwdt_disable(); 239 ibwdt_disable();
239 retval = 0; 240 retval = 0;
240 } 241 }
241 242 if (options & WDIOS_ENABLECARD) {
242 if (options & WDIOS_ENABLECARD) { 243 ibwdt_ping();
243 ibwdt_ping(); 244 retval = 0;
244 retval = 0; 245 }
245 } 246 return retval;
246
247 return retval;
248 } 247 }
249
250 default: 248 default:
251 return -ENOTTY; 249 return -ENOTTY;
252 } 250 }
253 return 0; 251 return 0;
254} 252}
255 253
256static int 254static int ibwdt_open(struct inode *inode, struct file *file)
257ibwdt_open(struct inode *inode, struct file *file)
258{ 255{
259 if (test_and_set_bit(0, &ibwdt_is_open)) { 256 if (test_and_set_bit(0, &ibwdt_is_open))
260 return -EBUSY; 257 return -EBUSY;
261 }
262 if (nowayout) 258 if (nowayout)
263 __module_get(THIS_MODULE); 259 __module_get(THIS_MODULE);
264 260
@@ -273,7 +269,8 @@ ibwdt_close(struct inode *inode, struct file *file)
273 if (expect_close == 42) { 269 if (expect_close == 42) {
274 ibwdt_disable(); 270 ibwdt_disable();
275 } else { 271 } else {
276 printk(KERN_CRIT PFX "WDT device closed unexpectedly. WDT will not stop!\n"); 272 printk(KERN_CRIT PFX
273 "WDT device closed unexpectedly. WDT will not stop!\n");
277 ibwdt_ping(); 274 ibwdt_ping();
278 } 275 }
279 clear_bit(0, &ibwdt_is_open); 276 clear_bit(0, &ibwdt_is_open);
@@ -289,7 +286,7 @@ static const struct file_operations ibwdt_fops = {
289 .owner = THIS_MODULE, 286 .owner = THIS_MODULE,
290 .llseek = no_llseek, 287 .llseek = no_llseek,
291 .write = ibwdt_write, 288 .write = ibwdt_write,
292 .ioctl = ibwdt_ioctl, 289 .unlocked_ioctl = ibwdt_ioctl,
293 .open = ibwdt_open, 290 .open = ibwdt_open,
294 .release = ibwdt_close, 291 .release = ibwdt_close,
295}; 292};
@@ -310,21 +307,23 @@ static int __devinit ibwdt_probe(struct platform_device *dev)
310 307
311#if WDT_START != WDT_STOP 308#if WDT_START != WDT_STOP
312 if (!request_region(WDT_STOP, 1, "IB700 WDT")) { 309 if (!request_region(WDT_STOP, 1, "IB700 WDT")) {
313 printk (KERN_ERR PFX "STOP method I/O %X is not available.\n", WDT_STOP); 310 printk(KERN_ERR PFX "STOP method I/O %X is not available.\n",
311 WDT_STOP);
314 res = -EIO; 312 res = -EIO;
315 goto out_nostopreg; 313 goto out_nostopreg;
316 } 314 }
317#endif 315#endif
318 316
319 if (!request_region(WDT_START, 1, "IB700 WDT")) { 317 if (!request_region(WDT_START, 1, "IB700 WDT")) {
320 printk (KERN_ERR PFX "START method I/O %X is not available.\n", WDT_START); 318 printk(KERN_ERR PFX "START method I/O %X is not available.\n",
319 WDT_START);
321 res = -EIO; 320 res = -EIO;
322 goto out_nostartreg; 321 goto out_nostartreg;
323 } 322 }
324 323
325 res = misc_register(&ibwdt_miscdev); 324 res = misc_register(&ibwdt_miscdev);
326 if (res) { 325 if (res) {
327 printk (KERN_ERR PFX "failed to register misc device\n"); 326 printk(KERN_ERR PFX "failed to register misc device\n");
328 goto out_nomisc; 327 goto out_nomisc;
329 } 328 }
330 return 0; 329 return 0;
@@ -342,9 +341,9 @@ out_nostopreg:
342static int __devexit ibwdt_remove(struct platform_device *dev) 341static int __devexit ibwdt_remove(struct platform_device *dev)
343{ 342{
344 misc_deregister(&ibwdt_miscdev); 343 misc_deregister(&ibwdt_miscdev);
345 release_region(WDT_START,1); 344 release_region(WDT_START, 1);
346#if WDT_START != WDT_STOP 345#if WDT_START != WDT_STOP
347 release_region(WDT_STOP,1); 346 release_region(WDT_STOP, 1);
348#endif 347#endif
349 return 0; 348 return 0;
350} 349}
@@ -369,13 +368,15 @@ static int __init ibwdt_init(void)
369{ 368{
370 int err; 369 int err;
371 370
372 printk(KERN_INFO PFX "WDT driver for IB700 single board computer initialising.\n"); 371 printk(KERN_INFO PFX
372 "WDT driver for IB700 single board computer initialising.\n");
373 373
374 err = platform_driver_register(&ibwdt_driver); 374 err = platform_driver_register(&ibwdt_driver);
375 if (err) 375 if (err)
376 return err; 376 return err;
377 377
378 ibwdt_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0); 378 ibwdt_platform_device = platform_device_register_simple(DRV_NAME,
379 -1, NULL, 0);
379 if (IS_ERR(ibwdt_platform_device)) { 380 if (IS_ERR(ibwdt_platform_device)) {
380 err = PTR_ERR(ibwdt_platform_device); 381 err = PTR_ERR(ibwdt_platform_device);
381 goto unreg_platform_driver; 382 goto unreg_platform_driver;
diff --git a/drivers/watchdog/ibmasr.c b/drivers/watchdog/ibmasr.c
index 94155f6136c2..6824bf80b37e 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,11 +270,10 @@ 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 };
@@ -254,53 +282,45 @@ static int asr_ioctl(struct inode *inode, struct file *file,
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_KEEPALIVE:
263 return put_user(0, p); 291 asr_toggle();
264 292 return 0;
265 case WDIOC_KEEPALIVE: 293 /*
294 * The hardware has a fixed timeout value, so no WDIOC_SETTIMEOUT
295 * and WDIOC_GETTIMEOUT always returns 256.
296 */
297 case WDIOC_GETTIMEOUT:
298 heartbeat = 256;
299 return put_user(heartbeat, p);
300 case WDIOC_SETOPTIONS:
301 {
302 int new_options, retval = -EINVAL;
303 if (get_user(new_options, p))
304 return -EFAULT;
305 if (new_options & WDIOS_DISABLECARD) {
306 asr_disable();
307 retval = 0;
308 }
309 if (new_options & WDIOS_ENABLECARD) {
310 asr_enable();
266 asr_toggle(); 311 asr_toggle();
267 return 0; 312 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 } 313 }
314 return retval;
315 }
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..0bffea37404e 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_KEEPALIVE:
123 return put_user(0,(int *)arg); 132 indydog_ping();
124 case WDIOC_KEEPALIVE: 133 return 0;
125 indydog_ping(); 134 case WDIOC_GETTIMEOUT:
126 return 0; 135 return put_user(WATCHDOG_TIMEOUT, (int *)arg);
127 case WDIOC_GETTIMEOUT: 136 case WDIOC_SETOPTIONS:
128 return put_user(WATCHDOG_TIMEOUT,(int *)arg); 137 {
129 case WDIOC_SETOPTIONS: 138 if (get_user(options, (int *)arg))
130 { 139 return -EFAULT;
131 if (get_user(options, (int *)arg)) 140 if (options & WDIOS_DISABLECARD) {
132 return -EFAULT; 141 indydog_stop();
133 142 retval = 0;
134 if (options & WDIOS_DISABLECARD) { 143 }
135 indydog_stop(); 144 if (options & WDIOS_ENABLECARD) {
136 retval = 0; 145 indydog_start();
137 } 146 retval = 0;
138
139 if (options & WDIOS_ENABLECARD) {
140 indydog_start();
141 retval = 0;
142 }
143
144 return retval;
145 } 147 }
148 return retval;
149 }
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 bbbd91af754d..e54c888d2afe 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,41 +122,39 @@ 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; 154 break;
156 155
157 case WDIOC_GETTIMEOUT: 156 case WDIOC_GETTIMEOUT:
158 ret = put_user(iop_watchdog_timeout(), (int *)arg); 157 ret = put_user(iop_watchdog_timeout(), argp);
159 break; 158 break;
160 159
161 case WDIOC_KEEPALIVE: 160 case WDIOC_KEEPALIVE:
@@ -177,14 +176,12 @@ iop_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
177 } else 176 } else
178 ret = 0; 177 ret = 0;
179 } 178 }
180
181 if (options & WDIOS_ENABLECARD) { 179 if (options & WDIOS_ENABLECARD) {
182 wdt_enable(); 180 wdt_enable();
183 ret = 0; 181 ret = 0;
184 } 182 }
185 break; 183 break;
186 } 184 }
187
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("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/ixp2000_wdt.c b/drivers/watchdog/ixp2000_wdt.c
index dc7548dcaf35..943ceffbd683 100644
--- a/drivers/watchdog/ixp2000_wdt.c
+++ b/drivers/watchdog/ixp2000_wdt.c
@@ -25,42 +25,45 @@
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#include <linux/uaccess.h>
28 29
29#include <asm/hardware.h> 30#include <asm/hardware.h>
30#include <asm/uaccess.h>
31 31
32static int nowayout = WATCHDOG_NOWAYOUT; 32static int nowayout = WATCHDOG_NOWAYOUT;
33static unsigned int heartbeat = 60; /* (secs) Default is 1 minute */ 33static unsigned int heartbeat = 60; /* (secs) Default is 1 minute */
34static unsigned long wdt_status; 34static unsigned long wdt_status;
35static spinlock_t wdt_lock;
35 36
36#define WDT_IN_USE 0 37#define WDT_IN_USE 0
37#define WDT_OK_TO_CLOSE 1 38#define WDT_OK_TO_CLOSE 1
38 39
39static unsigned long wdt_tick_rate; 40static unsigned long wdt_tick_rate;
40 41
41static void 42static void wdt_enable(void)
42wdt_enable(void)
43{ 43{
44 spin_lock(&wdt_lock);
44 ixp2000_reg_write(IXP2000_RESET0, *(IXP2000_RESET0) | WDT_RESET_ENABLE); 45 ixp2000_reg_write(IXP2000_RESET0, *(IXP2000_RESET0) | WDT_RESET_ENABLE);
45 ixp2000_reg_write(IXP2000_TWDE, WDT_ENABLE); 46 ixp2000_reg_write(IXP2000_TWDE, WDT_ENABLE);
46 ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate); 47 ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate);
47 ixp2000_reg_write(IXP2000_T4_CTL, TIMER_DIVIDER_256 | TIMER_ENABLE); 48 ixp2000_reg_write(IXP2000_T4_CTL, TIMER_DIVIDER_256 | TIMER_ENABLE);
49 spin_unlock(&wdt_lock);
48} 50}
49 51
50static void 52static void wdt_disable(void)
51wdt_disable(void)
52{ 53{
54 spin_lock(&wdt_lock);
53 ixp2000_reg_write(IXP2000_T4_CTL, 0); 55 ixp2000_reg_write(IXP2000_T4_CTL, 0);
56 spin_unlock(&wdt_lock);
54} 57}
55 58
56static void 59static void wdt_keepalive(void)
57wdt_keepalive(void)
58{ 60{
61 spin_lock(&wdt_lock);
59 ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate); 62 ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate);
63 spin_unlock(&wdt_lock);
60} 64}
61 65
62static int 66static int ixp2000_wdt_open(struct inode *inode, struct file *file)
63ixp2000_wdt_open(struct inode *inode, struct file *file)
64{ 67{
65 if (test_and_set_bit(WDT_IN_USE, &wdt_status)) 68 if (test_and_set_bit(WDT_IN_USE, &wdt_status))
66 return -EBUSY; 69 return -EBUSY;
@@ -72,8 +75,8 @@ ixp2000_wdt_open(struct inode *inode, struct file *file)
72 return nonseekable_open(inode, file); 75 return nonseekable_open(inode, file);
73} 76}
74 77
75static ssize_t 78static 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) 79 size_t len, loff_t *ppos)
77{ 80{
78 if (len) { 81 if (len) {
79 if (!nowayout) { 82 if (!nowayout) {
@@ -103,9 +106,8 @@ static struct watchdog_info ident = {
103 .identity = "IXP2000 Watchdog", 106 .identity = "IXP2000 Watchdog",
104}; 107};
105 108
106static int 109static long ixp2000_wdt_ioctl(struct file *file, unsigned int cmd,
107ixp2000_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 110 unsigned long arg)
108 unsigned long arg)
109{ 111{
110 int ret = -ENOTTY; 112 int ret = -ENOTTY;
111 int time; 113 int time;
@@ -151,16 +153,13 @@ ixp2000_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
151 return ret; 153 return ret;
152} 154}
153 155
154static int 156static int ixp2000_wdt_release(struct inode *inode, struct file *file)
155ixp2000_wdt_release(struct inode *inode, struct file *file)
156{ 157{
157 if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) { 158 if (test_bit(WDT_OK_TO_CLOSE, &wdt_status))
158 wdt_disable(); 159 wdt_disable();
159 } else { 160 else
160 printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - " 161 printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - "
161 "timer will not stop\n"); 162 "timer will not stop\n");
162 }
163
164 clear_bit(WDT_IN_USE, &wdt_status); 163 clear_bit(WDT_IN_USE, &wdt_status);
165 clear_bit(WDT_OK_TO_CLOSE, &wdt_status); 164 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
166 165
@@ -168,18 +167,16 @@ ixp2000_wdt_release(struct inode *inode, struct file *file)
168} 167}
169 168
170 169
171static const struct file_operations ixp2000_wdt_fops = 170static const struct file_operations ixp2000_wdt_fops = {
172{
173 .owner = THIS_MODULE, 171 .owner = THIS_MODULE,
174 .llseek = no_llseek, 172 .llseek = no_llseek,
175 .write = ixp2000_wdt_write, 173 .write = ixp2000_wdt_write,
176 .ioctl = ixp2000_wdt_ioctl, 174 .unlocked_ioctl = ixp2000_wdt_ioctl,
177 .open = ixp2000_wdt_open, 175 .open = ixp2000_wdt_open,
178 .release = ixp2000_wdt_release, 176 .release = ixp2000_wdt_release,
179}; 177};
180 178
181static struct miscdevice ixp2000_wdt_miscdev = 179static struct miscdevice ixp2000_wdt_miscdev = {
182{
183 .minor = WATCHDOG_MINOR, 180 .minor = WATCHDOG_MINOR,
184 .name = "watchdog", 181 .name = "watchdog",
185 .fops = &ixp2000_wdt_fops, 182 .fops = &ixp2000_wdt_fops,
@@ -191,9 +188,8 @@ static int __init ixp2000_wdt_init(void)
191 printk(KERN_INFO "Unable to use IXP2000 watchdog due to IXP2800 erratum #25.\n"); 188 printk(KERN_INFO "Unable to use IXP2000 watchdog due to IXP2800 erratum #25.\n");
192 return -EIO; 189 return -EIO;
193 } 190 }
194
195 wdt_tick_rate = (*IXP2000_T1_CLD * HZ) / 256; 191 wdt_tick_rate = (*IXP2000_T1_CLD * HZ) / 256;
196 192 spin_lock_init(&wdt_lock);
197 return misc_register(&ixp2000_wdt_miscdev); 193 return misc_register(&ixp2000_wdt_miscdev);
198} 194}
199 195
diff --git a/drivers/watchdog/ixp4xx_wdt.c b/drivers/watchdog/ixp4xx_wdt.c
index 5864bb865cfe..24e624c847ae 100644
--- a/drivers/watchdog/ixp4xx_wdt.c
+++ b/drivers/watchdog/ixp4xx_wdt.c
@@ -30,40 +30,40 @@ static int nowayout = WATCHDOG_NOWAYOUT;
30static int heartbeat = 60; /* (secs) Default is 1 minute */ 30static int heartbeat = 60; /* (secs) Default is 1 minute */
31static unsigned long wdt_status; 31static unsigned long wdt_status;
32static unsigned long boot_status; 32static unsigned long boot_status;
33static spin_lock_t wdt_lock;
33 34
34#define WDT_TICK_RATE (IXP4XX_PERIPHERAL_BUS_CLOCK * 1000000UL) 35#define WDT_TICK_RATE (IXP4XX_PERIPHERAL_BUS_CLOCK * 1000000UL)
35 36
36#define WDT_IN_USE 0 37#define WDT_IN_USE 0
37#define WDT_OK_TO_CLOSE 1 38#define WDT_OK_TO_CLOSE 1
38 39
39static void 40static void wdt_enable(void)
40wdt_enable(void)
41{ 41{
42 spin_lock(&wdt_lock);
42 *IXP4XX_OSWK = IXP4XX_WDT_KEY; 43 *IXP4XX_OSWK = IXP4XX_WDT_KEY;
43 *IXP4XX_OSWE = 0; 44 *IXP4XX_OSWE = 0;
44 *IXP4XX_OSWT = WDT_TICK_RATE * heartbeat; 45 *IXP4XX_OSWT = WDT_TICK_RATE * heartbeat;
45 *IXP4XX_OSWE = IXP4XX_WDT_COUNT_ENABLE | IXP4XX_WDT_RESET_ENABLE; 46 *IXP4XX_OSWE = IXP4XX_WDT_COUNT_ENABLE | IXP4XX_WDT_RESET_ENABLE;
46 *IXP4XX_OSWK = 0; 47 *IXP4XX_OSWK = 0;
48 spin_unlock(&wdt_lock);
47} 49}
48 50
49static void 51static void wdt_disable(void)
50wdt_disable(void)
51{ 52{
53 spin_lock(&wdt_lock);
52 *IXP4XX_OSWK = IXP4XX_WDT_KEY; 54 *IXP4XX_OSWK = IXP4XX_WDT_KEY;
53 *IXP4XX_OSWE = 0; 55 *IXP4XX_OSWE = 0;
54 *IXP4XX_OSWK = 0; 56 *IXP4XX_OSWK = 0;
57 spin_unlock(&wdt_lock);
55} 58}
56 59
57static int 60static int ixp4xx_wdt_open(struct inode *inode, struct file *file)
58ixp4xx_wdt_open(struct inode *inode, struct file *file)
59{ 61{
60 if (test_and_set_bit(WDT_IN_USE, &wdt_status)) 62 if (test_and_set_bit(WDT_IN_USE, &wdt_status))
61 return -EBUSY; 63 return -EBUSY;
62 64
63 clear_bit(WDT_OK_TO_CLOSE, &wdt_status); 65 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
64
65 wdt_enable(); 66 wdt_enable();
66
67 return nonseekable_open(inode, file); 67 return nonseekable_open(inode, file);
68} 68}
69 69
@@ -87,7 +87,6 @@ ixp4xx_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos)
87 } 87 }
88 wdt_enable(); 88 wdt_enable();
89 } 89 }
90
91 return len; 90 return len;
92} 91}
93 92
@@ -98,9 +97,8 @@ static struct watchdog_info ident = {
98}; 97};
99 98
100 99
101static int 100static long ixp4xx_wdt_ioctl(struct file *file, unsigned int cmd,
102ixp4xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 101 unsigned long arg)
103 unsigned long arg)
104{ 102{
105 int ret = -ENOTTY; 103 int ret = -ENOTTY;
106 int time; 104 int time;
@@ -145,16 +143,13 @@ ixp4xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
145 return ret; 143 return ret;
146} 144}
147 145
148static int 146static int ixp4xx_wdt_release(struct inode *inode, struct file *file)
149ixp4xx_wdt_release(struct inode *inode, struct file *file)
150{ 147{
151 if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) { 148 if (test_bit(WDT_OK_TO_CLOSE, &wdt_status))
152 wdt_disable(); 149 wdt_disable();
153 } else { 150 else
154 printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - " 151 printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - "
155 "timer will not stop\n"); 152 "timer will not stop\n");
156 }
157
158 clear_bit(WDT_IN_USE, &wdt_status); 153 clear_bit(WDT_IN_USE, &wdt_status);
159 clear_bit(WDT_OK_TO_CLOSE, &wdt_status); 154 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
160 155
@@ -167,7 +162,7 @@ static const struct file_operations ixp4xx_wdt_fops =
167 .owner = THIS_MODULE, 162 .owner = THIS_MODULE,
168 .llseek = no_llseek, 163 .llseek = no_llseek,
169 .write = ixp4xx_wdt_write, 164 .write = ixp4xx_wdt_write,
170 .ioctl = ixp4xx_wdt_ioctl, 165 .unlocked_ioctl = ixp4xx_wdt_ioctl,
171 .open = ixp4xx_wdt_open, 166 .open = ixp4xx_wdt_open,
172 .release = ixp4xx_wdt_release, 167 .release = ixp4xx_wdt_release,
173}; 168};
@@ -191,14 +186,12 @@ static int __init ixp4xx_wdt_init(void)
191 186
192 return -ENODEV; 187 return -ENODEV;
193 } 188 }
194 189 spin_lock_init(&wdt_lock);
190 boot_status = (*IXP4XX_OSST & IXP4XX_OSST_TIMER_WARM_RESET) ?
191 WDIOF_CARDRESET : 0;
195 ret = misc_register(&ixp4xx_wdt_miscdev); 192 ret = misc_register(&ixp4xx_wdt_miscdev);
196 if (ret == 0) 193 if (ret == 0)
197 printk("IXP4xx Watchdog Timer: heartbeat %d sec\n", heartbeat); 194 printk("IXP4xx Watchdog Timer: heartbeat %d sec\n", heartbeat);
198
199 boot_status = (*IXP4XX_OSST & IXP4XX_OSST_TIMER_WARM_RESET) ?
200 WDIOF_CARDRESET : 0;
201
202 return ret; 195 return ret;
203} 196}
204 197
diff --git a/drivers/watchdog/ks8695_wdt.c b/drivers/watchdog/ks8695_wdt.c
index df5a6b811ccd..6d052b80aa20 100644
--- a/drivers/watchdog/ks8695_wdt.c
+++ b/drivers/watchdog/ks8695_wdt.c
@@ -19,8 +19,8 @@
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 <asm/arch/regs-timer.h> 24#include <asm/arch/regs-timer.h>
25 25
26 26
@@ -31,38 +31,44 @@ static int wdt_time = WDT_DEFAULT_TIME;
31static int nowayout = WATCHDOG_NOWAYOUT; 31static int nowayout = WATCHDOG_NOWAYOUT;
32 32
33module_param(wdt_time, int, 0); 33module_param(wdt_time, int, 0);
34MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="__MODULE_STRING(WDT_DEFAULT_TIME) ")"); 34MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="
35 __MODULE_STRING(WDT_DEFAULT_TIME) ")");
35 36
36#ifdef CONFIG_WATCHDOG_NOWAYOUT 37#ifdef CONFIG_WATCHDOG_NOWAYOUT
37module_param(nowayout, int, 0); 38module_param(nowayout, int, 0);
38MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 39MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
40 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
39#endif 41#endif
40 42
41 43
42static unsigned long ks8695wdt_busy; 44static unsigned long ks8695wdt_busy;
45static spinlock_t ks8695_lock;
43 46
44/* ......................................................................... */ 47/* ......................................................................... */
45 48
46/* 49/*
47 * Disable the watchdog. 50 * Disable the watchdog.
48 */ 51 */
49static void inline ks8695_wdt_stop(void) 52static inline void ks8695_wdt_stop(void)
50{ 53{
51 unsigned long tmcon; 54 unsigned long tmcon;
52 55
56 spin_lock(&ks8695_lock);
53 /* disable timer0 */ 57 /* disable timer0 */
54 tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON); 58 tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON);
55 __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); 59 __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON);
60 spin_unlock(&ks8695_lock);
56} 61}
57 62
58/* 63/*
59 * Enable and reset the watchdog. 64 * Enable and reset the watchdog.
60 */ 65 */
61static void inline ks8695_wdt_start(void) 66static inline void ks8695_wdt_start(void)
62{ 67{
63 unsigned long tmcon; 68 unsigned long tmcon;
64 unsigned long tval = wdt_time * CLOCK_TICK_RATE; 69 unsigned long tval = wdt_time * CLOCK_TICK_RATE;
65 70
71 spin_lock(&ks8695_lock);
66 /* disable timer0 */ 72 /* disable timer0 */
67 tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON); 73 tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON);
68 __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); 74 __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON);
@@ -73,19 +79,22 @@ static void inline ks8695_wdt_start(void)
73 /* re-enable timer0 */ 79 /* re-enable timer0 */
74 tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON); 80 tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON);
75 __raw_writel(tmcon | TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); 81 __raw_writel(tmcon | TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON);
82 spin_unlock(&ks8695_lock);
76} 83}
77 84
78/* 85/*
79 * Reload the watchdog timer. (ie, pat the watchdog) 86 * Reload the watchdog timer. (ie, pat the watchdog)
80 */ 87 */
81static void inline ks8695_wdt_reload(void) 88static inline void ks8695_wdt_reload(void)
82{ 89{
83 unsigned long tmcon; 90 unsigned long tmcon;
84 91
92 spin_lock(&ks8695_lock);
85 /* disable, then re-enable timer0 */ 93 /* disable, then re-enable timer0 */
86 tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON); 94 tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON);
87 __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); 95 __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON);
88 __raw_writel(tmcon | TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); 96 __raw_writel(tmcon | TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON);
97 spin_unlock(&ks8695_lock);
89} 98}
90 99
91/* 100/*
@@ -102,7 +111,8 @@ static int ks8695_wdt_settimeout(int new_time)
102 if ((new_time <= 0) || (new_time > WDT_MAX_TIME)) 111 if ((new_time <= 0) || (new_time > WDT_MAX_TIME))
103 return -EINVAL; 112 return -EINVAL;
104 113
105 /* Set new watchdog time. It will be used when ks8695_wdt_start() is called. */ 114 /* Set new watchdog time. It will be used when
115 ks8695_wdt_start() is called. */
106 wdt_time = new_time; 116 wdt_time = new_time;
107 return 0; 117 return 0;
108} 118}
@@ -128,9 +138,9 @@ static int ks8695_wdt_open(struct inode *inode, struct file *file)
128 */ 138 */
129static int ks8695_wdt_close(struct inode *inode, struct file *file) 139static int ks8695_wdt_close(struct inode *inode, struct file *file)
130{ 140{
141 /* Disable the watchdog when file is closed */
131 if (!nowayout) 142 if (!nowayout)
132 ks8695_wdt_stop(); /* Disable the watchdog when file is closed */ 143 ks8695_wdt_stop();
133
134 clear_bit(0, &ks8695wdt_busy); 144 clear_bit(0, &ks8695wdt_busy);
135 return 0; 145 return 0;
136} 146}
@@ -143,60 +153,52 @@ static struct watchdog_info ks8695_wdt_info = {
143/* 153/*
144 * Handle commands from user-space. 154 * Handle commands from user-space.
145 */ 155 */
146static int ks8695_wdt_ioctl(struct inode *inode, struct file *file, 156static long ks8695_wdt_ioctl(struct file *file, unsigned int cmd,
147 unsigned int cmd, unsigned long arg) 157 unsigned long arg)
148{ 158{
149 void __user *argp = (void __user *)arg; 159 void __user *argp = (void __user *)arg;
150 int __user *p = argp; 160 int __user *p = argp;
151 int new_value; 161 int new_value;
152 162
153 switch(cmd) { 163 switch (cmd) {
154 case WDIOC_KEEPALIVE: 164 case WDIOC_KEEPALIVE:
155 ks8695_wdt_reload(); /* pat the watchdog */ 165 ks8695_wdt_reload(); /* pat the watchdog */
156 return 0; 166 return 0;
157 167 case WDIOC_GETSUPPORT:
158 case WDIOC_GETSUPPORT: 168 return copy_to_user(argp, &ks8695_wdt_info,
159 return copy_to_user(argp, &ks8695_wdt_info, sizeof(ks8695_wdt_info)) ? -EFAULT : 0; 169 sizeof(ks8695_wdt_info)) ? -EFAULT : 0;
160 170 case WDIOC_SETTIMEOUT:
161 case WDIOC_SETTIMEOUT: 171 if (get_user(new_value, p))
162 if (get_user(new_value, p)) 172 return -EFAULT;
163 return -EFAULT; 173 if (ks8695_wdt_settimeout(new_value))
164 174 return -EINVAL;
165 if (ks8695_wdt_settimeout(new_value)) 175 /* Enable new time value */
166 return -EINVAL; 176 ks8695_wdt_start();
167 177 /* Return current value */
168 /* Enable new time value */ 178 return put_user(wdt_time, p);
179 case WDIOC_GETTIMEOUT:
180 return put_user(wdt_time, p);
181 case WDIOC_GETSTATUS:
182 case WDIOC_GETBOOTSTATUS:
183 return put_user(0, p);
184 case WDIOC_SETOPTIONS:
185 if (get_user(new_value, p))
186 return -EFAULT;
187 if (new_value & WDIOS_DISABLECARD)
188 ks8695_wdt_stop();
189 if (new_value & WDIOS_ENABLECARD)
169 ks8695_wdt_start(); 190 ks8695_wdt_start();
170 191 return 0;
171 /* Return current value */ 192 default:
172 return put_user(wdt_time, p); 193 return -ENOTTY;
173
174 case WDIOC_GETTIMEOUT:
175 return put_user(wdt_time, p);
176
177 case WDIOC_GETSTATUS:
178 case WDIOC_GETBOOTSTATUS:
179 return put_user(0, p);
180
181 case WDIOC_SETOPTIONS:
182 if (get_user(new_value, p))
183 return -EFAULT;
184
185 if (new_value & WDIOS_DISABLECARD)
186 ks8695_wdt_stop();
187 if (new_value & WDIOS_ENABLECARD)
188 ks8695_wdt_start();
189 return 0;
190
191 default:
192 return -ENOTTY;
193 } 194 }
194} 195}
195 196
196/* 197/*
197 * Pat the watchdog whenever device is written to. 198 * Pat the watchdog whenever device is written to.
198 */ 199 */
199static ssize_t ks8695_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) 200static ssize_t ks8695_wdt_write(struct file *file, const char *data,
201 size_t len, loff_t *ppos)
200{ 202{
201 ks8695_wdt_reload(); /* pat the watchdog */ 203 ks8695_wdt_reload(); /* pat the watchdog */
202 return len; 204 return len;
@@ -207,7 +209,7 @@ static ssize_t ks8695_wdt_write(struct file *file, const char *data, size_t len,
207static const struct file_operations ks8695wdt_fops = { 209static const struct file_operations ks8695wdt_fops = {
208 .owner = THIS_MODULE, 210 .owner = THIS_MODULE,
209 .llseek = no_llseek, 211 .llseek = no_llseek,
210 .ioctl = ks8695_wdt_ioctl, 212 .unlocked_ioctl = ks8695_wdt_ioctl,
211 .open = ks8695_wdt_open, 213 .open = ks8695_wdt_open,
212 .release = ks8695_wdt_close, 214 .release = ks8695_wdt_close,
213 .write = ks8695_wdt_write, 215 .write = ks8695_wdt_write,
@@ -231,7 +233,8 @@ static int __init ks8695wdt_probe(struct platform_device *pdev)
231 if (res) 233 if (res)
232 return res; 234 return res;
233 235
234 printk("KS8695 Watchdog Timer enabled (%d seconds%s)\n", wdt_time, nowayout ? ", nowayout" : ""); 236 printk(KERN_INFO "KS8695 Watchdog Timer enabled (%d seconds%s)\n",
237 wdt_time, nowayout ? ", nowayout" : "");
235 return 0; 238 return 0;
236} 239}
237 240
@@ -285,12 +288,14 @@ static struct platform_driver ks8695wdt_driver = {
285 288
286static int __init ks8695_wdt_init(void) 289static int __init ks8695_wdt_init(void)
287{ 290{
288 /* Check that the heartbeat value is within range; if not reset to the default */ 291 spin_lock_init(&ks8695_lock);
292 /* Check that the heartbeat value is within range;
293 if not reset to the default */
289 if (ks8695_wdt_settimeout(wdt_time)) { 294 if (ks8695_wdt_settimeout(wdt_time)) {
290 ks8695_wdt_settimeout(WDT_DEFAULT_TIME); 295 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); 296 pr_info("ks8695_wdt: wdt_time value must be 1 <= wdt_time <= %i, using %d\n",
297 wdt_time, WDT_MAX_TIME);
292 } 298 }
293
294 return platform_driver_register(&ks8695wdt_driver); 299 return platform_driver_register(&ks8695wdt_driver);
295} 300}
296 301
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..2248a8187590 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_GETSTATUS:
209 case WDIOC_GETSTATUS: 212 status = mixcomwd_opened;
210 status=mixcomwd_opened; 213 if (!nowayout)
211 if (!nowayout) { 214 status |= mixcomwd_timer_alive;
212 status|=mixcomwd_timer_alive; 215 return put_user(status, p);
213 } 216 case WDIOC_GETBOOTSTATUS:
214 if (copy_to_user(p, &status, sizeof(int))) { 217 return put_user(0, p);
215 return -EFAULT; 218 case WDIOC_GETSUPPORT:
216 } 219 if (copy_to_user(argp, &ident, sizeof(ident)))
217 break; 220 return -EFAULT;
218 case WDIOC_GETBOOTSTATUS: 221 break;
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..ce1811d5d6b1 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 */
@@ -167,7 +170,8 @@ static const struct file_operations mpc5200_wdt_fops = {
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;
diff --git a/drivers/watchdog/mpc83xx_wdt.c b/drivers/watchdog/mpc83xx_wdt.c
index b16c5cd972eb..109eea0df2d0 100644
--- a/drivers/watchdog/mpc83xx_wdt.c
+++ b/drivers/watchdog/mpc83xx_wdt.c
@@ -22,8 +22,8 @@
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/watchdog.h> 24#include <linux/watchdog.h>
25#include <asm/io.h> 25#include <linux/io.h>
26#include <asm/uaccess.h> 26#include <linux/uaccess.h>
27 27
28struct mpc83xx_wdt { 28struct mpc83xx_wdt {
29 __be32 res0; 29 __be32 res0;
@@ -42,11 +42,13 @@ static struct mpc83xx_wdt __iomem *wd_base;
42 42
43static u16 timeout = 0xffff; 43static u16 timeout = 0xffff;
44module_param(timeout, ushort, 0); 44module_param(timeout, ushort, 0);
45MODULE_PARM_DESC(timeout, "Watchdog timeout in ticks. (0<timeout<65536, default=65535"); 45MODULE_PARM_DESC(timeout,
46 "Watchdog timeout in ticks. (0<timeout<65536, default=65535");
46 47
47static int reset = 1; 48static int reset = 1;
48module_param(reset, bool, 0); 49module_param(reset, bool, 0);
49MODULE_PARM_DESC(reset, "Watchdog Interrupt/Reset Mode. 0 = interrupt, 1 = reset"); 50MODULE_PARM_DESC(reset,
51 "Watchdog Interrupt/Reset Mode. 0 = interrupt, 1 = reset");
50 52
51/* 53/*
52 * We always prescale, but if someone really doesn't want to they can set this 54 * We always prescale, but if someone really doesn't want to they can set this
@@ -105,8 +107,8 @@ static int mpc83xx_wdt_release(struct inode *inode, struct file *file)
105 return 0; 107 return 0;
106} 108}
107 109
108static int mpc83xx_wdt_ioctl(struct inode *inode, struct file *file, 110static long mpc83xx_wdt_ioctl(struct file *file, unsigned int cmd,
109 unsigned int cmd, unsigned long arg) 111 unsigned long arg)
110{ 112{
111 void __user *argp = (void __user *)arg; 113 void __user *argp = (void __user *)arg;
112 int __user *p = argp; 114 int __user *p = argp;
@@ -136,7 +138,7 @@ static const struct file_operations mpc83xx_wdt_fops = {
136 .owner = THIS_MODULE, 138 .owner = THIS_MODULE,
137 .llseek = no_llseek, 139 .llseek = no_llseek,
138 .write = mpc83xx_wdt_write, 140 .write = mpc83xx_wdt_write,
139 .ioctl = mpc83xx_wdt_ioctl, 141 .unlocked_ioctl = mpc83xx_wdt_ioctl,
140 .open = mpc83xx_wdt_open, 142 .open = mpc83xx_wdt_open,
141 .release = mpc83xx_wdt_release, 143 .release = mpc83xx_wdt_release,
142}; 144};
@@ -161,8 +163,7 @@ static int __devinit mpc83xx_wdt_probe(struct platform_device *dev)
161 goto err_out; 163 goto err_out;
162 } 164 }
163 165
164 wd_base = ioremap(r->start, sizeof (struct mpc83xx_wdt)); 166 wd_base = ioremap(r->start, sizeof(struct mpc83xx_wdt));
165
166 if (wd_base == NULL) { 167 if (wd_base == NULL) {
167 ret = -ENOMEM; 168 ret = -ENOMEM;
168 goto err_out; 169 goto err_out;
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/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 009573b81496..5e58f8b73d00 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;
@@ -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
@@ -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..e0b8cdfa5e70 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_KEEPALIVE:
148 mtx1_wdt_reset(); 152 mtx1_wdt_reset();
149 break; 153 break;
150 case WDIOC_GETSTATUS: 154 case WDIOC_GETSTATUS:
151 case WDIOC_GETBOOTSTATUS: 155 case WDIOC_GETBOOTSTATUS:
152 if ( copy_to_user(argp, &value, sizeof(int)) ) 156 put_user(0, p);
153 return -EFAULT; 157 break;
154 break; 158 case WDIOC_GETSUPPORT:
155 case WDIOC_GETSUPPORT: 159 if (copy_to_user(argp, &ident, sizeof(ident)))
156 if ( copy_to_user(argp, &ident, sizeof(ident)) ) 160 return -EFAULT;
157 return -EFAULT; 161 break;
158 break; 162 case WDIOC_SETOPTIONS:
159 case WDIOC_SETOPTIONS: 163 if (get_user(value, p))
160 if ( copy_from_user(&value, argp, sizeof(int)) ) 164 return -EFAULT;
161 return -EFAULT; 165 if (value & WDIOS_ENABLECARD)
162 switch(value) { 166 mtx1_wdt_start();
163 case WDIOS_ENABLECARD: 167 else if (value & WDIOS_DISABLECARD)
164 mtx1_wdt_start(); 168 mtx1_wdt_stop();
165 break; 169 else
166 case WDIOS_DISABLECARD: 170 return -EINVAL;
167 return mtx1_wdt_stop(); 171 return 0;
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,7 +188,7 @@ 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
@@ -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..ac09fe4d9573 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
@@ -24,8 +24,8 @@
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25 25
26#include <linux/mv643xx.h> 26#include <linux/mv643xx.h>
27#include <asm/uaccess.h> 27#include <linux/uaccess.h>
28#include <asm/io.h> 28#include <linux/io.h>
29 29
30#define MV64x60_WDT_WDC_OFFSET 0 30#define MV64x60_WDT_WDC_OFFSET 0
31 31
@@ -61,7 +61,9 @@ static DEFINE_SPINLOCK(mv64x60_wdt_spinlock);
61 61
62static int nowayout = WATCHDOG_NOWAYOUT; 62static int nowayout = WATCHDOG_NOWAYOUT;
63module_param(nowayout, int, 0); 63module_param(nowayout, int, 0);
64MODULE_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) ")");
65 67
66static int mv64x60_wdt_toggle_wdc(int enabled_predicate, int field_shift) 68static int mv64x60_wdt_toggle_wdc(int enabled_predicate, int field_shift)
67{ 69{
@@ -150,7 +152,7 @@ static int mv64x60_wdt_release(struct inode *inode, struct file *file)
150} 152}
151 153
152static ssize_t mv64x60_wdt_write(struct file *file, const char __user *data, 154static ssize_t mv64x60_wdt_write(struct file *file, const char __user *data,
153 size_t len, loff_t * ppos) 155 size_t len, loff_t *ppos)
154{ 156{
155 if (len) { 157 if (len) {
156 if (!nowayout) { 158 if (!nowayout) {
@@ -160,7 +162,7 @@ static ssize_t mv64x60_wdt_write(struct file *file, const char __user *data,
160 162
161 for (i = 0; i != len; i++) { 163 for (i = 0; i != len; i++) {
162 char c; 164 char c;
163 if(get_user(c, data + i)) 165 if (get_user(c, data + i))
164 return -EFAULT; 166 return -EFAULT;
165 if (c == 'V') 167 if (c == 'V')
166 expect_close = 42; 168 expect_close = 42;
@@ -172,8 +174,8 @@ static ssize_t mv64x60_wdt_write(struct file *file, const char __user *data,
172 return len; 174 return len;
173} 175}
174 176
175static int mv64x60_wdt_ioctl(struct inode *inode, struct file *file, 177static long mv64x60_wdt_ioctl(struct file *file,
176 unsigned int cmd, unsigned long arg) 178 unsigned int cmd, unsigned long arg)
177{ 179{
178 int timeout; 180 int timeout;
179 int options; 181 int options;
@@ -240,7 +242,7 @@ static const struct file_operations mv64x60_wdt_fops = {
240 .owner = THIS_MODULE, 242 .owner = THIS_MODULE,
241 .llseek = no_llseek, 243 .llseek = no_llseek,
242 .write = mv64x60_wdt_write, 244 .write = mv64x60_wdt_write,
243 .ioctl = mv64x60_wdt_ioctl, 245 .unlocked_ioctl = mv64x60_wdt_ioctl,
244 .open = mv64x60_wdt_open, 246 .open = mv64x60_wdt_open,
245 .release = mv64x60_wdt_release, 247 .release = mv64x60_wdt_release,
246}; 248};
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index 74bc39aa1ce8..ccdf069792d9 100644
--- a/drivers/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -41,9 +41,9 @@
41#include <linux/clk.h> 41#include <linux/clk.h>
42#include <linux/bitops.h> 42#include <linux/bitops.h>
43 43
44#include <asm/io.h> 44#include </io.h>
45#include <asm/uaccess.h> 45#include <linux/uaccess.h>
46#include <asm/hardware.h> 46#include <linux/hardware.h>
47 47
48#include <asm/arch/prcm.h> 48#include <asm/arch/prcm.h>
49 49
@@ -54,11 +54,12 @@ module_param(timer_margin, uint, 0);
54MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)"); 54MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)");
55 55
56static int omap_wdt_users; 56static int omap_wdt_users;
57static struct clk *armwdt_ck = NULL; 57static struct clk *armwdt_ck;
58static struct clk *mpu_wdt_ick = NULL; 58static struct clk *mpu_wdt_ick;
59static struct clk *mpu_wdt_fck = NULL; 59static struct clk *mpu_wdt_fck;
60 60
61static unsigned int wdt_trgr_pattern = 0x1234; 61static unsigned int wdt_trgr_pattern = 0x1234;
62static spinlock_t wdt_lock;
62 63
63static void omap_wdt_ping(void) 64static void omap_wdt_ping(void)
64{ 65{
@@ -174,22 +175,23 @@ static int omap_wdt_release(struct inode *inode, struct file *file)
174 return 0; 175 return 0;
175} 176}
176 177
177static ssize_t 178static 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) 179 size_t len, loff_t *ppos)
180{ 180{
181 /* Refresh LOAD_TIME. */ 181 /* Refresh LOAD_TIME. */
182 if (len) 182 if (len) {
183 spin_lock(&wdt_lock);
183 omap_wdt_ping(); 184 omap_wdt_ping();
185 spin_unlock(&wdt_lock);
186 }
184 return len; 187 return len;
185} 188}
186 189
187static int 190static long omap_wdt_ioctl(struct file *file, unsigned int cmd,
188omap_wdt_ioctl(struct inode *inode, struct file *file, 191 unsigned long arg)
189 unsigned int cmd, unsigned long arg)
190{ 192{
191 int new_margin; 193 int new_margin;
192 static struct watchdog_info ident = { 194 static const struct watchdog_info ident = {
193 .identity = "OMAP Watchdog", 195 .identity = "OMAP Watchdog",
194 .options = WDIOF_SETTIMEOUT, 196 .options = WDIOF_SETTIMEOUT,
195 .firmware_version = 0, 197 .firmware_version = 0,
@@ -211,18 +213,22 @@ omap_wdt_ioctl(struct inode *inode, struct file *file,
211 return put_user(omap_prcm_get_reset_sources(), 213 return put_user(omap_prcm_get_reset_sources(),
212 (int __user *)arg); 214 (int __user *)arg);
213 case WDIOC_KEEPALIVE: 215 case WDIOC_KEEPALIVE:
216 spin_lock(&wdt_lock);
214 omap_wdt_ping(); 217 omap_wdt_ping();
218 spin_unlock(&wdt_lock);
215 return 0; 219 return 0;
216 case WDIOC_SETTIMEOUT: 220 case WDIOC_SETTIMEOUT:
217 if (get_user(new_margin, (int __user *)arg)) 221 if (get_user(new_margin, (int __user *)arg))
218 return -EFAULT; 222 return -EFAULT;
219 omap_wdt_adjust_timeout(new_margin); 223 omap_wdt_adjust_timeout(new_margin);
220 224
225 spin_lock(&wdt_lock);
221 omap_wdt_disable(); 226 omap_wdt_disable();
222 omap_wdt_set_timeout(); 227 omap_wdt_set_timeout();
223 omap_wdt_enable(); 228 omap_wdt_enable();
224 229
225 omap_wdt_ping(); 230 omap_wdt_ping();
231 spin_unlock(&wdt_lock);
226 /* Fall */ 232 /* Fall */
227 case WDIOC_GETTIMEOUT: 233 case WDIOC_GETTIMEOUT:
228 return put_user(timer_margin, (int __user *)arg); 234 return put_user(timer_margin, (int __user *)arg);
@@ -232,7 +238,7 @@ omap_wdt_ioctl(struct inode *inode, struct file *file,
232static const struct file_operations omap_wdt_fops = { 238static const struct file_operations omap_wdt_fops = {
233 .owner = THIS_MODULE, 239 .owner = THIS_MODULE,
234 .write = omap_wdt_write, 240 .write = omap_wdt_write,
235 .ioctl = omap_wdt_ioctl, 241 .unlocked_ioctl = omap_wdt_ioctl,
236 .open = omap_wdt_open, 242 .open = omap_wdt_open,
237 .release = omap_wdt_release, 243 .release = omap_wdt_release,
238}; 244};
@@ -373,6 +379,7 @@ static struct platform_driver omap_wdt_driver = {
373 379
374static int __init omap_wdt_init(void) 380static int __init omap_wdt_init(void)
375{ 381{
382 spin_lock_init(&wdt_lock);
376 return platform_driver_register(&omap_wdt_driver); 383 return platform_driver_register(&omap_wdt_driver);
377} 384}
378 385
diff --git a/drivers/watchdog/pc87413_wdt.c b/drivers/watchdog/pc87413_wdt.c
index 15e4f8887a9e..326f2d2ded3b 100644
--- a/drivers/watchdog/pc87413_wdt.c
+++ b/drivers/watchdog/pc87413_wdt.c
@@ -31,9 +31,9 @@
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 */
@@ -56,12 +56,12 @@
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,7 +95,7 @@ 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
@@ -129,12 +130,11 @@ static inline unsigned int pc87413_get_swc_base(void)
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,7 +370,8 @@ 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))
@@ -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_KEEPALIVE:
446 return put_user(pc87413_status(), uarg.i); 430 pc87413_refresh();
447
448 case WDIOC_GETBOOTSTATUS:
449 return put_user(0, uarg.i);
450
451 case WDIOC_KEEPALIVE:
452 pc87413_refresh();
453#ifdef DEBUG 431#ifdef DEBUG
454 printk(KERN_INFO DPFX "keepalive\n"); 432 printk(KERN_INFO DPFX "keepalive\n");
455#endif 433#endif
456 return 0; 434 return 0;
457 435 case WDIOC_SETTIMEOUT:
458 case WDIOC_SETTIMEOUT: 436 if (get_user(new_timeout, uarg.i))
459 if (get_user(new_timeout, uarg.i)) 437 return -EFAULT;
460 return -EFAULT; 438 /* the API states this is given in secs */
461 439 new_timeout /= 60;
462 // the API states this is given in secs 440 if (new_timeout < 0 || new_timeout > MAX_TIMEOUT)
463 new_timeout /= 60; 441 return -EINVAL;
464 442 timeout = new_timeout;
465 if (new_timeout < 0 || new_timeout > MAX_TIMEOUT) 443 pc87413_refresh();
466 return -EINVAL; 444 /* fall through and return the new timeout... */
467 445 case WDIOC_GETTIMEOUT:
468 timeout = new_timeout; 446 new_timeout = timeout * 60;
469 pc87413_refresh(); 447 return put_user(new_timeout, uarg.i);
470 448 case WDIOC_SETOPTIONS:
471 // fall through and return the new timeout... 449 {
472 450 int options, retval = -EINVAL;
473 case WDIOC_GETTIMEOUT: 451 if (get_user(options, uarg.i))
474 452 return -EFAULT;
475 new_timeout = timeout * 60; 453 if (options & WDIOS_DISABLECARD) {
476 454 pc87413_disable();
477 return put_user(new_timeout, uarg.i); 455 retval = 0;
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 } 456 }
457 if (options & WDIOS_ENABLECARD) {
458 pc87413_enable();
459 retval = 0;
460 }
461 return retval;
462 }
463 default:
464 return -ENOTTY;
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,18 +495,16 @@ 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
@@ -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,8 +560,7 @@ 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 }
@@ -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..e1259adf09f9 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 */
@@ -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);
@@ -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 */
@@ -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,12 @@ 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: 615 default:
595 return -ENOTTY; 616 return -ENOTTY;
596 617
597 case WDIOC_GETSUPPORT: 618 case WDIOC_GETSUPPORT:
598 if(copy_to_user(argp, &ident, sizeof(ident))) 619 if (copy_to_user(argp, &ident, sizeof(ident)))
599 return -EFAULT; 620 return -EFAULT;
600 return 0; 621 return 0;
601 622
@@ -613,25 +634,22 @@ static int pcwd_ioctl(struct inode *inode, struct file *file,
613 return put_user(temperature, argp); 634 return put_user(temperature, argp);
614 635
615 case WDIOC_SETOPTIONS: 636 case WDIOC_SETOPTIONS:
616 if (pcwd_private.revision == PCWD_REVISION_C) 637 if (pcwd_private.revision == PCWD_REVISION_C) {
617 { 638 if (get_user(rv, argp))
618 if(copy_from_user(&rv, argp, sizeof(int)))
619 return -EFAULT; 639 return -EFAULT;
620 640
621 if (rv & WDIOS_DISABLECARD) 641 if (rv & WDIOS_DISABLECARD) {
622 { 642 status = pcwd_stop();
623 return pcwd_stop(); 643 if (status < 0)
644 return status;
624 } 645 }
625 646 if (rv & WDIOS_ENABLECARD) {
626 if (rv & WDIOS_ENABLECARD) 647 status = pcwd_start();
627 { 648 if (status < 0)
628 return pcwd_start(); 649 return status;
629 } 650 }
630
631 if (rv & WDIOS_TEMPPANIC) 651 if (rv & WDIOS_TEMPPANIC)
632 {
633 temp_panic = 1; 652 temp_panic = 1;
634 }
635 } 653 }
636 return -EINVAL; 654 return -EINVAL;
637 655
@@ -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/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c
index 6b8483d3c783..8cd0d53941e7 100644
--- a/drivers/watchdog/pnx4008_wdt.c
+++ b/drivers/watchdog/pnx4008_wdt.c
@@ -30,8 +30,8 @@
30#include <linux/spinlock.h> 30#include <linux/spinlock.h>
31 31
32#include <asm/hardware.h> 32#include <asm/hardware.h>
33#include <asm/uaccess.h> 33#include <linux/uaccess.h>
34#include <asm/io.h> 34#include <linux/io.h>
35 35
36#define MODULE_NAME "PNX4008-WDT: " 36#define MODULE_NAME "PNX4008-WDT: "
37 37
@@ -144,9 +144,8 @@ static int pnx4008_wdt_open(struct inode *inode, struct file *file)
144 return nonseekable_open(inode, file); 144 return nonseekable_open(inode, file);
145} 145}
146 146
147static ssize_t 147static ssize_t pnx4008_wdt_write(struct file *file, const char *data,
148pnx4008_wdt_write(struct file *file, const char *data, size_t len, 148 size_t len, loff_t *ppos)
149 loff_t * ppos)
150{ 149{
151 if (len) { 150 if (len) {
152 if (!nowayout) { 151 if (!nowayout) {
@@ -169,15 +168,14 @@ pnx4008_wdt_write(struct file *file, const char *data, size_t len,
169 return len; 168 return len;
170} 169}
171 170
172static struct watchdog_info ident = { 171static const struct watchdog_info ident = {
173 .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | 172 .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE |
174 WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 173 WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
175 .identity = "PNX4008 Watchdog", 174 .identity = "PNX4008 Watchdog",
176}; 175};
177 176
178static int 177static long pnx4008_wdt_ioctl(struct inode *inode, struct file *file,
179pnx4008_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 178 unsigned int cmd, unsigned long arg)
180 unsigned long arg)
181{ 179{
182 int ret = -ENOTTY; 180 int ret = -ENOTTY;
183 int time; 181 int time;
@@ -238,7 +236,7 @@ static const struct file_operations pnx4008_wdt_fops = {
238 .owner = THIS_MODULE, 236 .owner = THIS_MODULE,
239 .llseek = no_llseek, 237 .llseek = no_llseek,
240 .write = pnx4008_wdt_write, 238 .write = pnx4008_wdt_write,
241 .ioctl = pnx4008_wdt_ioctl, 239 .unlocked_ioctl = pnx4008_wdt_ioctl,
242 .open = pnx4008_wdt_open, 240 .open = pnx4008_wdt_open,
243 .release = pnx4008_wdt_release, 241 .release = pnx4008_wdt_release,
244}; 242};
diff --git a/drivers/watchdog/rm9k_wdt.c b/drivers/watchdog/rm9k_wdt.c
index 5c921e471564..c172906b553c 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",
@@ -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
diff --git a/drivers/watchdog/sa1100_wdt.c b/drivers/watchdog/sa1100_wdt.c
index 34a2b3b81800..869d538c02f9 100644
--- a/drivers/watchdog/sa1100_wdt.c
+++ b/drivers/watchdog/sa1100_wdt.c
@@ -26,13 +26,13 @@
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 <asm/arch/pxa-regs.h> 32#include <asm/arch/pxa-regs.h>
32#endif 33#endif
33 34
34#include <asm/hardware.h> 35#include <asm/hardware.h>
35#include <asm/uaccess.h>
36 36
37#define OSCR_FREQ CLOCK_TICK_RATE 37#define OSCR_FREQ CLOCK_TICK_RATE
38 38
@@ -45,7 +45,7 @@ static int boot_status;
45 */ 45 */
46static int sa1100dog_open(struct inode *inode, struct file *file) 46static int sa1100dog_open(struct inode *inode, struct file *file)
47{ 47{
48 if (test_and_set_bit(1,&sa1100wdt_users)) 48 if (test_and_set_bit(1, &sa1100wdt_users))
49 return -EBUSY; 49 return -EBUSY;
50 50
51 /* Activate SA1100 Watchdog timer */ 51 /* Activate SA1100 Watchdog timer */
@@ -66,28 +66,27 @@ static int sa1100dog_open(struct inode *inode, struct file *file)
66static int sa1100dog_release(struct inode *inode, struct file *file) 66static int sa1100dog_release(struct inode *inode, struct file *file)
67{ 67{
68 printk(KERN_CRIT "WATCHDOG: Device closed - timer will not stop\n"); 68 printk(KERN_CRIT "WATCHDOG: Device closed - timer will not stop\n");
69
70 clear_bit(1, &sa1100wdt_users); 69 clear_bit(1, &sa1100wdt_users);
71
72 return 0; 70 return 0;
73} 71}
74 72
75static ssize_t sa1100dog_write(struct file *file, const char __user *data, size_t len, loff_t *ppos) 73static ssize_t sa1100dog_write(struct file *file, const char __user *data,
74 size_t len, loff_t *ppos)
76{ 75{
77 if (len) 76 if (len)
78 /* Refresh OSMR3 timer. */ 77 /* Refresh OSMR3 timer. */
79 OSMR3 = OSCR + pre_margin; 78 OSMR3 = OSCR + pre_margin;
80
81 return len; 79 return len;
82} 80}
83 81
84static struct watchdog_info ident = { 82static const struct watchdog_info ident = {
85 .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 83 .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT
84 | WDIOF_KEEPALIVEPING,
86 .identity = "SA1100/PXA255 Watchdog", 85 .identity = "SA1100/PXA255 Watchdog",
87}; 86};
88 87
89static int sa1100dog_ioctl(struct inode *inode, struct file *file, 88static long sa1100dog_ioctl(struct file *file, unsigned int cmd,
90 unsigned int cmd, unsigned long arg) 89 unsigned long arg)
91{ 90{
92 int ret = -ENOTTY; 91 int ret = -ENOTTY;
93 int time; 92 int time;
@@ -134,18 +133,16 @@ static int sa1100dog_ioctl(struct inode *inode, struct file *file,
134 return ret; 133 return ret;
135} 134}
136 135
137static const struct file_operations sa1100dog_fops = 136static const struct file_operations sa1100dog_fops = {
138{
139 .owner = THIS_MODULE, 137 .owner = THIS_MODULE,
140 .llseek = no_llseek, 138 .llseek = no_llseek,
141 .write = sa1100dog_write, 139 .write = sa1100dog_write,
142 .ioctl = sa1100dog_ioctl, 140 .unlocked_ioctl = sa1100dog_ioctl,
143 .open = sa1100dog_open, 141 .open = sa1100dog_open,
144 .release = sa1100dog_release, 142 .release = sa1100dog_release,
145}; 143};
146 144
147static struct miscdevice sa1100dog_miscdev = 145static struct miscdevice sa1100dog_miscdev = {
148{
149 .minor = WATCHDOG_MINOR, 146 .minor = WATCHDOG_MINOR,
150 .name = "watchdog", 147 .name = "watchdog",
151 .fops = &sa1100dog_fops, 148 .fops = &sa1100dog_fops,
@@ -167,8 +164,9 @@ static int __init sa1100dog_init(void)
167 164
168 ret = misc_register(&sa1100dog_miscdev); 165 ret = misc_register(&sa1100dog_miscdev);
169 if (ret == 0) 166 if (ret == 0)
170 printk("SA1100/PXA2xx Watchdog Timer: timer margin %d sec\n", 167 printk(KERN_INFO
171 margin); 168 "SA1100/PXA2xx Watchdog Timer: timer margin %d sec\n",
169 margin);
172 return ret; 170 return ret;
173} 171}
174 172
diff --git a/drivers/watchdog/sb_wdog.c b/drivers/watchdog/sb_wdog.c
index b94431433695..c8b544ce77fb 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;
@@ -180,9 +184,8 @@ static int sbwdog_ioctl(struct inode *inode, struct file *file,
180 184
181 case WDIOC_SETTIMEOUT: 185 case WDIOC_SETTIMEOUT:
182 ret = get_user(time, p); 186 ret = get_user(time, p);
183 if (ret) { 187 if (ret)
184 break; 188 break;
185 }
186 189
187 time *= 1000000; 190 time *= 1000000;
188 if (time > 0x7fffffUL) { 191 if (time > 0x7fffffUL) {
@@ -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..e284a5d4fb1b 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 default:
241 return -ENOTTY;
242 case WDIOC_GETSUPPORT:
243 return copy_to_user(argp, &ident, sizeof(ident))? -EFAULT : 0;
244 case WDIOC_GETSTATUS:
245 case WDIOC_GETBOOTSTATUS:
246 return put_user(0, p);
247 case WDIOC_KEEPALIVE:
248 wdt_keepalive();
249 return 0;
250 case WDIOC_SETOPTIONS:
232 { 251 {
233 default: 252 int new_options, retval = -EINVAL;
234 return -ENOTTY; 253 if (get_user(new_options, p))
235 case WDIOC_GETSUPPORT: 254 return -EFAULT;
236 return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; 255 if (new_options & WDIOS_DISABLECARD) {
237 case WDIOC_GETSTATUS: 256 wdt_turnoff();
238 case WDIOC_GETBOOTSTATUS: 257 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 } 258 }
262 case WDIOC_SETTIMEOUT: 259 if (new_options & WDIOS_ENABLECARD) {
263 { 260 wdt_startup();
264 int new_timeout; 261 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 } 262 }
276 case WDIOC_GETTIMEOUT: 263 return retval;
277 return put_user(timeout, p); 264 }
265 case WDIOC_SETTIMEOUT:
266 {
267 int new_timeout;
268 if (get_user(new_timeout, p))
269 return -EFAULT;
270 /* arbitrary upper limit */
271 if (new_timeout < 1 || new_timeout > 3600)
272 return -EINVAL;
273
274 timeout = new_timeout;
275 wdt_keepalive();
276 /* Fall through */
277 }
278 case WDIOC_GETTIMEOUT:
279 return put_user(timeout, p);
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..abccbe265249 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,14 +168,12 @@ 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);
@@ -225,7 +223,7 @@ static const struct file_operations wdt_fops = {
225 .write = fop_write, 223 .write = fop_write,
226 .open = fop_open, 224 .open = fop_open,
227 .release = fop_close, 225 .release = fop_close,
228 .ioctl = fop_ioctl, 226 .unlocked_ioctl = fop_ioctl,
229}; 227};
230 228
231static struct miscdevice wdt_miscdev = { 229static struct miscdevice wdt_miscdev = {
diff --git a/drivers/watchdog/sbc8360.c b/drivers/watchdog/sbc8360.c
index 2ee2677f3648..c66fa6694fc3 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.
@@ -232,8 +232,8 @@ static void sbc8360_ping(void)
232} 232}
233 233
234/* Userspace pings kernel driver, or requests clean close */ 234/* Userspace pings kernel driver, or requests clean close */
235static ssize_t sbc8360_write(struct file *file, const char __user * buf, 235static ssize_t sbc8360_write(struct file *file, const char __user *buf,
236 size_t count, loff_t * ppos) 236 size_t count, loff_t *ppos)
237{ 237{
238 if (count) { 238 if (count) {
239 if (!nowayout) { 239 if (!nowayout) {
@@ -257,16 +257,12 @@ static ssize_t sbc8360_write(struct file *file, const char __user * buf,
257 257
258static int sbc8360_open(struct inode *inode, struct file *file) 258static int sbc8360_open(struct inode *inode, struct file *file)
259{ 259{
260 spin_lock(&sbc8360_lock); 260 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; 261 return -EBUSY;
264 }
265 if (nowayout) 262 if (nowayout)
266 __module_get(THIS_MODULE); 263 __module_get(THIS_MODULE);
267 264
268 /* Activate and ping once to start the countdown */ 265 /* Activate and ping once to start the countdown */
269 spin_unlock(&sbc8360_lock);
270 sbc8360_activate(); 266 sbc8360_activate();
271 sbc8360_ping(); 267 sbc8360_ping();
272 return nonseekable_open(inode, file); 268 return nonseekable_open(inode, file);
@@ -274,16 +270,14 @@ static int sbc8360_open(struct inode *inode, struct file *file)
274 270
275static int sbc8360_close(struct inode *inode, struct file *file) 271static int sbc8360_close(struct inode *inode, struct file *file)
276{ 272{
277 spin_lock(&sbc8360_lock);
278 if (expect_close == 42) 273 if (expect_close == 42)
279 outb(0, SBC8360_ENABLE); 274 outb(0, SBC8360_ENABLE);
280 else 275 else
281 printk(KERN_CRIT PFX 276 printk(KERN_CRIT PFX
282 "SBC8360 device closed unexpectedly. SBC8360 will not stop!\n"); 277 "SBC8360 device closed unexpectedly. SBC8360 will not stop!\n");
283 278
284 clear_bit(0, &sbc8360_is_open); 279 clear_bit(0, &sbc8360_is_open);
285 expect_close = 0; 280 expect_close = 0;
286 spin_unlock(&sbc8360_lock);
287 return 0; 281 return 0;
288} 282}
289 283
@@ -382,13 +376,13 @@ static int __init sbc8360_init(void)
382 376
383 return 0; 377 return 0;
384 378
385 out_nomisc: 379out_nomisc:
386 unregister_reboot_notifier(&sbc8360_notifier); 380 unregister_reboot_notifier(&sbc8360_notifier);
387 out_noreboot: 381out_noreboot:
388 release_region(SBC8360_BASETIME, 1); 382 release_region(SBC8360_BASETIME, 1);
389 out_nobasetimereg: 383out_nobasetimereg:
390 release_region(SBC8360_ENABLE, 1); 384 release_region(SBC8360_ENABLE, 1);
391 out: 385out:
392 return res; 386 return res;
393} 387}
394 388
diff --git a/drivers/watchdog/sbc_epx_c3.c b/drivers/watchdog/sbc_epx_c3.c
index 82cbd8809a69..70ff9cbc8e9b 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,
@@ -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/sc520_wdt.c b/drivers/watchdog/sc520_wdt.c
index 2847324a2be2..01de239f49e8 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,63 @@ 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)
287 { 294 {
288 default: 295 default:
289 return -ENOTTY; 296 return -ENOTTY;
290 case WDIOC_GETSUPPORT: 297 case WDIOC_GETSUPPORT:
291 return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; 298 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
292 case WDIOC_GETSTATUS: 299 case WDIOC_GETSTATUS:
293 case WDIOC_GETBOOTSTATUS: 300 case WDIOC_GETBOOTSTATUS:
294 return put_user(0, p); 301 return put_user(0, p);
295 case WDIOC_KEEPALIVE: 302 case WDIOC_KEEPALIVE:
296 wdt_keepalive(); 303 wdt_keepalive();
297 return 0; 304 return 0;
298 case WDIOC_SETOPTIONS: 305 case WDIOC_SETOPTIONS:
299 { 306 {
300 int new_options, retval = -EINVAL; 307 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 308
310 if(new_options & WDIOS_ENABLECARD) { 309 if (get_user(new_options, p))
311 wdt_startup(); 310 return -EFAULT;
312 retval = 0; 311
313 } 312 if (new_options & WDIOS_DISABLECARD) {
313 wdt_turnoff();
314 retval = 0;
315 }
314 316
315 return retval; 317 if (new_options & WDIOS_ENABLECARD) {
318 wdt_startup();
319 retval = 0;
316 } 320 }
317 case WDIOC_SETTIMEOUT:
318 {
319 int new_timeout;
320 321
321 if(get_user(new_timeout, p)) 322 return retval;
322 return -EFAULT; 323 }
324 case WDIOC_SETTIMEOUT:
325 {
326 int new_timeout;
323 327
324 if(wdt_set_heartbeat(new_timeout)) 328 if (get_user(new_timeout, p))
325 return -EINVAL; 329 return -EFAULT;
326 330
327 wdt_keepalive(); 331 if (wdt_set_heartbeat(new_timeout))
328 /* Fall through */ 332 return -EINVAL;
329 } 333
330 case WDIOC_GETTIMEOUT: 334 wdt_keepalive();
331 return put_user(timeout, p); 335 /* Fall through */
336 }
337 case WDIOC_GETTIMEOUT:
338 return put_user(timeout, p);
332 } 339 }
333} 340}
334 341
@@ -338,7 +345,7 @@ static const struct file_operations wdt_fops = {
338 .write = fop_write, 345 .write = fop_write,
339 .open = fop_open, 346 .open = fop_open,
340 .release = fop_close, 347 .release = fop_close,
341 .ioctl = fop_ioctl, 348 .unlocked_ioctl = fop_ioctl,
342}; 349};
343 350
344static struct miscdevice wdt_miscdev = { 351static struct miscdevice wdt_miscdev = {
@@ -354,7 +361,7 @@ static struct miscdevice wdt_miscdev = {
354static int wdt_notify_sys(struct notifier_block *this, unsigned long code, 361static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
355 void *unused) 362 void *unused)
356{ 363{
357 if(code==SYS_DOWN || code==SYS_HALT) 364 if (code == SYS_DOWN || code == SYS_HALT)
358 wdt_turnoff(); 365 wdt_turnoff();
359 return NOTIFY_DONE; 366 return NOTIFY_DONE;
360} 367}
@@ -383,11 +390,13 @@ static int __init sc520_wdt_init(void)
383{ 390{
384 int rc = -EBUSY; 391 int rc = -EBUSY;
385 392
386 /* Check that the timeout value is within it's range ; if not reset to the default */ 393 /* Check that the timeout value is within it's range ;
394 if not reset to the default */
387 if (wdt_set_heartbeat(timeout)) { 395 if (wdt_set_heartbeat(timeout)) {
388 wdt_set_heartbeat(WATCHDOG_TIMEOUT); 396 wdt_set_heartbeat(WATCHDOG_TIMEOUT);
389 printk(KERN_INFO PFX "timeout value must be 1<=timeout<=3600, using %d\n", 397 printk(KERN_INFO PFX
390 WATCHDOG_TIMEOUT); 398 "timeout value must be 1 <= timeout <= 3600, using %d\n",
399 WATCHDOG_TIMEOUT);
391 } 400 }
392 401
393 wdtmrctl = ioremap((unsigned long)(MMCR_BASE + OFFS_WDTMRCTL), 2); 402 wdtmrctl = ioremap((unsigned long)(MMCR_BASE + OFFS_WDTMRCTL), 2);
@@ -399,20 +408,22 @@ static int __init sc520_wdt_init(void)
399 408
400 rc = register_reboot_notifier(&wdt_notifier); 409 rc = register_reboot_notifier(&wdt_notifier);
401 if (rc) { 410 if (rc) {
402 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 411 printk(KERN_ERR PFX
403 rc); 412 "cannot register reboot notifier (err=%d)\n", rc);
404 goto err_out_ioremap; 413 goto err_out_ioremap;
405 } 414 }
406 415
407 rc = misc_register(&wdt_miscdev); 416 rc = misc_register(&wdt_miscdev);
408 if (rc) { 417 if (rc) {
409 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 418 printk(KERN_ERR PFX
410 WATCHDOG_MINOR, rc); 419 "cannot register miscdev on minor=%d (err=%d)\n",
420 WATCHDOG_MINOR, rc);
411 goto err_out_notifier; 421 goto err_out_notifier;
412 } 422 }
413 423
414 printk(KERN_INFO PFX "WDT driver for SC520 initialised. timeout=%d sec (nowayout=%d)\n", 424 printk(KERN_INFO PFX
415 timeout,nowayout); 425 "WDT driver for SC520 initialised. timeout=%d sec (nowayout=%d)\n",
426 timeout, nowayout);
416 427
417 return 0; 428 return 0;
418 429
diff --git a/drivers/watchdog/scx200_wdt.c b/drivers/watchdog/scx200_wdt.c
index d55882bca319..7c1de94704f3 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();
@@ -152,15 +155,15 @@ 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
@@ -168,7 +171,7 @@ static int scx200_wdt_ioctl(struct inode *inode, struct file *file,
168 default: 171 default:
169 return -ENOTTY; 172 return -ENOTTY;
170 case WDIOC_GETSUPPORT: 173 case WDIOC_GETSUPPORT:
171 if(copy_to_user(argp, &ident, sizeof(ident))) 174 if (copy_to_user(argp, &ident, sizeof(ident)))
172 return -EFAULT; 175 return -EFAULT;
173 return 0; 176 return 0;
174 case WDIOC_GETSTATUS: 177 case WDIOC_GETSTATUS:
@@ -195,18 +198,18 @@ static int scx200_wdt_ioctl(struct inode *inode, struct file *file,
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..60f0036aaca6 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_KEEPALIVE:
335 case WDIOC_KEEPALIVE: 355 sh_wdt_keepalive();
336 sh_wdt_keepalive(); 356 return 0;
337 return 0; 357 case WDIOC_SETTIMEOUT:
338 case WDIOC_SETTIMEOUT: 358 if (get_user(new_heartbeat, (int *)arg))
339 if (get_user(new_heartbeat, (int *)arg)) 359 return -EFAULT;
340 return -EFAULT;
341
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 360
358 if (options & WDIOS_ENABLECARD) { 361 if (sh_wdt_set_heartbeat(new_heartbeat))
359 sh_wdt_start(); 362 return -EINVAL;
360 retval = 0;
361 }
362 363
363 return retval; 364 sh_wdt_keepalive();
364 default: 365 /* Fall */
365 return -ENOTTY; 366 case WDIOC_GETTIMEOUT:
366 } 367 return put_user(heartbeat, (int *)arg);
368 case WDIOC_SETOPTIONS:
369 if (get_user(options, (int *)arg))
370 return -EFAULT;
371
372 if (options & WDIOS_DISABLECARD) {
373 sh_wdt_stop();
374 retval = 0;
375 }
376
377 if (options & WDIOS_ENABLECARD) {
378 sh_wdt_start();
379 retval = 0;
380 }
367 381
382 return retval;
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..b7c6394b7d70 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,7 +404,8 @@ 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))
@@ -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,9 +433,9 @@ 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"
@@ -431,78 +444,62 @@ static int wb_smsc_wdt_ioctl(struct inode *inode, struct file *file,
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_KEEPALIVE:
442 return put_user(wb_smsc_wdt_status(), uarg.i); 455 wb_smsc_wdt_reset_timer();
443 456 return 0;
444 case WDIOC_GETBOOTSTATUS: 457 case WDIOC_SETTIMEOUT:
445 return put_user(0, uarg.i); 458 if (get_user(new_timeout, uarg.i))
446 459 return -EFAULT;
447 case WDIOC_KEEPALIVE: 460 /* the API states this is given in secs */
448 wb_smsc_wdt_reset_timer(); 461 if (unit == UNIT_MINUTE)
449 return 0; 462 new_timeout /= 60;
450 463 if (new_timeout < 0 || new_timeout > MAX_TIMEOUT)
451 case WDIOC_SETTIMEOUT: 464 return -EINVAL;
452 if (get_user(new_timeout, uarg.i)) 465 timeout = new_timeout;
453 return -EFAULT; 466 wb_smsc_wdt_set_timeout(timeout);
454 467 /* fall through and return the new timeout... */
455 // the API states this is given in secs 468 case WDIOC_GETTIMEOUT:
456 if (unit == UNIT_MINUTE) 469 new_timeout = timeout;
457 new_timeout /= 60; 470 if (unit == UNIT_MINUTE)
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; 471 new_timeout *= 60;
472 return put_user(new_timeout, uarg.i);
473 case WDIOC_SETOPTIONS:
474 {
475 int options, retval = -EINVAL;
473 476
474 return put_user(new_timeout, uarg.i); 477 if (get_user(options, uarg.i))
475 478 return -EFAULT;
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
488 if (options & WDIOS_ENABLECARD) {
489 wb_smsc_wdt_enable();
490 retval = 0;
491 }
492 479
493 return retval; 480 if (options & WDIOS_DISABLECARD) {
481 wb_smsc_wdt_disable();
482 retval = 0;
494 } 483 }
484 if (options & WDIOS_ENABLECARD) {
485 wb_smsc_wdt_enable();
486 retval = 0;
487 }
488 return retval;
489 }
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..bb3c75eed9df 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 default:
206 return -ENOTTY; 210 return -ENOTTY;
207 case WDIOC_GETSUPPORT: 211 case WDIOC_GETSUPPORT:
208 return copy_to_user(argp, &ident, 212 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
209 sizeof(ident)) ? -EFAULT : 0; 213 case WDIOC_GETSTATUS:
210 case WDIOC_GETSTATUS: 214 case WDIOC_GETBOOTSTATUS:
211 case WDIOC_GETBOOTSTATUS: 215 return put_user(0, p);
212 return put_user(0, p); 216 case WDIOC_KEEPALIVE:
213 case WDIOC_KEEPALIVE: 217 softdog_keepalive();
214 softdog_keepalive(); 218 return 0;
215 return 0; 219 case WDIOC_SETTIMEOUT:
216 case WDIOC_SETTIMEOUT: 220 if (get_user(new_margin, p))
217 if (get_user(new_margin, p)) 221 return -EFAULT;
218 return -EFAULT; 222 if (softdog_set_heartbeat(new_margin))
219 if (softdog_set_heartbeat(new_margin)) 223 return -EINVAL;
220 return -EINVAL; 224 softdog_keepalive();
221 softdog_keepalive(); 225 /* Fall */
222 /* Fall */ 226 case WDIOC_GETTIMEOUT:
223 case WDIOC_GETTIMEOUT: 227 return put_user(soft_margin, p);
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..b729cc447df3 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,
@@ -168,18 +175,18 @@ 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 = {
diff --git a/drivers/watchdog/w83627hf_wdt.c b/drivers/watchdog/w83627hf_wdt.c
index 386492821fc2..70c843f4201a 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) {
@@ -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: 214 case WDIOC_KEEPALIVE:
216 wdt_ping(); 215 wdt_ping();
217 break; 216 break;
218
219 case WDIOC_SETTIMEOUT: 217 case WDIOC_SETTIMEOUT:
220 if (get_user(new_timeout, p)) 218 if (get_user(new_timeout, p))
221 return -EFAULT; 219 return -EFAULT;
222 if (wdt_set_heartbeat(new_timeout)) 220 if (wdt_set_heartbeat(new_timeout))
223 return -EINVAL; 221 return -EINVAL;
224 wdt_ping(); 222 wdt_ping();
225 /* Fall */ 223 /* Fall */
226
227 case WDIOC_GETTIMEOUT: 224 case WDIOC_GETTIMEOUT:
228 return put_user(timeout, p); 225 return put_user(timeout, p);
229
230 case WDIOC_SETOPTIONS: 226 case WDIOC_SETOPTIONS:
231 { 227 {
232 int options, retval = -EINVAL; 228 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 229
247 return retval; 230 if (get_user(options, p))
231 return -EFAULT;
232 if (options & WDIOS_DISABLECARD) {
233 wdt_disable();
234 retval = 0;
235 }
236 if (options & WDIOS_ENABLECARD) {
237 wdt_ping();
238 retval = 0;
239 }
240 return retval;
248 } 241 }
249
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,8 +275,7 @@ 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) {
@@ -303,7 +293,7 @@ static const struct file_operations wdt_fops = {
303 .owner = THIS_MODULE, 293 .owner = THIS_MODULE,
304 .llseek = no_llseek, 294 .llseek = no_llseek,
305 .write = wdt_write, 295 .write = wdt_write,
306 .ioctl = wdt_ioctl, 296 .unlocked_ioctl = wdt_ioctl,
307 .open = wdt_open, 297 .open = wdt_open,
308 .release = wdt_close, 298 .release = wdt_close,
309}; 299};
@@ -323,8 +313,7 @@ static struct notifier_block wdt_notifier = {
323 .notifier_call = wdt_notify_sys, 313 .notifier_call = wdt_notify_sys,
324}; 314};
325 315
326static int __init 316static int __init wdt_init(void)
327wdt_init(void)
328{ 317{
329 int ret; 318 int ret;
330 319
@@ -332,12 +321,13 @@ wdt_init(void)
332 321
333 if (wdt_set_heartbeat(timeout)) { 322 if (wdt_set_heartbeat(timeout)) {
334 wdt_set_heartbeat(WATCHDOG_TIMEOUT); 323 wdt_set_heartbeat(WATCHDOG_TIMEOUT);
335 printk (KERN_INFO PFX "timeout value must be 1<=timeout<=255, using %d\n", 324 printk(KERN_INFO PFX
336 WATCHDOG_TIMEOUT); 325 "timeout value must be 1 <= timeout <= 255, using %d\n",
326 WATCHDOG_TIMEOUT);
337 } 327 }
338 328
339 if (!request_region(wdt_io, 1, WATCHDOG_NAME)) { 329 if (!request_region(wdt_io, 1, WATCHDOG_NAME)) {
340 printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", 330 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n",
341 wdt_io); 331 wdt_io);
342 ret = -EIO; 332 ret = -EIO;
343 goto out; 333 goto out;
@@ -347,20 +337,22 @@ wdt_init(void)
347 337
348 ret = register_reboot_notifier(&wdt_notifier); 338 ret = register_reboot_notifier(&wdt_notifier);
349 if (ret != 0) { 339 if (ret != 0) {
350 printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 340 printk(KERN_ERR PFX
351 ret); 341 "cannot register reboot notifier (err=%d)\n", ret);
352 goto unreg_regions; 342 goto unreg_regions;
353 } 343 }
354 344
355 ret = misc_register(&wdt_miscdev); 345 ret = misc_register(&wdt_miscdev);
356 if (ret != 0) { 346 if (ret != 0) {
357 printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 347 printk(KERN_ERR PFX
358 WATCHDOG_MINOR, ret); 348 "cannot register miscdev on minor=%d (err=%d)\n",
349 WATCHDOG_MINOR, ret);
359 goto unreg_reboot; 350 goto unreg_reboot;
360 } 351 }
361 352
362 printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n", 353 printk(KERN_INFO PFX
363 timeout, nowayout); 354 "initialized. timeout=%d sec (nowayout=%d)\n",
355 timeout, nowayout);
364 356
365out: 357out:
366 return ret; 358 return ret;
@@ -371,12 +363,11 @@ unreg_regions:
371 goto out; 363 goto out;
372} 364}
373 365
374static void __exit 366static void __exit wdt_exit(void)
375wdt_exit(void)
376{ 367{
377 misc_deregister(&wdt_miscdev); 368 misc_deregister(&wdt_miscdev);
378 unregister_reboot_notifier(&wdt_notifier); 369 unregister_reboot_notifier(&wdt_notifier);
379 release_region(wdt_io,1); 370 release_region(wdt_io, 1);
380} 371}
381 372
382module_init(wdt_init); 373module_init(wdt_init);
diff --git a/drivers/watchdog/w83697hf_wdt.c b/drivers/watchdog/w83697hf_wdt.c
index 528b882420b6..06ddd38675bd 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) {
@@ -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 };
@@ -295,8 +292,7 @@ wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
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,8 +322,7 @@ 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) {
@@ -345,7 +340,7 @@ static const struct file_operations wdt_fops = {
345 .owner = THIS_MODULE, 340 .owner = THIS_MODULE,
346 .llseek = no_llseek, 341 .llseek = no_llseek,
347 .write = wdt_write, 342 .write = wdt_write,
348 .ioctl = wdt_ioctl, 343 .unlocked_ioctl = wdt_ioctl,
349 .open = wdt_open, 344 .open = wdt_open,
350 .release = wdt_close, 345 .release = wdt_close,
351}; 346};
@@ -365,36 +360,38 @@ static struct notifier_block wdt_notifier = {
365 .notifier_call = wdt_notify_sys, 360 .notifier_call = wdt_notify_sys,
366}; 361};
367 362
368static int 363static int w83697hf_check_wdt(void)
369w83697hf_check_wdt(void)
370{ 364{
371 if (!request_region(wdt_io, 2, WATCHDOG_NAME)) { 365 if (!request_region(wdt_io, 2, WATCHDOG_NAME)) {
372 printk (KERN_ERR PFX "I/O address 0x%x already in use\n", wdt_io); 366 printk(KERN_ERR PFX
367 "I/O address 0x%x already in use\n", wdt_io);
373 return -EIO; 368 return -EIO;
374 } 369 }
375 370
376 printk (KERN_DEBUG PFX "Looking for watchdog at address 0x%x\n", wdt_io); 371 printk(KERN_DEBUG PFX
372 "Looking for watchdog at address 0x%x\n", wdt_io);
377 w83697hf_unlock(); 373 w83697hf_unlock();
378 if (w83697hf_get_reg(0x20) == 0x60) { 374 if (w83697hf_get_reg(0x20) == 0x60) {
379 printk (KERN_INFO PFX "watchdog found at address 0x%x\n", wdt_io); 375 printk(KERN_INFO PFX
376 "watchdog found at address 0x%x\n", wdt_io);
380 w83697hf_lock(); 377 w83697hf_lock();
381 return 0; 378 return 0;
382 } 379 }
383 w83697hf_lock(); /* Reprotect in case it was a compatible device */ 380 /* Reprotect in case it was a compatible device */
381 w83697hf_lock();
384 382
385 printk (KERN_INFO PFX "watchdog not found at address 0x%x\n", wdt_io); 383 printk(KERN_INFO PFX "watchdog not found at address 0x%x\n", wdt_io);
386 release_region(wdt_io, 2); 384 release_region(wdt_io, 2);
387 return -EIO; 385 return -EIO;
388} 386}
389 387
390static int w83697hf_ioports[] = { 0x2e, 0x4e, 0x00 }; 388static int w83697hf_ioports[] = { 0x2e, 0x4e, 0x00 };
391 389
392static int __init 390static int __init wdt_init(void)
393wdt_init(void)
394{ 391{
395 int ret, i, found = 0; 392 int ret, i, found = 0;
396 393
397 printk (KERN_INFO PFX "WDT driver for W83697HF/HG initializing\n"); 394 printk(KERN_INFO PFX "WDT driver for W83697HF/HG initializing\n");
398 395
399 if (wdt_io == 0) { 396 if (wdt_io == 0) {
400 /* we will autodetect the W83697HF/HG watchdog */ 397 /* we will autodetect the W83697HF/HG watchdog */
@@ -409,7 +406,7 @@ wdt_init(void)
409 } 406 }
410 407
411 if (!found) { 408 if (!found) {
412 printk (KERN_ERR PFX "No W83697HF/HG could be found\n"); 409 printk(KERN_ERR PFX "No W83697HF/HG could be found\n");
413 ret = -EIO; 410 ret = -EIO;
414 goto out; 411 goto out;
415 } 412 }
@@ -423,25 +420,27 @@ wdt_init(void)
423 420
424 if (wdt_set_heartbeat(timeout)) { 421 if (wdt_set_heartbeat(timeout)) {
425 wdt_set_heartbeat(WATCHDOG_TIMEOUT); 422 wdt_set_heartbeat(WATCHDOG_TIMEOUT);
426 printk (KERN_INFO PFX "timeout value must be 1<=timeout<=255, using %d\n", 423 printk(KERN_INFO PFX
427 WATCHDOG_TIMEOUT); 424 "timeout value must be 1 <= timeout <= 255, using %d\n",
425 WATCHDOG_TIMEOUT);
428 } 426 }
429 427
430 ret = register_reboot_notifier(&wdt_notifier); 428 ret = register_reboot_notifier(&wdt_notifier);
431 if (ret != 0) { 429 if (ret != 0) {
432 printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 430 printk(KERN_ERR PFX
433 ret); 431 "cannot register reboot notifier (err=%d)\n", ret);
434 goto unreg_regions; 432 goto unreg_regions;
435 } 433 }
436 434
437 ret = misc_register(&wdt_miscdev); 435 ret = misc_register(&wdt_miscdev);
438 if (ret != 0) { 436 if (ret != 0) {
439 printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 437 printk(KERN_ERR PFX
440 WATCHDOG_MINOR, ret); 438 "cannot register miscdev on minor=%d (err=%d)\n",
439 WATCHDOG_MINOR, ret);
441 goto unreg_reboot; 440 goto unreg_reboot;
442 } 441 }
443 442
444 printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n", 443 printk(KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n",
445 timeout, nowayout); 444 timeout, nowayout);
446 445
447out: 446out:
@@ -453,8 +452,7 @@ unreg_regions:
453 goto out; 452 goto out;
454} 453}
455 454
456static void __exit 455static void __exit wdt_exit(void)
457wdt_exit(void)
458{ 456{
459 misc_deregister(&wdt_miscdev); 457 misc_deregister(&wdt_miscdev);
460 unregister_reboot_notifier(&wdt_notifier); 458 unregister_reboot_notifier(&wdt_notifier);
diff --git a/drivers/watchdog/w83877f_wdt.c b/drivers/watchdog/w83877f_wdt.c
index f510a3a595e6..75b546d7d8c2 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 default:
258 return -ENOTTY;
259 case WDIOC_GETSUPPORT:
260 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
261 case WDIOC_GETSTATUS:
262 case WDIOC_GETBOOTSTATUS:
263 return put_user(0, p);
264 case WDIOC_KEEPALIVE:
265 wdt_keepalive();
266 return 0;
267 case WDIOC_SETOPTIONS:
251 { 268 {
252 default: 269 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 270
274 if(new_options & WDIOS_ENABLECARD) { 271 if (get_user(new_options, p))
275 wdt_startup(); 272 return -EFAULT;
276 retval = 0;
277 }
278 273
279 return retval; 274 if (new_options & WDIOS_DISABLECARD) {
275 wdt_turnoff();
276 retval = 0;
280 } 277 }
281 case WDIOC_SETTIMEOUT:
282 {
283 int new_timeout;
284 278
285 if(get_user(new_timeout, p)) 279 if (new_options & WDIOS_ENABLECARD) {
286 return -EFAULT; 280 wdt_startup();
281 retval = 0;
282 }
287 283
288 if(new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */ 284 return retval;
289 return -EINVAL; 285 }
286 case WDIOC_SETTIMEOUT:
287 {
288 int new_timeout;
290 289
291 timeout = new_timeout; 290 if (get_user(new_timeout, p))
292 wdt_keepalive(); 291 return -EFAULT;
293 /* Fall through */ 292
294 } 293 /* arbitrary upper limit */
295 case WDIOC_GETTIMEOUT: 294 if (new_timeout < 1 || new_timeout > 3600)
296 return put_user(timeout, p); 295 return -EINVAL;
296
297 timeout = new_timeout;
298 wdt_keepalive();
299 /* Fall through */
300 }
301 case WDIOC_GETTIMEOUT:
302 return put_user(timeout, p);
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..6860a13f5bb9 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,13 @@ 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: 393 default:
396 return -ENOTTY; 394 return -ENOTTY;
397 395
398 case WDIOC_GETSUPPORT: 396 case WDIOC_GETSUPPORT:
399 return copy_to_user(uarg.ident, &ident, sizeof(ident)) ? -EFAULT : 0; 397 return copy_to_user(uarg.ident, &ident,
398 sizeof(ident)) ? -EFAULT : 0;
400 399
401 case WDIOC_GETSTATUS: 400 case WDIOC_GETSTATUS:
402 wdt_get_status(&status); 401 wdt_get_status(&status);
@@ -410,7 +409,7 @@ static int wdt_ioctl(struct inode *inode, struct file *file,
410 return 0; 409 return 0;
411 410
412 case WDIOC_SETOPTIONS: 411 case WDIOC_SETOPTIONS:
413 if (get_user (new_options, uarg.i)) 412 if (get_user(new_options, uarg.i))
414 return -EFAULT; 413 return -EFAULT;
415 414
416 if (new_options & WDIOS_DISABLECARD) { 415 if (new_options & WDIOS_DISABLECARD) {
@@ -444,23 +443,21 @@ static int wdt_ioctl(struct inode *inode, struct file *file,
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..886cbbcf3eed 100644
--- a/drivers/watchdog/wafer5823wdt.c
+++ b/drivers/watchdog/wafer5823wdt.c
@@ -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 ": "
@@ -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{
@@ -90,7 +94,8 @@ wafwdt_stop(void)
90 inb_p(wdt_stop); 94 inb_p(wdt_stop);
91} 95}
92 96
93static ssize_t wafwdt_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos) 97static ssize_t wafwdt_write(struct file *file, const char __user *buf,
98 size_t count, loff_t *ppos)
94{ 99{
95 /* See if we got the magic character 'V' and reload the timer */ 100 /* See if we got the magic character 'V' and reload the timer */
96 if (count) { 101 if (count) {
@@ -100,7 +105,8 @@ static ssize_t wafwdt_write(struct file *file, const char __user *buf, size_t co
100 /* In case it was set long ago */ 105 /* In case it was set long ago */
101 expect_close = 0; 106 expect_close = 0;
102 107
103 /* scan to see whether or not we got the magic character */ 108 /* scan to see whether or not we got the magic
109 character */
104 for (i = 0; i != count; i++) { 110 for (i = 0; i != count; i++) {
105 char c; 111 char c;
106 if (get_user(c, buf + i)) 112 if (get_user(c, buf + i))
@@ -109,27 +115,29 @@ static ssize_t wafwdt_write(struct file *file, const char __user *buf, size_t co
109 expect_close = 42; 115 expect_close = 42;
110 } 116 }
111 } 117 }
112 /* Well, anyhow someone wrote to us, we should return that favour */ 118 /* Well, anyhow someone wrote to us, we should
119 return that favour */
113 wafwdt_ping(); 120 wafwdt_ping();
114 } 121 }
115 return count; 122 return count;
116} 123}
117 124
118static int wafwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 125static long wafwdt_ioctl(struct file *file, unsigned int cmd,
119 unsigned long arg) 126 unsigned long arg)
120{ 127{
121 int new_timeout; 128 int new_timeout;
122 void __user *argp = (void __user *)arg; 129 void __user *argp = (void __user *)arg;
123 int __user *p = argp; 130 int __user *p = argp;
124 static struct watchdog_info ident = { 131 static const struct watchdog_info ident = {
125 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, 132 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
133 WDIOF_MAGICCLOSE,
126 .firmware_version = 1, 134 .firmware_version = 1,
127 .identity = "Wafer 5823 WDT", 135 .identity = "Wafer 5823 WDT",
128 }; 136 };
129 137
130 switch (cmd) { 138 switch (cmd) {
131 case WDIOC_GETSUPPORT: 139 case WDIOC_GETSUPPORT:
132 if (copy_to_user(argp, &ident, sizeof (ident))) 140 if (copy_to_user(argp, &ident, sizeof(ident)))
133 return -EFAULT; 141 return -EFAULT;
134 break; 142 break;
135 143
@@ -194,10 +202,11 @@ static int wafwdt_open(struct inode *inode, struct file *file)
194static int 202static int
195wafwdt_close(struct inode *inode, struct file *file) 203wafwdt_close(struct inode *inode, struct file *file)
196{ 204{
197 if (expect_close == 42) { 205 if (expect_close == 42)
198 wafwdt_stop(); 206 wafwdt_stop();
199 } else { 207 else {
200 printk(KERN_CRIT PFX "WDT device closed unexpectedly. WDT will not stop!\n"); 208 printk(KERN_CRIT PFX
209 "WDT device closed unexpectedly. WDT will not stop!\n");
201 wafwdt_ping(); 210 wafwdt_ping();
202 } 211 }
203 clear_bit(0, &wafwdt_is_open); 212 clear_bit(0, &wafwdt_is_open);
@@ -209,12 +218,11 @@ wafwdt_close(struct inode *inode, struct file *file)
209 * Notifier for system down 218 * Notifier for system down
210 */ 219 */
211 220
212static int wafwdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) 221static int wafwdt_notify_sys(struct notifier_block *this, unsigned long code,
222 void *unused)
213{ 223{
214 if (code == SYS_DOWN || code == SYS_HALT) { 224 if (code == SYS_DOWN || code == SYS_HALT)
215 /* Turn the WDT off */
216 wafwdt_stop(); 225 wafwdt_stop();
217 }
218 return NOTIFY_DONE; 226 return NOTIFY_DONE;
219} 227}
220 228
@@ -226,7 +234,7 @@ static const struct file_operations wafwdt_fops = {
226 .owner = THIS_MODULE, 234 .owner = THIS_MODULE,
227 .llseek = no_llseek, 235 .llseek = no_llseek,
228 .write = wafwdt_write, 236 .write = wafwdt_write,
229 .ioctl = wafwdt_ioctl, 237 .unlocked_ioctl = wafwdt_ioctl,
230 .open = wafwdt_open, 238 .open = wafwdt_open,
231 .release = wafwdt_close, 239 .release = wafwdt_close,
232}; 240};
@@ -250,25 +258,28 @@ static int __init wafwdt_init(void)
250{ 258{
251 int ret; 259 int ret;
252 260
253 printk(KERN_INFO "WDT driver for Wafer 5823 single board computer initialising.\n"); 261 printk(KERN_INFO
262 "WDT driver for Wafer 5823 single board computer initialising.\n");
254 263
255 if (timeout < 1 || timeout > 255) { 264 if (timeout < 1 || timeout > 255) {
256 timeout = WD_TIMO; 265 timeout = WD_TIMO;
257 printk (KERN_INFO PFX "timeout value must be 1<=x<=255, using %d\n", 266 printk(KERN_INFO PFX
258 timeout); 267 "timeout value must be 1 <= x <= 255, using %d\n",
268 timeout);
259 } 269 }
260 270
261 if (wdt_stop != wdt_start) { 271 if (wdt_stop != wdt_start) {
262 if(!request_region(wdt_stop, 1, "Wafer 5823 WDT")) { 272 if (!request_region(wdt_stop, 1, "Wafer 5823 WDT")) {
263 printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", 273 printk(KERN_ERR PFX
264 wdt_stop); 274 "I/O address 0x%04x already in use\n",
275 wdt_stop);
265 ret = -EIO; 276 ret = -EIO;
266 goto error; 277 goto error;
267 } 278 }
268 } 279 }
269 280
270 if(!request_region(wdt_start, 1, "Wafer 5823 WDT")) { 281 if (!request_region(wdt_start, 1, "Wafer 5823 WDT")) {
271 printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", 282 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n",
272 wdt_start); 283 wdt_start);
273 ret = -EIO; 284 ret = -EIO;
274 goto error2; 285 goto error2;
@@ -276,19 +287,20 @@ static int __init wafwdt_init(void)
276 287
277 ret = register_reboot_notifier(&wafwdt_notifier); 288 ret = register_reboot_notifier(&wafwdt_notifier);
278 if (ret != 0) { 289 if (ret != 0) {
279 printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 290 printk(KERN_ERR PFX
280 ret); 291 "cannot register reboot notifier (err=%d)\n", ret);
281 goto error3; 292 goto error3;
282 } 293 }
283 294
284 ret = misc_register(&wafwdt_miscdev); 295 ret = misc_register(&wafwdt_miscdev);
285 if (ret != 0) { 296 if (ret != 0) {
286 printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 297 printk(KERN_ERR PFX
287 WATCHDOG_MINOR, ret); 298 "cannot register miscdev on minor=%d (err=%d)\n",
299 WATCHDOG_MINOR, ret);
288 goto error4; 300 goto error4;
289 } 301 }
290 302
291 printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n", 303 printk(KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n",
292 timeout, nowayout); 304 timeout, nowayout);
293 305
294 return ret; 306 return ret;
@@ -307,7 +319,7 @@ static void __exit wafwdt_exit(void)
307{ 319{
308 misc_deregister(&wafwdt_miscdev); 320 misc_deregister(&wafwdt_miscdev);
309 unregister_reboot_notifier(&wafwdt_notifier); 321 unregister_reboot_notifier(&wafwdt_notifier);
310 if(wdt_stop != wdt_start) 322 if (wdt_stop != wdt_start)
311 release_region(wdt_stop, 1); 323 release_region(wdt_stop, 1);
312 release_region(wdt_start, 1); 324 release_region(wdt_start, 1);
313} 325}
diff --git a/drivers/watchdog/wdrtas.c b/drivers/watchdog/wdrtas.c
index 1d64e277567d..20fd6715f25f 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,9 +304,9 @@ 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;
@@ -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/wdt285.c b/drivers/watchdog/wdt285.c
index e4cf661dc890..fea398a4ca32 100644
--- a/drivers/watchdog/wdt285.c
+++ b/drivers/watchdog/wdt285.c
@@ -26,9 +26,9 @@
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#include <linux/uaccess.h>
30#include <linux/irq.h>
29 31
30#include <asm/irq.h>
31#include <asm/uaccess.h>
32#include <asm/hardware.h> 32#include <asm/hardware.h>
33#include <asm/mach-types.h> 33#include <asm/mach-types.h>
34#include <asm/hardware/dec21285.h> 34#include <asm/hardware/dec21285.h>
@@ -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..bdc28e522f03 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,8 +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: 368 default:
364 return -ENOTTY; 369 return -ENOTTY;
365 370
@@ -379,7 +384,7 @@ static int wdt977_ioctl(struct inode *inode, struct file *file,
379 return 0; 384 return 0;
380 385
381 case WDIOC_SETOPTIONS: 386 case WDIOC_SETOPTIONS:
382 if (get_user (new_options, uarg.i)) 387 if (get_user(new_options, uarg.i))
383 return -EFAULT; 388 return -EFAULT;
384 389
385 if (new_options & WDIOS_DISABLECARD) { 390 if (new_options & WDIOS_DISABLECARD) {
@@ -413,23 +418,21 @@ static int wdt977_ioctl(struct inode *inode, struct file *file,
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);