ppc64: Add SMP support for PowerMac G5

parent 66d6b683
......@@ -62,7 +62,7 @@ cpumask_t cpu_present_at_boot = CPU_MASK_NONE;
EXPORT_SYMBOL(cpu_online_map);
EXPORT_SYMBOL(cpu_possible_map);
static struct smp_ops_t *smp_ops;
struct smp_ops_t *smp_ops;
static volatile unsigned int cpu_callin_map[NR_CPUS];
......@@ -76,6 +76,8 @@ extern long register_vpa(unsigned long flags, unsigned long proc,
#define smp_message_pass(t,m,d,w) smp_ops->message_pass((t),(m),(d),(w))
/* Low level assembly function used to backup CPU 0 state */
extern void __save_cpu_setup(void);
#ifdef CONFIG_PPC_ISERIES
static unsigned long iSeries_smp_message[NR_CPUS];
......@@ -175,21 +177,23 @@ static void __devinit smp_iSeries_setup_cpu(int nr)
{
}
static struct smp_ops_t iSeries_smp_ops = {
.message_pass = smp_iSeries_message_pass,
.probe = smp_iSeries_probe,
.kick_cpu = smp_iSeries_kick_cpu,
.setup_cpu = smp_iSeries_setup_cpu,
};
/* This is called very early. */
void __init smp_init_iSeries(void)
{
smp_ops = &ppc_md.smp_ops;
smp_ops->message_pass = smp_iSeries_message_pass;
smp_ops->probe = smp_iSeries_probe;
smp_ops->kick_cpu = smp_iSeries_kick_cpu;
smp_ops->setup_cpu = smp_iSeries_setup_cpu;
smp_ops = &iSeries_smp_ops;
systemcfg->processorCount = smp_iSeries_numProcs();
}
#endif
#ifdef CONFIG_PPC_PSERIES
static void
smp_openpic_message_pass(int target, int msg, unsigned long data, int wait)
void smp_openpic_message_pass(int target, int msg, unsigned long data, int wait)
{
/* make sure we're sending something that translates to an IPI */
if ( msg > 0x3 ){
......@@ -233,8 +237,7 @@ static void __devinit smp_openpic_setup_cpu(int cpu)
do_openpic_setup_cpu();
}
static void
smp_kick_cpu(int nr)
static void smp_pSeries_kick_cpu(int nr)
{
/* Verify we have a Paca for processor nr */
if ( ( nr <= 0 ) ||
......@@ -283,8 +286,7 @@ void vpa_init(int cpu)
register_vpa(flags, cpu, __pa((unsigned long)&(paca[cpu].xLpPaca)));
}
static void
smp_xics_message_pass(int target, int msg, unsigned long data, int wait)
static void smp_xics_message_pass(int target, int msg, unsigned long data, int wait)
{
int i;
......@@ -351,27 +353,34 @@ static void __devinit pSeries_take_timebase(void)
spin_unlock(&timebase_lock);
}
static struct smp_ops_t pSeries_openpic_smp_ops = {
.message_pass = smp_openpic_message_pass,
.probe = smp_openpic_probe,
.kick_cpu = smp_pSeries_kick_cpu,
.setup_cpu = smp_openpic_setup_cpu,
};
static struct smp_ops_t pSeries_xics_smp_ops = {
.message_pass = smp_xics_message_pass,
.probe = smp_xics_probe,
.kick_cpu = smp_pSeries_kick_cpu,
.setup_cpu = smp_xics_setup_cpu,
};
/* This is called very early */
void __init smp_init_pSeries(void)
{
smp_ops = &ppc_md.smp_ops;
if (naca->interrupt_controller == IC_OPEN_PIC) {
smp_ops->message_pass = smp_openpic_message_pass;
smp_ops->probe = smp_openpic_probe;
smp_ops->setup_cpu = smp_openpic_setup_cpu;
} else {
smp_ops->message_pass = smp_xics_message_pass;
smp_ops->probe = smp_xics_probe;
smp_ops->setup_cpu = smp_xics_setup_cpu;
}
if (naca->interrupt_controller == IC_OPEN_PIC)
smp_ops = &pSeries_openpic_smp_ops;
else
smp_ops = &pSeries_xics_smp_ops;
/* Non-lpar has additional take/give timebase */
if (systemcfg->platform == PLATFORM_PSERIES) {
smp_ops->give_timebase = pSeries_give_timebase;
smp_ops->take_timebase = pSeries_take_timebase;
}
smp_ops->kick_cpu = smp_kick_cpu;
}
#endif
......@@ -606,6 +615,10 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
#endif
max_cpus = smp_ops->probe();
/* Backup CPU 0 state if necessary */
__save_cpu_setup();
smp_space_timers(max_cpus);
}
......
......@@ -106,10 +106,6 @@ struct machdep_calls {
*/
long (*feature_call)(unsigned int feature, ...);
#ifdef CONFIG_SMP
/* functions for dealing with other cpus */
struct smp_ops_t smp_ops;
#endif /* CONFIG_SMP */
};
extern struct machdep_calls ppc_md;
......
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