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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [mips/] [philips/] [nino/] [irq.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *  arch/mips/philips/nino/irq.c
3
 *
4
 *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
5
 *
6
 * This program is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License version 2 as
8
 * published by the Free Software Foundation.
9
 *
10
 *  Interrupt service routines for Philips Nino
11
 */
12
#include <linux/config.h>
13
#include <linux/init.h>
14
#include <linux/irq.h>
15
#include <linux/sched.h>
16
#include <linux/interrupt.h>
17
#include <asm/io.h>
18
#include <asm/mipsregs.h>
19
#include <asm/tx3912.h>
20
 
21
#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
22
 
23
static void enable_irq6(unsigned int irq)
24
{
25
        if(irq == 0) {
26
                outl(inl(TX3912_INT6_ENABLE) |
27
                        TX3912_INT6_ENABLE_PRIORITYMASK_PERINT,
28
                        TX3912_INT6_ENABLE);
29
                outl(inl(TX3912_INT5_ENABLE) | TX3912_INT5_PERINT,
30
                        TX3912_INT5_ENABLE);
31
        }
32
        if(irq == 3) {
33
                outl(inl(TX3912_INT6_ENABLE) |
34
                        TX3912_INT6_ENABLE_PRIORITYMASK_UARTARXINT,
35
                        TX3912_INT6_ENABLE);
36
                outl(inl(TX3912_INT2_ENABLE) | TX3912_INT2_UARTA_RX_BITS,
37
                        TX3912_INT2_ENABLE);
38
        }
39
}
40
 
41
static unsigned int startup_irq6(unsigned int irq)
42
{
43
        enable_irq6(irq);
44
 
45
        return 0;                /* Never anything pending  */
46
}
47
 
48
static void disable_irq6(unsigned int irq)
49
{
50
        if(irq == 0) {
51
                outl(inl(TX3912_INT6_ENABLE) &
52
                        ~TX3912_INT6_ENABLE_PRIORITYMASK_PERINT,
53
                        TX3912_INT6_ENABLE);
54
                outl(inl(TX3912_INT5_ENABLE) & ~TX3912_INT5_PERINT,
55
                        TX3912_INT5_ENABLE);
56
                outl(inl(TX3912_INT5_CLEAR) | TX3912_INT5_PERINT,
57
                        TX3912_INT5_CLEAR);
58
        }
59
        if(irq == 3) {
60
                outl(inl(TX3912_INT6_ENABLE) &
61
                        ~TX3912_INT6_ENABLE_PRIORITYMASK_UARTARXINT,
62
                        TX3912_INT6_ENABLE);
63
                outl(inl(TX3912_INT2_ENABLE) & ~TX3912_INT2_UARTA_RX_BITS,
64
                        TX3912_INT2_ENABLE);
65
        }
66
}
67
 
68
#define shutdown_irq6           disable_irq6
69
#define mask_and_ack_irq6       disable_irq6
70
 
71
static void end_irq6(unsigned int irq)
72
{
73
        if(!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
74
                enable_irq6(irq);
75
}
76
 
77
static struct hw_interrupt_type irq6_type = {
78
        "MIPS",
79
        startup_irq6,
80
        shutdown_irq6,
81
        enable_irq6,
82
        disable_irq6,
83
        mask_and_ack_irq6,
84
        end_irq6,
85
        NULL
86
};
87
 
88
void irq6_dispatch(struct pt_regs *regs)
89
{
90
        int irq = -1;
91
 
92
        if((inl(TX3912_INT6_STATUS) & TX3912_INT6_STATUS_INTVEC_UARTARXINT) ==
93
                TX3912_INT6_STATUS_INTVEC_UARTARXINT) {
94
                irq = 3;
95
                goto done;
96
        }
97
        if ((inl(TX3912_INT6_STATUS) & TX3912_INT6_STATUS_INTVEC_PERINT) ==
98
                TX3912_INT6_STATUS_INTVEC_PERINT) {
99
                irq = 0;
100
                goto done;
101
        }
102
 
103
        /* if irq == -1, then interrupt was cleared or is invalid */
104
        if (irq == -1) {
105
                panic("Unhandled High Priority PR31700 Interrupt = 0x%08x",
106
                        inl(TX3912_INT6_STATUS));
107
        }
108
 
109
done:
110
        do_IRQ(irq, regs);
111
}
112
 
113
static void enable_irq4(unsigned int irq)
114
{
115
        set_c0_status(STATUSF_IP4);
116
        if (irq == 2) {
117
                outl(inl(TX3912_INT2_CLEAR) | TX3912_INT2_UARTA_TX_BITS,
118
                        TX3912_INT2_CLEAR);
119
                outl(inl(TX3912_INT2_ENABLE) | TX3912_INT2_UARTA_TX_BITS,
120
                        TX3912_INT2_ENABLE);
121
        }
122
}
123
 
124
static unsigned int startup_irq4(unsigned int irq)
125
{
126
        enable_irq4(irq);
127
 
128
        return 0;                /* Never anything pending  */
129
}
130
 
131
static void disable_irq4(unsigned int irq)
132
{
133
        clear_c0_status(STATUSF_IP4);
134
}
135
 
136
#define shutdown_irq4           disable_irq4
137
#define mask_and_ack_irq4       disable_irq4
138
 
139
static void end_irq4(unsigned int irq)
140
{
141
        if(!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
142
                enable_irq4(irq);
143
}
144
 
145
static struct hw_interrupt_type irq4_type = {
146
        "MIPS",
147
        startup_irq4,
148
        shutdown_irq4,
149
        enable_irq4,
150
        disable_irq4,
151
        mask_and_ack_irq4,
152
        end_irq4,
153
        NULL
154
};
155
 
156
void irq4_dispatch(struct pt_regs *regs)
157
{
158
        int irq = -1;
159
 
160
        if(inl(TX3912_INT2_STATUS) & TX3912_INT2_UARTA_TX_BITS) {
161
                irq = 2;
162
                goto done;
163
        }
164
 
165
        /* if irq == -1, then interrupt was cleared or is invalid */
166
        if (irq == -1) {
167
                printk("PR31700 Interrupt Status Register 1 = 0x%08x\n",
168
                        inl(TX3912_INT1_STATUS));
169
                printk("PR31700 Interrupt Status Register 2 = 0x%08x\n",
170
                        inl(TX3912_INT2_STATUS));
171
                printk("PR31700 Interrupt Status Register 3 = 0x%08x\n",
172
                        inl(TX3912_INT3_STATUS));
173
                printk("PR31700 Interrupt Status Register 4 = 0x%08x\n",
174
                        inl(TX3912_INT4_STATUS));
175
                printk("PR31700 Interrupt Status Register 5 = 0x%08x\n",
176
                        inl(TX3912_INT5_STATUS));
177
                panic("Unhandled Low Priority PR31700 Interrupt");
178
        }
179
 
180
done:
181
        do_IRQ(irq, regs);
182
        return;
183
}
184
 
185
void irq_bad(struct pt_regs *regs)
186
{
187
        /* This should never happen */
188
        printk(" CAUSE register = 0x%08lx\n", regs->cp0_cause);
189
        printk("STATUS register = 0x%08lx\n", regs->cp0_status);
190
        printk("   EPC register = 0x%08lx\n", regs->cp0_epc);
191
        panic("Stray interrupt, spinning...");
192
}
193
 
194
void __init nino_irq_setup(void)
195
{
196
        extern asmlinkage void ninoIRQ(void);
197
 
198
        unsigned int i;
199
 
200
        /* Disable all hardware interrupts */
201
        change_c0_status(ST0_IM, 0x00);
202
 
203
        /* Clear interrupts */
204
        outl(0xffffffff, TX3912_INT1_CLEAR);
205
        outl(0xffffffff, TX3912_INT2_CLEAR);
206
        outl(0xffffffff, TX3912_INT3_CLEAR);
207
        outl(0xffffffff, TX3912_INT4_CLEAR);
208
        outl(0xffffffff, TX3912_INT5_CLEAR);
209
 
210
        /*
211
         * Disable all PR31700 interrupts. We let the various
212
         * device drivers in the system register themselves
213
         * and set the proper hardware bits.
214
         */
215
        outl(0x00000000, TX3912_INT1_ENABLE);
216
        outl(0x00000000, TX3912_INT2_ENABLE);
217
        outl(0x00000000, TX3912_INT3_ENABLE);
218
        outl(0x00000000, TX3912_INT4_ENABLE);
219
        outl(0x00000000, TX3912_INT5_ENABLE);
220
 
221
        /* Initialize IRQ vector table */
222
        init_generic_irq();
223
 
224
        /* Initialize IRQ action handlers */
225
        for (i = 0; i < 16; i++) {
226
                hw_irq_controller *handler = NULL;
227
                if (i == 0 || i == 3)
228
                        handler         = &irq6_type;
229
                else
230
                        handler         = &irq4_type;
231
 
232
                irq_desc[i].status      = IRQ_DISABLED;
233
                irq_desc[i].action      = 0;
234
                irq_desc[i].depth       = 1;
235
                irq_desc[i].handler     = handler;
236
        }
237
 
238
        /* Set up the external interrupt exception vector */
239
        set_except_vector(0, ninoIRQ);
240
 
241
        /* Enable high priority interrupts */
242
        outl(TX3912_INT6_ENABLE_GLOBALEN | TX3912_INT6_ENABLE_HIGH_PRIORITY,
243
                TX3912_INT6_ENABLE);
244
 
245
        /* Enable all interrupts */
246
        change_c0_status(ST0_IM, ALLINTS);
247
}
248
 
249
void (*irq_setup)(void);
250
 
251
void __init init_IRQ(void)
252
{
253
#ifdef CONFIG_KGDB
254
        extern void breakpoint(void);
255
        extern void set_debug_traps(void);
256
 
257
        printk("Wait for gdb client connection ...\n");
258
        set_debug_traps();
259
        breakpoint();
260
#endif
261
 
262
        /* Invoke board-specific irq setup */
263
        irq_setup();
264
}

powered by: WebSVN 2.1.0

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