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

Subversion Repositories or1k

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

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
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/types.h>
20
#include <linux/kernel.h>
21
#include <linux/fs.h>
22
#include <linux/mm.h>
23
#include <linux/miscdevice.h>
24
#include <linux/watchdog.h>
25
#include <linux/reboot.h>
26
#include <linux/init.h>
27
#include <linux/interrupt.h>
28
#include <linux/smp_lock.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
#define TIMER_MARGIN    60              /* (secs) Default is 1 minute */
42
 
43
#define FCLK    (50*1000*1000)          /* 50MHz */
44
 
45
static int soft_margin = TIMER_MARGIN;  /* in seconds */
46
static int timer_alive;
47
 
48
#ifdef ONLY_TESTING
49
/*
50
 *      If the timer expires..
51
 */
52
 
53
static void watchdog_fire(int irq, void *dev_id, struct pt_regs *regs)
54
{
55
        printk(KERN_CRIT "Watchdog: Would Reboot.\n");
56
        *CSR_TIMER4_CNTL = 0;
57
        *CSR_TIMER4_CLR = 0;
58
}
59
#endif
60
 
61
static void watchdog_ping(void)
62
{
63
        /*
64
         *      Refresh the timer.
65
         */
66
        *CSR_TIMER4_LOAD = soft_margin * (FCLK / 256);
67
}
68
 
69
/*
70
 *      Allow only one person to hold it open
71
 */
72
 
73
static int watchdog_open(struct inode *inode, struct file *file)
74
{
75
        if(timer_alive)
76
                return -EBUSY;
77
        /*
78
         *      Ahead watchdog factor ten, Mr Sulu
79
         */
80
        *CSR_TIMER4_CLR = 0;
81
        watchdog_ping();
82
        *CSR_TIMER4_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD
83
                | TIMER_CNTL_DIV256;
84
#ifdef ONLY_TESTING
85
        request_irq(IRQ_TIMER4, watchdog_fire, 0, "watchdog", NULL);
86
#else
87
        *CSR_SA110_CNTL |= 1 << 13;
88
        MOD_INC_USE_COUNT;
89
#endif
90
        timer_alive = 1;
91
        return 0;
92
}
93
 
94
static int watchdog_release(struct inode *inode, struct file *file)
95
{
96
#ifdef ONLY_TESTING
97
        lock_kernel();
98
        free_irq(IRQ_TIMER4, NULL);
99
        timer_alive = 0;
100
        unlock_kernel();
101
#else
102
        /*
103
         *      It's irreversible!
104
         */
105
#endif
106
        return 0;
107
}
108
 
109
static ssize_t watchdog_write(struct file *file, const char *data, size_t len, loff_t *ppos)
110
{
111
        /*  Can't seek (pwrite) on this device  */
112
        if (ppos != &file->f_pos)
113
                return -ESPIPE;
114
 
115
        /*
116
         *      Refresh the timer.
117
         */
118
        if(len)
119
        {
120
                watchdog_ping();
121
                return 1;
122
        }
123
        return 0;
124
}
125
 
126
static int watchdog_ioctl(struct inode *inode, struct file *file,
127
        unsigned int cmd, unsigned long arg)
128
{
129
        int i, new_margin;
130
        static struct watchdog_info ident=
131
        {
132
                WDIOF_SETTIMEOUT,
133
                0,
134
                "Footbridge Watchdog"
135
        };
136
        switch(cmd)
137
        {
138
                default:
139
                        return -ENOTTY;
140
                case WDIOC_GETSUPPORT:
141
                        if(copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)))
142
                                return -EFAULT;
143
                        return 0;
144
                case WDIOC_GETSTATUS:
145
                case WDIOC_GETBOOTSTATUS:
146
                        return put_user(0,(int *)arg);
147
                case WDIOC_KEEPALIVE:
148
                        watchdog_ping();
149
                        return 0;
150
                case WDIOC_SETTIMEOUT:
151
                        if (get_user(new_margin, (int *)arg))
152
                                return -EFAULT;
153
                        /* Arbitrary, can't find the card's limits */
154
                        if ((new_marg < 0) || (new_margin > 60))
155
                                return -EINVAL;
156
                        soft_margin = new_margin;
157
                        watchdog_ping();
158
                        /* Fall */
159
                case WDIOC_GETTIMEOUT:
160
                        return put_user(soft_margin, (int *)arg);
161
        }
162
}
163
 
164
static struct file_operations watchdog_fops=
165
{
166
        owner:          THIS_MODULE,
167
        write:          watchdog_write,
168
        ioctl:          watchdog_ioctl,
169
        open:           watchdog_open,
170
        release:        watchdog_release,
171
};
172
 
173
static struct miscdevice watchdog_miscdev=
174
{
175
        WATCHDOG_MINOR,
176
        "watchdog",
177
        &watchdog_fops
178
};
179
 
180
static int __init footbridge_watchdog_init(void)
181
{
182
        int retval;
183
 
184
        if (machine_is_netwinder())
185
                return -ENODEV;
186
 
187
        retval = misc_register(&watchdog_miscdev);
188
        if(retval < 0)
189
                return retval;
190
 
191
        printk("Footbridge Watchdog Timer: 0.01, timer margin: %d sec\n",
192
               soft_margin);
193
        if (machine_is_cats())
194
                printk("Warning: Watchdog reset may not work on this machine.\n");
195
        return 0;
196
}
197
 
198
static void __exit footbridge_watchdog_exit(void)
199
{
200
        misc_deregister(&watchdog_miscdev);
201
}
202
 
203
EXPORT_NO_SYMBOLS;
204
 
205
MODULE_AUTHOR("Phil Blundell <pb@nexus.co.uk>");
206
MODULE_DESCRIPTION("21285 watchdog driver");
207
MODULE_LICENSE("GPL");
208
 
209
MODULE_PARM(soft_margin,"i");
210
MODULE_PARM_DESC(soft_margin,"Watchdog timeout in seconds");
211
 
212
module_init(footbridge_watchdog_init);
213
module_exit(footbridge_watchdog_exit);

powered by: WebSVN 2.1.0

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