vserver 1.9.5.x5
[linux-2.6.git] / arch / ppc64 / kernel / pSeries_smp.c
index 6eba926..27ab1ed 100644 (file)
@@ -19,9 +19,7 @@
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/smp.h>
-#include <asm/naca.h>
 #include <asm/paca.h>
 #include <asm/time.h>
-#include <asm/ppcdebug.h>
 #include <asm/machdep.h>
 #include <asm/xics.h>
 #include <asm/cputable.h>
@@ -57,7 +53,7 @@
 #define DBG(fmt...)
 #endif
 
-extern void pseries_secondary_smp_init(unsigned long); 
+extern void pSeries_secondary_smp_init(unsigned long);
 
 /* Get state of physical CPU.
  * Return codes:
@@ -88,11 +84,8 @@ static int query_cpu_stopped(unsigned int pcpu)
 
 #ifdef CONFIG_HOTPLUG_CPU
 
-int __cpu_disable(void)
+int pSeries_cpu_disable(void)
 {
-       /* FIXME: go put this in a header somewhere */
-       extern void xics_migrate_irqs_away(void);
-
        systemcfg->processorCount--;
 
        /*fix boot_cpuid here*/
@@ -104,7 +97,7 @@ int __cpu_disable(void)
        return 0;
 }
 
-void __cpu_die(unsigned int cpu)
+void pSeries_cpu_die(unsigned int cpu)
 {
        int tries;
        int cpu_status;
@@ -114,8 +107,7 @@ void __cpu_die(unsigned int cpu)
                cpu_status = query_cpu_stopped(pcpu);
                if (cpu_status == 0 || cpu_status == -1)
                        break;
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(HZ/5);
+               msleep(200);
        }
        if (cpu_status != 0) {
                printk("Querying DEAD? cpu %i (%i) shows %i\n",
@@ -193,7 +185,7 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu)
 {
        int status;
        unsigned long start_here = __pa((u32)*((unsigned long *)
-                                              pseries_secondary_smp_init));
+                                              pSeries_secondary_smp_init));
        unsigned int pcpu;
 
        /* At boot time the cpus are already spinning in hold
@@ -251,8 +243,6 @@ static void smp_xics_message_pass(int target, int msg)
        }
 }
 
-extern void xics_request_IPIs(void);
-
 static int __init smp_xics_probe(void)
 {
        xics_request_IPIs();
@@ -264,9 +254,20 @@ static void __devinit smp_xics_setup_cpu(int cpu)
 {
        if (cpu != boot_cpuid)
                xics_setup_cpu();
+
+       if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR)
+               vpa_init(cpu);
+
+       /*
+        * Put the calling processor into the GIQ.  This is really only
+        * necessary from a secondary thread as the OF start-cpu interface
+        * performs this function for us on primary threads.
+        */
+       rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
+               (1UL << interrupt_server_size) - 1 - default_distrib_server, 1);
 }
 
-static spinlock_t timebase_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(timebase_lock);
 static unsigned long timebase = 0;
 
 static void __devinit pSeries_give_timebase(void)
@@ -291,26 +292,7 @@ static void __devinit pSeries_take_timebase(void)
        spin_unlock(&timebase_lock);
 }
 
-static void __devinit pSeries_late_setup_cpu(int cpu)
-{
-       extern unsigned int default_distrib_server;
-
-       if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) {
-               vpa_init(cpu); 
-       }
-
-#ifdef CONFIG_IRQ_ALL_CPUS
-       /* Put the calling processor into the GIQ.  This is really only
-        * necessary from a secondary thread as the OF start-cpu interface
-        * performs this function for us on primary threads.
-        */
-       /* TODO: 9005 is #defined in rtas-proc.c -- move to a header */
-       rtas_set_indicator(9005, default_distrib_server, 1);
-#endif
-}
-
-
-void __devinit smp_pSeries_kick_cpu(int nr)
+static void __devinit smp_pSeries_kick_cpu(int nr)
 {
        BUG_ON(nr < 0 || nr >= NR_CPUS);
 
@@ -330,7 +312,6 @@ static struct smp_ops_t pSeries_mpic_smp_ops = {
        .probe          = smp_mpic_probe,
        .kick_cpu       = smp_pSeries_kick_cpu,
        .setup_cpu      = smp_mpic_setup_cpu,
-       .late_setup_cpu = pSeries_late_setup_cpu,
 };
 
 static struct smp_ops_t pSeries_xics_smp_ops = {
@@ -338,7 +319,6 @@ static struct smp_ops_t pSeries_xics_smp_ops = {
        .probe          = smp_xics_probe,
        .kick_cpu       = smp_pSeries_kick_cpu,
        .setup_cpu      = smp_xics_setup_cpu,
-       .late_setup_cpu = pSeries_late_setup_cpu,
 };
 
 /* This is called very early */
@@ -348,11 +328,16 @@ void __init smp_init_pSeries(void)
 
        DBG(" -> smp_init_pSeries()\n");
 
-       if (naca->interrupt_controller == IC_OPEN_PIC)
+       if (ppc64_interrupt_controller == IC_OPEN_PIC)
                smp_ops = &pSeries_mpic_smp_ops;
        else
                smp_ops = &pSeries_xics_smp_ops;
 
+#ifdef CONFIG_HOTPLUG_CPU
+       smp_ops->cpu_disable = pSeries_cpu_disable;
+       smp_ops->cpu_die = pSeries_cpu_die;
+#endif
+
        /* Start secondary threads on SMT systems; primary threads
         * are already in the running state.
         */
@@ -363,14 +348,11 @@ void __init smp_init_pSeries(void)
                        rtas_call(rtas_token("start-cpu"), 3, 1, &ret,
                                  get_hard_smp_processor_id(i),
                                  __pa((u32)*((unsigned long *)
-                                             pseries_secondary_smp_init)),
+                                             pSeries_secondary_smp_init)),
                                  i);
                }
        }
 
-       if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR)
-               vpa_init(boot_cpuid);
-
        /* Non-lpar has additional take/give timebase */
        if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) {
                smp_ops->give_timebase = pSeries_give_timebase;