~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/char/wdt977.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *      Wdt977  0.01:   A Watchdog Device for Netwinder W83977AF chip
  3  *
  4  *      (c) Copyright 1998 Rebel.com (Woody Suwalski <woody@netwinder.org>)
  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  */
 15  
 16 #include <linux/module.h>
 17 #include <linux/config.h>
 18 #include <linux/types.h>
 19 #include <linux/kernel.h>
 20 #include <linux/fs.h>
 21 #include <linux/miscdevice.h>
 22 #include <linux/init.h>
 23 #include <linux/smp_lock.h>
 24 
 25 #include <asm/io.h>
 26 #include <asm/system.h>
 27 #include <asm/mach-types.h>
 28 
 29 #define WATCHDOG_MINOR  130
 30 
 31 static  int timeout = 3;
 32 static  int timer_alive;
 33 static  int testmode;
 34 
 35 /*
 36  *      Allow only one person to hold it open
 37  */
 38  
 39 static int wdt977_open(struct inode *inode, struct file *file)
 40 {
 41         if(timer_alive)
 42                 return -EBUSY;
 43 #ifdef CONFIG_WATCHDOG_NOWAYOUT
 44         MOD_INC_USE_COUNT;
 45 #endif
 46         timer_alive++;
 47 
 48         //max timeout value = 255 minutes (0xFF). Write 0 to disable WatchDog.
 49         if (timeout>255)
 50             timeout = 255;
 51 
 52         printk(KERN_INFO "Watchdog: active, current timeout %d min.\n",timeout);
 53 
 54         // unlock the SuperIO chip
 55         outb(0x87,0x370); 
 56         outb(0x87,0x370); 
 57         
 58         //select device Aux2 (device=8) and set watchdog regs F2, F3 and F4
 59         //F2 has the timeout in minutes
 60         //F3 could be set to the POWER LED blink (with GP17 set to PowerLed)
 61         //   at timeout, and to reset timer on kbd/mouse activity (not now)
 62         //F4 is used to just clear the TIMEOUT'ed state (bit 0)
 63         
 64         outb(0x07,0x370);
 65         outb(0x08,0x371);
 66         outb(0xF2,0x370);
 67         outb(timeout,0x371);
 68         outb(0xF3,0x370);
 69         outb(0x00,0x371);       //another setting is 0E for kbd/mouse/LED
 70         outb(0xF4,0x370);
 71         outb(0x00,0x371);
 72         
 73         //at last select device Aux1 (dev=7) and set GP16 as a watchdog output
 74         if (!testmode)
 75         {
 76                 outb(0x07,0x370);
 77                 outb(0x07,0x371);
 78                 outb(0xE6,0x370);
 79                 outb(0x08,0x371);
 80         }
 81                 
 82         // lock the SuperIO chip
 83         outb(0xAA,0x370); 
 84 
 85         return 0;
 86 }
 87 
 88 static int wdt977_release(struct inode *inode, struct file *file)
 89 {
 90         /*
 91          *      Shut off the timer.
 92          *      Lock it in if it's a module and we defined ...NOWAYOUT
 93          */
 94 #ifndef CONFIG_WATCHDOG_NOWAYOUT
 95         lock_kernel();
 96 
 97         // unlock the SuperIO chip
 98         outb(0x87,0x370); 
 99         outb(0x87,0x370); 
100         
101         //select device Aux2 (device=8) and set watchdog regs F2,F3 and F4
102         //F3 is reset to its default state
103         //F4 can clear the TIMEOUT'ed state (bit 0) - back to default
104         //We can not use GP17 as a PowerLed, as we use its usage as a RedLed
105         
106         outb(0x07,0x370);
107         outb(0x08,0x371);
108         outb(0xF2,0x370);
109         outb(0xFF,0x371);
110         outb(0xF3,0x370);
111         outb(0x00,0x371);
112         outb(0xF4,0x370);
113         outb(0x00,0x371);
114         outb(0xF2,0x370);
115         outb(0x00,0x371);
116         
117         //at last select device Aux1 (dev=7) and set GP16 as a watchdog output
118         outb(0x07,0x370);
119         outb(0x07,0x371);
120         outb(0xE6,0x370);
121         outb(0x08,0x371);
122         
123         // lock the SuperIO chip
124         outb(0xAA,0x370);
125 
126         timer_alive=0;
127         unlock_kernel();
128 
129         printk(KERN_INFO "Watchdog: shutdown.\n");
130 #endif
131         return 0;
132 }
133 
134 static ssize_t wdt977_write(struct file *file, const char *data, size_t len, loff_t *ppos)
135 {
136 
137         //max timeout value = 255 minutes (0xFF). Write 0 to disable WatchDog.
138         if (timeout>255)
139             timeout = 255;
140 
141         /*
142          *      Refresh the timer.
143          */
144                 
145         //we have a hw bug somewhere, so each 977 minute is actually only 30sec
146         //as such limit the max timeout to half of max of 255 minutes...
147 //      if (timeout>126)
148 //          timeout = 126;
149         
150         // unlock the SuperIO chip
151         outb(0x87,0x370); 
152         outb(0x87,0x370); 
153         
154         //select device Aux2 (device=8) and kicks watchdog reg F2
155         //F2 has the timeout in minutes
156         
157         outb(0x07,0x370);
158         outb(0x08,0x371);
159         outb(0xF2,0x370);
160         outb(timeout,0x371);
161         
162         // lock the SuperIO chip
163         outb(0xAA,0x370); 
164         
165         return 1;
166 }
167 
168 static struct file_operations wdt977_fops=
169 {
170         owner:          THIS_MODULE,
171         write:          wdt977_write,
172         open:           wdt977_open,
173         release:        wdt977_release,
174 };
175 
176 static struct miscdevice wdt977_miscdev=
177 {
178         WATCHDOG_MINOR,
179         "watchdog",
180         &wdt977_fops
181 };
182 
183 static int __init nwwatchdog_init(void)
184 {
185         if (!machine_is_netwinder())
186                 return -ENODEV;
187 
188         misc_register(&wdt977_miscdev);
189         printk(KERN_INFO "NetWinder Watchdog sleeping.\n");
190         return 0;
191 }       
192 
193 static void __exit nwwatchdog_exit(void)
194 {
195         misc_deregister(&wdt977_miscdev);
196 }
197 
198 EXPORT_NO_SYMBOLS;
199 
200 module_init(nwwatchdog_init);
201 module_exit(nwwatchdog_exit);
202 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.