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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [or32/] [kernel/] [irq.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *  linux/arch/or32/kernel/irq.c
3
 *
4
 *  or32 version
5
 *    author(s): Matjaz Breskvar (phoenix@opencores.org)
6
 *
7
 *  derived from cris, i386, m68k, ppc, sh ports.
8
 *
9
 *  changes:
10
 *  18. 11. 2003: Matjaz Breskvar (phoenix@opencores.org)
11
 *    initial port to or32 architecture
12
 *
13
 */
14
 
15
#include <linux/config.h>
16
#include <linux/ptrace.h>
17
#include <linux/errno.h>
18
#include <linux/kernel_stat.h>
19
#include <linux/signal.h>
20
#include <linux/sched.h>
21
#include <linux/ioport.h>
22
#include <linux/interrupt.h>
23
#include <linux/timex.h>
24
#include <linux/slab.h>
25
#include <linux/random.h>
26
#include <linux/init.h>
27
 
28
#include <asm/system.h>
29
#include <asm/io.h>
30
#include <asm/irq.h>
31
#include <asm/bitops.h>
32
#include <asm/page.h>
33
#include <asm/machdep.h>
34
#include <asm/or32-hf.h>
35
 
36
/* table for system interrupt handlers */
37
static irq_handler_t irq_list[NR_IRQS];
38
 
39
static const char *default_names[NR_IRQS] = {
40
        "int0", "int1", "int2", "int3", "int4", "int5", "int6", "int7"
41
        "int8", "int9", "int10", "int11", "int12", "int13", "int14", "int15"
42
        "int16", "int17", "int18", "int19", "int20", "int21", "int22", "int23"
43
        "int24", "int25", "int26", "int27", "int28", "int29", "int30", "int31"
44
};
45
 
46
int pic_enable_irq(unsigned int irq)
47
{
48
        /* Enable in the IMR */
49
        mtspr(SPR_PICMR, mfspr(SPR_PICMR) | (0x00000001L << irq));
50
 
51
        return 0;
52
}
53
 
54
int pic_disable_irq(unsigned int irq)
55
{
56
        /* Disable in the IMR */
57
        mtspr(SPR_PICMR, mfspr(SPR_PICMR) & ~(0x00000001L << irq));
58
 
59
        return 0;
60
}
61
 
62
int pic_init(void)
63
{
64
        /* turn off all interrupts */
65
        mtspr(SPR_PICMR, 0);
66
        return 0;
67
}
68
 
69
int pic_do_irq(struct pt_regs *fp)
70
{
71
        int irq;
72
        int mask;
73
 
74
        unsigned long pend = mfspr(SPR_PICSR) & 0xfffffffc;
75
 
76
        if (pend & 0x0000ffff) {
77
                if (pend & 0x000000ff) {
78
                        if (pend & 0x0000000f) {
79
                                mask = 0x00000001;
80
                                irq = 0;
81
                        } else {
82
                                mask = 0x00000010;
83
                                irq = 4;
84
                        }
85
                } else {
86
                        if (pend & 0x00000f00) {
87
                                mask = 0x00000100;
88
                                irq = 8;
89
                        } else {
90
                                mask = 0x00001000;
91
                                irq = 12;
92
                        }
93
                }
94
        } else if(pend & 0xffff0000) {
95
                if (pend & 0x00ff0000) {
96
                        if (pend & 0x000f0000) {
97
                                mask = 0x00010000;
98
                                irq = 16;
99
                        } else {
100
                                mask = 0x00100000;
101
                                irq = 20;
102
                        }
103
                } else {
104
                        if (pend & 0x0f000000) {
105
                                mask = 0x01000000;
106
                                irq = 24;
107
                        } else {
108
                                mask = 0x10000000;
109
                                irq = 28;
110
                        }
111
                }
112
        } else {
113
                return -1;
114
        }
115
 
116
        while (! (mask & pend)) {
117
                mask <<=1;
118
                irq++;
119
        }
120
 
121
//      mtspr(SPR_PICSR, mfspr(SPR_PICSR) & ~mask);
122
        return irq;
123
}
124
 
125
void init_IRQ(void)
126
{
127
        int i;
128
 
129
        for (i = 0; i < NR_IRQS; i++) {
130
                irq_list[i].handler = NULL;
131
                irq_list[i].flags   = IRQ_FLG_STD;
132
                irq_list[i].dev_id  = NULL;
133
                irq_list[i].devname = default_names[i];
134
        }
135
 
136
        pic_init();
137
        mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_IEE);
138
}
139
 
