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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * Copyright (C) 2001 MontaVista Software Inc.
3
 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
4
 *
5
 * linux/arch/mips/vr4181/common/irq.c
6
 *      Completely re-written to use the new irq.c
7
 *
8
 * Credits to Bradley D. LaRonde and Michael Klar for writing the original
9
 * irq.c file which was derived from the common irq.c file.
10
 *
11
 * This file is subject to the terms and conditions of the GNU General Public
12
 * License.  See the file "COPYING" in the main directory of this archive
13
 * for more details.
14
 *
15
 */
16
#include <linux/config.h>
17
#include <linux/types.h>
18
#include <linux/init.h>
19
#include <linux/kernel_stat.h>
20
#include <linux/signal.h>
21
#include <linux/sched.h>
22
#include <linux/interrupt.h>
23
#include <linux/slab.h>
24
#include <linux/random.h>
25
 
26
#include <asm/irq.h>
27
#include <asm/mipsregs.h>
28
#include <asm/gdb-stub.h>
29
 
30
#include <asm/vr4181/vr4181.h>
31
 
32
/*
33
 * Strategy:
34
 *
35
 * We essentially have three irq controllers, CPU, system, and gpio.
36
 *
37
 * CPU irq controller is taken care by arch/mips/kernel/irq_cpu.c and
38
 * CONFIG_IRQ_CPU config option.
39
 *
40
 * We here provide sys_irq and gpio_irq controller code.
41
 */
42
 
43
static int sys_irq_base;
44
static int gpio_irq_base;
45
 
46
/* ---------------------- sys irq ------------------------ */
47
static void
48
sys_irq_enable(unsigned int irq)
49
{
50
        irq -= sys_irq_base;
51
        if (irq < 16) {
52
                *VR4181_MSYSINT1REG |= (u16)(1 << irq);
53
        } else {
54
                irq -= 16;
55
                *VR4181_MSYSINT2REG |= (u16)(1 << irq);
56
        }
57
}
58
 
59
static void
60
sys_irq_disable(unsigned int irq)
61
{
62
        irq -= sys_irq_base;
63
        if (irq < 16) {
64
                *VR4181_MSYSINT1REG &= ~((u16)(1 << irq));
65
        } else {
66
                irq -= 16;
67
                *VR4181_MSYSINT2REG &= ~((u16)(1 << irq));
68
        }
69
 
70
}
71
 
72
static unsigned int
73
sys_irq_startup(unsigned int irq)
74
{
75
        sys_irq_enable(irq);
76
        return 0;
77
}
78
 
79
#define sys_irq_shutdown        sys_irq_disable
80
#define sys_irq_ack             sys_irq_disable
81
 
82
static void
83
sys_irq_end(unsigned int irq)
84
{
85
        if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
86
                sys_irq_enable(irq);
87
}
88
 
89
static hw_irq_controller sys_irq_controller = {
90
        "vr4181_sys_irq",
91
        sys_irq_startup,
92
        sys_irq_shutdown,
93
        sys_irq_enable,
94
        sys_irq_disable,
95
        sys_irq_ack,
96
        sys_irq_end,
97
        NULL                    /* no affinity stuff for UP */
98
};
99
 
100
/* ---------------------- gpio irq ------------------------ */
101
/* gpio irq lines use reverse logic */
102
static void
103
gpio_irq_enable(unsigned int irq)
104
{
105
        irq -= gpio_irq_base;
106
        *VR4181_GPINTMSK &= ~((u16)(1 << irq));
107
}
108
 
109
static void
110
gpio_irq_disable(unsigned int irq)
111
{
112
        irq -= gpio_irq_base;
113
        *VR4181_GPINTMSK |= (u16)(1 << irq);
114
}
115
 
116
static unsigned int
117
gpio_irq_startup(unsigned int irq)
118
{
119
        gpio_irq_enable(irq);
120
 
121
        irq -= gpio_irq_base;
122
        *VR4181_GPINTEN |= (u16)(1 << irq );
123
 
124
        return 0;
125
}
126
 
127
static void
128
gpio_irq_shutdown(unsigned int irq)
129
{
130
        gpio_irq_disable(irq);
131
 
132
        irq -= gpio_irq_base;
133
        *VR4181_GPINTEN &= ~((u16)(1 << irq ));
134
}
135
 
