[PATCH] x86: Unify pcspeaker platform device code between i386/x86-64
[safe/jmp/linux-2.6] / arch / x86_64 / kernel / irq.c
index bfa82f5..3bc30d2 100644 (file)
 #include <asm/uaccess.h>
 #include <asm/io_apic.h>
 #include <asm/idle.h>
+#include <asm/smp.h>
 
 atomic_t irq_err_count;
-#ifdef CONFIG_X86_IO_APIC
-#ifdef APIC_MISMATCH_DEBUG
-atomic_t irq_mis_count;
-#endif
-#endif
 
 #ifdef CONFIG_DEBUG_STACKOVERFLOW
 /*
@@ -79,7 +75,8 @@ int show_interrupts(struct seq_file *p, void *v)
                for_each_online_cpu(j)
                        seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
 #endif
-               seq_printf(p, " %14s", irq_desc[i].handler->typename);
+               seq_printf(p, " %8s", irq_desc[i].chip->name);
+               seq_printf(p, "-%-8s", irq_desc[i].name);
 
                seq_printf(p, "  %s", action->name);
                for (action=action->next; action; action = action->next)
@@ -92,18 +89,11 @@ skip:
                for_each_online_cpu(j)
                        seq_printf(p, "%10u ", cpu_pda(j)->__nmi_count);
                seq_putc(p, '\n');
-#ifdef CONFIG_X86_LOCAL_APIC
                seq_printf(p, "LOC: ");
                for_each_online_cpu(j)
                        seq_printf(p, "%10u ", cpu_pda(j)->apic_timer_irqs);
                seq_putc(p, '\n');
-#endif
                seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
-#ifdef CONFIG_X86_IO_APIC
-#ifdef APIC_MISMATCH_DEBUG
-               seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
-#endif
-#endif
        }
        return 0;
 }
@@ -114,24 +104,35 @@ skip:
  * handlers).
  */
 asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
-{      
-       /* high bit used in ret_from_ code  */
-       unsigned irq = ~regs->orig_rax;
+{
+       struct pt_regs *old_regs = set_irq_regs(regs);
 
-       if (unlikely(irq >= NR_IRQS)) {
-               printk(KERN_EMERG "%s: cannot handle IRQ %d\n",
-                                       __FUNCTION__, irq);
-               BUG();
-       }
+       /* high bit used in ret_from_ code  */
+       unsigned vector = ~regs->orig_rax;
+       unsigned irq;
 
        exit_idle();
        irq_enter();
+       irq = __get_cpu_var(vector_irq)[vector];
+
 #ifdef CONFIG_DEBUG_STACKOVERFLOW
        stack_overflow_check(regs);
 #endif
-       __do_IRQ(irq, regs);
+
+       if (likely(irq < NR_IRQS))
+               generic_handle_irq(irq);
+       else {
+               if (!disable_apic)
+                       ack_APIC_irq();
+
+               if (printk_ratelimit())
+                       printk(KERN_EMERG "%s: %d.%d No irq handler for vector\n",
+                               __func__, smp_processor_id(), vector);
+       }
+
        irq_exit();
 
+       set_irq_regs(old_regs);
        return 1;
 }
 
@@ -146,13 +147,13 @@ void fixup_irqs(cpumask_t map)
                if (irq == 2)
                        continue;
 
-               cpus_and(mask, irq_affinity[irq], map);
+               cpus_and(mask, irq_desc[irq].affinity, map);
                if (any_online_cpu(mask) == NR_CPUS) {
                        printk("Breaking affinity for irq %i\n", irq);
                        mask = map;
                }
-               if (irq_desc[irq].handler->set_affinity)
-                       irq_desc[irq].handler->set_affinity(irq, mask);
+               if (irq_desc[irq].chip->set_affinity)
+                       irq_desc[irq].chip->set_affinity(irq, mask);
                else if (irq_desc[irq].action && !(warned++))
                        printk("Cannot set affinity for irq %i\n", irq);
        }
@@ -177,8 +178,10 @@ asmlinkage void do_softirq(void)
        local_irq_save(flags);
        pending = local_softirq_pending();
        /* Switch to interrupt stack */
-       if (pending)
+       if (pending) {
                call_softirq();
+               WARN_ON_ONCE(softirq_count());
+       }
        local_irq_restore(flags);
 }
 EXPORT_SYMBOL(do_softirq);