summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2005-11-10 14:26:12 +1100
committerPaul Mackerras <paulus@samba.org>2005-11-10 14:26:12 +1100
commit094fe2e712f38f49bf79ef93306c61b1b993b07b (patch)
tree8a01db1e3bdde65982eba66b1336c24aee329bdc
parent0a5cab42a1317326d87b0d074df50705a0c3fa77 (diff)
powerpc: Fixes for 32-bit powermac SMP
A couple of bugs crept in with the merge of smp.c... Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--arch/powerpc/kernel/smp.c8
-rw-r--r--arch/powerpc/platforms/powermac/smp.c51
2 files changed, 37 insertions, 22 deletions
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 7fd530898bd1..2ffdc863bff3 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -369,11 +369,11 @@ int generic_cpu_disable(void)
if (cpu == boot_cpuid)
return -EBUSY;
+ cpu_clear(cpu, cpu_online_map);
#ifdef CONFIG_PPC64
_systemcfg->processorCount--;
-#endif
- cpu_clear(cpu, cpu_online_map);
fixup_irqs(cpu_online_map);
+#endif
return 0;
}
@@ -391,9 +391,11 @@ int generic_cpu_enable(unsigned int cpu)
while (!cpu_online(cpu))
cpu_relax();
+#ifdef CONFIG_PPC64
fixup_irqs(cpu_online_map);
/* counter the irq disable in fixup_irqs */
local_irq_enable();
+#endif
return 0;
}
@@ -422,7 +424,9 @@ void generic_mach_cpu_die(void)
while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE)
cpu_relax();
+#ifdef CONFIG_PPC64
flush_tlb_pending();
+#endif
cpu_set(cpu, cpu_online_map);
local_irq_enable();
}
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index e1f9443cc872..957b09103422 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -305,9 +305,19 @@ static int __init smp_psurge_probe(void)
psurge_start = ioremap(PSURGE_START, 4);
psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4);
- /* this is not actually strictly necessary -- paulus. */
- for (i = 1; i < ncpus; ++i)
- smp_hw_index[i] = i;
+ /*
+ * This is necessary because OF doesn't know about the
+ * secondary cpu(s), and thus there aren't nodes in the
+ * device tree for them, and smp_setup_cpu_maps hasn't
+ * set their bits in cpu_possible_map and cpu_present_map.
+ */
+ if (ncpus > NR_CPUS)
+ ncpus = NR_CPUS;
+ for (i = 1; i < ncpus ; ++i) {
+ cpu_set(i, cpu_present_map);
+ cpu_set(i, cpu_possible_map);
+ set_hard_smp_processor_id(i, i);
+ }
if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352);
@@ -348,6 +358,7 @@ static void __init psurge_dual_sync_tb(int cpu_nr)
int t;
set_dec(tb_ticks_per_jiffy);
+ /* XXX fixme */
set_tb(0, 0);
last_jiffy_stamp(cpu_nr) = 0;
@@ -363,8 +374,6 @@ static void __init psurge_dual_sync_tb(int cpu_nr)
/* now interrupt the secondary, starting both TBs */
psurge_set_ipi(1);
-
- smp_tb_synchronized = 1;
}
static struct irqaction psurge_irqaction = {
@@ -625,9 +634,8 @@ void smp_core99_give_timebase(void)
for (t = 100000; t > 0 && sec_tb_reset; --t)
udelay(10);
if (sec_tb_reset)
+ /* XXX BUG_ON here? */
printk(KERN_WARNING "Timeout waiting sync(2) on second CPU\n");
- else
- smp_tb_synchronized = 1;
/* Now, restart the timebase by leaving the GPIO to an open collector */
pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 0);
@@ -810,19 +818,9 @@ static void __devinit smp_core99_setup_cpu(int cpu_nr)
}
-/* Core99 Macs (dual G4s and G5s) */
-struct smp_ops_t core99_smp_ops = {
- .message_pass = smp_mpic_message_pass,
- .probe = smp_core99_probe,
- .kick_cpu = smp_core99_kick_cpu,
- .setup_cpu = smp_core99_setup_cpu,
- .give_timebase = smp_core99_give_timebase,
- .take_timebase = smp_core99_take_timebase,
-};
-
#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)
-int __cpu_disable(void)
+int smp_core99_cpu_disable(void)
{
cpu_clear(smp_processor_id(), cpu_online_map);
@@ -846,7 +844,7 @@ void cpu_die(void)
low_cpu_die();
}
-void __cpu_die(unsigned int cpu)
+void smp_core99_cpu_die(unsigned int cpu)
{
int timeout;
@@ -858,8 +856,21 @@ void __cpu_die(unsigned int cpu)
}
msleep(1);
}
- cpu_callin_map[cpu] = 0;
cpu_dead[cpu] = 0;
}
#endif
+
+/* Core99 Macs (dual G4s and G5s) */
+struct smp_ops_t core99_smp_ops = {
+ .message_pass = smp_mpic_message_pass,
+ .probe = smp_core99_probe,
+ .kick_cpu = smp_core99_kick_cpu,
+ .setup_cpu = smp_core99_setup_cpu,
+ .give_timebase = smp_core99_give_timebase,
+ .take_timebase = smp_core99_take_timebase,
+#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)
+ .cpu_disable = smp_core99_cpu_disable,
+ .cpu_die = smp_core99_cpu_die,
+#endif
+};