[PATCH] genirq: x86_64 irq: Reenable migrating irqs to other cpus
[deliverable/linux.git] / arch / x86_64 / kernel / io_apic.c
index e1d1b4217cb2cc7f174b07458d42c1763e23bc8e..12dd938f5d54f70f01795773e020bbfb976ce4de 100644 (file)
@@ -1254,18 +1254,48 @@ static int ioapic_retrigger_vector(unsigned int vector)
  * races.
  */
 
-static void ack_apic(unsigned int vector)
+static void ack_apic(unsigned int irq)
 {
        ack_APIC_irq();
 }
 
+static void ack_apic_edge(unsigned int irq)
+{
+       move_native_irq(irq);
+       ack_APIC_irq();
+}
+
+static void ack_apic_level(unsigned int irq)
+{
+       int do_unmask_irq = 0;
+
+#if defined(CONFIG_GENERIC_PENDING_IRQ) || defined(CONFIG_IRQBALANCE)
+       /* If we are moving the irq we need to mask it */
+       if (unlikely(irq_desc[irq].status & IRQ_MOVE_PENDING)) {
+               do_unmask_irq = 1;
+               mask_IO_APIC_irq(irq);
+       }
+#endif
+
+       /*
+        * We must acknowledge the irq before we move it or the acknowledge will
+        * not propogate properly.
+        */
+       ack_APIC_irq();
+
+       /* Now we can move and renable the irq */
+       move_masked_irq(irq);
+       if (unlikely(do_unmask_irq))
+               unmask_IO_APIC_irq(irq);
+}
+
 static struct irq_chip ioapic_chip __read_mostly = {
        .name           = "IO-APIC",
        .startup        = startup_ioapic_vector,
        .mask           = mask_ioapic_vector,
        .unmask         = unmask_ioapic_vector,
-       .ack            = ack_apic,
-       .eoi            = ack_apic,
+       .ack            = ack_apic_edge,
+       .eoi            = ack_apic_level,
 #ifdef CONFIG_SMP
        .set_affinity   = set_ioapic_affinity_vector,
 #endif
This page took 0.03742 seconds and 5 git commands to generate.