136
static void
137
gpio_irq_ack(unsigned int irq)
138
{
139
        u16 irqtype;
140
        u16 irqshift;
141
 
142
        gpio_irq_disable(irq);
143
 
144
        /* we clear interrupt if it is edge triggered */
145
        irq -= gpio_irq_base;
146
        if (irq < 8) {
147
                irqtype = *VR4181_GPINTTYPL;
148
                irqshift = 2 << (irq*2);
149
        } else {
150
                irqtype = *VR4181_GPINTTYPH;
151
                irqshift = 2 << ((irq-8)*2);
152
        }
153
        if ( ! (irqtype & irqshift) ) {
154
                *VR4181_GPINTSTAT = (u16) (1 << irq);
155
        }
156
}
157
 
158
static void
159
gpio_irq_end(unsigned int irq)
160
{
161
        if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
162
                gpio_irq_enable(irq);
163
}
164
 
165
static hw_irq_controller gpio_irq_controller = {
166
        "vr4181_gpio_irq",
167
        gpio_irq_startup,
168
        gpio_irq_shutdown,
169
        gpio_irq_enable,
170
        gpio_irq_disable,
171
        gpio_irq_ack,
172
        gpio_irq_end,
173
        NULL                    /* no affinity stuff for UP */
174
};
175
 
176
/* ---------------------  IRQ init stuff ---------------------- */
177
 
178
extern asmlinkage void vr4181_handle_irq(void);
179
extern void breakpoint(void);
180
extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
181
extern void mips_cpu_irq_init(u32 irq_base);
182
 
183
static struct irqaction cascade =
184
        { no_action, SA_INTERRUPT, 0, "cascade", NULL, NULL };
185
static struct irqaction reserved =
186
        { no_action, SA_INTERRUPT, 0, "cascade", NULL, NULL };
187
 
188
void __init init_IRQ(void)
189
{
190
        int i;
191
        extern irq_desc_t irq_desc[];
192
 
193
        set_except_vector(0, vr4181_handle_irq);
194
 
195
        /* init CPU irqs */
196
        mips_cpu_irq_init(VR4181_CPU_IRQ_BASE);
197
 
198
        /* init sys irqs */
199
        sys_irq_base = VR4181_SYS_IRQ_BASE;
200
        for (i=sys_irq_base; i < sys_irq_base + VR4181_NUM_SYS_IRQ; i++) {
201
                irq_desc[i].status = IRQ_DISABLED;
202
                irq_desc[i].action = NULL;
203
                irq_desc[i].depth = 1;
204
                irq_desc[i].handler = &sys_irq_controller;
205
        }
206
 
207
        /* init gpio irqs */
208
        gpio_irq_base = VR4181_GPIO_IRQ_BASE;
209
        for (i=gpio_irq_base; i < gpio_irq_base + VR4181_NUM_GPIO_IRQ; i++) {
210
                irq_desc[i].status = IRQ_DISABLED;
211
                irq_desc[i].action = NULL;
212
                irq_desc[i].depth = 1;
213
                irq_desc[i].handler = &gpio_irq_controller;
214
        }
215
 
216
        /* Default all ICU IRQs to off ... */
217
        *VR4181_MSYSINT1REG = 0;
218
        *VR4181_MSYSINT2REG = 0;
219
 
220
        /* We initialize the level 2 ICU registers to all bits disabled. */
221
        *VR4181_MPIUINTREG = 0;
222
        *VR4181_MAIUINTREG = 0;
223
        *VR4181_MKIUINTREG = 0;
224
 
225
        /* disable all GPIO intrs */
226
        *VR4181_GPINTMSK = 0xffff;
227
 
228
        /* vector handler.  What these do is register the IRQ as non-sharable */
229
        setup_irq(VR4181_IRQ_INT0, &cascade);
230
        setup_irq(VR4181_IRQ_GIU, &cascade);
231
 
232
        /*
233
         * RTC interrupts are interesting.  They have two destinations.
234
         * One is at sys irq controller, and the other is at CPU IP3 and IP4.
235
         * RTC timer is used as system timer.
236
         * We enable them here, but timer routine will register later
237
         * with CPU IP3/IP4.
238
         */
239
        setup_irq(VR4181_IRQ_RTCL1, &reserved);
240
        setup_irq(VR4181_IRQ_RTCL2, &reserved);
241
 
242
#ifdef CONFIG_KGDB
243
        printk("Setting debug traps - please connect the remote debugger.\n");
244
 
245
        set_debug_traps();
246
 
247
        // you may move this line to whereever you want
248
        breakpoint();
249
#endif
250
}

powered by: WebSVN 2.1.0

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