Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
[pandora-kernel.git] / arch / x86 / kernel / smpboot.c
index af57f88..ef7d101 100644 (file)
 #include <asm/tlbflush.h>
 #include <asm/mtrr.h>
 #include <asm/vmi.h>
-#include <asm/genapic.h>
+#include <asm/apic.h>
 #include <asm/setup.h>
 #include <asm/uv/uv.h>
 #include <linux/mc146818rtc.h>
 
-#include <asm/genapic.h>
 #include <asm/smpboot_hooks.h>
 
 #ifdef CONFIG_X86_32
@@ -113,11 +112,7 @@ EXPORT_PER_CPU_SYMBOL(cpu_core_map);
 DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info);
 EXPORT_PER_CPU_SYMBOL(cpu_info);
 
-static atomic_t init_deasserted;
-
-
-/* Set if we find a B stepping CPU */
-static int __cpuinitdata smp_b_stepping;
+atomic_t init_deasserted;
 
 #if defined(CONFIG_NUMA) && defined(CONFIG_X86_32)
 
@@ -272,8 +267,6 @@ static void __cpuinit smp_callin(void)
        cpumask_set_cpu(cpuid, cpu_callin_mask);
 }
 
-static int __cpuinitdata unsafe_smp;
-
 /*
  * Activate a secondary processor.
  */
@@ -341,76 +334,6 @@ notrace static void __cpuinit start_secondary(void *unused)
        cpu_idle();
 }
 
-static void __cpuinit smp_apply_quirks(struct cpuinfo_x86 *c)
-{
-       /*
-        * Mask B, Pentium, but not Pentium MMX
-        */
-       if (c->x86_vendor == X86_VENDOR_INTEL &&
-           c->x86 == 5 &&
-           c->x86_mask >= 1 && c->x86_mask <= 4 &&
-           c->x86_model <= 3)
-               /*
-                * Remember we have B step Pentia with bugs
-                */
-               smp_b_stepping = 1;
-
-       /*
-        * Certain Athlons might work (for various values of 'work') in SMP
-        * but they are not certified as MP capable.
-        */
-       if ((c->x86_vendor == X86_VENDOR_AMD) && (c->x86 == 6)) {
-
-               if (num_possible_cpus() == 1)
-                       goto valid_k7;
-
-               /* Athlon 660/661 is valid. */
-               if ((c->x86_model == 6) && ((c->x86_mask == 0) ||
-                   (c->x86_mask == 1)))
-                       goto valid_k7;
-
-               /* Duron 670 is valid */
-               if ((c->x86_model == 7) && (c->x86_mask == 0))
-                       goto valid_k7;
-
-               /*
-                * Athlon 662, Duron 671, and Athlon >model 7 have capability
-                * bit. It's worth noting that the A5 stepping (662) of some
-                * Athlon XP's have the MP bit set.
-                * See http://www.heise.de/newsticker/data/jow-18.10.01-000 for
-                * more.
-                */
-               if (((c->x86_model == 6) && (c->x86_mask >= 2)) ||
-                   ((c->x86_model == 7) && (c->x86_mask >= 1)) ||
-                    (c->x86_model > 7))
-                       if (cpu_has_mp)
-                               goto valid_k7;
-
-               /* If we get here, not a certified SMP capable AMD system. */
-               unsafe_smp = 1;
-       }
-
-valid_k7:
-       ;
-}
-
-static void __cpuinit smp_checks(void)
-{
-       if (smp_b_stepping)
-               printk(KERN_WARNING "WARNING: SMP operation may be unreliable"
-                                   "with B stepping processors.\n");
-
-       /*
-        * Don't taint if we are running SMP kernel on a single non-MP
-        * approved Athlon
-        */
-       if (unsafe_smp && num_online_cpus() > 1) {
-               printk(KERN_INFO "WARNING: This combination of AMD"
-                       "processors is not suitable for SMP.\n");
-               add_taint(TAINT_UNSAFE_SMP);
-       }
-}
-
 /*
  * The bootstrap kernel entry code has set these up. Save them for
  * a given CPU
@@ -424,7 +347,6 @@ void __cpuinit smp_store_cpu_info(int id)
        c->cpu_index = id;
        if (id != 0)
                identify_secondary_cpu(c);
-       smp_apply_quirks(c);
 }
 
 
@@ -615,12 +537,6 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip)
        unsigned long send_status, accept_status = 0;
        int maxlvt, num_starts, j;
 
-       if (get_uv_system_type() == UV_NON_UNIQUE_APIC) {
-               send_status = uv_wakeup_secondary(phys_apicid, start_eip);
-               atomic_set(&init_deasserted, 1);
-               return send_status;
-       }
-
        maxlvt = lapic_get_maxlvt();
 
        /*
@@ -746,21 +662,22 @@ static void __cpuinit do_fork_idle(struct work_struct *work)
        complete(&c_idle->done);
 }
 
-static int __cpuinit do_boot_cpu(int apicid, int cpu)
 /*
  * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad
  * (ie clustered apic addressing mode), this is a LOGICAL apic ID.
- * Returns zero if CPU booted OK, else error code from ->wakeup_cpu.
+ * Returns zero if CPU booted OK, else error code from
+ * ->wakeup_secondary_cpu.
  */
