[MIPS] Make irq number allocator generally available for fixing EV64120.
authorRalf Baechle <ralf@linux-mips.org>
Mon, 6 Nov 2006 17:41:06 +0000 (17:41 +0000)
committerRalf Baechle <ralf@linux-mips.org>
Mon, 6 Nov 2006 20:55:38 +0000 (20:55 +0000)
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/kernel/irq.c
arch/mips/sgi-ip27/ip27-irq.c
arch/mips/sgi-ip27/ip27-timer.c
include/asm-mips/irq.h

index dd24434392b6355e248756869cbae341c2b47d17..9b0e49d63d7b2b1275b90890c4aabc3b4fcd580d 100644 (file)
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
+static unsigned long irq_map[NR_IRQS / BITS_PER_LONG];
+
+int __devinit allocate_irqno(void)
+{
+       int irq;
+
+again:
+       irq = find_first_zero_bit(irq_map, NR_IRQS);
+
+       if (irq >= NR_IRQS)
+               return -ENOSPC;
+
+       if (test_and_set_bit(irq, irq_map))
+               goto again;
+
+       return irq;
+}
+
+EXPORT_SYMBOL_GPL(allocate_irqno);
+
+/*
+ * Allocate the 16 legacy interrupts for i8259 devices.  This happens early
+ * in the kernel initialization so treating allocation failure as BUG() is
+ * ok.
+ */
+void __init alloc_legacy_irqno(void)
+{
+       int i;
+
+       for (i = 0; i <= 16; i++)
+               BUG_ON(test_and_set_bit(i, irq_map));
+}
+
+void __devinit free_irqno(unsigned int irq)
+{
+       smp_mb__before_clear_bit();
+       clear_bit(irq, irq_map);
+       smp_mb__after_clear_bit();
+}
+
+EXPORT_SYMBOL_GPL(free_irqno);
+
 /*
  * 'what should we do if we get a hw irq event on an illegal vector'.
  * each architecture has to answer this themselves.
index f01ba1f9077084852a051e53cb8d4624befedfa2..270ecd3e6b4a5fe1990cc104b4585c8f6f6d874d 100644 (file)
@@ -354,29 +354,6 @@ static struct irq_chip bridge_irq_type = {
        .end            = end_bridge_irq,
 };
 
-static unsigned long irq_map[NR_IRQS / BITS_PER_LONG];
-
-int allocate_irqno(void)
-{
-       int irq;
-
-again:
-       irq = find_first_zero_bit(irq_map, NR_IRQS);
-
-       if (irq >= NR_IRQS)
-               return -ENOSPC;
-
-       if (test_and_set_bit(irq, irq_map))
-               goto again;
-
-       return irq;
-}
-
-void free_irqno(unsigned int irq)
-{
-       clear_bit(irq, irq_map);
-}
-
 void __devinit register_bridge_irq(unsigned int irq)
 {
        irq_desc[irq].status    = IRQ_DISABLED;
index c965705f34275ba81a6c44a7633c40b6367e5268..5e82a268e3c921abb2da0ced1687246e7aacc0b8 100644 (file)
@@ -214,8 +214,6 @@ static struct irqaction rt_irqaction = {
        .name           = "timer"
 };
 
-extern int allocate_irqno(void);
-
 void __init plat_timer_setup(struct irqaction *irq)
 {
        int irqno  = allocate_irqno();
index 0ce2a80b689e5da23a72ed6f17bfe01458325ed5..35a05ca5560cf75bf4d8cc865cc21231a08311cc 100644 (file)
@@ -74,4 +74,8 @@ extern int setup_irq_smtc(unsigned int irq, struct irqaction * new,
                           unsigned long hwmask);
 #endif /* CONFIG_MIPS_MT_SMTC */
 
+extern int allocate_irqno(void);
+extern void alloc_legacy_irqno(void);
+extern void free_irqno(unsigned int irq);
+
 #endif /* _ASM_IRQ_H */