diff options
Diffstat (limited to 'drivers/watchdog/wafer5823wdt.c')
-rw-r--r-- | drivers/watchdog/wafer5823wdt.c | 80 |
1 files changed, 46 insertions, 34 deletions
diff --git a/drivers/watchdog/wafer5823wdt.c b/drivers/watchdog/wafer5823wdt.c index 9e368091f79..886cbbcf3ee 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 | ||
62 | static int timeout = WD_TIMO; /* in seconds */ | 62 | static int timeout = WD_TIMO; /* in seconds */ |
63 | module_param(timeout, int, 0); | 63 | module_param(timeout, int, 0); |
64 | MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=255, default=" __MODULE_STRING(WD_TIMO) "."); | 64 | MODULE_PARM_DESC(timeout, |
65 | "Watchdog timeout in seconds. 1 <= timeout <= 255, default=" | ||
66 | __MODULE_STRING(WD_TIMO) "."); | ||
65 | 67 | ||
66 | static int nowayout = WATCHDOG_NOWAYOUT; | 68 | static int nowayout = WATCHDOG_NOWAYOUT; |
67 | module_param(nowayout, int, 0); | 69 | module_param(nowayout, int, 0); |
68 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 70 | MODULE_PARM_DESC(nowayout, |
71 | "Watchdog cannot be stopped once started (default=" | ||
72 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
69 | 73 | ||
70 | static void wafwdt_ping(void) | 74 | static 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 | ||
93 | static ssize_t wafwdt_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos) | 97 | static 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 | ||
118 | static int wafwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 125 | static 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) | |||
194 | static int | 202 | static int |
195 | wafwdt_close(struct inode *inode, struct file *file) | 203 | wafwdt_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 | ||
212 | static int wafwdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) | 221 | static 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 | } |