From 1e031d65b0cb5f882b20ebc356ea0345ff18dbf0 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 4 Jul 2006 14:09:36 +1000 Subject: [POWERPC] Fix non-MPIC CHRPs with CONFIG_SMP set Pseudo-CHRP machines like Pegasos without an MPIC would crash at boot if CONFIG_SMP was set because the "smp_ops" pointer was set to MPIC related ops unconditionally. This patch makes it NULL on machines that don't support SMP and provides proper default behaviour in the callers when smp_ops is NULL. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/smp.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 46c56cfd1b2..6a9bc9ce54e 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -144,13 +144,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 @@ -158,7 +160,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); } @@ -220,6 +222,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); @@ -357,7 +362,10 @@ 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); @@ -453,7 +461,7 @@ 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; @@ -467,7 +475,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 @@ -568,7 +577,8 @@ 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); -- cgit v1.2.3