aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2006-10-09 23:51:00 -0400
committerPaul Mackerras <paulus@samba.org>2006-10-09 23:51:00 -0400
commitd6a29252ad120457cd544d44b2fbea46a00734a7 (patch)
tree7dcc33d03f0e1caf48bc749060d78d80946099c4 /arch/powerpc
parent39e3eb7265b8698e5f607a317af13c9478274736 (diff)
[POWERPC] Fix secondary CPU startup on old "powersurge" SMP powermacs
On the old "powersurge" SMP powermacs, the second CPU is started up by sending it an IPI, which has the side effect of stopping the timebase clock (so the secondary CPU's timebase can be synchronized with the primary's). The routine that did this used udelay, which will hang forever when the timebase is stopped, since udelay now spins until the timebase reaches a certain value. The end result is that the kernel would hang when bringing up the second CPU. This fixes it by using a simple loop which just does a fixed number of iterations to generate the delay. These old systems were all clocked at around 200 MHz or so, so a fixed number of iterations is acceptable. Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/platforms/powermac/smp.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index 574cd205b302..eeb2ae5ffc58 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -328,6 +328,7 @@ static void __init smp_psurge_kick_cpu(int nr)
328{ 328{
329 unsigned long start = __pa(__secondary_start_pmac_0) + nr * 8; 329 unsigned long start = __pa(__secondary_start_pmac_0) + nr * 8;
330 unsigned long a; 330 unsigned long a;
331 int i;
331 332
332 /* may need to flush here if secondary bats aren't setup */ 333 /* may need to flush here if secondary bats aren't setup */
333 for (a = KERNELBASE; a < KERNELBASE + 0x800000; a += 32) 334 for (a = KERNELBASE; a < KERNELBASE + 0x800000; a += 32)
@@ -340,7 +341,11 @@ static void __init smp_psurge_kick_cpu(int nr)
340 mb(); 341 mb();
341 342
342 psurge_set_ipi(nr); 343 psurge_set_ipi(nr);
343 udelay(10); 344 /*
345 * We can't use udelay here because the timebase is now frozen.
346 */
347 for (i = 0; i < 2000; ++i)
348 barrier();
344 psurge_clr_ipi(nr); 349 psurge_clr_ipi(nr);
345 350
346 if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354); 351 if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354);