diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2006-11-06 12:41:06 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2006-11-06 15:55:38 -0500 |
commit | 4a4cf77923eeb3cec40a302656d6ab5ced04ba48 (patch) | |
tree | 6388d7a2227a28697b4c833089980c26df696745 | |
parent | 325d08d1a44b601fbf70c259fb61c38d2af7d309 (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.c | 42 | ||||
-rw-r--r-- | arch/mips/sgi-ip27/ip27-irq.c | 23 | ||||
-rw-r--r-- | arch/mips/sgi-ip27/ip27-timer.c | 2 | ||||
-rw-r--r-- | include/asm-mips/irq.h | 4 |
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 | ||
29 | static unsigned long irq_map[NR_IRQS / BITS_PER_LONG]; | ||
30 | |||
31 | int __devinit allocate_irqno(void) | ||
32 | { | ||
33 | int irq; | ||
34 | |||
35 | again: | ||
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 | |||
47 | EXPORT_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 | */ | ||
54 | void __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 | |||
62 | void __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 | |||
69 | EXPORT_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 | ||
357 | static unsigned long irq_map[NR_IRQS / BITS_PER_LONG]; | ||
358 | |||
359 | int allocate_irqno(void) | ||
360 | { | ||
361 | int irq; | ||
362 | |||
363 | again: | ||
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 | |||
375 | void free_irqno(unsigned int irq) | ||
376 | { | ||
377 | clear_bit(irq, irq_map); | ||
378 | } | ||
379 | |||
380 | void __devinit register_bridge_irq(unsigned int irq) | 357 | void __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 | ||
217 | extern int allocate_irqno(void); | ||
218 | |||
219 | void __init plat_timer_setup(struct irqaction *irq) | 217 | void __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 | ||
77 | extern int allocate_irqno(void); | ||
78 | extern void alloc_legacy_irqno(void); | ||
79 | extern void free_irqno(unsigned int irq); | ||
80 | |||
77 | #endif /* _ASM_IRQ_H */ | 81 | #endif /* _ASM_IRQ_H */ |