aboutsummaryrefslogtreecommitdiffstats
path: root/arch/frv/kernel/irq.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2006-09-26 02:32:04 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-09-26 11:48:53 -0400
commit1bcbba306048ed86b935d57a95d887c23d52c94b (patch)
tree4c6e20b162415c79a177b72b97b6fb4d246a73b0 /arch/frv/kernel/irq.c
parent8d6b5eeea5eb644232cbbbe1c927fdf051e60fa5 (diff)
[PATCH] FRV: Use the generic IRQ stuff
Make the FRV arch use the generic IRQ code rather than having its own routines for doing so. Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/frv/kernel/irq.c')
-rw-r--r--arch/frv/kernel/irq.c750
1 files changed, 113 insertions, 637 deletions
diff --git a/arch/frv/kernel/irq.c b/arch/frv/kernel/irq.c
index 08967010be04..e1ab9f2e43fb 100644
--- a/arch/frv/kernel/irq.c
+++ b/arch/frv/kernel/irq.c
@@ -1,6 +1,6 @@
1/* irq.c: FRV IRQ handling 1/* irq.c: FRV IRQ handling
2 * 2 *
3 * Copyright (C) 2003, 2004 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2003, 2004, 2006 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -9,13 +9,6 @@
9 * 2 of the License, or (at your option) any later version. 9 * 2 of the License, or (at your option) any later version.
10 */ 10 */
11 11
12/*
13 * (mostly architecture independent, will move to kernel/irq.c in 2.5.)
14 *
15 * IRQs are in fact implemented a bit like signal handlers for the kernel.
16 * Naturally it's not a 1:1 relation, but there are similarities.
17 */
18
19#include <linux/ptrace.h> 12#include <linux/ptrace.h>
20#include <linux/errno.h> 13#include <linux/errno.h>
21#include <linux/signal.h> 14#include <linux/signal.h>
@@ -43,19 +36,16 @@
43#include <asm/delay.h> 36#include <asm/delay.h>
44#include <asm/irq.h> 37#include <asm/irq.h>
45#include <asm/irc-regs.h> 38#include <asm/irc-regs.h>
46#include <asm/irq-routing.h>
47#include <asm/gdb-stub.h> 39#include <asm/gdb-stub.h>
48 40
49extern void __init fpga_init(void); 41#define set_IRR(N,A,B,C,D) __set_IRR(N, (A << 28) | (B << 24) | (C << 20) | (D << 16))
50extern void __init route_mb93493_irqs(void);
51
52static void register_irq_proc (unsigned int irq);
53 42
54/* 43extern void __init fpga_init(void);
55 * Special irq handlers. 44#ifdef CONFIG_FUJITSU_MB93493
56 */ 45extern void __init mb93493_init(void);
46#endif
57 47
58irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs) { return IRQ_HANDLED; } 48#define __reg16(ADDR) (*(volatile unsigned short *)(ADDR))
59 49
60atomic_t irq_err_count; 50atomic_t irq_err_count;
61 51
@@ -64,215 +54,99 @@ atomic_t irq_err_count;
64 */ 54 */
65int show_interrupts(struct seq_file *p, void *v) 55int show_interrupts(struct seq_file *p, void *v)
66{ 56{
67 struct irqaction *action; 57 int i = *(loff_t *) v, cpu;
68 struct irq_group *group; 58 struct irqaction * action;
69 unsigned long flags; 59 unsigned long flags;
70 int level, grp, ix, i, j;
71
72 i = *(loff_t *) v;
73
74 switch (i) {
75 case 0:
76 seq_printf(p, " ");
77 for_each_online_cpu(j)
78 seq_printf(p, "CPU%d ",j);
79
80 seq_putc(p, '\n');
81 break;
82 60
83 case 1 ... NR_IRQ_GROUPS * NR_IRQ_ACTIONS_PER_GROUP: 61 if (i == 0) {
84 local_irq_save(flags); 62 char cpuname[12];
85
86 grp = (i - 1) / NR_IRQ_ACTIONS_PER_GROUP;
87 group = irq_groups[grp];
88 if (!group)
89 goto skip;
90
91 ix = (i - 1) % NR_IRQ_ACTIONS_PER_GROUP;
92 action = group->actions[ix];
93 if (!action)
94 goto skip;
95
96 seq_printf(p, "%3d: ", i - 1);
97
98#ifndef CONFIG_SMP
99 seq_printf(p, "%10u ", kstat_irqs(i));
100#else
101 for_each_online_cpu(j)
102 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i - 1]);
103#endif
104
105 level = group->sources[ix]->level - frv_irq_levels;
106
107 seq_printf(p, " %12s@%x", group->sources[ix]->muxname, level);
108 seq_printf(p, " %s", action->name);
109
110 for (action = action->next; action; action = action->next)
111 seq_printf(p, ", %s", action->name);
112 63
64 seq_printf(p, " ");
65 for_each_present_cpu(cpu) {
66 sprintf(cpuname, "CPU%d", cpu);
67 seq_printf(p, " %10s", cpuname);
68 }
113 seq_putc(p, '\n'); 69 seq_putc(p, '\n');
114skip: 70 }
115 local_irq_restore(flags);
116 break;
117 71
118 case NR_IRQ_GROUPS * NR_IRQ_ACTIONS_PER_GROUP + 1: 72 if (i < NR_IRQS) {
119 seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); 73 spin_lock_irqsave(&irq_desc[i].lock, flags);
120 break; 74 action = irq_desc[i].action;
75 if (action) {
76 seq_printf(p, "%3d: ", i);
77 for_each_present_cpu(cpu)
78 seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]);
79 seq_printf(p, " %10s", irq_desc[i].chip->name ? : "-");
80 seq_printf(p, " %s", action->name);
81 for (action = action->next;
82 action;
83 action = action->next)
84 seq_printf(p, ", %s", action->name);
85
86 seq_putc(p, '\n');
87 }
121 88
122 default: 89 spin_unlock_irqrestore(&irq_desc[i].lock, flags);
123 break; 90 } else if (i == NR_IRQS) {
91 seq_printf(p, "Err: %10u\n", atomic_read(&irq_err_count));
124 } 92 }
125 93
126 return 0; 94 return 0;
127} 95}
128 96
129
130/* 97/*
131 * Generic enable/disable code: this just calls 98 * on-CPU PIC operations
132 * down into the PIC-specific version for the actual
133 * hardware disable after having gotten the irq
134 * controller lock.
135 */ 99 */
136 100static void frv_cpupic_enable(unsigned int irqlevel)
137/**
138 * disable_irq_nosync - disable an irq without waiting
139 * @irq: Interrupt to disable
140 *
141 * Disable the selected interrupt line. Disables and Enables are
142 * nested.
143 * Unlike disable_irq(), this function does not ensure existing
144 * instances of the IRQ handler have completed before returning.
145 *
146 * This function may be called from IRQ context.
147 */
148
149void disable_irq_nosync(unsigned int irq)
150{ 101{
151 struct irq_source *source; 102 __clr_MASK(irqlevel);
152 struct irq_group *group;
153 struct irq_level *level;
154 unsigned long flags;
155 int idx = irq & (NR_IRQ_ACTIONS_PER_GROUP - 1);
156
157 group = irq_groups[irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP];
158 if (!group)
159 BUG();
160
161 source = group->sources[idx];
162 if (!source)
163 BUG();
164
165 level = source->level;
166
167 spin_lock_irqsave(&level->lock, flags);
168
169 if (group->control) {
170 if (!group->disable_cnt[idx]++)
171 group->control(group, idx, 0);
172 } else if (!level->disable_count++) {
173 __set_MASK(level - frv_irq_levels);
174 }
175
176 spin_unlock_irqrestore(&level->lock, flags);
177} 103}
178 104
179EXPORT_SYMBOL(disable_irq_nosync); 105static void frv_cpupic_disable(unsigned int irqlevel)
180
181/**
182 * disable_irq - disable an irq and wait for completion
183 * @irq: Interrupt to disable
184 *
185 * Disable the selected interrupt line. Enables and Disables are
186 * nested.
187 * This function waits for any pending IRQ handlers for this interrupt
188 * to complete before returning. If you use this function while
189 * holding a resource the IRQ handler may need you will deadlock.
190 *
191 * This function may be called - with care - from IRQ context.
192 */
193
194void disable_irq(unsigned int irq)
195{ 106{
196 disable_irq_nosync(irq); 107 __set_MASK(irqlevel);
197
198#ifdef CONFIG_SMP
199 if (!local_irq_count(smp_processor_id())) {
200 do {
201 barrier();
202 } while (irq_desc[irq].status & IRQ_INPROGRESS);
203 }
204#endif
205} 108}
206 109
207EXPORT_SYMBOL(disable_irq); 110static void frv_cpupic_ack(unsigned int irqlevel)
208
209/**
210 * enable_irq - enable handling of an irq
211 * @irq: Interrupt to enable
212 *
213 * Undoes the effect of one call to disable_irq(). If this
214 * matches the last disable, processing of interrupts on this
215 * IRQ line is re-enabled.
216 *
217 * This function may be called from IRQ context.
218 */
219
220void enable_irq(unsigned int irq)
221{ 111{
222 struct irq_source *source; 112 __set_MASK(irqlevel);
223 struct irq_group *group; 113 __clr_RC(irqlevel);
224 struct irq_level *level; 114 __clr_IRL();
225 unsigned long flags; 115}
226 int idx = irq & (NR_IRQ_ACTIONS_PER_GROUP - 1);
227 int count;
228
229 group = irq_groups[irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP];
230 if (!group)
231 BUG();
232
233 source = group->sources[idx];
234 if (!source)
235 BUG();
236
237 level = source->level;
238
239 spin_lock_irqsave(&level->lock, flags);
240
241 if (group->control)
242 count = group->disable_cnt[idx];
243 else
244 count = level->disable_count;
245
246 switch (count) {
247 case 1:
248 if (group->control) {
249 if (group->actions[idx])
250 group->control(group, idx, 1);
251 } else {
252 if (level->usage)
253 __clr_MASK(level - frv_irq_levels);
254 }
255 /* fall-through */
256 116
257 default: 117static void frv_cpupic_mask(unsigned int irqlevel)
258 count--; 118{
259 break; 119 __set_MASK(irqlevel);
120}
260 121
261 case 0: 122static void frv_cpupic_mask_ack(unsigned int irqlevel)
262 printk("enable_irq(%u) unbalanced from %p\n", irq, __builtin_return_address(0)); 123{
263 } 124 __set_MASK(irqlevel);
125 __clr_RC(irqlevel);
126 __clr_IRL();
127}
264 128
265 if (group->control) 129static void frv_cpupic_unmask(unsigned int irqlevel)
266 group->disable_cnt[idx] = count; 130{
267 else 131 __clr_MASK(irqlevel);
268 level->disable_count = count; 132}
269 133
270 spin_unlock_irqrestore(&level->lock, flags); 134static void frv_cpupic_end(unsigned int irqlevel)
135{
136 __clr_MASK(irqlevel);
271} 137}
272 138
273EXPORT_SYMBOL(enable_irq); 139static struct irq_chip frv_cpu_pic = {
140 .name = "cpu",
141 .enable = frv_cpupic_enable,
142 .disable = frv_cpupic_disable,
143 .ack = frv_cpupic_ack,
144 .mask = frv_cpupic_mask,
145 .mask_ack = frv_cpupic_mask_ack,
146 .unmask = frv_cpupic_unmask,
147 .end = frv_cpupic_end,
148};
274 149
275/*****************************************************************************/
276/* 150/*
277 * handles all normal device IRQ's 151 * handles all normal device IRQ's
278 * - registers are referred to by the __frame variable (GR28) 152 * - registers are referred to by the __frame variable (GR28)
@@ -281,463 +155,65 @@ EXPORT_SYMBOL(enable_irq);
281 */ 155 */
282asmlinkage void do_IRQ(void) 156asmlinkage void do_IRQ(void)
283{ 157{
284 struct irq_source *source;
285 int level, cpu;
286
287 irq_enter(); 158 irq_enter();
288 159 __do_IRQ(__get_IRL(), __frame);
289 level = (__frame->tbr >> 4) & 0xf;
290 cpu = smp_processor_id();
291
292 if ((unsigned long) __frame - (unsigned long) (current + 1) < 512)
293 BUG();
294
295 __set_MASK(level);
296 __clr_RC(level);
297 __clr_IRL();
298
299 kstat_this_cpu.irqs[level]++;
300
301 for (source = frv_irq_levels[level].sources; source; source = source->next)
302 source->doirq(source);
303
304 __clr_MASK(level);
305
306 irq_exit(); 160 irq_exit();
161}
307 162
308} /* end do_IRQ() */
309
310/*****************************************************************************/
311/* 163/*
312 * handles all NMIs when not co-opted by the debugger 164 * handles all NMIs when not co-opted by the debugger
313 * - registers are referred to by the __frame variable (GR28) 165 * - registers are referred to by the __frame variable (GR28)
314 */ 166 */
315asmlinkage void do_NMI(void) 167asmlinkage void do_NMI(void)
316{ 168{
317} /* end do_NMI() */
318
319/*****************************************************************************/
320/**
321 * request_irq - allocate an interrupt line
322 * @irq: Interrupt line to allocate
323 * @handler: Function to be called when the IRQ occurs
324 * @irqflags: Interrupt type flags
325 * @devname: An ascii name for the claiming device
326 * @dev_id: A cookie passed back to the handler function
327 *
328 * This call allocates interrupt resources and enables the
329 * interrupt line and IRQ handling. From the point this
330 * call is made your handler function may be invoked. Since
331 * your handler function must clear any interrupt the board
332 * raises, you must take care both to initialise your hardware
333 * and to set up the interrupt handler in the right order.
334 *
335 * Dev_id must be globally unique. Normally the address of the
336 * device data structure is used as the cookie. Since the handler
337 * receives this value it makes sense to use it.
338 *
339 * If your interrupt is shared you must pass a non NULL dev_id
340 * as this is required when freeing the interrupt.
341 *
342 * Flags:
343 *
344 * IRQF_SHARED Interrupt is shared
345 *
346 * IRQF_DISABLED Disable local interrupts while processing
347 *
348 * IRQF_SAMPLE_RANDOM The interrupt can be used for entropy
349 *
350 */
351
352int request_irq(unsigned int irq,
353 irqreturn_t (*handler)(int, void *, struct pt_regs *),
354 unsigned long irqflags,
355 const char * devname,
356 void *dev_id)
357{
358 int retval;
359 struct irqaction *action;
360
361#if 1
362 /*
363 * Sanity-check: shared interrupts should REALLY pass in
364 * a real dev-ID, otherwise we'll have trouble later trying
365 * to figure out which interrupt is which (messes up the
366 * interrupt freeing logic etc).
367 */
368 if (irqflags & IRQF_SHARED) {
369 if (!dev_id)
370 printk("Bad boy: %s (at 0x%x) called us without a dev_id!\n",
371 devname, (&irq)[-1]);
372 }
373#endif
374
375 if ((irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP) >= NR_IRQ_GROUPS)
376 return -EINVAL;
377 if (!handler)
378 return -EINVAL;
379
380 action = (struct irqaction *) kmalloc(sizeof(struct irqaction), GFP_KERNEL);
381 if (!action)
382 return -ENOMEM;
383
384 action->handler = handler;
385 action->flags = irqflags;
386 action->mask = CPU_MASK_NONE;
387 action->name = devname;
388 action->next = NULL;
389 action->dev_id = dev_id;
390
391 retval = setup_irq(irq, action);
392 if (retval)
393 kfree(action);
394 return retval;
395}
396
397EXPORT_SYMBOL(request_irq);
398
399/**
400 * free_irq - free an interrupt
401 * @irq: Interrupt line to free
402 * @dev_id: Device identity to free
403 *
404 * Remove an interrupt handler. The handler is removed and if the
405 * interrupt line is no longer in use by any driver it is disabled.
406 * On a shared IRQ the caller must ensure the interrupt is disabled
407 * on the card it drives before calling this function. The function
408 * does not return until any executing interrupts for this IRQ
409 * have completed.
410 *
411 * This function may be called from interrupt context.
412 *
413 * Bugs: Attempting to free an irq in a handler for the same irq hangs
414 * the machine.
415 */
416
417void free_irq(unsigned int irq, void *dev_id)
418{
419 struct irq_source *source;
420 struct irq_group *group;
421 struct irq_level *level;
422 struct irqaction **p, **pp;
423 unsigned long flags;
424
425 if ((irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP) >= NR_IRQ_GROUPS)
426 return;
427
428 group = irq_groups[irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP];
429 if (!group)
430 BUG();
431
432 source = group->sources[irq & (NR_IRQ_ACTIONS_PER_GROUP - 1)];
433 if (!source)
434 BUG();
435
436 level = source->level;
437 p = &group->actions[irq & (NR_IRQ_ACTIONS_PER_GROUP - 1)];
438
439 spin_lock_irqsave(&level->lock, flags);
440
441 for (pp = p; *pp; pp = &(*pp)->next) {
442 struct irqaction *action = *pp;
443
444 if (action->dev_id != dev_id)
445 continue;
446
447 /* found it - remove from the list of entries */
448 *pp = action->next;
449
450 level->usage--;
451
452 if (p == pp && group->control)
453 group->control(group, irq & (NR_IRQ_ACTIONS_PER_GROUP - 1), 0);
454
455 if (level->usage == 0)
456 __set_MASK(level - frv_irq_levels);
457
458 spin_unlock_irqrestore(&level->lock,flags);
459
460#ifdef CONFIG_SMP
461 /* Wait to make sure it's not being used on another CPU */
462 while (desc->status & IRQ_INPROGRESS)
463 barrier();
464#endif
465 kfree(action);
466 return;
467 }
468}
469
470EXPORT_SYMBOL(free_irq);
471
472/*
473 * IRQ autodetection code..
474 *
475 * This depends on the fact that any interrupt that comes in on to an
476 * unassigned IRQ will cause GxICR_DETECT to be set
477 */
478
479static DECLARE_MUTEX(probe_sem);
480
481/**
482 * probe_irq_on - begin an interrupt autodetect
483 *
484 * Commence probing for an interrupt. The interrupts are scanned
485 * and a mask of potential interrupt lines is returned.
486 *
487 */
488
489unsigned long probe_irq_on(void)
490{
491 down(&probe_sem);
492 return 0;
493} 169}
494 170
495EXPORT_SYMBOL(probe_irq_on);
496
497/*
498 * Return a mask of triggered interrupts (this
499 * can handle only legacy ISA interrupts).
500 */
501
502/**
503 * probe_irq_mask - scan a bitmap of interrupt lines
504 * @val: mask of interrupts to consider
505 *
506 * Scan the ISA bus interrupt lines and return a bitmap of
507 * active interrupts. The interrupt probe logic state is then
508 * returned to its previous value.
509 *
510 * Note: we need to scan all the irq's even though we will
511 * only return ISA irq numbers - just so that we reset them
512 * all to a known state.
513 */
514unsigned int probe_irq_mask(unsigned long xmask)
515{
516 up(&probe_sem);
517 return 0;
518}
519
520EXPORT_SYMBOL(probe_irq_mask);
521
522/* 171/*
523 * Return the one interrupt that triggered (this can 172 * initialise the interrupt system
524 * handle any interrupt source).
525 */
526
527/**
528 * probe_irq_off - end an interrupt autodetect
529 * @xmask: mask of potential interrupts (unused)
530 *
531 * Scans the unused interrupt lines and returns the line which
532 * appears to have triggered the interrupt. If no interrupt was
533 * found then zero is returned. If more than one interrupt is
534 * found then minus the first candidate is returned to indicate
535 * their is doubt.
536 *
537 * The interrupt probe logic state is returned to its previous
538 * value.
539 *
540 * BUGS: When used in a module (which arguably shouldnt happen)
541 * nothing prevents two IRQ probe callers from overlapping. The
542 * results of this are non-optimal.
543 */ 173 */
544 174void __init init_IRQ(void)
545int probe_irq_off(unsigned long xmask)
546{
547 up(&probe_sem);
548 return -1;
549}
550
551EXPORT_SYMBOL(probe_irq_off);
552
553/* this was setup_x86_irq but it seems pretty generic */
554int setup_irq(unsigned int irq, struct irqaction *new)
555{
556 struct irq_source *source;
557 struct irq_group *group;
558 struct irq_level *level;
559 struct irqaction **p, **pp;
560 unsigned long flags;
561
562 group = irq_groups[irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP];
563 if (!group)
564 BUG();
565
566 source = group->sources[irq & (NR_IRQ_ACTIONS_PER_GROUP - 1)];
567 if (!source)
568 BUG();
569
570 level = source->level;
571
572 p = &group->actions[irq & (NR_IRQ_ACTIONS_PER_GROUP - 1)];
573
574 /*
575 * Some drivers like serial.c use request_irq() heavily,
576 * so we have to be careful not to interfere with a
577 * running system.
578 */
579 if (new->flags & IRQF_SAMPLE_RANDOM) {
580 /*
581 * This function might sleep, we want to call it first,
582 * outside of the atomic block.
583 * Yes, this might clear the entropy pool if the wrong
584 * driver is attempted to be loaded, without actually
585 * installing a new handler, but is this really a problem,
586 * only the sysadmin is able to do this.
587 */
588 rand_initialize_irq(irq);
589 }
590
591 /* must juggle the interrupt processing stuff with interrupts disabled */
592 spin_lock_irqsave(&level->lock, flags);
593
594 /* can't share interrupts unless all parties agree to */
595 if (level->usage != 0 && !(level->flags & new->flags & IRQF_SHARED)) {
596 spin_unlock_irqrestore(&level->lock,flags);
597 return -EBUSY;
598 }
599
600 /* add new interrupt at end of irq queue */
601 pp = p;
602 while (*pp)
603 pp = &(*pp)->next;
604
605 *pp = new;
606
607 level->usage++;
608 level->flags = new->flags;
609
610 /* turn the interrupts on */
611 if (level->usage == 1)
612 __clr_MASK(level - frv_irq_levels);
613
614 if (p == pp && group->control)
615 group->control(group, irq & (NR_IRQ_ACTIONS_PER_GROUP - 1), 1);
616
617 spin_unlock_irqrestore(&level->lock, flags);
618 register_irq_proc(irq);
619 return 0;
620}
621
622static struct proc_dir_entry * root_irq_dir;
623static struct proc_dir_entry * irq_dir [NR_IRQS];
624
625#define HEX_DIGITS 8
626
627static unsigned int parse_hex_value (const char __user *buffer,
628 unsigned long count, unsigned long *ret)
629{
630 unsigned char hexnum [HEX_DIGITS];
631 unsigned long value;
632 int i;
633
634 if (!count)
635 return -EINVAL;
636 if (count > HEX_DIGITS)
637 count = HEX_DIGITS;
638 if (copy_from_user(hexnum, buffer, count))
639 return -EFAULT;
640
641 /*
642 * Parse the first 8 characters as a hex string, any non-hex char
643 * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
644 */
645 value = 0;
646
647 for (i = 0; i < count; i++) {
648 unsigned int c = hexnum[i];
649
650 switch (c) {
651 case '0' ... '9': c -= '0'; break;
652 case 'a' ... 'f': c -= 'a'-10; break;
653 case 'A' ... 'F': c -= 'A'-10; break;
654 default:
655 goto out;
656 }
657 value = (value << 4) | c;
658 }
659out:
660 *ret = value;
661 return 0;
662}
663
664
665static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
666 int count, int *eof, void *data)
667{
668 unsigned long *mask = (unsigned long *) data;
669 if (count < HEX_DIGITS+1)
670 return -EINVAL;
671 return sprintf (page, "%08lx\n", *mask);
672}
673
674static int prof_cpu_mask_write_proc (struct file *file, const char __user *buffer,
675 unsigned long count, void *data)
676{
677 unsigned long *mask = (unsigned long *) data, full_count = count, err;
678 unsigned long new_value;
679
680 show_state();
681 err = parse_hex_value(buffer, count, &new_value);
682 if (err)
683 return err;
684
685 *mask = new_value;
686 return full_count;
687}
688
689#define MAX_NAMELEN 10
690
691static void register_irq_proc (unsigned int irq)
692{
693 char name [MAX_NAMELEN];
694
695 if (!root_irq_dir || irq_dir[irq])
696 return;
697
698 memset(name, 0, MAX_NAMELEN);
699 sprintf(name, "%d", irq);
700
701 /* create /proc/irq/1234 */
702 irq_dir[irq] = proc_mkdir(name, root_irq_dir);
703}
704
705unsigned long prof_cpu_mask = -1;
706
707void init_irq_proc (void)
708{ 175{
709 struct proc_dir_entry *entry; 176 int level;
710 int i;
711 177
712 /* create /proc/irq */ 178 for (level = 1; level <= 14; level++)
713 root_irq_dir = proc_mkdir("irq", NULL); 179 set_irq_chip_and_handler(level, &frv_cpu_pic,
180 handle_level_irq);
714 181
715 /* create /proc/irq/prof_cpu_mask */ 182 set_irq_handler(IRQ_CPU_TIMER0, handle_edge_irq);
716 entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir);
717 if (!entry)
718 return;
719 183
720 entry->nlink = 1; 184 /* set the trigger levels for internal interrupt sources
721 entry->data = (void *)&prof_cpu_mask; 185 * - timers all falling-edge
722 entry->read_proc = prof_cpu_mask_read_proc; 186 * - ERR0 is rising-edge
723 entry->write_proc = prof_cpu_mask_write_proc; 187 * - all others are high-level
724
725 /*
726 * Create entries for all existing IRQs.
727 */ 188 */
728 for (i = 0; i < NR_IRQS; i++) 189 __set_IITMR(0, 0x003f0000); /* DMA0-3, TIMER0-2 */
729 register_irq_proc(i); 190 __set_IITMR(1, 0x20000000); /* ERR0-1, UART0-1, DMA4-7 */
730} 191
192 /* route internal interrupts */
193 set_IRR(4, IRQ_DMA3_LEVEL, IRQ_DMA2_LEVEL, IRQ_DMA1_LEVEL,
194 IRQ_DMA0_LEVEL);
195 set_IRR(5, 0, IRQ_TIMER2_LEVEL, IRQ_TIMER1_LEVEL, IRQ_TIMER0_LEVEL);
196 set_IRR(6, IRQ_GDBSTUB_LEVEL, IRQ_GDBSTUB_LEVEL,
197 IRQ_UART1_LEVEL, IRQ_UART0_LEVEL);
198 set_IRR(7, IRQ_DMA7_LEVEL, IRQ_DMA6_LEVEL, IRQ_DMA5_LEVEL,
199 IRQ_DMA4_LEVEL);
200
201 /* route external interrupts */
202 set_IRR(2, IRQ_XIRQ7_LEVEL, IRQ_XIRQ6_LEVEL, IRQ_XIRQ5_LEVEL,
203 IRQ_XIRQ4_LEVEL);
204 set_IRR(3, IRQ_XIRQ3_LEVEL, IRQ_XIRQ2_LEVEL, IRQ_XIRQ1_LEVEL,
205 IRQ_XIRQ0_LEVEL);
206
207#if defined(CONFIG_MB93091_VDK)
208 __set_TM1(0x55550000); /* XIRQ7-0 all active low */
209#elif defined(CONFIG_MB93093_PDK)
210 __set_TM1(0x15550000); /* XIRQ7 active high, 6-0 all active low */
211#else
212#error dont know external IRQ trigger levels for this setup
213#endif
731 214
732/*****************************************************************************/
733/*
734 * initialise the interrupt system
735 */
736void __init init_IRQ(void)
737{
738 route_cpu_irqs();
739 fpga_init(); 215 fpga_init();
740#ifdef CONFIG_FUJITSU_MB93493 216#ifdef CONFIG_FUJITSU_MB93493
741 route_mb93493_irqs(); 217 mb93493_init();
742#endif 218#endif
743} /* end init_IRQ() */ 219}