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>
This commit is contained in:
Olof Johansson 2012-09-22 00:06:21 -07:00
commit 25468fe89f
74 changed files with 535 additions and 401 deletions

View File

@ -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 */

View File

@ -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 */

View File

@ -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();

View File

@ -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);

View File

@ -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 */

View File

@ -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;
}

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -32,18 +32,13 @@
#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
@ -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
};

View File

@ -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;

View File

@ -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,

View File

@ -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;
}

View File

@ -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
};

View File

@ -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;
}

View File

@ -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,

View File

@ -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
};

View File

@ -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,

View File

@ -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,

2
arch/arm/mach-msm/core.h Normal file
View File

@ -0,0 +1,2 @@
extern struct smp_operations msm_smp_ops;
extern void msm_cpu_die(unsigned int cpu);

View File

@ -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;
}

View File

@ -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
};

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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

View File

@ -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;
}

View File

@ -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
};

View File

@ -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

View File

@ -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;
}

View File

@ -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
};

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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);
}

View File

@ -8,7 +8,6 @@ extern void shmobile_setup_delay(unsigned int max_cpu_core_mhz,
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 */

View File

@ -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__ */

View File

@ -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__ */

View File

@ -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__ */

View File

@ -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)
void __init shmobile_smp_init_cpus(unsigned int ncores)
{
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)
{
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();
}

View File

@ -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,

View File

@ -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
};

View File

@ -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
};

View File

@ -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
};

View File

@ -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;
}

View File

@ -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);

View File

@ -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
};

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -31,6 +31,7 @@
#include "board.h"
#include "clock.h"
#include "common.h"
#include "fuse.h"
#include "pmc.h"
#include "apbio.h"

View File

@ -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);

View File

@ -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

View File

@ -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
};

View File

@ -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 */

View File

@ -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;
}

View File

@ -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 */

View File

@ -27,12 +27,6 @@
/* This is called from headsmp.S to wakeup the secondary core */
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
@ -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
};

View File

@ -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);

View File

@ -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;
}

View File

@ -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
};

View File

@ -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,

View File

@ -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

View File

@ -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);

View File

@ -19,12 +19,6 @@
#include <asm/smp_plat.h>
#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
@ -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;