diff options
| author | Olof Johansson <olof@lixom.net> | 2012-09-22 00:06:21 -0700 | 
|---|---|---|
| committer | Olof Johansson <olof@lixom.net> | 2012-09-22 00:16:04 -0700 | 
| commit | 25468fe89f88c4ceeef94526e94ae0db176f6999 (patch) | |
| tree | d70a713525281276b5063c814413bb3141e6056c | |
| parent | a283580c52d3aa24305985e945dfccfbcfc6f4f9 (diff) | |
| parent | 28e8e29c616f947348cc66bea684d0035c76021a (diff) | |
| download | olio-linux-3.10-25468fe89f88c4ceeef94526e94ae0db176f6999.tar.xz olio-linux-3.10-25468fe89f88c4ceeef94526e94ae0db176f6999.zip | |
Merge branch 'multiplatform/smp_ops' into next/multiplatform
* multiplatform/smp_ops:
  ARM: consolidate pen_release instead of having per platform definitions
  ARM: smp: Make SMP operations mandatory
  ARM: SoC: convert spear13xx to SMP operations
  ARM: SoC: convert imx6q to SMP operations
  ARM: SoC: convert highbank to SMP operations
  ARM: SoC: convert shmobile SMP to SMP operations
  ARM: SoC: convert ux500 to SMP operations
  ARM: SoC: convert MSM to SMP operations
  ARM: SoC: convert Exynos4 to SMP operations
  ARM: SoC: convert Tegra to SMP operations
  ARM: SoC: convert OMAP4 to SMP operations
  ARM: SoC: convert VExpress/RealView to SMP operations
  ARM: SoC: add per-platform SMP operations
Conflicts due to file moves or removals in:
	arch/arm/mach-msm/board-msm8960.c
	arch/arm/mach-msm/board-msm8x60.c
	arch/arm/mach-tegra/board-harmony.c
	arch/arm/mach-tegra/board-trimslice.c
Conflicts due to board file cleanup:
	arch/arm/mach-tegra/board-paz00.c
Conflicts due to cpu hotplug addition:
	arch/arm/mach-tegra/hotplug.c