+static int __cpuinit do_boot_cpu(int apicid, int cpu)
 {
        unsigned long boot_error = 0;
-       int timeout;
        unsigned long start_ip;
-       unsigned short nmi_high = 0, nmi_low = 0;
+       int timeout;
        struct create_idle c_idle = {
-               .cpu = cpu,
-               .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
+               .cpu    = cpu,
+               .done   = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
        };
+
        INIT_WORK(&c_idle.work, do_fork_idle);
 
        alternatives_smp_switch(1);
@@ -825,9 +742,6 @@ do_rest:
 
                pr_debug("Setting warm reset code and vector.\n");
 
-               if (apic->store_NMI_vector)
-                       apic->store_NMI_vector(&nmi_high, &nmi_low);
-
                smpboot_setup_warm_reset_vector(start_ip);
                /*
                 * Be paranoid about clearing APIC errors.
@@ -839,9 +753,13 @@ do_rest:
        }
 
        /*
-        * Starting actual IPI sequence...
+        * Kick the secondary CPU. Use the method in the APIC driver
+        * if it's defined - or use an INIT boot APIC message otherwise:
         */
-       boot_error = apic->wakeup_cpu(apicid, start_ip);
+       if (apic->wakeup_secondary_cpu)
+               boot_error = apic->wakeup_secondary_cpu(apicid, start_ip);
+       else
+               boot_error = wakeup_secondary_cpu_via_init(apicid, start_ip);
 
        if (!boot_error) {
                /*
@@ -1128,8 +1046,8 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
        current_thread_info()->cpu = 0;  /* needed? */
        set_cpu_sibling_map(0);
 
-#ifdef CONFIG_X86_64
        enable_IR_x2apic();
+#ifdef CONFIG_X86_64
        default_setup_apic_routing();
 #endif
 
@@ -1154,13 +1072,12 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
         */
        setup_local_APIC();
 
-#ifdef CONFIG_X86_64
        /*
         * Enable IO APIC before setting up error vector
         */
        if (!skip_ioapic_setup && nr_ioapics)
                enable_IO_APIC();
-#endif
+
        end_local_APIC_setup();
 
        map_cpu_to_logical_apicid();
@@ -1199,7 +1116,6 @@ void __init native_smp_cpus_done(unsigned int max_cpus)
        pr_debug("Boot done.\n");
 
        impress_friends();
-       smp_checks();
 #ifdef CONFIG_X86_IO_APIC
        setup_ioapic_dest();
 #endif