Merge branch 'x86/irq' into x86/apic
[pandora-kernel.git] / arch / x86 / kernel / apic / io_apic.c
index d55e43d..9795898 100644 (file)
@@ -1540,6 +1540,56 @@ static void __init setup_IO_APIC_irqs(void)
                        " (apicid-pin) not connected\n");
 }
 
+/*
+ * for the gsit that is not in first ioapic
+ * but could not use acpi_register_gsi()
+ * like some special sci in IBM x3330
+ */
+void setup_IO_APIC_irq_extra(u32 gsi)
+{
+       int apic_id = 0, pin, idx, irq;
+       int node = cpu_to_node(boot_cpu_id);
+       struct irq_desc *desc;
+       struct irq_cfg *cfg;
+
+       /*
+        * Convert 'gsi' to 'ioapic.pin'.
+        */
+       apic_id = mp_find_ioapic(gsi);
+       if (apic_id < 0)
+               return;
+
+       pin = mp_find_ioapic_pin(apic_id, gsi);
+       idx = find_irq_entry(apic_id, pin, mp_INT);
+       if (idx == -1)
+               return;
+
+       irq = pin_2_irq(idx, apic_id, pin);
+#ifdef CONFIG_SPARSE_IRQ
+       desc = irq_to_desc(irq);
+       if (desc)
+               return;
+#endif
+       desc = irq_to_desc_alloc_node(irq, node);
+       if (!desc) {
+               printk(KERN_INFO "can not get irq_desc for %d\n", irq);
+               return;
+       }
+
+       cfg = desc->chip_data;
+       add_pin_to_irq_node(cfg, node, apic_id, pin);
+
+       if (test_bit(pin, mp_ioapic_routing[apic_id].pin_programmed)) {
+               pr_debug("Pin %d-%d already programmed\n",
+                        mp_ioapics[apic_id].apicid, pin);
+               return;
+       }
+       set_bit(pin, mp_ioapic_routing[apic_id].pin_programmed);
+
+       setup_IO_APIC_irq(apic_id, pin, irq, desc,
+                       irq_trigger(idx), irq_polarity(idx));
+}
+
 /*
  * Set up the timer pin, possibly with the 8259A-master behind.
  */
@@ -1832,7 +1882,7 @@ __apicdebuginit(void) print_PIC(void)
 
        printk(KERN_DEBUG "\nprinting PIC contents\n");
 
-       spin_lock_irqsave(&i8259A_lock, flags);
+       raw_spin_lock_irqsave(&i8259A_lock, flags);
 
        v = inb(0xa1) << 8 | inb(0x21);
        printk(KERN_DEBUG "... PIC  IMR: %04x\n", v);
@@ -1846,7 +1896,7 @@ __apicdebuginit(void) print_PIC(void)
        outb(0x0a,0xa0);
        outb(0x0a,0x20);
 
-       spin_unlock_irqrestore(&i8259A_lock, flags);
+       raw_spin_unlock_irqrestore(&i8259A_lock, flags);
 
        printk(KERN_DEBUG "... PIC  ISR: %04x\n", v);
 
@@ -2436,6 +2486,13 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void)
                cfg = irq_cfg(irq);
                raw_spin_lock(&desc->lock);
 
+               /*
+                * Check if the irq migration is in progress. If so, we
+                * haven't received the cleanup request yet for this irq.
+                */
+               if (cfg->move_in_progress)
+                       goto unlock;
+
                if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain))
                        goto unlock;
 
@@ -3223,12 +3280,9 @@ unsigned int create_irq_nr(unsigned int irq_want, int node)
        }
        raw_spin_unlock_irqrestore(&vector_lock, flags);
 
-       if (irq > 0) {
-               dynamic_irq_init(irq);
-               /* restore it, in case dynamic_irq_init clear it */
-               if (desc_new)
-                       desc_new->chip_data = cfg_new;
-       }
+       if (irq > 0)
+               dynamic_irq_init_keep_chip_data(irq);
+
        return irq;
 }
 
@@ -3250,19 +3304,12 @@ int create_irq(void)
 void destroy_irq(unsigned int irq)
 {
        unsigned long flags;
-       struct irq_cfg *cfg;
-       struct irq_desc *desc;
 
-       /* store it, in case dynamic_irq_cleanup clear it */
-       desc = irq_to_desc(irq);
-       cfg = desc->chip_data;
-       dynamic_irq_cleanup(irq);
-       /* connect back irq_cfg */
-       desc->chip_data = cfg;
+       dynamic_irq_cleanup_keep_chip_data(irq);
 
        free_irte(irq);
        raw_spin_lock_irqsave(&vector_lock, flags);
-       __clear_irq_vector(irq, cfg);
+       __clear_irq_vector(irq, get_irq_chip_data(irq));
        raw_spin_unlock_irqrestore(&vector_lock, flags);
 }
 
@@ -3829,28 +3876,6 @@ void __init probe_nr_irqs_gsi(void)
        printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi);
 }
 
-#ifdef CONFIG_SPARSE_IRQ
-int __init arch_probe_nr_irqs(void)
-{
-       int nr;
-
-       if (nr_irqs > (NR_VECTORS * nr_cpu_ids))
-               nr_irqs = NR_VECTORS * nr_cpu_ids;
-
-       nr = nr_irqs_gsi + 8 * nr_cpu_ids;
-#if defined(CONFIG_PCI_MSI) || defined(CONFIG_HT_IRQ)
-       /*
-        * for MSI and HT dyn irq
-        */
-       nr += nr_irqs_gsi * 64;
-#endif
-       if (nr < nr_irqs)
-               nr_irqs = nr;
-
-       return 0;
-}
-#endif
-
 static int __io_apic_set_pci_routing(struct device *dev, int irq,
                                struct io_apic_irq_attr *irq_attr)
 {