x86/irq: Initialize PCI/MSI domain at PCI init time
[linux-2.6-microblaze.git] / arch / x86 / kernel / apic / vector.c
index dae32d9..1eac536 100644 (file)
@@ -161,6 +161,7 @@ static void apic_update_vector(struct irq_data *irqd, unsigned int newvec,
                apicd->move_in_progress = true;
                apicd->prev_vector = apicd->vector;
                apicd->prev_cpu = apicd->cpu;
+               WARN_ON_ONCE(apicd->cpu == newcpu);
        } else {
                irq_matrix_free(vector_matrix, apicd->cpu, apicd->vector,
                                managed);
@@ -713,8 +714,6 @@ int __init arch_early_irq_init(void)
        BUG_ON(x86_vector_domain == NULL);
        irq_set_default_host(x86_vector_domain);
 
-       arch_init_msi_domain(x86_vector_domain);
-
        BUG_ON(!alloc_cpumask_var(&vector_searchmask, GFP_KERNEL));
 
        /*
@@ -823,6 +822,7 @@ static struct irq_chip lapic_controller = {
        .name                   = "APIC",
        .irq_ack                = apic_ack_edge,
        .irq_set_affinity       = apic_set_affinity,
+       .irq_compose_msi_msg    = x86_vector_msi_compose_msg,
        .irq_retrigger          = apic_retrigger_irq,
 };
 
@@ -910,7 +910,7 @@ void send_cleanup_vector(struct irq_cfg *cfg)
                __send_cleanup_vector(apicd);
 }
 
-static void __irq_complete_move(struct irq_cfg *cfg, unsigned vector)
+void irq_complete_move(struct irq_cfg *cfg)
 {
        struct apic_chip_data *apicd;
 
@@ -918,15 +918,16 @@ static void __irq_complete_move(struct irq_cfg *cfg, unsigned vector)
        if (likely(!apicd->move_in_progress))
                return;
 
-       if (vector == apicd->vector && apicd->cpu == smp_processor_id())
+       /*
+        * If the interrupt arrived on the new target CPU, cleanup the
+        * vector on the old target CPU. A vector check is not required
+        * because an interrupt can never move from one vector to another
+        * on the same CPU.
+        */
+       if (apicd->cpu == smp_processor_id())
                __send_cleanup_vector(apicd);
 }
 
-void irq_complete_move(struct irq_cfg *cfg)
-{
-       __irq_complete_move(cfg, ~get_irq_regs()->orig_ax);
-}
-
 /*
  * Called from fixup_irqs() with @desc->lock held and interrupts disabled.
  */