aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2006-11-06 12:41:06 -0500
committerRalf Baechle <ralf@linux-mips.org>2006-11-06 15:55:38 -0500
commit4a4cf77923eeb3cec40a302656d6ab5ced04ba48 (patch)
tree6388d7a2227a28697b4c833089980c26df696745
parent325d08d1a44b601fbf70c259fb61c38d2af7d309 (diff)
[MIPS] Make irq number allocator generally available for fixing EV64120.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/kernel/irq.c42
-rw-r--r--arch/mips/sgi-ip27/ip27-irq.c23
-rw-r--r--arch/mips/sgi-ip27/ip27-timer.c2
-rw-r--r--include/asm-mips/irq.h4
4 files changed, 46 insertions, 25 deletions
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
index dd24434392b6..9b0e49d63d7b 100644
--- a/arch/mips/kernel/irq.c
+++ b/arch/mips/kernel/irq.c
@@ -26,6 +26,48 @@
26#include <asm/system.h> 26#include <asm/system.h>
27#include <asm/uaccess.h> 27#include <asm/uaccess.h>
28 28
29static unsigned long irq_map[NR_IRQS / BITS_PER_LONG];
30
31int __devinit allocate_irqno(void)
32{
33 int irq;
34
35again:
36 irq = find_first_zero_bit(irq_map, NR_IRQS);
37
38 if (irq >= NR_IRQS)
39 return -ENOSPC;
40
41 if (test_and_set_bit(irq, irq_map))
42 goto again;
43
44 return irq;
45}
46
47EXPORT_SYMBOL_GPL(allocate_irqno);
48
49/*
50 * Allocate the 16 legacy interrupts for i8259 devices. This happens early
51 * in the kernel initialization so treating allocation failure as BUG() is
52 * ok.
53 */
54void __init alloc_legacy_irqno(void)
55{
56 int i;
57
58 for (i = 0; i <= 16; i++)
59 BUG_ON(test_and_set_bit(i, irq_map));
60}
61
62void __devinit free_irqno(unsigned int irq)
63{
64 smp_mb__before_clear_bit();
65 clear_bit(irq, irq_map);
66 smp_mb__after_clear_bit();
67}
68
69EXPORT_SYMBOL_GPL(free_irqno);
70
29/* 71/*
30 * 'what should we do if we get a hw irq event on an illegal vector'. 72 * 'what should we do if we get a hw irq event on an illegal vector'.
31 * each architecture has to answer this themselves. 73 * each architecture has to answer this themselves.
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c
index f01ba1f90770..270ecd3e6b4a 100644
--- a/arch/mips/sgi-ip27/ip27-irq.c
+++ b/arch/mips/sgi-ip27/ip27-irq.c
@@ -354,29 +354,6 @@ static struct irq_chip bridge_irq_type = {
354 .end = end_bridge_irq, 354 .end = end_bridge_irq,
355}; 355};
356 356
357static unsigned long irq_map[NR_IRQS / BITS_PER_LONG];
358
359int allocate_irqno(void)
360{
361 int irq;
362
363again:
364 irq = find_first_zero_bit(irq_map, NR_IRQS);
365
366 if (irq >= NR_IRQS)
367 return -ENOSPC;
368
369 if (test_and_set_bit(irq, irq_map))
370 goto again;
371
372 return irq;
373}
374
375void free_irqno(unsigned int irq)
376{
377 clear_bit(irq, irq_map);
378}
379
380void __devinit register_bridge_irq(unsigned int irq) 357void __devinit register_bridge_irq(unsigned int irq)
381{ 358{
382 irq_desc[irq].status = IRQ_DISABLED; 359 irq_desc[irq].status = IRQ_DISABLED;
diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c
index c965705f3427..5e82a268e3c9 100644
--- a/arch/mips/sgi-ip27/ip27-timer.c
+++ b/arch/mips/sgi-ip27/ip27-timer.c
@@ -214,8 +214,6 @@ static struct irqaction rt_irqaction = {
214 .name = "timer" 214 .name = "timer"
215}; 215};
216 216
217extern int allocate_irqno(void);
218
219void __init plat_timer_setup(struct irqaction *irq) 217void __init plat_timer_setup(struct irqaction *irq)
220{ 218{
221 int irqno = allocate_irqno(); 219 int irqno = allocate_irqno();
diff --git a/include/asm-mips/irq.h b/include/asm-mips/irq.h
index 0ce2a80b689e..35a05ca5560c 100644
--- a/include/asm-mips/irq.h
+++ b/include/asm-mips/irq.h
@@ -74,4 +74,8 @@ extern int setup_irq_smtc(unsigned int irq, struct irqaction * new,
74 unsigned long hwmask); 74 unsigned long hwmask);
75#endif /* CONFIG_MIPS_MT_SMTC */ 75#endif /* CONFIG_MIPS_MT_SMTC */
76 76
77extern int allocate_irqno(void);
78extern void alloc_legacy_irqno(void);
79extern void free_irqno(unsigned int irq);
80
77#endif /* _ASM_IRQ_H */ 81#endif /* _ASM_IRQ_H */