diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2006-07-04 00:09:36 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-07-25 11:27:04 -0400 |
commit | 8cffc6ac66a2b251df2490702923611aa4ac1fc5 (patch) | |
tree | 7ae7509d009739702cab10441a61c4c36c5913a8 | |
parent | 21bd2e6696bb5c8b32b00a0ea597f49bfda0ddc6 (diff) |
[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 <benh@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r-- | arch/powerpc/kernel/smp.c | 24 | ||||
-rw-r--r-- | arch/powerpc/platforms/chrp/setup.c | 12 |
2 files changed, 25 insertions, 11 deletions
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 46c56cfd1b2f..6a9bc9ce54e0 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) | |||
144 | 144 | ||
145 | void smp_send_reschedule(int cpu) | 145 | void smp_send_reschedule(int cpu) |
146 | { | 146 | { |
147 | smp_ops->message_pass(cpu, PPC_MSG_RESCHEDULE); | 147 | if (likely(smp_ops)) |
148 | smp_ops->message_pass(cpu, PPC_MSG_RESCHEDULE); | ||
148 | } | 149 | } |
149 | 150 | ||
150 | #ifdef CONFIG_DEBUGGER | 151 | #ifdef CONFIG_DEBUGGER |
151 | void smp_send_debugger_break(int cpu) | 152 | void smp_send_debugger_break(int cpu) |
152 | { | 153 | { |
153 | smp_ops->message_pass(cpu, PPC_MSG_DEBUGGER_BREAK); | 154 | if (likely(smp_ops)) |
155 | smp_ops->message_pass(cpu, PPC_MSG_DEBUGGER_BREAK); | ||
154 | } | 156 | } |
155 | #endif | 157 | #endif |
156 | 158 | ||
@@ -158,7 +160,7 @@ void smp_send_debugger_break(int cpu) | |||
158 | void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *)) | 160 | void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *)) |
159 | { | 161 | { |
160 | crash_ipi_function_ptr = crash_ipi_callback; | 162 | crash_ipi_function_ptr = crash_ipi_callback; |
161 | if (crash_ipi_callback) { | 163 | if (crash_ipi_callback && smp_ops) { |
162 | mb(); | 164 | mb(); |
163 | smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_DEBUGGER_BREAK); | 165 | smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_DEBUGGER_BREAK); |
164 | } | 166 | } |
@@ -220,6 +222,9 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic, | |||
220 | /* Can deadlock when called with interrupts disabled */ | 222 | /* Can deadlock when called with interrupts disabled */ |
221 | WARN_ON(irqs_disabled()); | 223 | WARN_ON(irqs_disabled()); |
222 | 224 | ||
225 | if (unlikely(smp_ops == NULL)) | ||
226 | return -1; | ||
227 | |||
223 | data.func = func; | 228 | data.func = func; |
224 | data.info = info; | 229 | data.info = info; |
225 | atomic_set(&data.started, 0); | 230 | atomic_set(&data.started, 0); |
@@ -357,7 +362,10 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
357 | smp_store_cpu_info(boot_cpuid); | 362 | smp_store_cpu_info(boot_cpuid); |
358 | cpu_callin_map[boot_cpuid] = 1; | 363 | cpu_callin_map[boot_cpuid] = 1; |
359 | 364 | ||
360 | max_cpus = smp_ops->probe(); | 365 | if (smp_ops) |
366 | max_cpus = smp_ops->probe(); | ||
367 | else | ||
368 | max_cpus = 1; | ||
361 | 369 | ||
362 | smp_space_timers(max_cpus); | 370 | smp_space_timers(max_cpus); |
363 | 371 | ||
@@ -453,7 +461,7 @@ void generic_mach_cpu_die(void) | |||
453 | 461 | ||
454 | static int __devinit cpu_enable(unsigned int cpu) | 462 | static int __devinit cpu_enable(unsigned int cpu) |
455 | { | 463 | { |
456 | if (smp_ops->cpu_enable) | 464 | if (smp_ops && smp_ops->cpu_enable) |
457 | return smp_ops->cpu_enable(cpu); | 465 | return smp_ops->cpu_enable(cpu); |
458 | 466 | ||
459 | return -ENOSYS; | 467 | return -ENOSYS; |
@@ -467,7 +475,8 @@ int __devinit __cpu_up(unsigned int cpu) | |||
467 | if (!cpu_enable(cpu)) | 475 | if (!cpu_enable(cpu)) |
468 | return 0; | 476 | return 0; |
469 | 477 | ||
470 | if (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu)) | 478 | if (smp_ops == NULL || |
479 | (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu))) | ||
471 | return -EINVAL; | 480 | return -EINVAL; |
472 | 481 | ||
473 | /* Make sure callin-map entry is 0 (can be leftover a CPU | 482 | /* 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) | |||
568 | old_mask = current->cpus_allowed; | 577 | old_mask = current->cpus_allowed; |
569 | set_cpus_allowed(current, cpumask_of_cpu(boot_cpuid)); | 578 | set_cpus_allowed(current, cpumask_of_cpu(boot_cpuid)); |
570 | 579 | ||
571 | smp_ops->setup_cpu(boot_cpuid); | 580 | if (smp_ops) |
581 | smp_ops->setup_cpu(boot_cpuid); | ||
572 | 582 | ||
573 | set_cpus_allowed(current, old_mask); | 583 | set_cpus_allowed(current, old_mask); |
574 | 584 | ||
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index 538e337d63e2..9c08ff322290 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c | |||
@@ -291,10 +291,6 @@ void __init chrp_setup_arch(void) | |||
291 | 291 | ||
292 | pci_create_OF_bus_map(); | 292 | pci_create_OF_bus_map(); |
293 | 293 | ||
294 | #ifdef CONFIG_SMP | ||
295 | smp_ops = &chrp_smp_ops; | ||
296 | #endif /* CONFIG_SMP */ | ||
297 | |||
298 | /* | 294 | /* |
299 | * Print the banner, then scroll down so boot progress | 295 | * Print the banner, then scroll down so boot progress |
300 | * can be printed. -- Cort | 296 | * can be printed. -- Cort |
@@ -479,6 +475,14 @@ void __init chrp_init_IRQ(void) | |||
479 | chrp_find_openpic(); | 475 | chrp_find_openpic(); |
480 | chrp_find_8259(); | 476 | chrp_find_8259(); |
481 | 477 | ||
478 | #ifdef CONFIG_SMP | ||
479 | /* Pegasos has no MPIC, those ops would make it crash. It might be an | ||
480 | * option to move setting them to after we probe the PIC though | ||
481 | */ | ||
482 | if (chrp_mpic != NULL) | ||
483 | smp_ops = &chrp_smp_ops; | ||
484 | #endif /* CONFIG_SMP */ | ||
485 | |||
482 | if (_chrp_type == _CHRP_Pegasos) | 486 | if (_chrp_type == _CHRP_Pegasos) |
483 | ppc_md.get_irq = i8259_irq; | 487 | ppc_md.get_irq = i8259_irq; |
484 | 488 | ||