Signed-off-by: Olof Johansson <olof@lixom.net>
74 files changed, 535 insertions, 401 deletions
| diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h index 0b1c94b8c65..917d4fcfd9b 100644 --- a/arch/arm/include/asm/mach/arch.h +++ b/arch/arm/include/asm/mach/arch.h @@ -14,6 +14,12 @@ struct tag;  struct meminfo;  struct sys_timer;  struct pt_regs; +struct smp_operations; +#ifdef CONFIG_SMP +#define smp_ops(ops) (&(ops)) +#else +#define smp_ops(ops) (struct smp_operations *)NULL +#endif  struct machine_desc {  	unsigned int		nr;		/* architecture number	*/ @@ -35,6 +41,7 @@ struct machine_desc {  	unsigned char		reserve_lp1 :1;	/* never has lp1	*/  	unsigned char		reserve_lp2 :1;	/* never has lp2	*/  	char			restart_mode;	/* default restart mode	*/ +	struct smp_operations	*smp;		/* SMP operations	*/  	void			(*fixup)(struct tag *, char **,  					 struct meminfo *);  	void			(*reserve)(void);/* reserve mem blocks	*/ diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h index ae29293270a..2e3be16c676 100644 --- a/arch/arm/include/asm/smp.h +++ b/arch/arm/include/asm/smp.h @@ -60,15 +60,6 @@ extern int boot_secondary(unsigned int cpu, struct task_struct *);   */  asmlinkage void secondary_start_kernel(void); -/* - * Perform platform specific initialisation of the specified CPU. - */ -extern void platform_secondary_init(unsigned int cpu); - -/* - * Initialize cpu_possible map, and enable coherency - */ -extern void platform_smp_prepare_cpus(unsigned int);  /*   * Initial data for bringing up a secondary CPU. @@ -79,18 +70,47 @@ struct secondary_data {  	void *stack;  };  extern struct secondary_data secondary_data; +extern volatile int pen_release;  extern int __cpu_disable(void); -extern int platform_cpu_disable(unsigned int cpu);  extern void __cpu_die(unsigned int cpu);  extern void cpu_die(void); -extern void platform_cpu_die(unsigned int cpu); -extern int platform_cpu_kill(unsigned int cpu); -extern void platform_cpu_enable(unsigned int cpu); -  extern void arch_send_call_function_single_ipi(int cpu);  extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); +struct smp_operations { +#ifdef CONFIG_SMP +	/* +	 * Setup the set of possible CPUs (via set_cpu_possible) +	 */ +	void (*smp_init_cpus)(void); +	/* +	 * Initialize cpu_possible map, and enable coherency +	 */ +	void (*smp_prepare_cpus)(unsigned int max_cpus); + +	/* +	 * Perform platform specific initialisation of the specified CPU. +	 */ +	void (*smp_secondary_init)(unsigned int cpu); +	/* +	 * Boot a secondary CPU, and assign it the specified idle task. +	 * This also gives us the initial stack to use for this CPU. +	 */ +	int  (*smp_boot_secondary)(unsigned int cpu, struct task_struct *idle); +#ifdef CONFIG_HOTPLUG_CPU +	int  (*cpu_kill)(unsigned int cpu); +	void (*cpu_die)(unsigned int cpu); +	int  (*cpu_disable)(unsigned int cpu); +#endif +#endif +}; + +/* + * set platform specific SMP operations + */ +extern void smp_set_ops(struct smp_operations *); +  #endif /* ifndef __ASM_ARM_SMP_H */ diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index a81dcecc734..725f9f2a954 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -977,8 +977,10 @@ void __init setup_arch(char **cmdline_p)  	unflatten_device_tree();  #ifdef CONFIG_SMP -	if (is_smp()) +	if (is_smp()) { +		smp_set_ops(mdesc->smp);  		smp_init_cpus(); +	}  #endif  	reserve_crashkernel(); diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index ebd8ad274d7..aa4ffe6e5ec 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -19,7 +19,6 @@  #include <linux/mm.h>  #include <linux/err.h>  #include <linux/cpu.h> -#include <linux/smp.h>  #include <linux/seq_file.h>  #include <linux/irq.h>  #include <linux/percpu.h> @@ -27,6 +26,7 @@  #include <linux/completion.h>  #include <linux/atomic.h> +#include <asm/smp.h>  #include <asm/cacheflush.h>  #include <asm/cpu.h>  #include <asm/cputype.h> @@ -42,6 +42,7 @@  #include <asm/ptrace.h>  #include <asm/localtimer.h>  #include <asm/smp_plat.h> +#include <asm/mach/arch.h>  /*   * as from 2.5, kernels no longer have an init_tasks structure @@ -50,6 +51,12 @@   */  struct secondary_data secondary_data; +/* + * control for which core is the next to come out of the secondary + * boot "holding pen" + */ +volatile int __cpuinitdata pen_release = -1; +  enum ipi_msg_type {  	IPI_TIMER = 2,  	IPI_RESCHEDULE, @@ -60,6 +67,14 @@ enum ipi_msg_type {  static DECLARE_COMPLETION(cpu_running); +static struct smp_operations smp_ops; + +void __init smp_set_ops(struct smp_operations *ops) +{ +	if (ops) +		smp_ops = *ops; +}; +  int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)  {  	int ret; @@ -100,13 +115,64 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)  	return ret;  } +/* platform specific SMP operations */ +void __init smp_init_cpus(void) +{ +	if (smp_ops.smp_init_cpus) +		smp_ops.smp_init_cpus(); +} + +static void __init platform_smp_prepare_cpus(unsigned int max_cpus) +{ +	if (smp_ops.smp_prepare_cpus) +		smp_ops.smp_prepare_cpus(max_cpus); +} + +static void __cpuinit platform_secondary_init(unsigned int cpu) +{ +	if (smp_ops.smp_secondary_init) +		smp_ops.smp_secondary_init(cpu); +} + +int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) +{ +	if (smp_ops.smp_boot_secondary) +		return smp_ops.smp_boot_secondary(cpu, idle); +	return -ENOSYS; +} +  #ifdef CONFIG_HOTPLUG_CPU  static void percpu_timer_stop(void); +static int platform_cpu_kill(unsigned int cpu) +{ +	if (smp_ops.cpu_kill) +		return smp_ops.cpu_kill(cpu); +	return 1; +} + +static void platform_cpu_die(unsigned int cpu) +{ +	if (smp_ops.cpu_die) +		smp_ops.cpu_die(cpu); +} + +static int platform_cpu_disable(unsigned int cpu) +{ +	if (smp_ops.cpu_disable) +		return smp_ops.cpu_disable(cpu); + +	/* +	 * By default, allow disabling all CPUs except the first one, +	 * since this is special on a lot of platforms, e.g. because +	 * of clock tick interrupts. +	 */ +	return cpu == 0 ? -EPERM : 0; +}  /*   * __cpu_disable runs on the processor to be shutdown.   */ -int __cpu_disable(void) +int __cpuinit __cpu_disable(void)  {  	unsigned int cpu = smp_processor_id();  	int ret; @@ -149,7 +215,7 @@ static DECLARE_COMPLETION(cpu_died);   * called on the thread which is asking for a CPU to be shutdown -   * waits until shutdown has completed, or it is timed out.   */ -void __cpu_die(unsigned int cpu) +void __cpuinit __cpu_die(unsigned int cpu)  {  	if (!wait_for_completion_timeout(&cpu_died, msecs_to_jiffies(5000))) {  		pr_err("CPU%u: cpu didn't die\n", cpu); diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h index aed2eeb0651..dac146df79a 100644 --- a/arch/arm/mach-exynos/common.h +++ b/arch/arm/mach-exynos/common.h @@ -14,6 +14,7 @@  extern struct sys_timer exynos4_timer; +struct map_desc;  void exynos_init_io(struct map_desc *mach_desc, int size);  void exynos4_init_irq(void);  void exynos5_init_irq(void); @@ -59,4 +60,8 @@ void exynos4212_register_clocks(void);  #define exynos4212_register_clocks()  #endif +extern struct smp_operations exynos_smp_ops; + +extern void exynos_cpu_die(unsigned int cpu); +  #endif /* __ARCH_ARM_MACH_EXYNOS_COMMON_H */ diff --git a/arch/arm/mach-exynos/hotplug.c b/arch/arm/mach-exynos/hotplug.c index 9c17a0a4385..f4d7dd20cda 100644 --- a/arch/arm/mach-exynos/hotplug.c +++ b/arch/arm/mach-exynos/hotplug.c @@ -21,7 +21,7 @@  #include <mach/regs-pmu.h> -extern volatile int pen_release; +#include "common.h"  static inline void cpu_enter_lowpower(void)  { @@ -95,17 +95,12 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)  	}  } -int platform_cpu_kill(unsigned int cpu) -{ -	return 1; -} -  /*   * platform-specific code to shutdown a CPU   *   * Called with IRQs disabled   */ -void platform_cpu_die(unsigned int cpu) +void __ref exynos_cpu_die(unsigned int cpu)  {  	int spurious = 0; @@ -124,12 +119,3 @@ void platform_cpu_die(unsigned int cpu)  	if (spurious)  		pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);  } - -int platform_cpu_disable(unsigned int cpu) -{ -	/* -	 * we don't allow CPU 0 to be shutdown (it is still too special -	 * e.g. clock tick interrupts) -	 */ -	return cpu == 0 ? -EPERM : 0; -} diff --git a/arch/arm/mach-exynos/mach-armlex4210.c b/arch/arm/mach-exynos/mach-armlex4210.c index 5a3daa0168d..3f37a5e8a1f 100644 --- a/arch/arm/mach-exynos/mach-armlex4210.c +++ b/arch/arm/mach-exynos/mach-armlex4210.c @@ -199,6 +199,7 @@ static void __init armlex4210_machine_init(void)  MACHINE_START(ARMLEX4210, "ARMLEX4210")  	/* Maintainer: Alim Akhtar <alim.akhtar@samsung.com> */  	.atag_offset	= 0x100, +	.smp		= smp_ops(exynos_smp_ops),  	.init_irq	= exynos4_init_irq,  	.map_io		= armlex4210_map_io,  	.handle_irq	= gic_handle_irq, diff --git a/arch/arm/mach-exynos/mach-exynos5-dt.c b/arch/arm/mach-exynos/mach-exynos5-dt.c index ef770bc2318..8833060f77e 100644 --- a/arch/arm/mach-exynos/mach-exynos5-dt.c +++ b/arch/arm/mach-exynos/mach-exynos5-dt.c @@ -79,6 +79,7 @@ static char const *exynos5250_dt_compat[] __initdata = {  DT_MACHINE_START(EXYNOS5_DT, "SAMSUNG EXYNOS5 (Flattened Device Tree)")  	/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */  	.init_irq	= exynos5_init_irq, +	.smp		= smp_ops(exynos_smp_ops),  	.map_io		= exynos5250_dt_map_io,  	.handle_irq	= gic_handle_irq,  	.init_machine	= exynos5250_dt_machine_init, diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c index ea785fcaf6c..ffaa355c1bd 100644 --- a/arch/arm/mach-exynos/mach-nuri.c +++ b/arch/arm/mach-exynos/mach-nuri.c @@ -1383,6 +1383,7 @@ static void __init nuri_machine_init(void)  MACHINE_START(NURI, "NURI")  	/* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */  	.atag_offset	= 0x100, +	.smp		= smp_ops(exynos_smp_ops),  	.init_irq	= exynos4_init_irq,  	.map_io		= nuri_map_io,  	.handle_irq	= gic_handle_irq, diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c index 4e574c24581..abd0e6059ab 100644 --- a/arch/arm/mach-exynos/mach-origen.c +++ b/arch/arm/mach-exynos/mach-origen.c @@ -806,6 +806,7 @@ static void __init origen_machine_init(void)  MACHINE_START(ORIGEN, "ORIGEN")  	/* Maintainer: JeongHyeon Kim <jhkim@insignal.co.kr> */  	.atag_offset	= 0x100, +	.smp		= smp_ops(exynos_smp_ops),  	.init_irq	= exynos4_init_irq,  	.map_io		= origen_map_io,  	.handle_irq	= gic_handle_irq, diff --git a/arch/arm/mach-exynos/mach-smdk4x12.c b/arch/arm/mach-exynos/mach-smdk4x12.c index b26beb13ebe..964693bdc24 100644 --- a/arch/arm/mach-exynos/mach-smdk4x12.c +++ b/arch/arm/mach-exynos/mach-smdk4x12.c @@ -370,6 +370,7 @@ static void __init smdk4x12_machine_init(void)  MACHINE_START(SMDK4212, "SMDK4212")  	/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */  	.atag_offset	= 0x100, +	.smp		= smp_ops(exynos_smp_ops),  	.init_irq	= exynos4_init_irq,  	.map_io		= smdk4x12_map_io,  	.handle_irq	= gic_handle_irq, @@ -383,6 +384,7 @@ MACHINE_START(SMDK4412, "SMDK4412")  	/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */  	/* Maintainer: Changhwan Youn <chaos.youn@samsung.com> */  	.atag_offset	= 0x100, +	.smp		= smp_ops(exynos_smp_ops),  	.init_irq	= exynos4_init_irq,  	.map_io		= smdk4x12_map_io,  	.handle_irq	= gic_handle_irq, diff --git a/arch/arm/mach-exynos/mach-smdkv310.c b/arch/arm/mach-exynos/mach-smdkv310.c index 73f2bce097e..69b858ceefc 100644 --- a/arch/arm/mach-exynos/mach-smdkv310.c +++ b/arch/arm/mach-exynos/mach-smdkv310.c @@ -417,6 +417,7 @@ MACHINE_START(SMDKV310, "SMDKV310")  	/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */  	/* Maintainer: Changhwan Youn <chaos.youn@samsung.com> */  	.atag_offset	= 0x100, +	.smp		= smp_ops(exynos_smp_ops),  	.init_irq	= exynos4_init_irq,  	.map_io		= smdkv310_map_io,  	.handle_irq	= gic_handle_irq, @@ -429,6 +430,7 @@ MACHINE_END  MACHINE_START(SMDKC210, "SMDKC210")  	/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */  	.atag_offset	= 0x100, +	.smp		= smp_ops(exynos_smp_ops),  	.init_irq	= exynos4_init_irq,  	.map_io		= smdkv310_map_io,  	.handle_irq	= gic_handle_irq, diff --git a/arch/arm/mach-exynos/mach-universal_c210.c b/arch/arm/mach-exynos/mach-universal_c210.c index 4d1f40d44ed..922ca0f1179 100644 --- a/arch/arm/mach-exynos/mach-universal_c210.c +++ b/arch/arm/mach-exynos/mach-universal_c210.c @@ -1155,6 +1155,7 @@ static void __init universal_machine_init(void)  MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210")  	/* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */  	.atag_offset	= 0x100, +	.smp		= smp_ops(exynos_smp_ops),  	.init_irq	= exynos4_init_irq,  	.map_io		= universal_map_io,  	.handle_irq	= gic_handle_irq, diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c index 36c3984aaa4..8d57e4223bd 100644 --- a/arch/arm/mach-exynos/platsmp.c +++ b/arch/arm/mach-exynos/platsmp.c @@ -32,19 +32,14 @@  #include <plat/cpu.h> +#include "common.h" +  extern void exynos4_secondary_startup(void);  #define CPU1_BOOT_REG		(samsung_rev() == EXYNOS4210_REV_1_1 ? \  				S5P_INFORM5 : S5P_VA_SYSRAM)  /* - * control for which core is the next to come out of the secondary - * boot "holding pen" - */ - -volatile int __cpuinitdata pen_release = -1; - -/*   * Write pen_release in a way that is guaranteed to be visible to all   * observers, irrespective of whether they're taking part in coherency   * or not.  This is necessary for the hotplug code to work reliably. @@ -64,7 +59,7 @@ static void __iomem *scu_base_addr(void)  static DEFINE_SPINLOCK(boot_lock); -void __cpuinit platform_secondary_init(unsigned int cpu) +static void __cpuinit exynos_secondary_init(unsigned int cpu)  {  	/*  	 * if any interrupts are already enabled for the primary @@ -86,7 +81,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)  	spin_unlock(&boot_lock);  } -int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) +static int __cpuinit exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)  {  	unsigned long timeout; @@ -161,7 +156,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)   * which may be present or become present in the system.   */ -void __init smp_init_cpus(void) +static void __init exynos_smp_init_cpus(void)  {  	void __iomem *scu_base = scu_base_addr();  	unsigned int i, ncores; @@ -184,7 +179,7 @@ void __init smp_init_cpus(void)  	set_smp_cross_call(gic_raise_softirq);  } -void __init platform_smp_prepare_cpus(unsigned int max_cpus) +static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)  {  	if (!soc_is_exynos5250())  		scu_enable(scu_base_addr()); @@ -198,3 +193,13 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)  	__raw_writel(virt_to_phys(exynos4_secondary_startup),  			CPU1_BOOT_REG);  } + +struct smp_operations exynos_smp_ops __initdata = { +	.smp_init_cpus		= exynos_smp_init_cpus, +	.smp_prepare_cpus	= exynos_smp_prepare_cpus, +	.smp_secondary_init	= exynos_secondary_init, +	.smp_boot_secondary	= exynos_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU +	.cpu_die		= exynos_cpu_die, +#endif +}; diff --git a/arch/arm/mach-highbank/core.h b/arch/arm/mach-highbank/core.h index 8b9fb1a46a9..286ec82a4f6 100644 --- a/arch/arm/mach-highbank/core.h +++ b/arch/arm/mach-highbank/core.h @@ -15,3 +15,6 @@ static inline void highbank_pm_init(void) {}  #endif  extern void highbank_smc1(int fn, int arg); +extern void highbank_cpu_die(unsigned int cpu); + +extern struct smp_operations highbank_smp_ops; diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c index f376c26cb0e..af1da34ccf9 100644 --- a/arch/arm/mach-highbank/highbank.c +++ b/arch/arm/mach-highbank/highbank.c @@ -163,6 +163,7 @@ static const char *highbank_match[] __initconst = {  };  DT_MACHINE_START(HIGHBANK, "Highbank") +	.smp		= smp_ops(highbank_smp_ops),  	.map_io		= highbank_map_io,  	.init_irq	= highbank_init_irq,  	.timer		= &highbank_timer, diff --git a/arch/arm/mach-highbank/hotplug.c b/arch/arm/mach-highbank/hotplug.c index 977cebbea58..2c1b8c3c8e4 100644 --- a/arch/arm/mach-highbank/hotplug.c +++ b/arch/arm/mach-highbank/hotplug.c @@ -24,16 +24,11 @@  extern void secondary_startup(void); -int platform_cpu_kill(unsigned int cpu) -{ -	return 1; -} -  /*   * platform-specific code to shutdown a CPU   *   */ -void platform_cpu_die(unsigned int cpu) +void __ref highbank_cpu_die(unsigned int cpu)  {  	flush_cache_all(); @@ -45,12 +40,3 @@ void platform_cpu_die(unsigned int cpu)  	/* We should never return from idle */  	panic("highbank: cpu %d unexpectedly exit from shutdown\n", cpu);  } - -int platform_cpu_disable(unsigned int cpu) -{ -	/* -	 * CPU0 should not be shut down via hotplug.  cpu_idle can WFI -	 * or a proper shutdown or hibernate should be used. -	 */ -	return cpu == 0 ? -EPERM : 0; -} diff --git a/arch/arm/mach-highbank/platsmp.c b/arch/arm/mach-highbank/platsmp.c index d01364c72b4..fa9560ec6e7 100644 --- a/arch/arm/mach-highbank/platsmp.c +++ b/arch/arm/mach-highbank/platsmp.c @@ -25,12 +25,12 @@  extern void secondary_startup(void); -void __cpuinit platform_secondary_init(unsigned int cpu) +static void __cpuinit highbank_secondary_init(unsigned int cpu)  {  	gic_secondary_init(0);  } -int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) +static int __cpuinit highbank_boot_secondary(unsigned int cpu, struct task_struct *idle)  {  	gic_raise_softirq(cpumask_of(cpu), 0);  	return 0; @@ -40,7 +40,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)   * Initialise the CPU possible map early - this describes the CPUs   * which may be present or become present in the system.   */ -void __init smp_init_cpus(void) +static void __init highbank_smp_init_cpus(void)  {  	unsigned int i, ncores; @@ -61,7 +61,7 @@ void __init smp_init_cpus(void)  	set_smp_cross_call(gic_raise_softirq);  } -void __init platform_smp_prepare_cpus(unsigned int max_cpus) +static void __init highbank_smp_prepare_cpus(unsigned int max_cpus)  {  	int i; @@ -76,3 +76,13 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)  	for (i = 1; i < max_cpus; i++)  		highbank_set_cpu_jump(i, secondary_startup);  } + +struct smp_operations highbank_smp_ops __initdata = { +	.smp_init_cpus		= highbank_smp_init_cpus, +	.smp_prepare_cpus	= highbank_smp_prepare_cpus, +	.smp_secondary_init	= highbank_secondary_init, +	.smp_boot_secondary	= highbank_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU +	.cpu_die		= highbank_cpu_die, +#endif +}; diff --git a/arch/arm/mach-imx/hotplug.c b/arch/arm/mach-imx/hotplug.c index f8f7437c83b..b07b778dc9a 100644 --- a/arch/arm/mach-imx/hotplug.c +++ b/arch/arm/mach-imx/hotplug.c @@ -15,11 +15,6 @@  #include <asm/cp15.h>  #include <mach/common.h> -int platform_cpu_kill(unsigned int cpu) -{ -	return 1; -} -  static inline void cpu_enter_lowpower(void)  {  	unsigned int v; @@ -47,7 +42,7 @@ static inline void cpu_enter_lowpower(void)   *   * Called with IRQs disabled   */ -void platform_cpu_die(unsigned int cpu) +void imx_cpu_die(unsigned int cpu)  {  	cpu_enter_lowpower();  	imx_enable_cpu(cpu, false); @@ -56,12 +51,3 @@ void platform_cpu_die(unsigned int cpu)  	while (1)  		;  } - -int platform_cpu_disable(unsigned int cpu) -{ -	/* -	 * we don't allow CPU 0 to be shutdown (it is still too special -	 * e.g. clock tick interrupts) -	 */ -	return cpu == 0 ? -EPERM : 0; -} diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 692b4b143bb..36979d3dfe3 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -215,6 +215,7 @@ static const char *imx6q_dt_compat[] __initdata = {  };  DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad (Device Tree)") +	.smp		= smp_ops(imx_smp_ops),  	.map_io		= imx6q_map_io,  	.init_irq	= imx6q_init_irq,  	.handle_irq	= imx6q_handle_irq, diff --git a/arch/arm/mach-imx/platsmp.c b/arch/arm/mach-imx/platsmp.c index ab98c6fec9e..2ac43e1a2df 100644 --- a/arch/arm/mach-imx/platsmp.c +++ b/arch/arm/mach-imx/platsmp.c @@ -41,7 +41,7 @@ void __init imx_scu_map_io(void)  	scu_base = IMX_IO_ADDRESS(base);  } -void __cpuinit platform_secondary_init(unsigned int cpu) +static void __cpuinit imx_secondary_init(unsigned int cpu)  {  	/*  	 * if any interrupts are already enabled for the primary @@ -51,7 +51,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)  	gic_secondary_init(0);  } -int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) +static int __cpuinit imx_boot_secondary(unsigned int cpu, struct task_struct *idle)  {  	imx_set_cpu_jump(cpu, v7_secondary_startup);  	imx_enable_cpu(cpu, true); @@ -62,7 +62,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)   * Initialise the CPU possible map early - this describes the CPUs   * which may be present or become present in the system.   */ -void __init smp_init_cpus(void) +static void __init imx_smp_init_cpus(void)  {  	int i, ncores; @@ -79,7 +79,17 @@ void imx_smp_prepare(void)  	scu_enable(scu_base);  } -void __init platform_smp_prepare_cpus(unsigned int max_cpus) +static void __init imx_smp_prepare_cpus(unsigned int max_cpus)  {  	imx_smp_prepare();  } + +struct smp_operations  imx_smp_ops __initdata = { +	.smp_init_cpus		= imx_smp_init_cpus, +	.smp_prepare_cpus	= imx_smp_prepare_cpus, +	.smp_secondary_init	= imx_secondary_init, +	.smp_boot_secondary	= imx_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU +	.cpu_die		= imx_cpu_die, +#endif +}; diff --git a/arch/arm/mach-msm/board-dt-8660.c b/arch/arm/mach-msm/board-dt-8660.c index f77f57f3910..e5643f629dc 100644 --- a/arch/arm/mach-msm/board-dt-8660.c +++ b/arch/arm/mach-msm/board-dt-8660.c @@ -20,6 +20,7 @@  #include <mach/board.h>  #include "common.h" +#include "core.h"  static const struct of_device_id msm_dt_gic_match[] __initconst = {  	{ .compatible = "qcom,msm-8660-qgic", .data = gic_of_init }, @@ -53,6 +54,7 @@ static const char *msm8x60_fluid_match[] __initdata = {  };  DT_MACHINE_START(MSM_DT, "Qualcomm MSM (Flattened Device Tree)") +	.smp = smp_ops(msm_smp_ops),  	.map_io = msm_map_msm8x60_io,  	.init_irq = msm8x60_init_irq,  	.handle_irq = gic_handle_irq, diff --git a/arch/arm/mach-msm/board-dt-8960.c b/arch/arm/mach-msm/board-dt-8960.c index 8df99b8f3c9..139d61bbc8e 100644 --- a/arch/arm/mach-msm/board-dt-8960.c +++ b/arch/arm/mach-msm/board-dt-8960.c @@ -18,6 +18,7 @@  #include <asm/mach/arch.h>  #include "common.h" +#include "core.h"  static const struct of_device_id msm_dt_gic_match[] __initconst = {  	{ .compatible = "qcom,msm-qgic2", .data = gic_of_init }, @@ -40,6 +41,7 @@ static const char * const msm8960_dt_match[] __initconst = {  };  DT_MACHINE_START(MSM8960_DT, "Qualcomm MSM (Flattened Device Tree)") +	.smp = smp_ops(msm_smp_ops),  	.map_io = msm_map_msm8960_io,  	.init_irq = msm_dt_init_irq,  	.timer = &msm_dt_timer, diff --git a/arch/arm/mach-msm/core.h b/arch/arm/mach-msm/core.h new file mode 100644 index 00000000000..a9bab53dddf --- /dev/null +++ b/arch/arm/mach-msm/core.h @@ -0,0 +1,2 @@ +extern struct smp_operations msm_smp_ops; +extern void msm_cpu_die(unsigned int cpu); diff --git a/arch/arm/mach-msm/hotplug.c b/arch/arm/mach-msm/hotplug.c index a446fc14221..002ac1e4723 100644 --- a/arch/arm/mach-msm/hotplug.c +++ b/arch/arm/mach-msm/hotplug.c @@ -13,7 +13,7 @@  #include <asm/cacheflush.h>  #include <asm/smp_plat.h> -extern volatile int pen_release; +#include "core.h"  static inline void cpu_enter_lowpower(void)  { @@ -57,17 +57,12 @@ static inline void platform_do_lowpower(unsigned int cpu)  	}  } -int platform_cpu_kill(unsigned int cpu) -{ -	return 1; -} -  /*   * platform-specific code to shutdown a CPU   *   * Called with IRQs disabled   */ -void platform_cpu_die(unsigned int cpu) +void __ref msm_cpu_die(unsigned int cpu)  {  	/*  	 * we're ready for shutdown now, so do it @@ -81,12 +76,3 @@ void platform_cpu_die(unsigned int cpu)  	 */  	cpu_leave_lowpower();  } - -int platform_cpu_disable(unsigned int cpu) -{ -	/* -	 * we don't allow CPU 0 to be shutdown (it is still too special -	 * e.g. clock tick interrupts) -	 */ -	return cpu == 0 ? -EPERM : 0; -} diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c index 2d791e6b4ad..637021c0d8a 100644 --- a/arch/arm/mach-msm/platsmp.c +++ b/arch/arm/mach-msm/platsmp.c @@ -23,17 +23,13 @@  #include <asm/smp_plat.h>  #include "scm-boot.h" +#include "core.h"  #define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x15A0  #define SCSS_CPU1CORE_RESET 0xD80  #define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64  extern void msm_secondary_startup(void); -/* - * control for which core is the next to come out of the secondary - * boot "holding pen". - */ -volatile int pen_release = -1;  static DEFINE_SPINLOCK(boot_lock); @@ -43,7 +39,7 @@ static inline int get_core_count(void)  	return ((read_cpuid_id() >> 4) & 3) + 1;  } -void __cpuinit platform_secondary_init(unsigned int cpu) +static void __cpuinit msm_secondary_init(unsigned int cpu)  {  	/*  	 * if any interrupts are already enabled for the primary @@ -85,7 +81,7 @@ static __cpuinit void prepare_cold_cpu(unsigned int cpu)  				  "address\n");  } -int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) +static int __cpuinit msm_boot_secondary(unsigned int cpu, struct task_struct *idle)  {  	unsigned long timeout;  	static int cold_boot_done; @@ -145,7 +141,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)   * does not support the ARM SCU, so just set the possible cpu mask to   * NR_CPUS.   */ -void __init smp_init_cpus(void) +static void __init msm_smp_init_cpus(void)  {  	unsigned int i, ncores = get_core_count(); @@ -161,6 +157,16 @@ void __init smp_init_cpus(void)          set_smp_cross_call(gic_raise_softirq);  } -void __init platform_smp_prepare_cpus(unsigned int max_cpus) +static void __init msm_smp_prepare_cpus(unsigned int max_cpus)  {  } + +struct smp_operations msm_smp_ops __initdata = { +	.smp_init_cpus		= msm_smp_init_cpus, +	.smp_prepare_cpus	= msm_smp_prepare_cpus, +	.smp_secondary_init	= msm_secondary_init, +	.smp_boot_secondary	= msm_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU +	.cpu_die		= msm_cpu_die, +#endif +}; diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index e82098fbedd..6fe90796d46 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -907,6 +907,7 @@ static void __init omap_4430sdp_init(void)  MACHINE_START(OMAP_4430SDP, "OMAP4430 4430SDP board")  	/* Maintainer: Santosh Shilimkar - Texas Instruments Inc */  	.atag_offset	= 0x100, +	.smp		= smp_ops(omap4_smp_ops),  	.reserve	= omap_reserve,  	.map_io		= omap4_map_io,  	.init_early	= omap4430_init_early, diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index 2ea7c577b29..601ecdfb1cf 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -125,6 +125,7 @@ static const char *omap4_boards_compat[] __initdata = {  DT_MACHINE_START(OMAP4_DT, "Generic OMAP4 (Flattened Device Tree)")  	.reserve	= omap_reserve, +	.smp		= smp_ops(omap4_smp_ops),  	.map_io		= omap4_map_io,  	.init_early	= omap4430_init_early,  	.init_irq	= omap_gic_of_init, @@ -145,6 +146,7 @@ static const char *omap5_boards_compat[] __initdata = {  DT_MACHINE_START(OMAP5_DT, "Generic OMAP5 (Flattened Device Tree)")  	.reserve	= omap_reserve, +	.smp		= smp_ops(omap4_smp_ops),  	.map_io		= omap5_map_io,  	.init_early	= omap5_init_early,  	.init_irq	= omap_gic_of_init, diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index 45fe2d3f59b..8ebb16c5182 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -516,6 +516,7 @@ static void __init omap4_panda_init(void)  MACHINE_START(OMAP4_PANDA, "OMAP4 Panda board")  	/* Maintainer: David Anders - Texas Instruments Inc */  	.atag_offset	= 0x100, +	.smp		= smp_ops(omap4_smp_ops),  	.reserve	= omap_reserve,  	.map_io		= omap4_map_io,  	.init_early	= omap4430_init_early, diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index da0f5c18735..7045e4d61ac 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -285,6 +285,11 @@ extern void omap_secondary_startup(void);  extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask);  extern void omap_auxcoreboot_addr(u32 cpu_addr);  extern u32 omap_read_auxcoreboot0(void); + +extern void omap4_cpu_die(unsigned int cpu); + +extern struct smp_operations omap4_smp_ops; +  extern void omap5_secondary_startup(void);  #endif diff --git a/arch/arm/mach-omap2/omap-hotplug.c b/arch/arm/mach-omap2/omap-hotplug.c index 765a2aceb66..e712d1725a8 100644 --- a/arch/arm/mach-omap2/omap-hotplug.c +++ b/arch/arm/mach-omap2/omap-hotplug.c @@ -26,16 +26,11 @@  #include "powerdomain.h" -int platform_cpu_kill(unsigned int cpu) -{ -	return 1; -} -  /*   * platform-specific code to shutdown a CPU   * Called with IRQs disabled   */ -void __ref platform_cpu_die(unsigned int cpu) +void __ref omap4_cpu_die(unsigned int cpu)  {  	unsigned int boot_cpu = 0;  	void __iomem *base = omap_get_wakeupgen_base(); @@ -75,12 +70,3 @@ void __ref platform_cpu_die(unsigned int cpu)  		pr_debug("CPU%u: spurious wakeup call\n", cpu);  	}  } - -int platform_cpu_disable(unsigned int cpu) -{ -	/* -	 * we don't allow CPU 0 to be shutdown (it is still too special -	 * e.g. clock tick interrupts) -	 */ -	return cpu == 0 ? -EPERM : 0; -} diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index 06d8bc3a888..4d05fa8a4e4 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -49,7 +49,7 @@ void __iomem *omap4_get_scu_base(void)  	return scu_base;  } -void __cpuinit platform_secondary_init(unsigned int cpu) +static void __cpuinit omap4_secondary_init(unsigned int cpu)  {  	/*  	 * Configure ACTRL and enable NS SMP bit access on CPU1 on HS device. @@ -77,7 +77,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)  	spin_unlock(&boot_lock);  } -int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) +static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *idle)  {  	static struct clockdomain *cpu1_clkdm;  	static bool booted; @@ -165,7 +165,7 @@ static void __init wakeup_secondary(void)   * Initialise the CPU possible map early - this describes the CPUs   * which may be present or become present in the system.   */ -void __init smp_init_cpus(void) +static void __init omap4_smp_init_cpus(void)  {  	unsigned int i = 0, ncores = 1, cpu_id; @@ -196,7 +196,7 @@ void __init smp_init_cpus(void)  	set_smp_cross_call(gic_raise_softirq);  } -void __init platform_smp_prepare_cpus(unsigned int max_cpus) +static void __init omap4_smp_prepare_cpus(unsigned int max_cpus)  {  	/* @@ -207,3 +207,13 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)  		scu_enable(scu_base);  	wakeup_secondary();  } + +struct smp_operations omap4_smp_ops __initdata = { +	.smp_init_cpus		= omap4_smp_init_cpus, +	.smp_prepare_cpus	= omap4_smp_prepare_cpus, +	.smp_secondary_init	= omap4_secondary_init, +	.smp_boot_secondary	= omap4_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU +	.cpu_die		= omap4_cpu_die, +#endif +}; diff --git a/arch/arm/mach-realview/core.h b/arch/arm/mach-realview/core.h index f8f2c0ac4c0..78cd970c80f 100644 --- a/arch/arm/mach-realview/core.h +++ b/arch/arm/mach-realview/core.h @@ -56,4 +56,7 @@ extern void realview_init_early(void);  extern void realview_fixup(struct tag *tags, char **from,  			   struct meminfo *meminfo); +extern struct smp_operations realview_smp_ops; +extern void realview_cpu_die(unsigned int cpu); +  #endif diff --git a/arch/arm/mach-realview/hotplug.c b/arch/arm/mach-realview/hotplug.c index 57d9efba295..53818e5cd3a 100644 --- a/arch/arm/mach-realview/hotplug.c +++ b/arch/arm/mach-realview/hotplug.c @@ -16,8 +16,6 @@  #include <asm/cp15.h>  #include <asm/smp_plat.h> -extern volatile int pen_release; -  static inline void cpu_enter_lowpower(void)  {  	unsigned int v; @@ -89,17 +87,12 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)  	}  } -int platform_cpu_kill(unsigned int cpu) -{ -	return 1; -} -  /*   * platform-specific code to shutdown a CPU   *   * Called with IRQs disabled   */ -void platform_cpu_die(unsigned int cpu) +void __ref realview_cpu_die(unsigned int cpu)  {  	int spurious = 0; @@ -118,12 +111,3 @@ void platform_cpu_die(unsigned int cpu)  	if (spurious)  		pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);  } - -int platform_cpu_disable(unsigned int cpu) -{ -	/* -	 * we don't allow CPU 0 to be shutdown (it is still too special -	 * e.g. clock tick interrupts) -	 */ -	return cpu == 0 ? -EPERM : 0; -} diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c index 17c878ddbc7..300f7064465 100644 --- a/arch/arm/mach-realview/platsmp.c +++ b/arch/arm/mach-realview/platsmp.c @@ -22,9 +22,9 @@  #include <mach/board-pb11mp.h>  #include <mach/board-pbx.h> -#include "core.h" +#include <plat/platsmp.h> -extern void versatile_secondary_startup(void); +#include "core.h"  static void __iomem *scu_base_addr(void)  { @@ -43,7 +43,7 @@ static void __iomem *scu_base_addr(void)   * Initialise the CPU possible map early - this describes the CPUs   * which may be present or become present in the system.   */ -void __init smp_init_cpus(void) +static void __init realview_smp_init_cpus(void)  {  	void __iomem *scu_base = scu_base_addr();  	unsigned int i, ncores; @@ -63,7 +63,7 @@ void __init smp_init_cpus(void)  	set_smp_cross_call(gic_raise_softirq);  } -void __init platform_smp_prepare_cpus(unsigned int max_cpus) +static void __init realview_smp_prepare_cpus(unsigned int max_cpus)  {  	scu_enable(scu_base_addr()); @@ -77,3 +77,13 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)  	__raw_writel(virt_to_phys(versatile_secondary_startup),  		     __io_address(REALVIEW_SYS_FLAGSSET));  } + +struct smp_operations realview_smp_ops __initdata = { +	.smp_init_cpus		= realview_smp_init_cpus, +	.smp_prepare_cpus	= realview_smp_prepare_cpus, +	.smp_secondary_init	= versatile_secondary_init, +	.smp_boot_secondary	= versatile_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU +	.cpu_die		= realview_cpu_die, +#endif +}; diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c index b442fb276d5..a80269981dd 100644 --- a/arch/arm/mach-realview/realview_pb11mp.c +++ b/arch/arm/mach-realview/realview_pb11mp.c @@ -367,6 +367,7 @@ static void __init realview_pb11mp_init(void)  MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore")  	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */  	.atag_offset	= 0x100, +	.smp		= smp_ops(realview_smp_ops),  	.fixup		= realview_fixup,  	.map_io		= realview_pb11mp_map_io,  	.init_early	= realview_init_early, diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c index 5d2c8bebb06..a4b1aa93bb5 100644 --- a/arch/arm/mach-realview/realview_pbx.c +++ b/arch/arm/mach-realview/realview_pbx.c @@ -404,6 +404,7 @@ static void __init realview_pbx_init(void)  MACHINE_START(REALVIEW_PBX, "ARM-RealView PBX")  	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */  	.atag_offset	= 0x100, +	.smp		= smp_ops(realview_smp_ops),  	.fixup		= realview_pbx_fixup,  	.map_io		= realview_pbx_map_io,  	.init_early	= realview_init_early, diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c index cfc3b5c43ba..25eb88a923e 100644 --- a/arch/arm/mach-shmobile/board-ag5evm.c +++ b/arch/arm/mach-shmobile/board-ag5evm.c @@ -649,6 +649,7 @@ static void __init ag5evm_init(void)  }  MACHINE_START(AG5EVM, "ag5evm") +	.smp		= smp_ops(sh73a0_smp_ops),  	.map_io		= sh73a0_map_io,  	.init_early	= sh73a0_add_early_devices,  	.nr_irqs	= NR_IRQS_LEGACY, diff --git a/arch/arm/mach-shmobile/board-kota2.c b/arch/arm/mach-shmobile/board-kota2.c index 21dbe54304d..bf88f9a8b7a 100644 --- a/arch/arm/mach-shmobile/board-kota2.c +++ b/arch/arm/mach-shmobile/board-kota2.c @@ -545,6 +545,7 @@ static void __init kota2_init(void)  }  MACHINE_START(KOTA2, "kota2") +	.smp		= smp_ops(sh73a0_smp_ops),  	.map_io		= sh73a0_map_io,  	.init_early	= sh73a0_add_early_devices,  	.nr_irqs	= NR_IRQS_LEGACY, diff --git a/arch/arm/mach-shmobile/board-kzm9d.c b/arch/arm/mach-shmobile/board-kzm9d.c index 2c986eaae7b..b52bc0d1273 100644 --- a/arch/arm/mach-shmobile/board-kzm9d.c +++ b/arch/arm/mach-shmobile/board-kzm9d.c @@ -84,6 +84,7 @@ static const char *kzm9d_boards_compat_dt[] __initdata = {  };  DT_MACHINE_START(KZM9D_DT, "kzm9d") +	.smp		= smp_ops(emev2_smp_ops),  	.map_io		= emev2_map_io,  	.init_early	= emev2_add_early_devices,  	.nr_irqs	= NR_IRQS_LEGACY, diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c index fd21fb6f995..0a3d1f19077 100644 --- a/arch/arm/mach-shmobile/board-kzm9g.c +++ b/arch/arm/mach-shmobile/board-kzm9g.c @@ -776,6 +776,7 @@ static const char *kzm9g_boards_compat_dt[] __initdata = {  };  DT_MACHINE_START(KZM9G_DT, "kzm9g") +	.smp		= smp_ops(sh73a0_smp_ops),  	.map_io		= sh73a0_map_io,  	.init_early	= sh73a0_add_early_devices,  	.nr_irqs	= NR_IRQS_LEGACY, diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c index fcf5a47f477..01ce3f15c6a 100644 --- a/arch/arm/mach-shmobile/board-marzen.c +++ b/arch/arm/mach-shmobile/board-marzen.c @@ -102,6 +102,7 @@ static void __init marzen_init(void)  }  MACHINE_START(MARZEN, "marzen") +	.smp		= smp_ops(r8a7779_smp_ops),  	.map_io		= r8a7779_map_io,  	.init_early	= r8a7779_add_early_devices,  	.nr_irqs	= NR_IRQS_LEGACY, diff --git a/arch/arm/mach-shmobile/hotplug.c b/arch/arm/mach-shmobile/hotplug.c index 828d22f3af5..b09a0bdbf81 100644 --- a/arch/arm/mach-shmobile/hotplug.c +++ b/arch/arm/mach-shmobile/hotplug.c @@ -14,30 +14,16 @@  #include <linux/smp.h>  #include <linux/cpumask.h>  #include <linux/delay.h> +#include <linux/of.h>  #include <mach/common.h> +#include <mach/r8a7779.h> +#include <mach/emev2.h>  #include <asm/cacheflush.h> +#include <asm/mach-types.h>  static cpumask_t dead_cpus; -int platform_cpu_kill(unsigned int cpu) -{ -	int k; - -	/* this function is running on another CPU than the offline target, -	 * here we need wait for shutdown code in platform_cpu_die() to -	 * finish before asking SoC-specific code to power off the CPU core. -	 */ -	for (k = 0; k < 1000; k++) { -		if (cpumask_test_cpu(cpu, &dead_cpus)) -			return shmobile_platform_cpu_kill(cpu); - -		mdelay(1); -	} - -	return 0; -} - -void platform_cpu_die(unsigned int cpu) +void shmobile_cpu_die(unsigned int cpu)  {  	/* hardware shutdown code running on the CPU that is being offlined */  	flush_cache_all(); @@ -60,7 +46,7 @@ void platform_cpu_die(unsigned int cpu)  	}  } -int platform_cpu_disable(unsigned int cpu) +int shmobile_cpu_disable(unsigned int cpu)  {  	cpumask_clear_cpu(cpu, &dead_cpus);  	/* @@ -69,3 +55,8 @@ int platform_cpu_disable(unsigned int cpu)  	 */  	return cpu == 0 ? -EPERM : 0;  } + +int shmobile_cpu_is_dead(unsigned int cpu) +{ +	return cpumask_test_cpu(cpu, &dead_cpus); +} diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h index 45e61dada03..f80f9c54939 100644 --- a/arch/arm/mach-shmobile/include/mach/common.h +++ b/arch/arm/mach-shmobile/include/mach/common.h @@ -4,11 +4,10 @@  extern void shmobile_earlytimer_init(void);  extern struct sys_timer shmobile_timer;  extern void shmobile_setup_delay(unsigned int max_cpu_core_mhz, -				 unsigned int mult, unsigned int div); +			 unsigned int mult, unsigned int div);  struct twd_local_timer;  extern void shmobile_setup_console(void);  extern void shmobile_secondary_vector(void); -extern int shmobile_platform_cpu_kill(unsigned int cpu);  struct clk;  extern int shmobile_clk_init(void);  extern void shmobile_handle_irq_intc(struct pt_regs *); @@ -58,11 +57,6 @@ extern struct clk sh73a0_extal2_clk;  extern struct clk sh73a0_extcki_clk;  extern struct clk sh73a0_extalr_clk; -extern unsigned int sh73a0_get_core_count(void); -extern void sh73a0_secondary_init(unsigned int cpu); -extern int sh73a0_boot_secondary(unsigned int cpu); -extern void sh73a0_smp_prepare_cpus(void); -  extern void r8a7740_init_irq(void);  extern void r8a7740_map_io(void);  extern void r8a7740_add_early_devices(void); @@ -79,11 +73,6 @@ extern void r8a7779_pinmux_init(void);  extern void r8a7779_pm_init(void);  extern void r8a7740_meram_workaround(void); -extern unsigned int r8a7779_get_core_count(void); -extern int r8a7779_platform_cpu_kill(unsigned int cpu); -extern void r8a7779_secondary_init(unsigned int cpu); -extern int r8a7779_boot_secondary(unsigned int cpu); -extern void r8a7779_smp_prepare_cpus(void);  extern void r8a7779_register_twd(void);  extern void shmobile_init_late(void); @@ -100,4 +89,15 @@ int shmobile_cpuidle_init(void);  static inline int shmobile_cpuidle_init(void) { return 0; }  #endif +extern void shmobile_cpu_die(unsigned int cpu); +extern int shmobile_cpu_disable(unsigned int cpu); + +#ifdef CONFIG_HOTPLUG_CPU +extern int shmobile_cpu_is_dead(unsigned int cpu); +#else +static inline int shmobile_cpu_is_dead(unsigned int cpu) { return 1; } +#endif + +extern void shmobile_smp_init_cpus(unsigned int ncores); +  #endif /* __ARCH_MACH_COMMON_H */ diff --git a/arch/arm/mach-shmobile/include/mach/emev2.h b/arch/arm/mach-shmobile/include/mach/emev2.h index e6b0c1bf4b7..ac3751705ca 100644 --- a/arch/arm/mach-shmobile/include/mach/emev2.h +++ b/arch/arm/mach-shmobile/include/mach/emev2.h @@ -7,13 +7,10 @@ extern void emev2_add_early_devices(void);  extern void emev2_add_standard_devices(void);  extern void emev2_clock_init(void);  extern void emev2_set_boot_vector(unsigned long value); -extern unsigned int emev2_get_core_count(void); -extern int emev2_platform_cpu_kill(unsigned int cpu); -extern void emev2_secondary_init(unsigned int cpu); -extern int emev2_boot_secondary(unsigned int cpu); -extern void emev2_smp_prepare_cpus(void);  #define EMEV2_GPIO_BASE 200  #define EMEV2_GPIO_IRQ(n) (EMEV2_GPIO_BASE + (n)) +extern struct smp_operations emev2_smp_ops; +  #endif /* __ASM_EMEV2_H__ */ diff --git a/arch/arm/mach-shmobile/include/mach/r8a7779.h b/arch/arm/mach-shmobile/include/mach/r8a7779.h index b07ad318eb2..f504c5e81b4 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7779.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7779.h @@ -360,4 +360,6 @@ extern void r8a7779_add_device_to_domain(struct r8a7779_pm_domain *r8a7779_pd,  #define r8a7779_add_device_to_domain(pd, pdev) do { } while (0)  #endif /* CONFIG_PM */ +extern struct smp_operations r8a7779_smp_ops; +  #endif /* __ASM_R8A7779_H__ */ diff --git a/arch/arm/mach-shmobile/include/mach/sh73a0.h b/arch/arm/mach-shmobile/include/mach/sh73a0.h index fe950f25d79..606d31d02a4 100644 --- a/arch/arm/mach-shmobile/include/mach/sh73a0.h +++ b/arch/arm/mach-shmobile/include/mach/sh73a0.h @@ -557,4 +557,6 @@ enum {  #define SH73A0_PINT0_IRQ(irq) ((irq) + 700)  #define SH73A0_PINT1_IRQ(irq) ((irq) + 732) +extern struct smp_operations sh73a0_smp_ops; +  #endif /* __ASM_SH73A0_H__ */ diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c index fde0d23121d..ed8d2351915 100644 --- a/arch/arm/mach-shmobile/platsmp.c +++ b/arch/arm/mach-shmobile/platsmp.c @@ -11,100 +11,11 @@   * published by the Free Software Foundation.   */  #include <linux/init.h> -#include <linux/errno.h> -#include <linux/delay.h> -#include <linux/device.h>  #include <linux/smp.h> -#include <linux/io.h> -#include <linux/of.h>  #include <asm/hardware/gic.h> -#include <asm/mach-types.h> -#include <mach/common.h> -#include <mach/emev2.h> -#ifdef CONFIG_ARCH_SH73A0 -#define is_sh73a0() (machine_is_ag5evm() || machine_is_kota2() || \ -			of_machine_is_compatible("renesas,sh73a0")) -#else -#define is_sh73a0() (0) -#endif - -#define is_r8a7779() machine_is_marzen() - -#ifdef CONFIG_ARCH_EMEV2 -#define is_emev2() of_machine_is_compatible("renesas,emev2") -#else -#define is_emev2() (0) -#endif - -static unsigned int __init shmobile_smp_get_core_count(void) -{ -	if (is_sh73a0()) -		return sh73a0_get_core_count(); - -	if (is_r8a7779()) -		return r8a7779_get_core_count(); - -	if (is_emev2()) -		return emev2_get_core_count(); - -	return 1; -} - -static void __init shmobile_smp_prepare_cpus(void) -{ -	if (is_sh73a0()) -		sh73a0_smp_prepare_cpus(); - -	if (is_r8a7779()) -		r8a7779_smp_prepare_cpus(); - -	if (is_emev2()) -		emev2_smp_prepare_cpus(); -} - -int shmobile_platform_cpu_kill(unsigned int cpu) -{ -	if (is_r8a7779()) -		return r8a7779_platform_cpu_kill(cpu); - -	if (is_emev2()) -		return emev2_platform_cpu_kill(cpu); - -	return 1; -} - -void __cpuinit platform_secondary_init(unsigned int cpu) +void __init shmobile_smp_init_cpus(unsigned int ncores)  { -	trace_hardirqs_off(); - -	if (is_sh73a0()) -		sh73a0_secondary_init(cpu); - -	if (is_r8a7779()) -		r8a7779_secondary_init(cpu); - -	if (is_emev2()) -		emev2_secondary_init(cpu); -} - -int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) -{ -	if (is_sh73a0()) -		return sh73a0_boot_secondary(cpu); - -	if (is_r8a7779()) -		return r8a7779_boot_secondary(cpu); - -	if (is_emev2()) -		return emev2_boot_secondary(cpu); - -	return -ENOSYS; -} - -void __init smp_init_cpus(void) -{ -	unsigned int ncores = shmobile_smp_get_core_count();  	unsigned int i;  	if (ncores > nr_cpu_ids) { @@ -118,8 +29,3 @@ void __init smp_init_cpus(void)  	set_smp_cross_call(gic_raise_softirq);  } - -void __init platform_smp_prepare_cpus(unsigned int max_cpus) -{ -	shmobile_smp_prepare_cpus(); -} diff --git a/arch/arm/mach-shmobile/setup-emev2.c b/arch/arm/mach-shmobile/setup-emev2.c index 61446f30e39..a47beeb1828 100644 --- a/arch/arm/mach-shmobile/setup-emev2.c +++ b/arch/arm/mach-shmobile/setup-emev2.c @@ -461,6 +461,7 @@ void __init emev2_init_irq_dt(void)  }  DT_MACHINE_START(EMEV2_DT, "Generic Emma Mobile EV2 (Flattened Device Tree)") +	.smp		= smp_ops(emev2_smp_ops),  	.init_early	= emev2_init_delay,  	.nr_irqs	= NR_IRQS_LEGACY,  	.init_irq	= emev2_init_irq_dt, diff --git a/arch/arm/mach-shmobile/smp-emev2.c b/arch/arm/mach-shmobile/smp-emev2.c index 6a35c4a31e6..f978c5d0e1a 100644 --- a/arch/arm/mach-shmobile/smp-emev2.c +++ b/arch/arm/mach-shmobile/smp-emev2.c @@ -50,7 +50,7 @@ static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)  } -unsigned int __init emev2_get_core_count(void) +static unsigned int __init emev2_get_core_count(void)  {  	if (!scu_base) {  		scu_base = ioremap(EMEV2_SCU_BASE, PAGE_SIZE); @@ -62,17 +62,35 @@ unsigned int __init emev2_get_core_count(void)  	return scu_base ? scu_get_core_count(scu_base) : 1;  } -int emev2_platform_cpu_kill(unsigned int cpu) +static int emev2_platform_cpu_kill(unsigned int cpu)  {  	return 0; /* not supported yet */  } -void __cpuinit emev2_secondary_init(unsigned int cpu) +static int __maybe_unused emev2_cpu_kill(unsigned int cpu) +{ +	int k; + +	/* this function is running on another CPU than the offline target, +	 * here we need wait for shutdown code in platform_cpu_die() to +	 * finish before asking SoC-specific code to power off the CPU core. +	 */ +	for (k = 0; k < 1000; k++) { +		if (shmobile_cpu_is_dead(cpu)) +			return emev2_platform_cpu_kill(cpu); +		mdelay(1); +	} + +	return 0; +} + + +static void __cpuinit emev2_secondary_init(unsigned int cpu)  {  	gic_secondary_init(0);  } -int __cpuinit emev2_boot_secondary(unsigned int cpu) +static int __cpuinit emev2_boot_secondary(unsigned int cpu, struct task_struct *idle)  {  	cpu = cpu_logical_map(cpu); @@ -86,7 +104,7 @@ int __cpuinit emev2_boot_secondary(unsigned int cpu)  	return 0;  } -void __init emev2_smp_prepare_cpus(void) +static void __init emev2_smp_prepare_cpus(unsigned int max_cpus)  {  	int cpu = cpu_logical_map(0); @@ -95,3 +113,22 @@ void __init emev2_smp_prepare_cpus(void)  	/* enable cache coherency on CPU0 */  	modify_scu_cpu_psr(0, 3 << (cpu * 8));  } + +static void __init emev2_smp_init_cpus(void) +{ +	unsigned int ncores = emev2_get_core_count(); + +	shmobile_smp_init_cpus(ncores); +} + +struct smp_operations emev2_smp_ops __initdata = { +	.smp_init_cpus		= emev2_smp_init_cpus, +	.smp_prepare_cpus	= emev2_smp_prepare_cpus, +	.smp_secondary_init	= emev2_secondary_init, +	.smp_boot_secondary	= emev2_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU +	.cpu_kill		= emev2_cpu_kill, +	.cpu_die		= shmobile_cpu_die, +	.cpu_disable		= shmobile_cpu_disable, +#endif +}; diff --git a/arch/arm/mach-shmobile/smp-r8a7779.c b/arch/arm/mach-shmobile/smp-r8a7779.c index 6d1d0238cbf..2ce6af9a6a3 100644 --- a/arch/arm/mach-shmobile/smp-r8a7779.c +++ b/arch/arm/mach-shmobile/smp-r8a7779.c @@ -87,14 +87,14 @@ static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)  	__raw_writel(tmp, scu_base + 8);  } -unsigned int __init r8a7779_get_core_count(void) +static unsigned int __init r8a7779_get_core_count(void)  {  	void __iomem *scu_base = scu_base_addr();  	return scu_get_core_count(scu_base);  } -int r8a7779_platform_cpu_kill(unsigned int cpu) +static int r8a7779_platform_cpu_kill(unsigned int cpu)  {  	struct r8a7779_pm_ch *ch = NULL;  	int ret = -EIO; @@ -113,12 +113,31 @@ int r8a7779_platform_cpu_kill(unsigned int cpu)  	return ret ? ret : 1;  } -void __cpuinit r8a7779_secondary_init(unsigned int cpu) +static int __maybe_unused r8a7779_cpu_kill(unsigned int cpu) +{ +	int k; + +	/* this function is running on another CPU than the offline target, +	 * here we need wait for shutdown code in platform_cpu_die() to +	 * finish before asking SoC-specific code to power off the CPU core. +	 */ +	for (k = 0; k < 1000; k++) { +		if (shmobile_cpu_is_dead(cpu)) +			return r8a7779_platform_cpu_kill(cpu); + +		mdelay(1); +	} + +	return 0; +} + + +static void __cpuinit r8a7779_secondary_init(unsigned int cpu)  {  	gic_secondary_init(0);  } -int __cpuinit r8a7779_boot_secondary(unsigned int cpu) +static int __cpuinit r8a7779_boot_secondary(unsigned int cpu, struct task_struct *idle)  {  	struct r8a7779_pm_ch *ch = NULL;  	int ret = -EIO; @@ -137,7 +156,7 @@ int __cpuinit r8a7779_boot_secondary(unsigned int cpu)  	return ret;  } -void __init r8a7779_smp_prepare_cpus(void) +static void __init r8a7779_smp_prepare_cpus(unsigned int max_cpus)  {  	int cpu = cpu_logical_map(0); @@ -156,3 +175,22 @@ void __init r8a7779_smp_prepare_cpus(void)  	r8a7779_platform_cpu_kill(2);  	r8a7779_platform_cpu_kill(3);  } + +static void __init r8a7779_smp_init_cpus(void) +{ +	unsigned int ncores = r8a7779_get_core_count(); + +	shmobile_smp_init_cpus(ncores); +} + +struct smp_operations r8a7779_smp_ops  __initdata = { +	.smp_init_cpus		= r8a7779_smp_init_cpus, +	.smp_prepare_cpus	= r8a7779_smp_prepare_cpus, +	.smp_secondary_init	= r8a7779_secondary_init, +	.smp_boot_secondary	= r8a7779_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU +	.cpu_kill		= r8a7779_cpu_kill, +	.cpu_die		= shmobile_cpu_die, +	.cpu_disable		= shmobile_cpu_disable, +#endif +}; diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c index e36c41c4ab4..624f00f70ab 100644 --- a/arch/arm/mach-shmobile/smp-sh73a0.c +++ b/arch/arm/mach-shmobile/smp-sh73a0.c @@ -22,8 +22,10 @@  #include <linux/smp.h>  #include <linux/spinlock.h>  #include <linux/io.h> +#include <linux/delay.h>  #include <mach/common.h>  #include <asm/smp_plat.h> +#include <mach/sh73a0.h>  #include <asm/smp_scu.h>  #include <asm/smp_twd.h>  #include <asm/hardware/gic.h> @@ -64,19 +66,19 @@ static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)  	__raw_writel(tmp, scu_base + 8);  } -unsigned int __init sh73a0_get_core_count(void) +static unsigned int __init sh73a0_get_core_count(void)  {  	void __iomem *scu_base = scu_base_addr();  	return scu_get_core_count(scu_base);  } -void __cpuinit sh73a0_secondary_init(unsigned int cpu) +static void __cpuinit sh73a0_secondary_init(unsigned int cpu)  {  	gic_secondary_init(0);  } -int __cpuinit sh73a0_boot_secondary(unsigned int cpu) +static int __cpuinit sh73a0_boot_secondary(unsigned int cpu, struct task_struct *idle)  {  	cpu = cpu_logical_map(cpu); @@ -91,7 +93,7 @@ int __cpuinit sh73a0_boot_secondary(unsigned int cpu)  	return 0;  } -void __init sh73a0_smp_prepare_cpus(void) +static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus)  {  	int cpu = cpu_logical_map(0); @@ -104,3 +106,41 @@ void __init sh73a0_smp_prepare_cpus(void)  	/* enable cache coherency on CPU0 */  	modify_scu_cpu_psr(0, 3 << (cpu * 8));  } + +static void __init sh73a0_smp_init_cpus(void) +{ +	unsigned int ncores = sh73a0_get_core_count(); + +	shmobile_smp_init_cpus(ncores); +} + +static int __maybe_unused sh73a0_cpu_kill(unsigned int cpu) +{ +	int k; + +	/* this function is running on another CPU than the offline target, +	 * here we need wait for shutdown code in platform_cpu_die() to +	 * finish before asking SoC-specific code to power off the CPU core. +	 */ +	for (k = 0; k < 1000; k++) { +		if (shmobile_cpu_is_dead(cpu)) +			return 1; + +		mdelay(1); +	} + +	return 0; +} + + +struct smp_operations sh73a0_smp_ops __initdata = { +	.smp_init_cpus		= sh73a0_smp_init_cpus, +	.smp_prepare_cpus	= sh73a0_smp_prepare_cpus, +	.smp_secondary_init	= sh73a0_secondary_init, +	.smp_boot_secondary	= sh73a0_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU +	.cpu_kill		= sh73a0_cpu_kill, +	.cpu_die		= shmobile_cpu_die, +	.cpu_disable		= shmobile_cpu_disable, +#endif +}; diff --git a/arch/arm/mach-spear13xx/hotplug.c b/arch/arm/mach-spear13xx/hotplug.c index 5c6867b46d0..a7d2dd11a4f 100644 --- a/arch/arm/mach-spear13xx/hotplug.c +++ b/arch/arm/mach-spear13xx/hotplug.c @@ -17,8 +17,6 @@  #include <asm/cp15.h>  #include <asm/smp_plat.h> -extern volatile int pen_release; -  static inline void cpu_enter_lowpower(void)  {  	unsigned int v; @@ -56,7 +54,7 @@ static inline void cpu_leave_lowpower(void)  	: "cc");  } -static inline void platform_do_lowpower(unsigned int cpu, int *spurious) +static inline void spear13xx_do_lowpower(unsigned int cpu, int *spurious)  {  	for (;;) {  		wfi(); @@ -79,17 +77,12 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)  	}  } -int platform_cpu_kill(unsigned int cpu) -{ -	return 1; -} -  /*   * platform-specific code to shutdown a CPU   *   * Called with IRQs disabled   */ -void __cpuinit platform_cpu_die(unsigned int cpu) +void __ref spear13xx_cpu_die(unsigned int cpu)  {  	int spurious = 0; @@ -97,7 +90,7 @@ void __cpuinit platform_cpu_die(unsigned int cpu)  	 * we're ready for shutdown now, so do it  	 */  	cpu_enter_lowpower(); -	platform_do_lowpower(cpu, &spurious); +	spear13xx_do_lowpower(cpu, &spurious);  	/*  	 * bring this CPU back into the world of cache @@ -108,12 +101,3 @@ void __cpuinit platform_cpu_die(unsigned int cpu)  	if (spurious)  		pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);  } - -int platform_cpu_disable(unsigned int cpu) -{ -	/* -	 * we don't allow CPU 0 to be shutdown (it is still too special -	 * e.g. clock tick interrupts) -	 */ -	return cpu == 0 ? -EPERM : 0; -} diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h index dac57fd0cdf..c33f4d9361b 100644 --- a/arch/arm/mach-spear13xx/include/mach/generic.h +++ b/arch/arm/mach-spear13xx/include/mach/generic.h @@ -33,6 +33,9 @@ void __init spear13xx_l2x0_init(void);  bool dw_dma_filter(struct dma_chan *chan, void *slave);  void spear_restart(char, const char *);  void spear13xx_secondary_startup(void); +void __cpuinit spear13xx_cpu_die(unsigned int cpu); + +extern struct smp_operations spear13xx_smp_ops;  #ifdef CONFIG_MACH_SPEAR1310  void __init spear1310_clk_init(void); diff --git a/arch/arm/mach-spear13xx/platsmp.c b/arch/arm/mach-spear13xx/platsmp.c index f5d07f2663d..2eaa3fa7b43 100644 --- a/arch/arm/mach-spear13xx/platsmp.c +++ b/arch/arm/mach-spear13xx/platsmp.c @@ -19,18 +19,13 @@  #include <asm/hardware/gic.h>  #include <asm/smp_scu.h>  #include <mach/spear.h> +#include <mach/generic.h> -/* - * control for which core is the next to come out of the secondary - * boot "holding pen" - */ -volatile int __cpuinitdata pen_release = -1;  static DEFINE_SPINLOCK(boot_lock);  static void __iomem *scu_base = IOMEM(VA_SCU_BASE); -extern void spear13xx_secondary_startup(void); -void __cpuinit platform_secondary_init(unsigned int cpu) +static void __cpuinit spear13xx_secondary_init(unsigned int cpu)  {  	/*  	 * if any interrupts are already enabled for the primary @@ -53,7 +48,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)  	spin_unlock(&boot_lock);  } -int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) +static int __cpuinit spear13xx_boot_secondary(unsigned int cpu, struct task_struct *idle)  {  	unsigned long timeout; @@ -97,7 +92,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)   * Initialise the CPU possible map early - this describes the CPUs   * which may be present or become present in the system.   */ -void __init smp_init_cpus(void) +static void __init spear13xx_smp_init_cpus(void)  {  	unsigned int i, ncores = scu_get_core_count(scu_base); @@ -113,7 +108,7 @@ void __init smp_init_cpus(void)  	set_smp_cross_call(gic_raise_softirq);  } -void __init platform_smp_prepare_cpus(unsigned int max_cpus) +static void __init spear13xx_smp_prepare_cpus(unsigned int max_cpus)  {  	scu_enable(scu_base); @@ -125,3 +120,13 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)  	 */  	__raw_writel(virt_to_phys(spear13xx_secondary_startup), SYS_LOCATION);  } + +struct smp_operations spear13xx_smp_ops __initdata = { +       .smp_init_cpus		= spear13xx_smp_init_cpus, +       .smp_prepare_cpus	= spear13xx_smp_prepare_cpus, +       .smp_secondary_init	= spear13xx_secondary_init, +       .smp_boot_secondary	= spear13xx_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU +       .cpu_die			= spear13xx_cpu_die, +#endif +}; diff --git a/arch/arm/mach-spear13xx/spear1310.c b/arch/arm/mach-spear13xx/spear1310.c index 732d29bc733..9fbbfc5650a 100644 --- a/arch/arm/mach-spear13xx/spear1310.c +++ b/arch/arm/mach-spear13xx/spear1310.c @@ -78,6 +78,7 @@ static void __init spear1310_map_io(void)  }  DT_MACHINE_START(SPEAR1310_DT, "ST SPEAr1310 SoC with Flattened Device Tree") +	.smp		=	smp_ops(spear13xx_smp_ops),  	.map_io		=	spear1310_map_io,  	.init_irq	=	spear13xx_dt_init_irq,  	.handle_irq	=	gic_handle_irq, diff --git a/arch/arm/mach-spear13xx/spear1340.c b/arch/arm/mach-spear13xx/spear1340.c index 81e4ed76ad0..081014fb314 100644 --- a/arch/arm/mach-spear13xx/spear1340.c +++ b/arch/arm/mach-spear13xx/spear1340.c @@ -182,6 +182,7 @@ static const char * const spear1340_dt_board_compat[] = {  };  DT_MACHINE_START(SPEAR1340_DT, "ST SPEAr1340 SoC with Flattened Device Tree") +	.smp		=	smp_ops(spear13xx_smp_ops),  	.map_io		=	spear13xx_map_io,  	.init_irq	=	spear13xx_dt_init_irq,  	.handle_irq	=	gic_handle_irq, diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c index 5957ffbd4af..5d8c8fb060b 100644 --- a/arch/arm/mach-tegra/board-dt-tegra20.c +++ b/arch/arm/mach-tegra/board-dt-tegra20.c @@ -44,6 +44,7 @@  #include "board.h"  #include "clock.h"  #include "devices.h" +#include "common.h"  struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {  	OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC1_BASE, "sdhci-tegra.0", NULL), @@ -152,6 +153,7 @@ static const char *tegra20_dt_board_compat[] = {  DT_MACHINE_START(TEGRA_DT, "nVidia Tegra20 (Flattened Device Tree)")  	.map_io		= tegra_map_common_io, +	.smp		= smp_ops(tegra_smp_ops),  	.init_early	= tegra20_init_early,  	.init_irq	= tegra_dt_init_irq,  	.handle_irq	= gic_handle_irq, diff --git a/arch/arm/mach-tegra/board-dt-tegra30.c b/arch/arm/mach-tegra/board-dt-tegra30.c index 53bf60f1158..e4a676d4ddf 100644 --- a/arch/arm/mach-tegra/board-dt-tegra30.c +++ b/arch/arm/mach-tegra/board-dt-tegra30.c @@ -37,6 +37,7 @@  #include "board.h"  #include "clock.h" +#include "common.h"  struct of_dev_auxdata tegra30_auxdata_lookup[] __initdata = {  	OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000000, "sdhci-tegra.0", NULL), @@ -83,6 +84,7 @@ static const char *tegra30_dt_board_compat[] = {  };  DT_MACHINE_START(TEGRA30_DT, "NVIDIA Tegra30 (Flattened Device Tree)") +	.smp		= smp_ops(tegra_smp_ops),  	.map_io		= tegra_map_common_io,  	.init_early	= tegra30_init_early,  	.init_irq	= tegra_dt_init_irq, diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c index 0560538bf59..0b0a5f556d3 100644 --- a/arch/arm/mach-tegra/common.c +++ b/arch/arm/mach-tegra/common.c @@ -31,6 +31,7 @@  #include "board.h"  #include "clock.h" +#include "common.h"  #include "fuse.h"  #include "pmc.h"  #include "apbio.h" diff --git a/arch/arm/mach-tegra/common.h b/arch/arm/mach-tegra/common.h new file mode 100644 index 00000000000..02f71b4f1e5 --- /dev/null +++ b/arch/arm/mach-tegra/common.h @@ -0,0 +1,4 @@ +extern struct smp_operations tegra_smp_ops; + +extern void tegra_cpu_die(unsigned int cpu); +extern int tegra_cpu_disable(unsigned int cpu); diff --git a/arch/arm/mach-tegra/hotplug.c b/arch/arm/mach-tegra/hotplug.c index d02a3547613..dca5141a2c3 100644 --- a/arch/arm/mach-tegra/hotplug.c +++ b/arch/arm/mach-tegra/hotplug.c @@ -19,17 +19,12 @@  static void (*tegra_hotplug_shutdown)(void); -int platform_cpu_kill(unsigned int cpu) -{ -	return 1; -} -  /*   * platform-specific code to shutdown a CPU   *   * Called with IRQs disabled   */ -void platform_cpu_die(unsigned int cpu) +void __ref tegra_cpu_die(unsigned int cpu)  {  	cpu = cpu_logical_map(cpu); @@ -47,7 +42,7 @@ void platform_cpu_die(unsigned int cpu)  	BUG();  } -int platform_cpu_disable(unsigned int cpu) +int tegra_cpu_disable(unsigned int cpu)  {  	/*  	 * we don't allow CPU 0 to be shutdown (it is still too special diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c index 96ed1718eef..81cb26591ac 100644 --- a/arch/arm/mach-tegra/platsmp.c +++ b/arch/arm/mach-tegra/platsmp.c @@ -33,6 +33,8 @@  #include "reset.h"  #include "tegra_cpu_car.h" +#include "common.h" +  extern void tegra_secondary_startup(void);  static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE); @@ -40,7 +42,7 @@ static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE);  #define EVP_CPU_RESET_VECTOR \  	(IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100) -void __cpuinit platform_secondary_init(unsigned int cpu) +static void __cpuinit tegra_secondary_init(unsigned int cpu)  {  	/*  	 * if any interrupts are already enabled for the primary @@ -100,7 +102,7 @@ static int tegra30_power_up_cpu(unsigned int cpu)  	return 0;  } -int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) +static int __cpuinit tegra_boot_secondary(unsigned int cpu, struct task_struct *idle)  {  	int status; @@ -146,7 +148,7 @@ done:   * Initialise the CPU possible map early - this describes the CPUs   * which may be present or become present in the system.   */ -void __init smp_init_cpus(void) +static void __init tegra_smp_init_cpus(void)  {  	unsigned int i, ncores = scu_get_core_count(scu_base); @@ -162,8 +164,19 @@ void __init smp_init_cpus(void)  	set_smp_cross_call(gic_raise_softirq);  } -void __init platform_smp_prepare_cpus(unsigned int max_cpus) +static void __init tegra_smp_prepare_cpus(unsigned int max_cpus)  {  	tegra_cpu_reset_handler_init();  	scu_enable(scu_base);  } + +struct smp_operations tegra_smp_ops __initdata = { +	.smp_init_cpus		= tegra_smp_init_cpus, +	.smp_prepare_cpus	= tegra_smp_prepare_cpus, +	.smp_secondary_init	= tegra_secondary_init, +	.smp_boot_secondary	= tegra_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU +	.cpu_die		= tegra_cpu_die, +	.cpu_disable		= tegra_cpu_disable, +#endif +}; diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 1d2e3c6f8b5..e783790c79c 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -673,6 +673,7 @@ static void __init hrefv60_init_machine(void)  MACHINE_START(U8500, "ST-Ericsson MOP500 platform")  	/* Maintainer: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> */  	.atag_offset	= 0x100, +	.smp		= smp_ops(ux500_smp_ops),  	.map_io		= u8500_map_io,  	.init_irq	= ux500_init_irq,  	/* we re-use nomadik timer here */ @@ -684,6 +685,7 @@ MACHINE_END  MACHINE_START(HREFV60, "ST-Ericsson U8500 Platform HREFv60+")  	.atag_offset	= 0x100, +	.smp		= smp_ops(ux500_smp_ops),  	.map_io		= u8500_map_io,  	.init_irq	= ux500_init_irq,  	.timer		= &ux500_timer, @@ -694,6 +696,7 @@ MACHINE_END  MACHINE_START(SNOWBALL, "Calao Systems Snowball platform")  	.atag_offset	= 0x100, +	.smp		= smp_ops(ux500_smp_ops),  	.map_io		= u8500_map_io,  	.init_irq	= ux500_init_irq,  	/* we re-use nomadik timer here */ @@ -823,6 +826,7 @@ static const char * u8500_dt_board_compat[] = {  DT_MACHINE_START(U8500_DT, "ST-Ericsson U8500 platform (Device Tree Support)") +	.smp		= smp_ops(ux500_smp_ops),  	.map_io		= u8500_map_io,  	.init_irq	= ux500_init_irq,  	/* we re-use nomadik timer here */ diff --git a/arch/arm/mach-ux500/hotplug.c b/arch/arm/mach-ux500/hotplug.c index c76f0f456f0..2f6af259015 100644 --- a/arch/arm/mach-ux500/hotplug.c +++ b/arch/arm/mach-ux500/hotplug.c @@ -15,13 +15,18 @@  #include <asm/cacheflush.h>  #include <asm/smp_plat.h> -extern volatile int pen_release; +#include <mach/setup.h> -static inline void platform_do_lowpower(unsigned int cpu) +/* + * platform-specific code to shutdown a CPU + * + * Called with IRQs disabled + */ +void __ref ux500_cpu_die(unsigned int cpu)  {  	flush_cache_all(); -	/* we put the platform to just WFI */ +	/* directly enter low power state, skipping secure registers */  	for (;;) {  		__asm__ __volatile__("dsb\n\t" "wfi\n\t"  				: : : "memory"); @@ -33,28 +38,3 @@ static inline void platform_do_lowpower(unsigned int cpu)  		}  	}  } - -int platform_cpu_kill(unsigned int cpu) -{ -	return 1; -} - -/* - * platform-specific code to shutdown a CPU - * - * Called with IRQs disabled - */ -void platform_cpu_die(unsigned int cpu) -{ -	/* directly enter low power state, skipping secure registers */ -	platform_do_lowpower(cpu); -} - -int platform_cpu_disable(unsigned int cpu) -{ -	/* -	 * we don't allow CPU 0 to be shutdown (it is still too special -	 * e.g. clock tick interrupts) -	 */ -	return cpu == 0 ? -EPERM : 0; -} diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h index 7914e5eaa9c..6be4c4d2ab8 100644 --- a/arch/arm/mach-ux500/include/mach/setup.h +++ b/arch/arm/mach-ux500/include/mach/setup.h @@ -45,4 +45,7 @@ extern struct sys_timer ux500_timer;  	.type		= MT_MEMORY,		\  } +extern struct smp_operations ux500_smp_ops; +extern void ux500_cpu_die(unsigned int cpu); +  #endif /*  __ASM_ARCH_SETUP_H */ diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c index a5dda68444d..3db7782f3af 100644 --- a/arch/arm/mach-ux500/platsmp.c +++ b/arch/arm/mach-ux500/platsmp.c @@ -28,12 +28,6 @@  extern void u8500_secondary_startup(void);  /* - * control for which core is the next to come out of the secondary - * boot "holding pen" - */ -volatile int pen_release = -1; - -/*   * Write pen_release in a way that is guaranteed to be visible to all   * observers, irrespective of whether they're taking part in coherency   * or not.  This is necessary for the hotplug code to work reliably. @@ -58,7 +52,7 @@ static void __iomem *scu_base_addr(void)  static DEFINE_SPINLOCK(boot_lock); -void __cpuinit platform_secondary_init(unsigned int cpu) +static void __cpuinit ux500_secondary_init(unsigned int cpu)  {  	/*  	 * if any interrupts are already enabled for the primary @@ -80,7 +74,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)  	spin_unlock(&boot_lock);  } -int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) +static int __cpuinit ux500_boot_secondary(unsigned int cpu, struct task_struct *idle)  {  	unsigned long timeout; @@ -145,7 +139,7 @@ static void __init wakeup_secondary(void)   * Initialise the CPU possible map early - this describes the CPUs   * which may be present or become present in the system.   */ -void __init smp_init_cpus(void) +static void __init ux500_smp_init_cpus(void)  {  	void __iomem *scu_base = scu_base_addr();  	unsigned int i, ncores; @@ -165,9 +159,19 @@ void __init smp_init_cpus(void)  	set_smp_cross_call(gic_raise_softirq);  } -void __init platform_smp_prepare_cpus(unsigned int max_cpus) +static void __init ux500_smp_prepare_cpus(unsigned int max_cpus)  {  	scu_enable(scu_base_addr());  	wakeup_secondary();  } + +struct smp_operations ux500_smp_ops __initdata = { +	.smp_init_cpus		= ux500_smp_init_cpus, +	.smp_prepare_cpus	= ux500_smp_prepare_cpus, +	.smp_secondary_init	= ux500_secondary_init, +	.smp_boot_secondary	= ux500_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU +	.cpu_die		= ux500_cpu_die, +#endif +}; diff --git a/arch/arm/mach-vexpress/core.h b/arch/arm/mach-vexpress/core.h index a3a4980770b..f134cd4a85f 100644 --- a/arch/arm/mach-vexpress/core.h +++ b/arch/arm/mach-vexpress/core.h @@ -5,3 +5,7 @@  #define V2T_PERIPH 0xf8200000  void vexpress_dt_smp_map_io(void); + +extern struct smp_operations	vexpress_smp_ops; + +extern void vexpress_cpu_die(unsigned int cpu); diff --git a/arch/arm/mach-vexpress/hotplug.c b/arch/arm/mach-vexpress/hotplug.c index c504a72b94d..a141b98d84f 100644 --- a/arch/arm/mach-vexpress/hotplug.c +++ b/arch/arm/mach-vexpress/hotplug.c @@ -16,8 +16,6 @@  #include <asm/smp_plat.h>  #include <asm/cp15.h> -extern volatile int pen_release; -  static inline void cpu_enter_lowpower(void)  {  	unsigned int v; @@ -84,17 +82,12 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)  	}  } -int platform_cpu_kill(unsigned int cpu) -{ -	return 1; -} -  /*   * platform-specific code to shutdown a CPU   *   * Called with IRQs disabled   */ -void platform_cpu_die(unsigned int cpu) +void __ref vexpress_cpu_die(unsigned int cpu)  {  	int spurious = 0; @@ -113,12 +106,3 @@ void platform_cpu_die(unsigned int cpu)  	if (spurious)  		pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);  } - -int platform_cpu_disable(unsigned int cpu) -{ -	/* -	 * we don't allow CPU 0 to be shutdown (it is still too special -	 * e.g. clock tick interrupts) -	 */ -	return cpu == 0 ? -EPERM : 0; -} diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c index 14ba1128ae8..7db27c8c05c 100644 --- a/arch/arm/mach-vexpress/platsmp.c +++ b/arch/arm/mach-vexpress/platsmp.c @@ -20,9 +20,9 @@  #include <mach/motherboard.h> -#include "core.h" +#include <plat/platsmp.h> -extern void versatile_secondary_startup(void); +#include "core.h"  #if defined(CONFIG_OF) @@ -167,7 +167,7 @@ void __init vexpress_dt_smp_prepare_cpus(unsigned int max_cpus)   * Initialise the CPU possible map early - this describes the CPUs   * which may be present or become present in the system.   */ -void __init smp_init_cpus(void) +static void __init vexpress_smp_init_cpus(void)  {  	if (ct_desc)  		ct_desc->init_cpu_map(); @@ -176,7 +176,7 @@ void __init smp_init_cpus(void)  } -void __init platform_smp_prepare_cpus(unsigned int max_cpus) +static void __init vexpress_smp_prepare_cpus(unsigned int max_cpus)  {  	/*  	 * Initialise the present map, which describes the set of CPUs @@ -195,3 +195,13 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)  	 */  	v2m_flags_set(virt_to_phys(versatile_secondary_startup));  } + +struct smp_operations __initdata vexpress_smp_ops = { +	.smp_init_cpus		= vexpress_smp_init_cpus, +	.smp_prepare_cpus	= vexpress_smp_prepare_cpus, +	.smp_secondary_init	= versatile_secondary_init, +	.smp_boot_secondary	= versatile_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU +	.cpu_die		= vexpress_cpu_die, +#endif +}; diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c index 2ca86c50174..5f6b7d543e5 100644 --- a/arch/arm/mach-vexpress/v2m.c +++ b/arch/arm/mach-vexpress/v2m.c @@ -5,6 +5,7 @@  #include <linux/amba/bus.h>  #include <linux/amba/mmci.h>  #include <linux/io.h> +#include <linux/smp.h>  #include <linux/init.h>  #include <linux/of_address.h>  #include <linux/of_fdt.h> @@ -38,6 +39,7 @@  #include <mach/motherboard.h>  #include <plat/sched_clock.h> +#include <plat/platsmp.h>  #include "core.h" @@ -530,6 +532,7 @@ static void __init v2m_init(void)  MACHINE_START(VEXPRESS, "ARM-Versatile Express")  	.atag_offset	= 0x100, +	.smp		= smp_ops(vexpress_smp_ops),  	.map_io		= v2m_map_io,  	.init_early	= v2m_init_early,  	.init_irq	= v2m_init_irq, @@ -661,6 +664,7 @@ const static char *v2m_dt_match[] __initconst = {  DT_MACHINE_START(VEXPRESS_DT, "ARM-Versatile Express")  	.dt_compat	= v2m_dt_match, +	.smp		= smp_ops(vexpress_smp_ops),  	.map_io		= v2m_dt_map_io,  	.init_early	= v2m_dt_init_early,  	.init_irq	= v2m_dt_init_irq, diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h index 28ba09f4ebb..ead901814c0 100644 --- a/arch/arm/plat-mxc/include/mach/common.h +++ b/arch/arm/plat-mxc/include/mach/common.h @@ -139,6 +139,8 @@ extern void imx_gpc_post_resume(void);  extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);  extern void imx6q_clock_map_io(void); +extern void imx_cpu_die(unsigned int cpu); +  #ifdef CONFIG_PM  extern void imx6q_pm_init(void);  extern void imx51_pm_init(void); @@ -155,4 +157,6 @@ extern int mx51_neon_fixup(void);  static inline int mx51_neon_fixup(void) { return 0; }  #endif +extern struct smp_operations imx_smp_ops; +  #endif diff --git a/arch/arm/plat-versatile/include/plat/platsmp.h b/arch/arm/plat-versatile/include/plat/platsmp.h new file mode 100644 index 00000000000..50fb830192e --- /dev/null +++ b/arch/arm/plat-versatile/include/plat/platsmp.h @@ -0,0 +1,14 @@ +/* + *  linux/arch/arm/plat-versatile/include/plat/platsmp.h + * + *  Copyright (C) 2011 ARM Ltd. + *  All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +extern void versatile_secondary_startup(void); +extern void versatile_secondary_init(unsigned int cpu); +extern int  versatile_boot_secondary(unsigned int cpu, struct task_struct *idle); diff --git a/arch/arm/plat-versatile/platsmp.c b/arch/arm/plat-versatile/platsmp.c index d7c5c171f5a..04ca4937d8c 100644 --- a/arch/arm/plat-versatile/platsmp.c +++ b/arch/arm/plat-versatile/platsmp.c @@ -20,12 +20,6 @@  #include <asm/hardware/gic.h>  /* - * control for which core is the next to come out of the secondary - * boot "holding pen" - */ -volatile int __cpuinitdata pen_release = -1; - -/*   * Write pen_release in a way that is guaranteed to be visible to all   * observers, irrespective of whether they're taking part in coherency   * or not.  This is necessary for the hotplug code to work reliably. @@ -40,7 +34,7 @@ static void __cpuinit write_pen_release(int val)  static DEFINE_SPINLOCK(boot_lock); -void __cpuinit platform_secondary_init(unsigned int cpu) +void __cpuinit versatile_secondary_init(unsigned int cpu)  {  	/*  	 * if any interrupts are already enabled for the primary @@ -62,7 +56,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)  	spin_unlock(&boot_lock);  } -int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) +int __cpuinit versatile_boot_secondary(unsigned int cpu, struct task_struct *idle)  {  	unsigned long timeout; |