diff options
Diffstat (limited to 'arch/sparc/kernel/smp_32.c')
| -rw-r--r-- | arch/sparc/kernel/smp_32.c | 86 | 
1 files changed, 86 insertions, 0 deletions
diff --git a/arch/sparc/kernel/smp_32.c b/arch/sparc/kernel/smp_32.c index 79db45e5134..e3f2b81c23f 100644 --- a/arch/sparc/kernel/smp_32.c +++ b/arch/sparc/kernel/smp_32.c @@ -20,6 +20,7 @@  #include <linux/seq_file.h>  #include <linux/cache.h>  #include <linux/delay.h> +#include <linux/cpu.h>  #include <asm/ptrace.h>  #include <linux/atomic.h> @@ -32,8 +33,10 @@  #include <asm/cacheflush.h>  #include <asm/tlbflush.h>  #include <asm/cpudata.h> +#include <asm/timer.h>  #include <asm/leon.h> +#include "kernel.h"  #include "irq.h"  volatile unsigned long cpu_callin_map[NR_CPUS] __cpuinitdata = {0,}; @@ -294,6 +297,89 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)  	return ret;  } +void __cpuinit arch_cpu_pre_starting(void *arg) +{ +	local_ops->cache_all(); +	local_ops->tlb_all(); + +	switch(sparc_cpu_model) { +	case sun4m: +		sun4m_cpu_pre_starting(arg); +		break; +	case sun4d: +		sun4d_cpu_pre_starting(arg); +		break; +	case sparc_leon: +		leon_cpu_pre_starting(arg); +		break; +	default: +		BUG(); +	} +} + +void __cpuinit arch_cpu_pre_online(void *arg) +{ +	unsigned int cpuid = hard_smp_processor_id(); + +	register_percpu_ce(cpuid); + +	calibrate_delay(); +	smp_store_cpu_info(cpuid); + +	local_ops->cache_all(); +	local_ops->tlb_all(); + +	switch(sparc_cpu_model) { +	case sun4m: +		sun4m_cpu_pre_online(arg); +		break; +	case sun4d: +		sun4d_cpu_pre_online(arg); +		break; +	case sparc_leon: +		leon_cpu_pre_online(arg); +		break; +	default: +		BUG(); +	} +} + +void __cpuinit sparc_start_secondary(void *arg) +{ +	unsigned int cpu; + +	/* +	 * SMP booting is extremely fragile in some architectures. So run +	 * the cpu initialization code first before anything else. +	 */ +	arch_cpu_pre_starting(arg); + +	preempt_disable(); +	cpu = smp_processor_id(); + +	/* Invoke the CPU_STARTING notifier callbacks */ +	notify_cpu_starting(cpu); + +	arch_cpu_pre_online(arg); + +	/* Set the CPU in the cpu_online_mask */ +	set_cpu_online(cpu, true); + +	/* Enable local interrupts now */ +	local_irq_enable(); + +	wmb(); +	cpu_startup_entry(CPUHP_ONLINE); + +	/* We should never reach here! */ +	BUG(); +} + +void __cpuinit smp_callin(void) +{ +	sparc_start_secondary(NULL); +} +  void smp_bogo(struct seq_file *m)  {  	int i;  |