summaryrefslogtreecommitdiff
path: root/arch/powerpc/platforms/85xx/smp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/85xx/smp.c')
-rw-r--r--arch/powerpc/platforms/85xx/smp.c42
1 files changed, 24 insertions, 18 deletions
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c
index d6a93a10c0f5..2df4785ffd4e 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -2,7 +2,7 @@
* Author: Andy Fleming <afleming@freescale.com>
* Kumar Gala <galak@kernel.crashing.org>
*
- * Copyright 2006-2008 Freescale Semiconductor Inc.
+ * Copyright 2006-2008, 2011 Freescale Semiconductor Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -48,10 +48,11 @@ smp_85xx_kick_cpu(int nr)
const u64 *cpu_rel_addr;
__iomem u32 *bptr_vaddr;
struct device_node *np;
- int n = 0;
+ int n = 0, hw_cpu = get_hard_smp_processor_id(nr);
int ioremappable;
- WARN_ON (nr < 0 || nr >= NR_CPUS);
+ WARN_ON(nr < 0 || nr >= NR_CPUS);
+ WARN_ON(hw_cpu < 0 || hw_cpu >= NR_CPUS);
pr_debug("smp_85xx_kick_cpu: kick CPU #%d\n", nr);
@@ -79,7 +80,7 @@ smp_85xx_kick_cpu(int nr)
local_irq_save(flags);
- out_be32(bptr_vaddr + BOOT_ENTRY_PIR, nr);
+ out_be32(bptr_vaddr + BOOT_ENTRY_PIR, hw_cpu);
#ifdef CONFIG_PPC32
out_be32(bptr_vaddr + BOOT_ENTRY_ADDR_LOWER, __pa(__early_start));
@@ -88,7 +89,7 @@ smp_85xx_kick_cpu(int nr)
(ulong)(bptr_vaddr + SIZE_BOOT_ENTRY));
/* Wait a bit for the CPU to ack. */
- while ((__secondary_hold_acknowledge != nr) && (++n < 1000))
+ while ((__secondary_hold_acknowledge != hw_cpu) && (++n < 1000))
mdelay(1);
#else
smp_generic_kick_cpu(nr);
@@ -111,14 +112,6 @@ smp_85xx_kick_cpu(int nr)
return 0;
}
-static void __init
-smp_85xx_setup_cpu(int cpu_nr)
-{
- mpic_setup_this_cpu();
- if (cpu_has_feature(CPU_FTR_DBELL))
- doorbell_setup_this_cpu();
-}
-
struct smp_ops_t smp_85xx_ops = {
.kick_cpu = smp_85xx_kick_cpu,
#ifdef CONFIG_KEXEC
@@ -214,7 +207,7 @@ static void mpc85xx_smp_machine_kexec(struct kimage *image)
if ( !timeout )
printk(KERN_ERR "Unable to bring down secondary cpu(s)");
- for (i = 0; i < num_cpus; i++)
+ for_each_online_cpu(i)
{
if ( i == smp_processor_id() ) continue;
mpic_reset_core(i);
@@ -224,24 +217,37 @@ static void mpc85xx_smp_machine_kexec(struct kimage *image)
}
#endif /* CONFIG_KEXEC */
+static void __init
+smp_85xx_setup_cpu(int cpu_nr)
+{
+ if (smp_85xx_ops.probe == smp_mpic_probe)
+ mpic_setup_this_cpu();
+
+ if (cpu_has_feature(CPU_FTR_DBELL))
+ doorbell_setup_this_cpu();
+}
+
void __init mpc85xx_smp_init(void)
{
struct device_node *np;
+ smp_85xx_ops.setup_cpu = smp_85xx_setup_cpu;
+
np = of_find_node_by_type(NULL, "open-pic");
if (np) {
smp_85xx_ops.probe = smp_mpic_probe;
- smp_85xx_ops.setup_cpu = smp_85xx_setup_cpu;
smp_85xx_ops.message_pass = smp_mpic_message_pass;
}
if (cpu_has_feature(CPU_FTR_DBELL)) {
- smp_85xx_ops.message_pass = smp_muxed_ipi_message_pass;
+ /*
+ * If left NULL, .message_pass defaults to
+ * smp_muxed_ipi_message_pass
+ */
+ smp_85xx_ops.message_pass = NULL;
smp_85xx_ops.cause_ipi = doorbell_cause_ipi;
}
- BUG_ON(!smp_85xx_ops.message_pass);
-
smp_ops = &smp_85xx_ops;
#ifdef CONFIG_KEXEC