Merge branch 'for-linus' of git://oss.sgi.com:8090/xfs/xfs-2.6 into for-linus
[sfrench/cifs-2.6.git] / arch / parisc / kernel / irq.c
index 9bdd0197ceb777f555efc995e1581c17d2167938..76ce5e3b00505b264f3188fa2329919b3dcbfd45 100644 (file)
@@ -35,8 +35,8 @@
 
 #undef PARISC_IRQ_CR16_COUNTS
 
-extern irqreturn_t timer_interrupt(int, void *, struct pt_regs *);
-extern irqreturn_t ipi_interrupt(int, void *, struct pt_regs *);
+extern irqreturn_t timer_interrupt(int, void *);
+extern irqreturn_t ipi_interrupt(int, void *);
 
 #define EIEM_MASK(irq)       (1UL<<(CPU_IRQ_MAX - irq))
 
@@ -46,14 +46,10 @@ extern irqreturn_t ipi_interrupt(int, void *, struct pt_regs *);
 static volatile unsigned long cpu_eiem = 0;
 
 /*
-** ack bitmap ... habitually set to 1, but reset to zero
+** local ACK bitmap ... habitually set to 1, but reset to zero
 ** between ->ack() and ->end() of the interrupt to prevent
 ** re-interruption of a processing interrupt.
 */
-static volatile unsigned long global_ack_eiem = ~0UL;
-/*
-** Local bitmap, same as above but for per-cpu interrupts
-*/
 static DEFINE_PER_CPU(unsigned long, local_ack_eiem) = ~0UL;
 
 static void cpu_disable_irq(unsigned int irq)
@@ -94,13 +90,11 @@ void cpu_ack_irq(unsigned int irq)
        int cpu = smp_processor_id();
 
        /* Clear in EIEM so we can no longer process */
-       if (CHECK_IRQ_PER_CPU(irq_desc[irq].status))
-               per_cpu(local_ack_eiem, cpu) &= ~mask;
-       else
-               global_ack_eiem &= ~mask;
+       per_cpu(local_ack_eiem, cpu) &= ~mask;
 
        /* disable the interrupt */
-       set_eiem(cpu_eiem & global_ack_eiem & per_cpu(local_ack_eiem, cpu));
+       set_eiem(cpu_eiem & per_cpu(local_ack_eiem, cpu));
+
        /* and now ack it */
        mtctl(mask, 23);
 }
@@ -111,13 +105,10 @@ void cpu_end_irq(unsigned int irq)
        int cpu = smp_processor_id();
 
        /* set it in the eiems---it's no longer in process */
-       if (CHECK_IRQ_PER_CPU(irq_desc[irq].status))
-               per_cpu(local_ack_eiem, cpu) |= mask;
-       else
-               global_ack_eiem |= mask;
+       per_cpu(local_ack_eiem, cpu) |= mask;
 
        /* enable the interrupt */
-       set_eiem(cpu_eiem & global_ack_eiem & per_cpu(local_ack_eiem, cpu));
+       set_eiem(cpu_eiem & per_cpu(local_ack_eiem, cpu));
 }
 
 #ifdef CONFIG_SMP
@@ -336,28 +327,25 @@ unsigned int txn_alloc_data(unsigned int virt_irq)
 
 static inline int eirr_to_irq(unsigned long eirr)
 {
-#ifdef CONFIG_64BIT
-       int bit = fls64(eirr);
-#else
-       int bit = fls(eirr);
-#endif
+       int bit = fls_long(eirr);
        return (BITS_PER_LONG - bit) + TIMER_IRQ;
 }
 
 /* ONLY called from entry.S:intr_extint() */
 void do_cpu_irq_mask(struct pt_regs *regs)
 {
+       struct pt_regs *old_regs;
        unsigned long eirr_val;
        int irq, cpu = smp_processor_id();
 #ifdef CONFIG_SMP
        cpumask_t dest;
 #endif
 
+       old_regs = set_irq_regs(regs);
        local_irq_disable();
        irq_enter();
 
-       eirr_val = mfctl(23) & cpu_eiem & global_ack_eiem &
-               per_cpu(local_ack_eiem, cpu);
+       eirr_val = mfctl(23) & cpu_eiem & per_cpu(local_ack_eiem, cpu);
        if (!eirr_val)
                goto set_out;
        irq = eirr_to_irq(eirr_val);
@@ -375,21 +363,22 @@ void do_cpu_irq_mask(struct pt_regs *regs)
                goto set_out;
        }
 #endif
-       __do_IRQ(irq, regs);
+       __do_IRQ(irq);
 
  out:
        irq_exit();
+       set_irq_regs(old_regs);
        return;
 
  set_out:
-       set_eiem(cpu_eiem & global_ack_eiem & per_cpu(local_ack_eiem, cpu));
+       set_eiem(cpu_eiem & per_cpu(local_ack_eiem, cpu));
        goto out;
 }
 
 static struct irqaction timer_action = {
        .handler = timer_interrupt,
        .name = "timer",
-       .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_PERCPU,
+       .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_PERCPU | IRQF_IRQPOLL,
 };
 
 #ifdef CONFIG_SMP