2 * Wdt977 0.02: A Watchdog Device for Netwinder W83977AF chip
4 * (c) Copyright 1998 Rebel.com (Woody Suwalski <woody@netwinder.org>)
6 * -----------------------
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.
13 * -----------------------
14 * 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
15 * Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
18 #include <linux/module.h>
19 #include <linux/config.h>
20 #include <linux/types.h>
21 #include <linux/kernel.h>
23 #include <linux/miscdevice.h>
24 #include <linux/init.h>
25 #include <linux/smp_lock.h>
28 #include <asm/system.h>
29 #include <asm/mach-types.h>
31 #define WATCHDOG_MINOR 130
33 static int timeout = 3;
34 static int timer_alive;
36 static int expect_close = 0;
38 #ifdef CONFIG_WATCHDOG_NOWAYOUT
39 static int nowayout = 1;
41 static int nowayout = 0;
44 MODULE_PARM(nowayout,"i");
45 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
49 * Allow only one person to hold it open
52 static int wdt977_open(struct inode *inode, struct file *file)
61 //max timeout value = 255 minutes (0xFF). Write 0 to disable WatchDog.
65 printk(KERN_INFO "Watchdog: active, current timeout %d min.\n",timeout);
67 // unlock the SuperIO chip
71 //select device Aux2 (device=8) and set watchdog regs F2, F3 and F4
72 //F2 has the timeout in minutes
73 //F3 could be set to the POWER LED blink (with GP17 set to PowerLed)
74 // at timeout, and to reset timer on kbd/mouse activity (not now)
75 //F4 is used to just clear the TIMEOUT'ed state (bit 0)
82 outb(0x00,0x371); //another setting is 0E for kbd/mouse/LED
86 //at last select device Aux1 (dev=7) and set GP16 as a watchdog output
95 // lock the SuperIO chip
101 static int wdt977_release(struct inode *inode, struct file *file)
104 * Shut off the timer.
105 * Lock it in if it's a module and we set nowayout
110 // unlock the SuperIO chip
114 //select device Aux2 (device=8) and set watchdog regs F2,F3 and F4
115 //F3 is reset to its default state
116 //F4 can clear the TIMEOUT'ed state (bit 0) - back to default
117 //We can not use GP17 as a PowerLed, as we use its usage as a RedLed
130 //at last select device Aux1 (dev=7) and set GP16 as a watchdog output
136 // lock the SuperIO chip
138 printk(KERN_INFO "Watchdog: shutdown.\n");
140 printk(KERN_CRIT "WDT device closed unexpectedly. WDT will not stop!\n");
149 static ssize_t wdt977_write(struct file *file, const char *data, size_t len, loff_t *ppos)
154 /* In case it was set long ago */
157 for (i = 0; i != len; i++) {
159 if (get_user(c, data + i))
166 //max timeout value = 255 minutes (0xFF). Write 0 to disable WatchDog.
174 //we have a hw bug somewhere, so each 977 minute is actually only 30sec
175 //as such limit the max timeout to half of max of 255 minutes...
179 // unlock the SuperIO chip
183 //select device Aux2 (device=8) and kicks watchdog reg F2
184 //F2 has the timeout in minutes
191 // lock the SuperIO chip
197 static struct file_operations wdt977_fops=
202 release: wdt977_release,
205 static struct miscdevice wdt977_miscdev=
212 static int __init nwwatchdog_init(void)
214 if (!machine_is_netwinder())
217 misc_register(&wdt977_miscdev);
218 printk(KERN_INFO "NetWinder Watchdog sleeping.\n");
222 static void __exit nwwatchdog_exit(void)
224 misc_deregister(&wdt977_miscdev);
229 module_init(nwwatchdog_init);
230 module_exit(nwwatchdog_exit);
232 MODULE_LICENSE("GPL");