140
asmlinkage void do_IRQ(struct pt_regs *regs)
141
{
142
        int irq;
143
        int cpu;
144
        unsigned long flags;
145
 
146
//      printk("x");
147
        save_and_cli(flags);
148
 
149
        check_stack(NULL, __FILE__, __FUNCTION__, __LINE__);
150
        cpu = smp_processor_id();
151
 
152
        while((irq = pic_do_irq(regs)) >= 0) {
153
//              printk("*");
154
//              mtspr(SPR_PICMR, mfspr(SPR_PICMR) & ~(1UL << irq));
155
 
156
                if (irq_list[irq].handler)
157
                        irq_list[irq].handler(irq, irq_list[irq].dev_id, regs);
158
                else
159
                        panic("No interrupt handler for autovector %d\n", irq);
160
//              mtspr(SPR_PICMR, mfspr(SPR_PICMR) | (1UL << irq));
161
                mtspr(SPR_PICSR, mfspr(SPR_PICSR) & ~(1UL << irq));
162
 
163
        }
164
        restore_flags(flags);
165
 
166
        if (softirq_pending(cpu))
167
                do_softirq();
168
 
169
}
170
 
171
int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
172
                unsigned long flags, const char *devname, void *dev_id)
173
{
174
        if (irq >= NR_IRQS) {
175
                printk("%s: Incorrect IRQ %d from %s\n", __FUNCTION__, irq, devname);
176
                return -ENXIO;
177
        }
178
 
179
        if (!(irq_list[irq].flags & IRQ_FLG_STD)) {
180
                if (irq_list[irq].flags & IRQ_FLG_LOCK) {
181
                        printk("%s: IRQ %d from %s is not replaceable\n",
182
                               __FUNCTION__, irq, irq_list[irq].devname);
183
                        return -EBUSY;
184
                }
185
                if (flags & IRQ_FLG_REPLACE) {
186
                        printk("%s: %s can't replace IRQ %d from %s\n",
187
                               __FUNCTION__, devname, irq, irq_list[irq].devname);
188
                        return -EBUSY;
189
                }
190
        }
191
        irq_list[irq].handler = handler;
192
        irq_list[irq].flags   = flags;
193
        irq_list[irq].dev_id  = dev_id;
194
        irq_list[irq].devname = devname;
195
 
196
        pic_enable_irq(irq);
197
 
198
        return 0;
199
}
200
 
201
void free_irq(unsigned int irq, void *dev_id)
202
{
203
        if (irq >= NR_IRQS) {
204
                printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
205
                return;
206
        }
207
 
208
        pic_disable_irq(irq);
209
 
210
        irq_list[irq].handler = NULL;
211
        irq_list[irq].flags   = IRQ_FLG_STD;
212
        irq_list[irq].dev_id  = NULL;
213
        irq_list[irq].devname = default_names[irq];
214
}
215
 
216
unsigned long probe_irq_on (void)
217
{
218
        return 0;
219
}
220
 
221
int probe_irq_off (unsigned long irqs)
222
{
223
        return 0;
224
}
225
 
226
void enable_irq(unsigned int irq)
227
{
228
        if (irq >= NR_IRQS) {
229
                printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
230
                return;
231
        }
232
        pic_enable_irq(irq);
233
}
234
 
235
void disable_irq(unsigned int irq)
236
{
237
        if (irq >= NR_IRQS) {
238
                printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
239
                return;
240
        }
241
        pic_disable_irq(irq);
242
}
243
 
244
int get_irq_list(char *buf)
245
{
246
        int i, len = 0;
247
 
248
        /* autovector interrupts */
249
        for (i = 0; i < NR_IRQS; i++) {
250
                if (irq_list[i].handler) {
251
                        if (irq_list[i].flags & IRQ_FLG_LOCK)
252
                                len += sprintf(buf+len, "L ");
253
                        else
254
                                len += sprintf(buf+len, "  ");
255
                        if (irq_list[i].flags & IRQ_FLG_PRI_HI)
256
                                len += sprintf(buf+len, "H ");
257
                        else
258
                                len += sprintf(buf+len, "L ");
259
                        len += sprintf(buf+len, "%s\n", irq_list[i].devname);
260
                }
261
        }
262
 
263
        return len;
264
}
265
 
