Commit 094fe2e7 authored by Paul Mackerras's avatar Paul Mackerras

powerpc: Fixes for 32-bit powermac SMP

A couple of bugs crept in with the merge of smp.c...
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent 0a5cab42
...@@ -369,11 +369,11 @@ int generic_cpu_disable(void) ...@@ -369,11 +369,11 @@ int generic_cpu_disable(void)
if (cpu == boot_cpuid) if (cpu == boot_cpuid)
return -EBUSY; return -EBUSY;
cpu_clear(cpu, cpu_online_map);
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
_systemcfg->processorCount--; _systemcfg->processorCount--;
#endif
cpu_clear(cpu, cpu_online_map);
fixup_irqs(cpu_online_map); fixup_irqs(cpu_online_map);
#endif
return 0; return 0;
} }
...@@ -391,9 +391,11 @@ int generic_cpu_enable(unsigned int cpu) ...@@ -391,9 +391,11 @@ int generic_cpu_enable(unsigned int cpu)
while (!cpu_online(cpu)) while (!cpu_online(cpu))
cpu_relax(); cpu_relax();
#ifdef CONFIG_PPC64
fixup_irqs(cpu_online_map); fixup_irqs(cpu_online_map);
/* counter the irq disable in fixup_irqs */ /* counter the irq disable in fixup_irqs */
local_irq_enable(); local_irq_enable();
#endif
return 0; return 0;
} }
...@@ -422,7 +424,9 @@ void generic_mach_cpu_die(void) ...@@ -422,7 +424,9 @@ void generic_mach_cpu_die(void)
while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE) while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE)
cpu_relax(); cpu_relax();
#ifdef CONFIG_PPC64
flush_tlb_pending(); flush_tlb_pending();
#endif
cpu_set(cpu, cpu_online_map); cpu_set(cpu, cpu_online_map);
local_irq_enable(); local_irq_enable();
} }
......
...@@ -305,9 +305,19 @@ static int __init smp_psurge_probe(void) ...@@ -305,9 +305,19 @@ static int __init smp_psurge_probe(void)
psurge_start = ioremap(PSURGE_START, 4); psurge_start = ioremap(PSURGE_START, 4);
psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4); psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4);
/* this is not actually strictly necessary -- paulus. */ /*
for (i = 1; i < ncpus; ++i) * This is necessary because OF doesn't know about the
smp_hw_index[i] = i; * 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); 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) ...@@ -348,6 +358,7 @@ static void __init psurge_dual_sync_tb(int cpu_nr)
int t; int t;
set_dec(tb_ticks_per_jiffy); set_dec(tb_ticks_per_jiffy);
/* XXX fixme */
set_tb(0, 0); set_tb(0, 0);
last_jiffy_stamp(cpu_nr) = 0; last_jiffy_stamp(cpu_nr) = 0;
...@@ -363,8 +374,6 @@ static void __init psurge_dual_sync_tb(int cpu_nr) ...@@ -363,8 +374,6 @@ static void __init psurge_dual_sync_tb(int cpu_nr)
/* now interrupt the secondary, starting both TBs */ /* now interrupt the secondary, starting both TBs */
psurge_set_ipi(1); psurge_set_ipi(1);
smp_tb_synchronized = 1;
} }
static struct irqaction psurge_irqaction = { static struct irqaction psurge_irqaction = {
...@@ -625,9 +634,8 @@ void smp_core99_give_timebase(void) ...@@ -625,9 +634,8 @@ void smp_core99_give_timebase(void)
for (t = 100000; t > 0 && sec_tb_reset; --t) for (t = 100000; t > 0 && sec_tb_reset; --t)
udelay(10); udelay(10);
if (sec_tb_reset) if (sec_tb_reset)
/* XXX BUG_ON here? */
printk(KERN_WARNING "Timeout waiting sync(2) on second CPU\n"); 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 */ /* Now, restart the timebase by leaving the GPIO to an open collector */
pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 0); 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,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) #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); cpu_clear(smp_processor_id(), cpu_online_map);
...@@ -846,7 +844,7 @@ void cpu_die(void) ...@@ -846,7 +844,7 @@ void cpu_die(void)
low_cpu_die(); low_cpu_die();
} }
void __cpu_die(unsigned int cpu) void smp_core99_cpu_die(unsigned int cpu)
{ {
int timeout; int timeout;
...@@ -858,8 +856,21 @@ void __cpu_die(unsigned int cpu) ...@@ -858,8 +856,21 @@ void __cpu_die(unsigned int cpu)
} }
msleep(1); msleep(1);
} }
cpu_callin_map[cpu] = 0;
cpu_dead[cpu] = 0; cpu_dead[cpu] = 0;
} }
#endif #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
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment