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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [char/] [mcfwatchdog.c] - Blame information for rev 1626

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

Line No. Rev Author Line
1 1626 jcastillo
/***************************************************************************/
2
 
3
/*
4
 *      linux/drivers/char/mcfwatchdog.c
5
 *
6
 *      Copyright (C) 1999-2000, Greg Ungerer (gerg@moreton.com.au)
7
 */
8
 
9
/***************************************************************************/
10
 
11
#include <linux/config.h>
12
#include <linux/kernel.h>
13
#include <linux/sched.h>
14
#include <linux/param.h>
15
#include <asm/irq.h>
16
#include <asm/traps.h>
17
#include <asm/machdep.h>
18
#include <asm/coldfire.h>
19
#include <asm/mcftimer.h>
20
#include <asm/mcfsim.h>
21
#include <asm/irq.h>
22
#include <asm/delay.h>
23
 
24
/***************************************************************************/
25
 
26
/*
27
 *      Define the watchdog vector.
28
 */
29
#define IRQ_WATCHDOG    250
30
 
31
/***************************************************************************/
32
 
33
void    watchdog_alive(unsigned long arg);
34
void    watchdog_init(void);
35
void    watchdog_timeout(int irq, void *dummy, struct pt_regs *fp);
36
 
37
extern void     dump(struct pt_regs *fp);
38
 
39
 
40
/*
41
 *      Data for registering the watchdog alive routine with ticker.
42
 */
43
struct timer_list       watchdog_timerlist = {
44
        NULL, NULL, 0, 0, watchdog_alive
45
};
46
 
47
 
48
#if CONFIG_OLDMASK
49
/*
50
 *      The old mask 5307 has a broken watchdog timer. It will interrupt
51
 *      you regardless of writing to its "alive" register. It can still
52
 *      be useful but you have to play some tricks with it. This code
53
 *      supports a clock ticker timeout. If the right number of clock
54
 *      ticks are not counted then it is assumed that the watchdog saved
55
 *      us from a bad bus cycle.
56
 *
57
 *      Hardwire the reference counts for different boards. Ugly, but
58
 *      there is really no other way to hold it all together...
59
 */
60
#ifdef CONFIG_eLIA
61
#define SWTREF_COUNT    37
62
#else
63
#define SWTREF_COUNT    30
64
#endif
65
 
66
int     swt_doit = 0;                    /* Start delay before tripping */
67
int     swt_lastjiffies = 0;             /* Tick count at last watchdog */
68
int     swt_reference = SWTREF_COUNT;   /* Refereence tick count */
69
#endif
70
 
71
/***************************************************************************/
72
 
73
/*
74
 *      Software Watchdog Timer enable. Seems to be the same across all
75
 *      ColdFire CPu members.
76
 */
77
void watchdog_enable(void)
78
{
79
        volatile unsigned char  *mbar;
80
 
81
        mbar = (volatile unsigned char *) MCF_MBAR;
82
        *(mbar + MCFSIM_SWSR) = 0x55;
83
        *(mbar + MCFSIM_SWSR) = 0xaa;
84
        *(mbar + MCFSIM_SYPCR) = 0xbe;
85
}
86
 
87
/***************************************************************************/
88
 
89
void watchdog_disable(void)
90
{
91
        volatile unsigned char  *mbar;
92
 
93
        mbar = (volatile unsigned char *) MCF_MBAR;
94
        *(mbar + MCFSIM_SWSR) = 0x55;
95
        *(mbar + MCFSIM_SWSR) = 0xaa;
96
        *(mbar + MCFSIM_SYPCR) = 0x00 /*0x3e*/;
97
}
98
 
99
/***************************************************************************/
100
 
101
#define TIMEDELAY       45
102
 
103
/*
104
 *      Process a watchdog timeout interrupt. For a normal clean watchdog
105
 *      we just do a process dump. For old broken 5307 we need to verify
106
 *      if this was a real watchdog event or not...
107
 */
108
void watchdog_timeout(int irq, void *dummy, struct pt_regs *fp)
109
{
110
#ifdef CONFIG_OLDMASK
111
        /*
112
         *      Debuging code for software watchdog. If we get in here
113
         *      and timer interrupt counts don't match we know that a
114
         *      bad external bus cycle must have locked the CPU.
115
         */
116
        if ((swt_doit++ > TIMEDELAY) &&
117
            ((swt_lastjiffies + swt_reference) > jiffies)) {
118
                static int      inside = 0;
119
 
120
                if (inside) {
121
                        cli();
122
                        watchdog_disable();
123
                        mcf_setimr(mcf_getimr() | MCFSIM_IMR_SWD);
124
                        printk("%s(%d): Double WATCHDOG PANIC!!\n",
125
                                __FILE__, __LINE__);
126
                        for (;;)
127
                                ;
128
                }
129
 
130
                inside++;
131
                swt_doit = TIMEDELAY - 8;       /* 8 seconds grace */
132
                printk("WATCHDOG: expired last=%d(%d) jiffies=%d!\n",
133
                        swt_lastjiffies, swt_reference, jiffies);
134
                dump(fp);
135
                force_sig(SIGSEGV, current);
136
                inside = 0;
137
        }
138
        swt_lastjiffies = jiffies;
139
#else
140
        printk("WATCHDOG: expired!\n");
141
        dump(fp);
142
#endif /* CONFIG_OLDMASK */
143
}
144
 
145
/***************************************************************************/
146
 
147
void watchdog_init(void)
148
{
149
        volatile unsigned char  *mbar;
150
 
151
        printk("WATCHDOG: initializing at vector=%d\n", IRQ_WATCHDOG);
152
        request_irq(IRQ_WATCHDOG, watchdog_timeout, SA_INTERRUPT,
153
                "Watchdog Timer", NULL);
154
 
155
        watchdog_timerlist.expires = jiffies + 1;
156
        add_timer(&watchdog_timerlist);
157
 
158
        mbar = (volatile unsigned char *) MCF_MBAR;
159
        *(mbar + MCFSIM_SWDICR) = MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3;
160
        *(mbar + MCFSIM_SWIVR) = IRQ_WATCHDOG;
161
        mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_SWD);
162
        watchdog_enable();
163
}
164
 
165
/***************************************************************************/
166
 
167
void watchdog_alive(unsigned long arg)
168
{
169
        volatile unsigned char  *mbar;
170
 
171
        mbar = (volatile unsigned char *) MCF_MBAR;
172
        *(mbar + MCFSIM_SWSR) = 0x55;
173
        *(mbar + MCFSIM_SWSR) = 0xaa;
174
 
175
        /* Re-arm the watchdog alive poll */
176
        watchdog_timerlist.expires = jiffies + 1;
177
        add_timer(&watchdog_timerlist);
178
}
179
 
180
/***************************************************************************/

powered by: WebSVN 2.1.0

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