vserver 1.9.5.x5
[linux-2.6.git] / arch / ia64 / kernel / irq_ia64.c
index 335d827..5ba06eb 100644 (file)
@@ -30,8 +30,8 @@
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/threads.h>
+#include <linux/bitops.h>
 
-#include <asm/bitops.h>
 #include <asm/delay.h>
 #include <asm/intrinsics.h>
 #include <asm/io.h>
@@ -60,33 +60,35 @@ __u8 isa_irq_to_vector_map[16] = {
 };
 EXPORT_SYMBOL(isa_irq_to_vector_map);
 
-static inline void
-irq_enter (void)
-{
-       preempt_count() += HARDIRQ_OFFSET;
-}
-
-static inline void
-irq_exit (void)
-{
-       preempt_count() -= IRQ_EXIT_OFFSET;
-       if (!in_interrupt() && local_softirq_pending())
-               do_softirq();
-       preempt_enable_no_resched();
-}
+static unsigned long ia64_vector_mask[BITS_TO_LONGS(IA64_NUM_DEVICE_VECTORS)];
 
 int
 assign_irq_vector (int irq)
 {
-       static int next_vector = IA64_FIRST_DEVICE_VECTOR;
-
-       if (next_vector > IA64_LAST_DEVICE_VECTOR)
+       int pos, vector;
+ again:
+       pos = find_first_zero_bit(ia64_vector_mask, IA64_NUM_DEVICE_VECTORS);
+       vector = IA64_FIRST_DEVICE_VECTOR + pos;
+       if (vector > IA64_LAST_DEVICE_VECTOR)
                /* XXX could look for sharable vectors instead of panic'ing... */
                panic("assign_irq_vector: out of interrupt vectors!");
-       return next_vector++;
+       if (test_and_set_bit(pos, ia64_vector_mask))
+               goto again;
+       return vector;
 }
 
-extern unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs);
+void
+free_irq_vector (int vector)
+{
+       int pos;
+
+       if (vector < IA64_FIRST_DEVICE_VECTOR || vector > IA64_LAST_DEVICE_VECTOR)
+               return;
+
+       pos = vector - IA64_FIRST_DEVICE_VECTOR;
+       if (!test_and_clear_bit(pos, ia64_vector_mask))
+               printk(KERN_WARNING "%s: double free!\n", __FUNCTION__);
+}
 
 #ifdef CONFIG_SMP
 #      define IS_RESCHEDULE(vec)       (vec == IA64_IPI_RESCHEDULE)
@@ -115,7 +117,7 @@ ia64_handle_irq (ia64_vector vector, struct pt_regs *regs)
                 * switched atomically.
                 */
                bsp = ia64_getreg(_IA64_REG_AR_BSP);
-               sp = ia64_getreg(_IA64_REG_AR_SP);
+               sp = ia64_getreg(_IA64_REG_SP);
 
                if ((sp - bsp) < 1024) {
                        static unsigned char count;
@@ -146,7 +148,7 @@ ia64_handle_irq (ia64_vector vector, struct pt_regs *regs)
                        ia64_setreg(_IA64_REG_CR_TPR, vector);
                        ia64_srlz_d();
 
-                       do_IRQ(local_vector_to_irq(vector), regs);
+                       __do_IRQ(local_vector_to_irq(vector), regs);
 
                        /*
                         * Disable interrupts and send EOI:
@@ -197,7 +199,7 @@ void ia64_process_pending_intr(void)
                         * Probably could shared code.
                         */
                        vectors_in_migration[local_vector_to_irq(vector)]=0;
-                       do_IRQ(local_vector_to_irq(vector), NULL);
+                       __do_IRQ(local_vector_to_irq(vector), NULL);
 
                        /*
                         * Disable interrupts and send EOI