Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
wdt977.c
Go to the documentation of this file.
1 /*
2  * Wdt977 0.04: A Watchdog Device for Netwinder W83977AF chip
3  *
4  * (c) Copyright 1998 Rebel.com (Woody Suwalski <[email protected]>)
5  *
6  * -----------------------
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version
11  * 2 of the License, or (at your option) any later version.
12  *
13  * -----------------------
14  * 14-Dec-2001 Matt Domsch <[email protected]>
15  * Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
16  * 19-Dec-2001 Woody Suwalski: Netwinder fixes, ioctl interface
17  * 06-Jan-2002 Woody Suwalski: For compatibility, convert all timeouts
18  * from minutes to seconds.
19  * 07-Jul-2003 Daniele Bellucci: Audit return code of misc_register in
20  * nwwatchdog_init.
21  * 25-Oct-2005 Woody Suwalski: Convert addresses to #defs, add spinlocks
22  * remove limitiation to be used on
23  * Netwinders only
24  */
25 
26 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
27 
28 #include <linux/module.h>
29 #include <linux/moduleparam.h>
30 #include <linux/types.h>
31 #include <linux/kernel.h>
32 #include <linux/fs.h>
33 #include <linux/miscdevice.h>
34 #include <linux/init.h>
35 #include <linux/ioport.h>
36 #include <linux/watchdog.h>
37 #include <linux/notifier.h>
38 #include <linux/reboot.h>
39 #include <linux/io.h>
40 #include <linux/uaccess.h>
41 
42 #include <asm/mach-types.h>
43 
44 #define WATCHDOG_VERSION "0.04"
45 #define WATCHDOG_NAME "Wdt977"
46 
47 #define IO_INDEX_PORT 0x370 /* on some systems it can be 0x3F0 */
48 #define IO_DATA_PORT (IO_INDEX_PORT + 1)
49 
50 #define UNLOCK_DATA 0x87
51 #define LOCK_DATA 0xAA
52 #define DEVICE_REGISTER 0x07
53 
54 
55 #define DEFAULT_TIMEOUT 60 /* default timeout in seconds */
56 
57 static int timeout = DEFAULT_TIMEOUT;
58 static int timeoutM; /* timeout in minutes */
59 static unsigned long timer_alive;
60 static int testmode;
61 static char expect_close;
63 
64 module_param(timeout, int, 0);
65 MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (60..15300, default="
67 module_param(testmode, int, 0);
68 MODULE_PARM_DESC(testmode, "Watchdog testmode (1 = no reboot), default=0");
69 
70 static bool nowayout = WATCHDOG_NOWAYOUT;
71 module_param(nowayout, bool, 0);
72 MODULE_PARM_DESC(nowayout,
73  "Watchdog cannot be stopped once started (default="
75 
76 /*
77  * Start the watchdog
78  */
79 
80 static int wdt977_start(void)
81 {
82  unsigned long flags;
83 
84  spin_lock_irqsave(&spinlock, flags);
85 
86  /* unlock the SuperIO chip */
89 
90  /* select device Aux2 (device=8) and set watchdog regs F2, F3 and F4
91  * F2 has the timeout in minutes
92  * F3 could be set to the POWER LED blink (with GP17 set to PowerLed)
93  * at timeout, and to reset timer on kbd/mouse activity (not impl.)
94  * F4 is used to just clear the TIMEOUT'ed state (bit 0)
95  */
97  outb_p(0x08, IO_DATA_PORT);
98  outb_p(0xF2, IO_INDEX_PORT);
99  outb_p(timeoutM, IO_DATA_PORT);
100  outb_p(0xF3, IO_INDEX_PORT);
101  outb_p(0x00, IO_DATA_PORT); /* another setting is 0E for
102  kbd/mouse/LED */
103  outb_p(0xF4, IO_INDEX_PORT);
104  outb_p(0x00, IO_DATA_PORT);
105 
106  /* At last select device Aux1 (dev=7) and set GP16 as a
107  * watchdog output. In test mode watch the bit 1 on F4 to
108  * indicate "triggered"
109  */
110  if (!testmode) {
112  outb_p(0x07, IO_DATA_PORT);
113  outb_p(0xE6, IO_INDEX_PORT);
114  outb_p(0x08, IO_DATA_PORT);
115  }
116 
117  /* lock the SuperIO chip */
119 
120  spin_unlock_irqrestore(&spinlock, flags);
121  pr_info("activated\n");
122 
123  return 0;
124 }
125 
126 /*
127  * Stop the watchdog
128  */
129 
130 static int wdt977_stop(void)
131 {
132  unsigned long flags;
133  spin_lock_irqsave(&spinlock, flags);
134 
135  /* unlock the SuperIO chip */
138 
139  /* select device Aux2 (device=8) and set watchdog regs F2,F3 and F4
140  * F3 is reset to its default state
141  * F4 can clear the TIMEOUT'ed state (bit 0) - back to default
142  * We can not use GP17 as a PowerLed, as we use its usage as a RedLed
143  */
145  outb_p(0x08, IO_DATA_PORT);
146  outb_p(0xF2, IO_INDEX_PORT);
147  outb_p(0xFF, IO_DATA_PORT);
148  outb_p(0xF3, IO_INDEX_PORT);
149  outb_p(0x00, IO_DATA_PORT);
150  outb_p(0xF4, IO_INDEX_PORT);
151  outb_p(0x00, IO_DATA_PORT);
152  outb_p(0xF2, IO_INDEX_PORT);
153  outb_p(0x00, IO_DATA_PORT);
154 
155  /* at last select device Aux1 (dev=7) and set
156  GP16 as a watchdog output */
158  outb_p(0x07, IO_DATA_PORT);
159  outb_p(0xE6, IO_INDEX_PORT);
160  outb_p(0x08, IO_DATA_PORT);
161 
162  /* lock the SuperIO chip */
164 
165  spin_unlock_irqrestore(&spinlock, flags);
166  pr_info("shutdown\n");
167 
168  return 0;
169 }
170 
171 /*
172  * Send a keepalive ping to the watchdog
173  * This is done by simply re-writing the timeout to reg. 0xF2
174  */
175 
176 static int wdt977_keepalive(void)
177 {
178  unsigned long flags;
179  spin_lock_irqsave(&spinlock, flags);
180 
181  /* unlock the SuperIO chip */
184 
185  /* select device Aux2 (device=8) and kicks watchdog reg F2 */
186  /* F2 has the timeout in minutes */
188  outb_p(0x08, IO_DATA_PORT);
189  outb_p(0xF2, IO_INDEX_PORT);
190  outb_p(timeoutM, IO_DATA_PORT);
191 
192  /* lock the SuperIO chip */
194  spin_unlock_irqrestore(&spinlock, flags);
195 
196  return 0;
197 }
198 
199 /*
200  * Set the watchdog timeout value
201  */
202 
203 static int wdt977_set_timeout(int t)
204 {
205  int tmrval;
206 
207  /* convert seconds to minutes, rounding up */
208  tmrval = (t + 59) / 60;
209 
210  if (machine_is_netwinder()) {
211  /* we have a hw bug somewhere, so each 977 minute is actually
212  * only 30sec. This limits the max timeout to half of device
213  * max of 255 minutes...
214  */
215  tmrval += tmrval;
216  }
217 
218  if (tmrval < 1 || tmrval > 255)
219  return -EINVAL;
220 
221  /* timeout is the timeout in seconds, timeoutM is
222  the timeout in minutes) */
223  timeout = t;
224  timeoutM = tmrval;
225  return 0;
226 }
227 
228 /*
229  * Get the watchdog status
230  */
231 
232 static int wdt977_get_status(int *status)
233 {
234  int new_status;
235  unsigned long flags;
236 
237  spin_lock_irqsave(&spinlock, flags);
238 
239  /* unlock the SuperIO chip */
242 
243  /* select device Aux2 (device=8) and read watchdog reg F4 */
245  outb_p(0x08, IO_DATA_PORT);
246  outb_p(0xF4, IO_INDEX_PORT);
247  new_status = inb_p(IO_DATA_PORT);
248 
249  /* lock the SuperIO chip */
251 
252  spin_unlock_irqrestore(&spinlock, flags);
253 
254  *status = 0;
255  if (new_status & 1)
256  *status |= WDIOF_CARDRESET;
257 
258  return 0;
259 }
260 
261 
262 /*
263  * /dev/watchdog handling
264  */
265 
266 static int wdt977_open(struct inode *inode, struct file *file)
267 {
268  /* If the watchdog is alive we don't need to start it again */
269  if (test_and_set_bit(0, &timer_alive))
270  return -EBUSY;
271 
272  if (nowayout)
273  __module_get(THIS_MODULE);
274 
275  wdt977_start();
276  return nonseekable_open(inode, file);
277 }
278 
279 static int wdt977_release(struct inode *inode, struct file *file)
280 {
281  /*
282  * Shut off the timer.
283  * Lock it in if it's a module and we set nowayout
284  */
285  if (expect_close == 42) {
286  wdt977_stop();
287  clear_bit(0, &timer_alive);
288  } else {
289  wdt977_keepalive();
290  pr_crit("Unexpected close, not stopping watchdog!\n");
291  }
292  expect_close = 0;
293  return 0;
294 }
295 
296 
297 /*
298  * wdt977_write:
299  * @file: file handle to the watchdog
300  * @buf: buffer to write (unused as data does not matter here
301  * @count: count of bytes
302  * @ppos: pointer to the position to write. No seeks allowed
303  *
304  * A write to a watchdog device is defined as a keepalive signal. Any
305  * write of data will do, as we we don't define content meaning.
306  */
307 
308 static ssize_t wdt977_write(struct file *file, const char __user *buf,
309  size_t count, loff_t *ppos)
310 {
311  if (count) {
312  if (!nowayout) {
313  size_t i;
314 
315  /* In case it was set long ago */
316  expect_close = 0;
317 
318  for (i = 0; i != count; i++) {
319  char c;
320  if (get_user(c, buf + i))
321  return -EFAULT;
322  if (c == 'V')
323  expect_close = 42;
324  }
325  }
326 
327  /* someone wrote to us, we should restart timer */
328  wdt977_keepalive();
329  }
330  return count;
331 }
332 
333 static const struct watchdog_info ident = {
334  .options = WDIOF_SETTIMEOUT |
337  .firmware_version = 1,
338  .identity = WATCHDOG_NAME,
339 };
340 
341 /*
342  * wdt977_ioctl:
343  * @inode: inode of the device
344  * @file: file handle to the device
345  * @cmd: watchdog command
346  * @arg: argument pointer
347  *
348  * The watchdog API defines a common set of functions for all watchdogs
349  * according to their available features.
350  */
351 
352 static long wdt977_ioctl(struct file *file, unsigned int cmd,
353  unsigned long arg)
354 {
355  int status;
356  int new_options, retval = -EINVAL;
357  int new_timeout;
358  union {
359  struct watchdog_info __user *ident;
360  int __user *i;
361  } uarg;
362 
363  uarg.i = (int __user *)arg;
364 
365  switch (cmd) {
366  case WDIOC_GETSUPPORT:
367  return copy_to_user(uarg.ident, &ident,
368  sizeof(ident)) ? -EFAULT : 0;
369 
370  case WDIOC_GETSTATUS:
371  wdt977_get_status(&status);
372  return put_user(status, uarg.i);
373 
374  case WDIOC_GETBOOTSTATUS:
375  return put_user(0, uarg.i);
376 
377  case WDIOC_SETOPTIONS:
378  if (get_user(new_options, uarg.i))
379  return -EFAULT;
380 
381  if (new_options & WDIOS_DISABLECARD) {
382  wdt977_stop();
383  retval = 0;
384  }
385 
386  if (new_options & WDIOS_ENABLECARD) {
387  wdt977_start();
388  retval = 0;
389  }
390 
391  return retval;
392 
393  case WDIOC_KEEPALIVE:
394  wdt977_keepalive();
395  return 0;
396 
397  case WDIOC_SETTIMEOUT:
398  if (get_user(new_timeout, uarg.i))
399  return -EFAULT;
400 
401  if (wdt977_set_timeout(new_timeout))
402  return -EINVAL;
403 
404  wdt977_keepalive();
405  /* Fall */
406 
407  case WDIOC_GETTIMEOUT:
408  return put_user(timeout, uarg.i);
409 
410  default:
411  return -ENOTTY;
412 
413  }
414 }
415 
416 static int wdt977_notify_sys(struct notifier_block *this, unsigned long code,
417  void *unused)
418 {
419  if (code == SYS_DOWN || code == SYS_HALT)
420  wdt977_stop();
421  return NOTIFY_DONE;
422 }
423 
424 static const struct file_operations wdt977_fops = {
425  .owner = THIS_MODULE,
426  .llseek = no_llseek,
427  .write = wdt977_write,
428  .unlocked_ioctl = wdt977_ioctl,
429  .open = wdt977_open,
430  .release = wdt977_release,
431 };
432 
433 static struct miscdevice wdt977_miscdev = {
434  .minor = WATCHDOG_MINOR,
435  .name = "watchdog",
436  .fops = &wdt977_fops,
437 };
438 
439 static struct notifier_block wdt977_notifier = {
440  .notifier_call = wdt977_notify_sys,
441 };
442 
443 static int __init wd977_init(void)
444 {
445  int rc;
446 
447  pr_info("driver v%s\n", WATCHDOG_VERSION);
448 
449  /* Check that the timeout value is within its range;
450  if not reset to the default */
451  if (wdt977_set_timeout(timeout)) {
452  wdt977_set_timeout(DEFAULT_TIMEOUT);
453  pr_info("timeout value must be 60 < timeout < 15300, using %d\n",
455  }
456 
457  /* on Netwinder the IOports are already reserved by
458  * arch/arm/mach-footbridge/netwinder-hw.c
459  */
460  if (!machine_is_netwinder()) {
462  pr_err("I/O address 0x%04x already in use\n",
463  IO_INDEX_PORT);
464  rc = -EIO;
465  goto err_out;
466  }
467  }
468 
469  rc = register_reboot_notifier(&wdt977_notifier);
470  if (rc) {
471  pr_err("cannot register reboot notifier (err=%d)\n", rc);
472  goto err_out_region;
473  }
474 
475  rc = misc_register(&wdt977_miscdev);
476  if (rc) {
477  pr_err("cannot register miscdev on minor=%d (err=%d)\n",
478  wdt977_miscdev.minor, rc);
479  goto err_out_reboot;
480  }
481 
482  pr_info("initialized. timeout=%d sec (nowayout=%d, testmode=%i)\n",
483  timeout, nowayout, testmode);
484 
485  return 0;
486 
487 err_out_reboot:
488  unregister_reboot_notifier(&wdt977_notifier);
489 err_out_region:
490  if (!machine_is_netwinder())
492 err_out:
493  return rc;
494 }
495 
496 static void __exit wd977_exit(void)
497 {
498  wdt977_stop();
499  misc_deregister(&wdt977_miscdev);
500  unregister_reboot_notifier(&wdt977_notifier);
502 }
503 
504 module_init(wd977_init);
505 module_exit(wd977_exit);
506 
507 MODULE_AUTHOR("Woody Suwalski <[email protected]>");
508 MODULE_DESCRIPTION("W83977AF Watchdog driver");
509 MODULE_LICENSE("GPL");