fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / arch / powerpc / kernel / smp.c
index 13595a6..0e8beca 100644 (file)
@@ -17,7 +17,6 @@
 
 #undef DEBUG
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/sched.h>
@@ -66,6 +65,7 @@ cpumask_t cpu_sibling_map[NR_CPUS] = { [0 ... NR_CPUS-1] = CPU_MASK_NONE };
 
 EXPORT_SYMBOL(cpu_online_map);
 EXPORT_SYMBOL(cpu_possible_map);
+EXPORT_SYMBOL(cpu_sibling_map);
 
 /* SMP operations for this machine */
 struct smp_ops_t *smp_ops;
@@ -116,7 +116,7 @@ void __devinit smp_generic_kick_cpu(int nr)
 }
 #endif
 
-void smp_message_recv(int msg, struct pt_regs *regs)
+void smp_message_recv(int msg)
 {
        switch(msg) {
        case PPC_MSG_CALL_FUNCTION:
@@ -128,11 +128,11 @@ void smp_message_recv(int msg, struct pt_regs *regs)
                break;
        case PPC_MSG_DEBUGGER_BREAK:
                if (crash_ipi_function_ptr) {
-                       crash_ipi_function_ptr(regs);
+                       crash_ipi_function_ptr(get_irq_regs());
                        break;
                }
 #ifdef CONFIG_DEBUGGER
-               debugger_ipi(regs);
+               debugger_ipi(get_irq_regs());
                break;
 #endif /* CONFIG_DEBUGGER */
                /* FALLTHROUGH */
@@ -145,13 +145,15 @@ void smp_message_recv(int msg, struct pt_regs *regs)
 
 void smp_send_reschedule(int cpu)
 {
-       smp_ops->message_pass(cpu, PPC_MSG_RESCHEDULE);
+       if (likely(smp_ops))
+               smp_ops->message_pass(cpu, PPC_MSG_RESCHEDULE);
 }
 
 #ifdef CONFIG_DEBUGGER
 void smp_send_debugger_break(int cpu)
 {
-       smp_ops->message_pass(cpu, PPC_MSG_DEBUGGER_BREAK);
+       if (likely(smp_ops))
+               smp_ops->message_pass(cpu, PPC_MSG_DEBUGGER_BREAK);
 }
 #endif
 
@@ -159,7 +161,7 @@ void smp_send_debugger_break(int cpu)
 void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *))
 {
        crash_ipi_function_ptr = crash_ipi_callback;
-       if (crash_ipi_callback) {
+       if (crash_ipi_callback && smp_ops) {
                mb();
                smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_DEBUGGER_BREAK);
        }
@@ -221,6 +223,9 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
        /* Can deadlock when called with interrupts disabled */
        WARN_ON(irqs_disabled());
 
+       if (unlikely(smp_ops == NULL))
+               return -1;
+
        data.func = func;
        data.info = info;
        atomic_set(&data.started, 0);
@@ -358,11 +363,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
        smp_store_cpu_info(boot_cpuid);
        cpu_callin_map[boot_cpuid] = 1;
 
-       max_cpus = smp_ops->probe();
+       if (smp_ops)
+               max_cpus = smp_ops->probe();
+       else
+               max_cpus = 1;
  
        smp_space_timers(max_cpus);
 
-       for_each_cpu(cpu)
+       for_each_possible_cpu(cpu)
                if (cpu != boot_cpuid)
                        smp_create_idle(cpu);
 }
@@ -454,13 +462,13 @@ void generic_mach_cpu_die(void)
 
 static int __devinit cpu_enable(unsigned int cpu)
 {
-       if (smp_ops->cpu_enable)
+       if (smp_ops && smp_ops->cpu_enable)
                return smp_ops->cpu_enable(cpu);
 
        return -ENOSYS;
 }
 
-int __devinit __cpu_up(unsigned int cpu)
+int __cpuinit __cpu_up(unsigned int cpu)
 {
        int c;
 
@@ -468,7 +476,8 @@ int __devinit __cpu_up(unsigned int cpu)
        if (!cpu_enable(cpu))
                return 0;
 
-       if (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu))
+       if (smp_ops == NULL ||
+           (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu)))
                return -EINVAL;
 
        /* Make sure callin-map entry is 0 (can be leftover a CPU
@@ -492,7 +501,7 @@ int __devinit __cpu_up(unsigned int cpu)
         * -- Cort
         */
        if (system_state < SYSTEM_RUNNING)
-               for (c = 5000; c && !cpu_callin_map[cpu]; c--)
+               for (c = 50000; c && !cpu_callin_map[cpu]; c--)
                        udelay(100);
 #ifdef CONFIG_HOTPLUG_CPU
        else
@@ -541,7 +550,7 @@ int __devinit start_secondary(void *unused)
                smp_ops->take_timebase();
 
        if (system_state > SYSTEM_BOOTING)
-               per_cpu(last_jiffy, cpu) = get_tb();
+               snapshot_timebase();
 
        spin_lock(&call_lock);
        cpu_set(cpu, cpu_online_map);
@@ -569,10 +578,13 @@ void __init smp_cpus_done(unsigned int max_cpus)
        old_mask = current->cpus_allowed;
        set_cpus_allowed(current, cpumask_of_cpu(boot_cpuid));
        
-       smp_ops->setup_cpu(boot_cpuid);
+       if (smp_ops)
+               smp_ops->setup_cpu(boot_cpuid);
 
        set_cpus_allowed(current, old_mask);
 
+       snapshot_timebases();
+
        dump_numa_cpu_topology();
 }