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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [watchdog/] [wdt285.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 *      Intel 21285 watchdog driver
3
 *      Copyright (c) Phil Blundell <pb@nexus.co.uk>, 1998
4
 *
5
 *      based on
6
 *
7
 *      SoftDog 0.05:   A Software Watchdog Device
8
 *
9
 *      (c) Copyright 1996 Alan Cox <alan@redhat.com>, All Rights Reserved.
10
 *
11
 *      This program is free software; you can redistribute it and/or
12
 *      modify it under the terms of the GNU General Public License
13
 *      as published by the Free Software Foundation; either version
14
 *      2 of the License, or (at your option) any later version.
15
 *
16
 */
17
 
18
#include <linux/module.h>
19
#include <linux/moduleparam.h>
20
#include <linux/types.h>
21
#include <linux/kernel.h>
22
#include <linux/fs.h>
23
#include <linux/mm.h>
24
#include <linux/miscdevice.h>
25
#include <linux/watchdog.h>
26
#include <linux/reboot.h>
27
#include <linux/init.h>
28
#include <linux/interrupt.h>
29
 
30
#include <asm/irq.h>
31
#include <asm/uaccess.h>
32
#include <asm/hardware.h>
33
#include <asm/mach-types.h>
34
#include <asm/hardware/dec21285.h>
35
 
36
/*
37
 * Define this to stop the watchdog actually rebooting the machine.
38
 */
39
#undef ONLY_TESTING
40
 
41
static unsigned int soft_margin = 60;           /* in seconds */
42
static unsigned int reload;
43
static unsigned long timer_alive;
44
 
45
#ifdef ONLY_TESTING
46
/*
47
 *      If the timer expires..
48
 */
49
static void watchdog_fire(int irq, void *dev_id)
50
{
51
        printk(KERN_CRIT "Watchdog: Would Reboot.\n");
52
        *CSR_TIMER4_CNTL = 0;
53
        *CSR_TIMER4_CLR = 0;
54
}
55
#endif
56
 
57
/*
58
 *      Refresh the timer.
59
 */
60
static void watchdog_ping(void)
61
{
62
        *CSR_TIMER4_LOAD = reload;
63
}
64
 
65
/*
66
 *      Allow only one person to hold it open
67
 */
68
static int watchdog_open(struct inode *inode, struct file *file)
69
{
70
        int ret;
71
 
72
        if (*CSR_SA110_CNTL & (1 << 13))
73
                return -EBUSY;
74
 
75
        if (test_and_set_bit(1, &timer_alive))
76
                return -EBUSY;
77
 
78
        reload = soft_margin * (mem_fclk_21285 / 256);
79
 
80
        *CSR_TIMER4_CLR = 0;
81
        watchdog_ping();
82
        *CSR_TIMER4_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD
83
                | TIMER_CNTL_DIV256;
84
 
85
#ifdef ONLY_TESTING
86
        ret = request_irq(IRQ_TIMER4, watchdog_fire, 0, "watchdog", NULL);
87
        if (ret) {
88
                *CSR_TIMER4_CNTL = 0;
89
                clear_bit(1, &timer_alive);
90
        }
91
#else
92
        /*
93
         * Setting this bit is irreversible; once enabled, there is
94
         * no way to disable the watchdog.
95
         */
96
        *CSR_SA110_CNTL |= 1 << 13;
97
 
98
        ret = 0;
99
#endif
100
        nonseekable_open(inode, file);
101
        return ret;
102
}
103
 
104
/*
105
 *      Shut off the timer.
106
 *      Note: if we really have enabled the watchdog, there
107
 *      is no way to turn off.
108
 */
109
static int watchdog_release(struct inode *inode, struct file *file)
110
{
111
#ifdef ONLY_TESTING
112
        free_irq(IRQ_TIMER4, NULL);
113
        clear_bit(1, &timer_alive);
114
#endif
115
        return 0;
116
}
117
 
118
static ssize_t
119
watchdog_write(struct file *file, const char *data, size_t len, loff_t *ppos)
120
{
121
        /*
122
         *      Refresh the timer.
123
         */
124
        if (len)
125
                watchdog_ping();
126
 
127
        return len;
128
}
129
 
130
static struct watchdog_info ident = {
131
        .options        = WDIOF_SETTIMEOUT,
132
        .identity       = "Footbridge Watchdog",
133
};
134
 
135
static int
136
watchdog_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
137
               unsigned long arg)
138
{
139
        unsigned int new_margin;
140
        int ret = -ENOTTY;
141
 
142
        switch(cmd) {
143
        case WDIOC_GETSUPPORT:
144
                ret = 0;
145
                if (copy_to_user((void *)arg, &ident, sizeof(ident)))
146
                        ret = -EFAULT;
147
                break;
148
 
149
        case WDIOC_GETSTATUS:
150
        case WDIOC_GETBOOTSTATUS:
151
                ret = put_user(0,(int *)arg);
152
                break;
153
 
154
        case WDIOC_KEEPALIVE:
155
                watchdog_ping();
156
                ret = 0;
157
                break;
158
 
159
        case WDIOC_SETTIMEOUT:
160
                ret = get_user(new_margin, (int *)arg);
161
                if (ret)
162
                        break;
163
 
164
                /* Arbitrary, can't find the card's limits */
165
                if (new_margin < 0 || new_margin > 60) {
166
                        ret = -EINVAL;
167
                        break;
168
                }
169
 
170
                soft_margin = new_margin;
171
                reload = soft_margin * (mem_fclk_21285 / 256);
172
                watchdog_ping();
173
                /* Fall */
174
        case WDIOC_GETTIMEOUT:
175
                ret = put_user(soft_margin, (int *)arg);
176
                break;
177
        }
178
        return ret;
179
}
180
 
181
static const struct file_operations watchdog_fops = {
182
        .owner          = THIS_MODULE,
183
        .llseek         = no_llseek,
184
        .write          = watchdog_write,
185
        .ioctl          = watchdog_ioctl,
186
        .open           = watchdog_open,
187
        .release        = watchdog_release,
188
};
189
 
190
static struct miscdevice watchdog_miscdev = {
191
        .minor          = WATCHDOG_MINOR,
192
        .name           = "watchdog",
193
        .fops           = &watchdog_fops,
194
};
195
 
196
static int __init footbridge_watchdog_init(void)
197
{
198
        int retval;
199
 
200
        if (machine_is_netwinder())
201
                return -ENODEV;
202
 
203
        retval = misc_register(&watchdog_miscdev);
204
        if (retval < 0)
205
                return retval;
206
 
207
        printk("Footbridge Watchdog Timer: 0.01, timer margin: %d sec\n",
208
               soft_margin);
209
 
210
        if (machine_is_cats())
211
                printk("Warning: Watchdog reset may not work on this machine.\n");
212
        return 0;
213
}
214
 
215
static void __exit footbridge_watchdog_exit(void)
216
{
217
        misc_deregister(&watchdog_miscdev);
218
}
219
 
220
MODULE_AUTHOR("Phil Blundell <pb@nexus.co.uk>");
221
MODULE_DESCRIPTION("Footbridge watchdog driver");
222
MODULE_LICENSE("GPL");
223
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
224
 
225
module_param(soft_margin, int, 0);
226
MODULE_PARM_DESC(soft_margin,"Watchdog timeout in seconds");
227
 
228
module_init(footbridge_watchdog_init);
229
module_exit(footbridge_watchdog_exit);

powered by: WebSVN 2.1.0

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