diff options
author | Paul Mackerras <paulus@samba.org> | 2005-11-09 22:26:12 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2005-11-09 22:26:12 -0500 |
commit | 094fe2e712f38f49bf79ef93306c61b1b993b07b (patch) | |
tree | 8a01db1e3bdde65982eba66b1336c24aee329bdc /arch | |
parent | 0a5cab42a1317326d87b0d074df50705a0c3fa77 (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>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/kernel/smp.c | 8 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/smp.c | 51 |
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) | |||
369 | if (cpu == boot_cpuid) | 369 | if (cpu == boot_cpuid) |
370 | return -EBUSY; | 370 | return -EBUSY; |
371 | 371 | ||
372 | cpu_clear(cpu, cpu_online_map); | ||
372 | #ifdef CONFIG_PPC64 | 373 | #ifdef CONFIG_PPC64 |
373 | _systemcfg->processorCount--; | 374 | _systemcfg->processorCount--; |
374 | #endif | ||
375 | cpu_clear(cpu, cpu_online_map); | ||
376 | fixup_irqs(cpu_online_map); | 375 | fixup_irqs(cpu_online_map); |
376 | #endif | ||
377 | return 0; | 377 | return 0; |
378 | } | 378 | } |
379 | 379 | ||
@@ -391,9 +391,11 @@ int generic_cpu_enable(unsigned int cpu) | |||
391 | while (!cpu_online(cpu)) | 391 | while (!cpu_online(cpu)) |
392 | cpu_relax(); | 392 | cpu_relax(); |
393 | 393 | ||
394 | #ifdef CONFIG_PPC64 | ||
394 | fixup_irqs(cpu_online_map); | 395 | fixup_irqs(cpu_online_map); |
395 | /* counter the irq disable in fixup_irqs */ | 396 | /* counter the irq disable in fixup_irqs */ |
396 | local_irq_enable(); | 397 | local_irq_enable(); |
398 | #endif | ||
397 | return 0; | 399 | return 0; |
398 | } | 400 | } |
399 | 401 | ||
@@ -422,7 +424,9 @@ void generic_mach_cpu_die(void) | |||
422 | while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE) | 424 | while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE) |
423 | cpu_relax(); | 425 | cpu_relax(); |
424 | 426 | ||
427 | #ifdef CONFIG_PPC64 | ||
425 | flush_tlb_pending(); | 428 | flush_tlb_pending(); |
429 | #endif | ||
426 | cpu_set(cpu, cpu_online_map); | 430 | cpu_set(cpu, cpu_online_map); |
427 | local_irq_enable(); | 431 | local_irq_enable(); |
428 | } | 432 | } |
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) | |||
305 | psurge_start = ioremap(PSURGE_START, 4); | 305 | psurge_start = ioremap(PSURGE_START, 4); |
306 | psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4); | 306 | psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4); |
307 | 307 | ||
308 | /* this is not actually strictly necessary -- paulus. */ | 308 | /* |
309 | for (i = 1; i < ncpus; ++i) | 309 | * This is necessary because OF doesn't know about the |
310 | smp_hw_index[i] = i; | 310 | * secondary cpu(s), and thus there aren't nodes in the |
311 | * device tree for them, and smp_setup_cpu_maps hasn't | ||
312 | * set their bits in cpu_possible_map and cpu_present_map. | ||
313 | */ | ||
314 | if (ncpus > NR_CPUS) | ||
315 | ncpus = NR_CPUS; | ||
316 | for (i = 1; i < ncpus ; ++i) { | ||
317 | cpu_set(i, cpu_present_map); | ||
318 | cpu_set(i, cpu_possible_map); | ||
319 | set_hard_smp_processor_id(i, i); | ||
320 | } | ||
311 | 321 | ||
312 | if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352); | 322 | if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352); |
313 | 323 | ||
@@ -348,6 +358,7 @@ static void __init psurge_dual_sync_tb(int cpu_nr) | |||
348 | int t; | 358 | int t; |
349 | 359 | ||
350 | set_dec(tb_ticks_per_jiffy); | 360 | set_dec(tb_ticks_per_jiffy); |
361 | /* XXX fixme */ | ||
351 | set_tb(0, 0); | 362 | set_tb(0, 0); |
352 | last_jiffy_stamp(cpu_nr) = 0; | 363 | last_jiffy_stamp(cpu_nr) = 0; |
353 | 364 | ||
@@ -363,8 +374,6 @@ static void __init psurge_dual_sync_tb(int cpu_nr) | |||
363 | 374 | ||
364 | /* now interrupt the secondary, starting both TBs */ | 375 | /* now interrupt the secondary, starting both TBs */ |
365 | psurge_set_ipi(1); | 376 | psurge_set_ipi(1); |
366 | |||
367 | smp_tb_synchronized = 1; | ||
368 | } | 377 | } |
369 | 378 | ||
370 | static struct irqaction psurge_irqaction = { | 379 | static struct irqaction psurge_irqaction = { |
@@ -625,9 +634,8 @@ void smp_core99_give_timebase(void) | |||
625 | for (t = 100000; t > 0 && sec_tb_reset; --t) | 634 | for (t = 100000; t > 0 && sec_tb_reset; --t) |
626 | udelay(10); | 635 | udelay(10); |
627 | if (sec_tb_reset) | 636 | if (sec_tb_reset) |
637 | /* XXX BUG_ON here? */ | ||
628 | printk(KERN_WARNING "Timeout waiting sync(2) on second CPU\n"); | 638 | printk(KERN_WARNING "Timeout waiting sync(2) on second CPU\n"); |
629 | else | ||
630 | smp_tb_synchronized = 1; | ||
631 | 639 | ||
632 | /* Now, restart the timebase by leaving the GPIO to an open collector */ | 640 | /* Now, restart the timebase by leaving the GPIO to an open collector */ |
633 | pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 0); | 641 | 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) | |||
810 | } | 818 | } |
811 | 819 | ||
812 | 820 | ||
813 | /* Core99 Macs (dual G4s and G5s) */ | ||
814 | struct smp_ops_t core99_smp_ops = { | ||
815 | .message_pass = smp_mpic_message_pass, | ||
816 | .probe = smp_core99_probe, | ||
817 | .kick_cpu = smp_core99_kick_cpu, | ||
818 | .setup_cpu = smp_core99_setup_cpu, | ||
819 | .give_timebase = smp_core99_give_timebase, | ||
820 | .take_timebase = smp_core99_take_timebase, | ||
821 | }; | ||
822 | |||
823 | #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32) | 821 | #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32) |
824 | 822 | ||
825 | int __cpu_disable(void) | 823 | int smp_core99_cpu_disable(void) |
826 | { | 824 | { |
827 | cpu_clear(smp_processor_id(), cpu_online_map); | 825 | cpu_clear(smp_processor_id(), cpu_online_map); |
828 | 826 | ||
@@ -846,7 +844,7 @@ void cpu_die(void) | |||
846 | low_cpu_die(); | 844 | low_cpu_die(); |
847 | } | 845 | } |
848 | 846 | ||
849 | void __cpu_die(unsigned int cpu) | 847 | void smp_core99_cpu_die(unsigned int cpu) |
850 | { | 848 | { |
851 | int timeout; | 849 | int timeout; |
852 | 850 | ||
@@ -858,8 +856,21 @@ void __cpu_die(unsigned int cpu) | |||
858 | } | 856 | } |
859 | msleep(1); | 857 | msleep(1); |
860 | } | 858 | } |
861 | cpu_callin_map[cpu] = 0; | ||
862 | cpu_dead[cpu] = 0; | 859 | cpu_dead[cpu] = 0; |
863 | } | 860 | } |
864 | 861 | ||
865 | #endif | 862 | #endif |
863 | |||
864 | /* Core99 Macs (dual G4s and G5s) */ | ||
865 | struct smp_ops_t core99_smp_ops = { | ||
866 | .message_pass = smp_mpic_message_pass, | ||
867 | .probe = smp_core99_probe, | ||
868 | .kick_cpu = smp_core99_kick_cpu, | ||
869 | .setup_cpu = smp_core99_setup_cpu, | ||
870 | .give_timebase = smp_core99_give_timebase, | ||
871 | .take_timebase = smp_core99_take_timebase, | ||
872 | #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32) | ||
873 | .cpu_disable = smp_core99_cpu_disable, | ||
874 | .cpu_die = smp_core99_cpu_die, | ||
875 | #endif | ||
876 | }; | ||