Merge ../linux-2.6-watchdog-mm
[linux-drm-fsl-dcu.git] / arch / x86_64 / kernel / smpboot.c
index 540c0ccbcccc8953c95ee6b6c2baf5ad11e44aaf..62c2e747af58006a917d279150254a280aa9f364 100644 (file)
@@ -38,7 +38,6 @@
  */
 
 
-#include <linux/config.h>
 #include <linux/init.h>
 
 #include <linux/mm.h>
 #include <linux/bootmem.h>
 #include <linux/thread_info.h>
 #include <linux/module.h>
-
 #include <linux/delay.h>
 #include <linux/mc146818rtc.h>
+#include <linux/smp.h>
+
 #include <asm/mtrr.h>
 #include <asm/pgalloc.h>
 #include <asm/desc.h>
@@ -581,12 +581,16 @@ void __cpuinit start_secondary(void)
         * smp_call_function().
         */
        lock_ipi_call_lock();
+       spin_lock(&vector_lock);
 
+       /* Setup the per cpu irq handling data structures */
+       __setup_vector_irq(smp_processor_id());
        /*
         * Allow the master to continue.
         */
        cpu_set(smp_processor_id(), cpu_online_map);
        per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
+       spin_unlock(&vector_lock);
        unlock_ipi_call_lock();
 
        cpu_idle();
@@ -772,7 +776,7 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid)
        unsigned long start_rip;
        struct create_idle c_idle = {
                .cpu = cpu,
-               .done = COMPLETION_INITIALIZER(c_idle.done),
+               .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
        };
        DECLARE_WORK(work, do_fork_idle, &c_idle);
 
@@ -799,7 +803,6 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid)
                                cpu, node);
        }
 
-
        alternatives_smp_switch(1);
 
        c_idle.idle = get_idle_for_cpu(cpu);
@@ -1091,7 +1094,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
        /*
         * Switch from PIC to APIC mode.
         */
-       connect_bsp_APIC();
        setup_local_APIC();
 
        if (GET_APIC_ID(apic_read(APIC_ID)) != boot_cpu_id) {
@@ -1176,12 +1178,9 @@ int __cpuinit __cpu_up(unsigned int cpu)
 void __init smp_cpus_done(unsigned int max_cpus)
 {
        smp_cleanup_boot();
-
-#ifdef CONFIG_X86_IO_APIC
        setup_ioapic_dest();
-#endif
-
        check_nmi_watchdog();
+       time_init_gtod();
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
@@ -1234,6 +1233,8 @@ int __cpu_disable(void)
        if (cpu == 0)
                return -EBUSY;
 
+       if (nmi_watchdog == NMI_LOCAL_APIC)
+               stop_apic_nmi_watchdog(NULL);
        clear_local_APIC();
 
        /*
@@ -1248,8 +1249,10 @@ int __cpu_disable(void)
        local_irq_disable();
        remove_siblinginfo(cpu);
 
+       spin_lock(&vector_lock);
        /* It's now safe to remove this processor from the online map */
        cpu_clear(cpu, cpu_online_map);
+       spin_unlock(&vector_lock);
        remove_cpu_from_maps();
        fixup_irqs(cpu_online_map);
        return 0;
@@ -1273,11 +1276,11 @@ void __cpu_die(unsigned int cpu)
        printk(KERN_ERR "CPU %u didn't die...\n", cpu);
 }
 
-__init int setup_additional_cpus(char *s)
+static __init int setup_additional_cpus(char *s)
 {
-       return get_option(&s, &additional_cpus);
+       return s && get_option(&s, &additional_cpus) ? 0 : -EINVAL;
 }
-__setup("additional_cpus=", setup_additional_cpus);
+early_param("additional_cpus", setup_additional_cpus);
 
 #else /* ... !CONFIG_HOTPLUG_CPU */