266
#if 0
267
void dump(struct pt_regs *fp)
268
{
269
        unsigned long   *sp;
270
        unsigned char   *tp;
271
        int             i;
272
 
273
        printk("\nCURRENT PROCESS:\n\n");
274
        printk("COMM=%s PID=%d\n", current->comm, current->pid);
275
        if (current->mm) {
276
                printk("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n",
277
                        (int) current->mm->start_code,
278
                        (int) current->mm->end_code,
279
                        (int) current->mm->start_data,
280
                        (int) current->mm->end_data,
281
                        (int) current->mm->end_data,
282
                        (int) current->mm->brk);
283
                printk("USER-STACK=%08x  KERNEL-STACK=%08x\n\n",
284
                        (int) current->mm->start_stack,
285
                        (int) current->kernel_stack_page);
286
        }
287
        printk("PC: %08lx  Status: %08lx\n",
288
               fp->pc, fp->sr);
289
        printk("R0 : %08lx  %08lx  %08lx  %08lx  %08lx  %08lx  %08lx  %08lx\n",
290
                0L,             fp->sp,      fp->gprs[0], fp->gprs[1],
291
                fp->gprs[2], fp->gprs[3], fp->gprs[4], fp->gprs[5]);
292
        printk("R8 : %08lx  %08lx  %08lx  %08lx  %08lx  %08lx  %08lx  %08lx\n",
293
                fp->gprs[6], fp->gprs[7], fp->gprs[8], fp->gprs[9],
294
                fp->gprs[10], fp->gprs[11], fp->gprs[12], fp->gprs[13]);
295
        printk("R16: %08lx  %08lx  %08lx  %08lx  %08lx  %08lx  %08lx  %08lx\n",
296
                fp->gprs[14], fp->gprs[15], fp->gprs[16], fp->gprs[17],
297
                fp->gprs[18], fp->gprs[19], fp->gprs[20], fp->gprs[21]);
298
        printk("R24: %08lx  %08lx  %08lx  %08lx  %08lx  %08lx  %08lx  %08lx\n",
299
                fp->gprs[22], fp->gprs[23], fp->gprs[24], fp->gprs[25],
300
                fp->gprs[26], fp->gprs[27], fp->gprs[28], fp->gprs[29]);
301
 
302
        printk("\nUSP: %08lx   TRAPFRAME: %08x\n",
303
                fp->sp, (unsigned int) fp);
304
 
305
        printk("\nCODE:");
306
        tp = ((unsigned char *) fp->pc) - 0x20;
307
        for (sp = (unsigned long *) tp, i = 0; (i < 0x40);  i += 4) {
308
                if ((i % 0x10) == 0)
309
                        printk("\n%08x: ", (int) (tp + i));
310
                printk("%08x ", (int) *sp++);
311
        }
312
        printk("\n");
313
 
314
        printk("\nKERNEL STACK:");
315
        tp = ((unsigned char *) fp) - 0x40;
316
        for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) {
317
                if ((i % 0x10) == 0)
318
                        printk("\n%08x: ", (int) (tp + i));
319
                printk("%08x ", (int) *sp++);
320
        }
321
        printk("\n");
322
        if (STACK_MAGIC != *(unsigned long *)current->kernel_stack_page)
323
                printk("(Possibly corrupted stack page??)\n");
324
        printk("\n");
325
 
326
        printk("\nUSER STACK:");
327
        tp = (unsigned char *) (fp->sp - 0x10);
328
        for (sp = (unsigned long *) tp, i = 0; (i < 0x80); i += 4) {
329
                if ((i % 0x10) == 0)
330
                        printk("\n%08x: ", (int) (tp + i));
331
                printk("%08x ", (int) *sp++);
332
        }
333
        printk("\n\n");
334
}
335
#endif /* 0 */
336
 
337
void init_irq_proc(void)
338
{
339
        phx_warn("TODO");
340
}

powered by: WebSVN 2.1.0

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