[MIPS] Make irq number allocator generally available for fixing EV64120.

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

+46 -25
+42
arch/mips/kernel/irq.c
··· 26 #include <asm/system.h> 27 #include <asm/uaccess.h> 28 29 /* 30 * 'what should we do if we get a hw irq event on an illegal vector'. 31 * each architecture has to answer this themselves.
··· 26 #include <asm/system.h> 27 #include <asm/uaccess.h> 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 + 71 /* 72 * 'what should we do if we get a hw irq event on an illegal vector'. 73 * each architecture has to answer this themselves.
-23
arch/mips/sgi-ip27/ip27-irq.c
··· 354 .end = end_bridge_irq, 355 }; 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) 381 { 382 irq_desc[irq].status = IRQ_DISABLED;
··· 354 .end = end_bridge_irq, 355 }; 356 357 void __devinit register_bridge_irq(unsigned int irq) 358 { 359 irq_desc[irq].status = IRQ_DISABLED;
-2
arch/mips/sgi-ip27/ip27-timer.c
··· 214 .name = "timer" 215 }; 216 217 - extern int allocate_irqno(void); 218 - 219 void __init plat_timer_setup(struct irqaction *irq) 220 { 221 int irqno = allocate_irqno();
··· 214 .name = "timer" 215 }; 216 217 void __init plat_timer_setup(struct irqaction *irq) 218 { 219 int irqno = allocate_irqno();
+4
include/asm-mips/irq.h
··· 74 unsigned long hwmask); 75 #endif /* CONFIG_MIPS_MT_SMTC */ 76 77 #endif /* _ASM_IRQ_H */
··· 74 unsigned long hwmask); 75 #endif /* CONFIG_MIPS_MT_SMTC */ 76 77 + extern int allocate_irqno(void); 78 + extern void alloc_legacy_irqno(void); 79 + extern void free_irqno(unsigned int irq); 80 + 81 #endif /* _ASM_IRQ_H */