OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [char/] [wdt977.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *      Wdt977  0.02:   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
 *      14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
15
 *           Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
16
 */
17
 
18
#include <linux/module.h>
19
#include <linux/config.h>
20
#include <linux/types.h>
21
#include <linux/kernel.h>
22
#include <linux/fs.h>
23
#include <linux/miscdevice.h>
24
#include <linux/init.h>
25
#include <linux/smp_lock.h>
26
 
27
#include <asm/io.h>
28
#include <asm/system.h>
29
#include <asm/mach-types.h>
30
 
31
#define WATCHDOG_MINOR  130
32
 
33
static  int timeout = 3;
34
static  int timer_alive;
35
static  int testmode;
36
static  int expect_close = 0;
37
 
38
#ifdef CONFIG_WATCHDOG_NOWAYOUT
39
static int nowayout = 1;
40
#else
41
static int nowayout = 0;
42
#endif
43
 
44
MODULE_PARM(nowayout,"i");
45
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
46
 
47
 
48
/*
49
 *      Allow only one person to hold it open
50
 */
51
 
52
static int wdt977_open(struct inode *inode, struct file *file)
53
{
54
        if(timer_alive)
55
                return -EBUSY;
56
        if (nowayout) {
57
                MOD_INC_USE_COUNT;
58
        }
59
        timer_alive++;
60
 
61
        //max timeout value = 255 minutes (0xFF). Write 0 to disable WatchDog.
62
        if (timeout>255)
63
            timeout = 255;
64
 
65
        printk(KERN_INFO "Watchdog: active, current timeout %d min.\n",timeout);
66
 
67
        // unlock the SuperIO chip
68
        outb(0x87,0x370);
69
        outb(0x87,0x370);
70
 
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)
76
 
77
        outb(0x07,0x370);
78
        outb(0x08,0x371);
79
        outb(0xF2,0x370);
80
        outb(timeout,0x371);
81
        outb(0xF3,0x370);
82
        outb(0x00,0x371);       //another setting is 0E for kbd/mouse/LED
83
        outb(0xF4,0x370);
84
        outb(0x00,0x371);
85
 
86
        //at last select device Aux1 (dev=7) and set GP16 as a watchdog output
87
        if (!testmode)
88
        {
89
                outb(0x07,0x370);
90
                outb(0x07,0x371);
91
                outb(0xE6,0x370);
92
                outb(0x08,0x371);
93
        }
94
 
95
        // lock the SuperIO chip
96
        outb(0xAA,0x370);
97
 
98
        return 0;
99
}
100
 
101
static int wdt977_release(struct inode *inode, struct file *file)
102
{
103
        /*
104
         *      Shut off the timer.
105
         *      Lock it in if it's a module and we set nowayout
106
         */
107
        lock_kernel();
108
        if (expect_close) {
109
 
110
                // unlock the SuperIO chip
111
                outb(0x87,0x370);
112
                outb(0x87,0x370);
113
 
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
118
 
119
                outb(0x07,0x370);
120
                outb(0x08,0x371);
121
                outb(0xF2,0x370);
122
                outb(0xFF,0x371);
123
                outb(0xF3,0x370);
124
                outb(0x00,0x371);
125
                outb(0xF4,0x370);
126
                outb(0x00,0x371);
127
                outb(0xF2,0x370);
128
                outb(0x00,0x371);
129
 
130
                //at last select device Aux1 (dev=7) and set GP16 as a watchdog output
131
                outb(0x07,0x370);
132
                outb(0x07,0x371);
133
                outb(0xE6,0x370);
134
                outb(0x08,0x371);
135
 
136
                // lock the SuperIO chip
137
                outb(0xAA,0x370);
138
                printk(KERN_INFO "Watchdog: shutdown.\n");
139
        } else {
140
                printk(KERN_CRIT "WDT device closed unexpectedly.  WDT will not stop!\n");
141
        }
142
 
143
        timer_alive=0;
144
        unlock_kernel();
145
 
146
        return 0;
147
}
148
 
149
static ssize_t wdt977_write(struct file *file, const char *data, size_t len, loff_t *ppos)
150
{
151
        if (!nowayout) {
152
                size_t i;
153
 
154
                /* In case it was set long ago */
155
                expect_close = 0;
156
 
157
                for (i = 0; i != len; i++) {
158
                        char c;
159
                        if (get_user(c, data + i))
160
                                return -EFAULT;
161
                        if (c == 'V')
162
                                expect_close = 1;
163
                }
164
        }
165
 
166
        //max timeout value = 255 minutes (0xFF). Write 0 to disable WatchDog.
167
        if (timeout>255)
168
            timeout = 255;
169
 
170
        /*
171
         *      Refresh the timer.
172
         */
173
 
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...
176
//      if (timeout>126)
177
//          timeout = 126;
178
 
179
        // unlock the SuperIO chip
180
        outb(0x87,0x370);
181
        outb(0x87,0x370);
182
 
183
        //select device Aux2 (device=8) and kicks watchdog reg F2
184
        //F2 has the timeout in minutes
185
 
186
        outb(0x07,0x370);
187
        outb(0x08,0x371);
188
        outb(0xF2,0x370);
189
        outb(timeout,0x371);
190
 
191
        // lock the SuperIO chip
192
        outb(0xAA,0x370);
193
 
194
        return 1;
195
}
196
 
197
static struct file_operations wdt977_fops=
198
{
199
        owner:          THIS_MODULE,
200
        write:          wdt977_write,
201
        open:           wdt977_open,
202
        release:        wdt977_release,
203
};
204
 
205
static struct miscdevice wdt977_miscdev=
206
{
207
        WATCHDOG_MINOR,
208
        "watchdog",
209
        &wdt977_fops
210
};
211
 
212
static int __init nwwatchdog_init(void)
213
{
214
        if (!machine_is_netwinder())
215
                return -ENODEV;
216
 
217
        misc_register(&wdt977_miscdev);
218
        printk(KERN_INFO "NetWinder Watchdog sleeping.\n");
219
        return 0;
220
}
221
 
222
static void __exit nwwatchdog_exit(void)
223
{
224
        misc_deregister(&wdt977_miscdev);
225
}
226
 
227
EXPORT_NO_SYMBOLS;
228
 
229
module_init(nwwatchdog_init);
230
module_exit(nwwatchdog_exit);
231
 
232
MODULE_LICENSE("GPL");

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.