Commit 25468fe8 authored by Olof Johansson's avatar Olof Johansson

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: default avatarOlof Johansson <olof@lixom.net>
parents a283580c 28e8e29c
...@@ -14,6 +14,12 @@ struct tag; ...@@ -14,6 +14,12 @@ struct tag;
struct meminfo; struct meminfo;
struct sys_timer; struct sys_timer;
struct pt_regs; 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 { struct machine_desc {
unsigned int nr; /* architecture number */ unsigned int nr; /* architecture number */
...@@ -35,6 +41,7 @@ struct machine_desc { ...@@ -35,6 +41,7 @@ struct machine_desc {
unsigned char reserve_lp1 :1; /* never has lp1 */ unsigned char reserve_lp1 :1; /* never has lp1 */
unsigned char reserve_lp2 :1; /* never has lp2 */ unsigned char reserve_lp2 :1; /* never has lp2 */
char restart_mode; /* default restart mode */ char restart_mode; /* default restart mode */
struct smp_operations *smp; /* SMP operations */
void (*fixup)(struct tag *, char **, void (*fixup)(struct tag *, char **,
struct meminfo *); struct meminfo *);
void (*reserve)(void);/* reserve mem blocks */ void (*reserve)(void);/* reserve mem blocks */
......
...@@ -60,15 +60,6 @@ extern int boot_secondary(unsigned int cpu, struct task_struct *); ...@@ -60,15 +60,6 @@ extern int boot_secondary(unsigned int cpu, struct task_struct *);
*/ */
asmlinkage void secondary_start_kernel(void); 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. * Initial data for bringing up a secondary CPU.
...@@ -79,18 +70,47 @@ struct secondary_data { ...@@ -79,18 +70,47 @@ struct secondary_data {
void *stack; void *stack;
}; };
extern struct secondary_data secondary_data; extern struct secondary_data secondary_data;
extern volatile int pen_release;
extern int __cpu_disable(void); extern int __cpu_disable(void);
extern int platform_cpu_disable(unsigned int cpu);
extern void __cpu_die(unsigned int cpu); extern void __cpu_die(unsigned int cpu);
extern void cpu_die(void); 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_single_ipi(int cpu);
extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); 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 */ #endif /* ifndef __ASM_ARM_SMP_H */
...@@ -977,8 +977,10 @@ void __init setup_arch(char **cmdline_p) ...@@ -977,8 +977,10 @@ void __init setup_arch(char **cmdline_p)
unflatten_device_tree(); unflatten_device_tree();
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
if (is_smp()) if (is_smp()) {
smp_set_ops(mdesc->smp);
smp_init_cpus(); smp_init_cpus();
}
#endif #endif
reserve_crashkernel(); reserve_crashkernel();
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/smp.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/percpu.h> #include <linux/percpu.h>
...@@ -27,6 +26,7 @@ ...@@ -27,6 +26,7 @@
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/atomic.h> #include <linux/atomic.h>
#include <asm/smp.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/cpu.h> #include <asm/cpu.h>
#include <asm/cputype.h> #include <asm/cputype.h>
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/localtimer.h> #include <asm/localtimer.h>
#include <asm/smp_plat.h> #include <asm/smp_plat.h>
#include <asm/mach/arch.h>
/* /*
* as from 2.5, kernels no longer have an init_tasks structure * as from 2.5, kernels no longer have an init_tasks structure
...@@ -50,6 +51,12 @@ ...@@ -50,6 +51,12 @@
*/ */
struct secondary_data secondary_data; 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 { enum ipi_msg_type {
IPI_TIMER = 2, IPI_TIMER = 2,
IPI_RESCHEDULE, IPI_RESCHEDULE,
...@@ -60,6 +67,14 @@ enum ipi_msg_type { ...@@ -60,6 +67,14 @@ enum ipi_msg_type {
static DECLARE_COMPLETION(cpu_running); 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 __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
{ {
int ret; int ret;
...@@ -100,13 +115,64 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle) ...@@ -100,13 +115,64 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
return ret; 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 #ifdef CONFIG_HOTPLUG_CPU
static void percpu_timer_stop(void); 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. * __cpu_disable runs on the processor to be shutdown.
*/ */
int __cpu_disable(void) int __cpuinit __cpu_disable(void)
{ {
unsigned int cpu = smp_processor_id(); unsigned int cpu = smp_processor_id();
int ret; int ret;
...@@ -149,7 +215,7 @@ static DECLARE_COMPLETION(cpu_died); ...@@ -149,7 +215,7 @@ static DECLARE_COMPLETION(cpu_died);
* called on the thread which is asking for a CPU to be shutdown - * called on the thread which is asking for a CPU to be shutdown -
* waits until shutdown has completed, or it is timed out. * 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))) { if (!wait_for_completion_timeout(&cpu_died, msecs_to_jiffies(5000))) {
pr_err("CPU%u: cpu didn't die\n", cpu); pr_err("CPU%u: cpu didn't die\n", cpu);
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
extern struct sys_timer exynos4_timer; extern struct sys_timer exynos4_timer;
struct map_desc;
void exynos_init_io(struct map_desc *mach_desc, int size); void exynos_init_io(struct map_desc *mach_desc, int size);
void exynos4_init_irq(void); void exynos4_init_irq(void);
void exynos5_init_irq(void); void exynos5_init_irq(void);
...@@ -59,4 +60,8 @@ void exynos4212_register_clocks(void); ...@@ -59,4 +60,8 @@ void exynos4212_register_clocks(void);
#define exynos4212_register_clocks() #define exynos4212_register_clocks()
#endif #endif
extern struct smp_operations exynos_smp_ops;
extern void exynos_cpu_die(unsigned int cpu);
#endif /* __ARCH_ARM_MACH_EXYNOS_COMMON_H */ #endif /* __ARCH_ARM_MACH_EXYNOS_COMMON_H */
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#include <mach/regs-pmu.h> #include <mach/regs-pmu.h>
extern volatile int pen_release; #include "common.h"
static inline void cpu_enter_lowpower(void) static inline void cpu_enter_lowpower(void)
{ {
...@@ -95,17 +95,12 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious) ...@@ -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 * platform-specific code to shutdown a CPU
* *
* Called with IRQs disabled * Called with IRQs disabled
*/ */
void platform_cpu_die(unsigned int cpu) void __ref exynos_cpu_die(unsigned int cpu)
{ {
int spurious = 0; int spurious = 0;
...@@ -124,12 +119,3 @@ void platform_cpu_die(unsigned int cpu) ...@@ -124,12 +119,3 @@ void platform_cpu_die(unsigned int cpu)
if (spurious) if (spurious)
pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, 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;
}
...@@ -199,6 +199,7 @@ static void __init armlex4210_machine_init(void) ...@@ -199,6 +199,7 @@ static void __init armlex4210_machine_init(void)
MACHINE_START(ARMLEX4210, "ARMLEX4210") MACHINE_START(ARMLEX4210, "ARMLEX4210")
/* Maintainer: Alim Akhtar <alim.akhtar@samsung.com> */ /* Maintainer: Alim Akhtar <alim.akhtar@samsung.com> */
.atag_offset = 0x100, .atag_offset = 0x100,
.smp = smp_ops(exynos_smp_ops),
.init_irq = exynos4_init_irq, .init_irq = exynos4_init_irq,
.map_io = armlex4210_map_io, .map_io = armlex4210_map_io,
.handle_irq = gic_handle_irq, .handle_irq = gic_handle_irq,
......
...@@ -79,6 +79,7 @@ static char const *exynos5250_dt_compat[] __initdata = { ...@@ -79,6 +79,7 @@ static char const *exynos5250_dt_compat[] __initdata = {
DT_MACHINE_START(EXYNOS5_DT, "SAMSUNG EXYNOS5 (Flattened Device Tree)") DT_MACHINE_START(EXYNOS5_DT, "SAMSUNG EXYNOS5 (Flattened Device Tree)")
/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */ /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
.init_irq = exynos5_init_irq, .init_irq = exynos5_init_irq,
.smp = smp_ops(exynos_smp_ops),
.map_io = exynos5250_dt_map_io, .map_io = exynos5250_dt_map_io,
.handle_irq = gic_handle_irq, .handle_irq = gic_handle_irq,
.init_machine = exynos5250_dt_machine_init, .init_machine = exynos5250_dt_machine_init,
......
...@@ -1383,6 +1383,7 @@ static void __init nuri_machine_init(void) ...@@ -1383,6 +1383,7 @@ static void __init nuri_machine_init(void)
MACHINE_START(NURI, "NURI") MACHINE_START(NURI, "NURI")
/* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */ /* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
.atag_offset = 0x100, .atag_offset = 0x100,
.smp = smp_ops(exynos_smp_ops),
.init_irq = exynos4_init_irq, .init_irq = exynos4_init_irq,
.map_io = nuri_map_io, .map_io = nuri_map_io,
.handle_irq = gic_handle_irq, .handle_irq = gic_handle_irq,
......
...@@ -806,6 +806,7 @@ static void __init origen_machine_init(void) ...@@ -806,6 +806,7 @@ static void __init origen_machine_init(void)
MACHINE_START(ORIGEN, "ORIGEN") MACHINE_START(ORIGEN, "ORIGEN")
/* Maintainer: JeongHyeon Kim <jhkim@insignal.co.kr> */ /* Maintainer: JeongHyeon Kim <jhkim@insignal.co.kr> */
.atag_offset = 0x100, .atag_offset = 0x100,
.smp = smp_ops(exynos_smp_ops),
.init_irq = exynos4_init_irq, .init_irq = exynos4_init_irq,
.map_io = origen_map_io, .map_io = origen_map_io,
.handle_irq = gic_handle_irq, .handle_irq = gic_handle_irq,
......
...@@ -370,6 +370,7 @@ static void __init smdk4x12_machine_init(void) ...@@ -370,6 +370,7 @@ static void __init smdk4x12_machine_init(void)
MACHINE_START(SMDK4212, "SMDK4212") MACHINE_START(SMDK4212, "SMDK4212")
/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */ /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
.atag_offset = 0x100, .atag_offset = 0x100,
.smp = smp_ops(exynos_smp_ops),
.init_irq = exynos4_init_irq, .init_irq = exynos4_init_irq,
.map_io = smdk4x12_map_io, .map_io = smdk4x12_map_io,
.handle_irq = gic_handle_irq, .handle_irq = gic_handle_irq,
...@@ -383,6 +384,7 @@ MACHINE_START(SMDK4412, "SMDK4412") ...@@ -383,6 +384,7 @@ MACHINE_START(SMDK4412, "SMDK4412")
/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */ /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
/* Maintainer: Changhwan Youn <chaos.youn@samsung.com> */ /* Maintainer: Changhwan Youn <chaos.youn@samsung.com> */
.atag_offset = 0x100, .atag_offset = 0x100,
.smp = smp_ops(exynos_smp_ops),
.init_irq = exynos4_init_irq, .init_irq = exynos4_init_irq,
.map_io = smdk4x12_map_io, .map_io = smdk4x12_map_io,
.handle_irq = gic_handle_irq, .handle_irq = gic_handle_irq,
......
...@@ -417,6 +417,7 @@ MACHINE_START(SMDKV310, "SMDKV310") ...@@ -417,6 +417,7 @@ MACHINE_START(SMDKV310, "SMDKV310")
/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */ /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
/* Maintainer: Changhwan Youn <chaos.youn@samsung.com> */ /* Maintainer: Changhwan Youn <chaos.youn@samsung.com> */
.atag_offset = 0x100, .atag_offset = 0x100,
.smp = smp_ops(exynos_smp_ops),
.init_irq = exynos4_init_irq, .init_irq = exynos4_init_irq,
.map_io = smdkv310_map_io, .map_io = smdkv310_map_io,
.handle_irq = gic_handle_irq, .handle_irq = gic_handle_irq,
...@@ -429,6 +430,7 @@ MACHINE_END ...@@ -429,6 +430,7 @@ MACHINE_END
MACHINE_START(SMDKC210, "SMDKC210") MACHINE_START(SMDKC210, "SMDKC210")
/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */ /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
.atag_offset = 0x100, .atag_offset = 0x100,
.smp = smp_ops(exynos_smp_ops),
.init_irq = exynos4_init_irq, .init_irq = exynos4_init_irq,
.map_io = smdkv310_map_io, .map_io = smdkv310_map_io,
.handle_irq = gic_handle_irq, .handle_irq = gic_handle_irq,
......
...@@ -1155,6 +1155,7 @@ static void __init universal_machine_init(void) ...@@ -1155,6 +1155,7 @@ static void __init universal_machine_init(void)
MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210") MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210")
/* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */ /* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
.atag_offset = 0x100, .atag_offset = 0x100,
.smp = smp_ops(exynos_smp_ops),
.init_irq = exynos4_init_irq, .init_irq = exynos4_init_irq,
.map_io = universal_map_io, .map_io = universal_map_io,
.handle_irq = gic_handle_irq, .handle_irq = gic_handle_irq,
......
...@@ -32,18 +32,13 @@ ...@@ -32,18 +32,13 @@
#include <plat/cpu.h> #include <plat/cpu.h>
#include "common.h"
extern void exynos4_secondary_startup(void); extern void exynos4_secondary_startup(void);
#define CPU1_BOOT_REG (samsung_rev() == EXYNOS4210_REV_1_1 ? \ #define CPU1_BOOT_REG (samsung_rev() == EXYNOS4210_REV_1_1 ? \
S5P_INFORM5 : S5P_VA_SYSRAM) 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 * Write pen_release in a way that is guaranteed to be visible to all
* observers, irrespective of whether they're taking part in coherency * observers, irrespective of whether they're taking part in coherency
...@@ -64,7 +59,7 @@ static void __iomem *scu_base_addr(void) ...@@ -64,7 +59,7 @@ static void __iomem *scu_base_addr(void)
static DEFINE_SPINLOCK(boot_lock); 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 * if any interrupts are already enabled for the primary
...@@ -86,7 +81,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu) ...@@ -86,7 +81,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
spin_unlock(&boot_lock); 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; unsigned long timeout;
...@@ -161,7 +156,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) ...@@ -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. * 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(); void __iomem *scu_base = scu_base_addr();
unsigned int i, ncores; unsigned int i, ncores;
...@@ -184,7 +179,7 @@ void __init smp_init_cpus(void) ...@@ -184,7 +179,7 @@ void __init smp_init_cpus(void)
set_smp_cross_call(gic_raise_softirq); 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()) if (!soc_is_exynos5250())
scu_enable(scu_base_addr()); scu_enable(scu_base_addr());
...@@ -198,3 +193,13 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus) ...@@ -198,3 +193,13 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
__raw_writel(virt_to_phys(exynos4_secondary_startup), __raw_writel(virt_to_phys(exynos4_secondary_startup),
CPU1_BOOT_REG); 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
};
...@@ -15,3 +15,6 @@ static inline void highbank_pm_init(void) {} ...@@ -15,3 +15,6 @@ static inline void highbank_pm_init(void) {}
#endif #endif
extern void highbank_smc1(int fn, int arg); extern void highbank_smc1(int fn, int arg);
extern void highbank_cpu_die(unsigned int cpu);
extern struct smp_operations highbank_smp_ops;
...@@ -163,6 +163,7 @@ static const char *highbank_match[] __initconst = { ...@@ -163,6 +163,7 @@ static const char *highbank_match[] __initconst = {
}; };
DT_MACHINE_START(HIGHBANK, "Highbank") DT_MACHINE_START(HIGHBANK, "Highbank")
.smp = smp_ops(highbank_smp_ops),
.map_io = highbank_map_io, .map_io = highbank_map_io,
.init_irq = highbank_init_irq, .init_irq = highbank_init_irq,
.timer = &highbank_timer, .timer = &highbank_timer,
......
...@@ -24,16 +24,11 @@ ...@@ -24,16 +24,11 @@
extern void secondary_startup(void); extern void secondary_startup(void);
int platform_cpu_kill(unsigned int cpu)
{
return 1;
}
/* /*
* platform-specific code to shutdown a CPU * 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(); flush_cache_all();
...@@ -45,12 +40,3 @@ void platform_cpu_die(unsigned int cpu) ...@@ -45,12 +40,3 @@ void platform_cpu_die(unsigned int cpu)
/* We should never return from idle */ /* We should never return from idle */
panic("highbank: cpu %d unexpectedly exit from shutdown\n", cpu); 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;
}
...@@ -25,12 +25,12 @@ ...@@ -25,12 +25,12 @@
extern void secondary_startup(void); 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); 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); gic_raise_softirq(cpumask_of(cpu), 0);
return 0; return 0;
...@@ -40,7 +40,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) ...@@ -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 * Initialise the CPU possible map early - this describes the CPUs
* which may be present or become present in the system. * 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; unsigned int i, ncores;
...@@ -61,7 +61,7 @@ void __init smp_init_cpus(void) ...@@ -61,7 +61,7 @@ void __init smp_init_cpus(void)
set_smp_cross_call(gic_raise_softirq); 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; int i;
...@@ -76,3 +76,13 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus) ...@@ -76,3 +76,13 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
for (i = 1; i < max_cpus; i++) for (i = 1; i < max_cpus; i++)
highbank_set_cpu_jump(i, secondary_startup); 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
};
...@@ -15,11 +15,6 @@ ...@@ -15,11 +15,6 @@
#include <asm/cp15.h> #include <asm/cp15.h>
#include <mach/common.h> #include <mach/common.h>
int platform_cpu_kill(unsigned int cpu)
{
return 1;
}
static inline void cpu_enter_lowpower(void) static inline void cpu_enter_lowpower(void)
{ {
unsigned int v; unsigned int v;
...@@ -47,7 +42,7 @@ static inline void cpu_enter_lowpower(void) ...@@ -47,7 +42,7 @@ static inline void cpu_enter_lowpower(void)
* *
* Called with IRQs disabled * Called with IRQs disabled
*/ */
void platform_cpu_die(unsigned int cpu) void imx_cpu_die(unsigned int cpu)
{ {
cpu_enter_lowpower(); cpu_enter_lowpower();
imx_enable_cpu(cpu, false); imx_enable_cpu(cpu, false);
...@@ -56,12 +51,3 @@ void platform_cpu_die(unsigned int cpu) ...@@ -56,12 +51,3 @@ void platform_cpu_die(unsigned int cpu)
while (1) 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;
}
...@@ -215,6 +215,7 @@ static const char *imx6q_dt_compat[] __initdata = { ...@@ -215,6 +215,7 @@ static const char *imx6q_dt_compat[] __initdata = {
}; };
DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad (Device Tree)") DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad (Device Tree)")
.smp = smp_ops(imx_smp_ops),
.map_io = imx6q_map_io, .map_io = imx6q_map_io,
.init_irq = imx6q_init_irq, .init_irq = imx6q_init_irq,
.handle_irq = imx6q_handle_irq, .handle_irq = imx6q_handle_irq,
......
...@@ -41,7 +41,7 @@ void __init imx_scu_map_io(void) ...@@ -41,7 +41,7 @@ void __init imx_scu_map_io(void)
scu_base = IMX_IO_ADDRESS(base); 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 * if any interrupts are already enabled for the primary
...@@ -51,7 +51,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu) ...@@ -51,7 +51,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
gic_secondary_init(0); 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_set_cpu_jump(cpu, v7_secondary_startup);
imx_enable_cpu(cpu, true); imx_enable_cpu(cpu, true);
...@@ -62,7 +62,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) ...@@ -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 * Initialise the CPU possible map early - this describes the CPUs
* which may be present or become present in the system. * 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; int i, ncores;
...@@ -79,7 +79,17 @@ void imx_smp_prepare(void) ...@@ -79,7 +79,17 @@ void imx_smp_prepare(void)
scu_enable(scu_base); 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(); 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
};
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <mach/board.h> #include <mach/board.h>
#include "common.h" #include "common.h"
#include "core.h"
static const struct of_device_id msm_dt_gic_match[] __initconst = { static const struct of_device_id msm_dt_gic_match[] __initconst = {
{ .compatible = "qcom,msm-8660-qgic", .data = gic_of_init }, { .compatible = "qcom,msm-8660-qgic", .data = gic_of_init },
...@@ -53,6 +54,7 @@ static const char *msm8x60_fluid_match[] __initdata = { ...@@ -53,6 +54,7 @@ static const char *msm8x60_fluid_match[] __initdata = {
}; };
DT_MACHINE_START(MSM_DT, "Qualcomm MSM (Flattened Device Tree)") DT_MACHINE_START(MSM_DT, "Qualcomm MSM (Flattened Device Tree)")
.smp = smp_ops(msm_smp_ops),
.map_io = msm_map_msm8x60_io, .map_io = msm_map_msm8x60_io,
.init_irq = msm8x60_init_irq, .init_irq = msm8x60_init_irq,
.handle_irq = gic_handle_irq, .handle_irq = gic_handle_irq,
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include "common.h" #include "common.h"
#include "core.h"
static const struct of_device_id msm_dt_gic_match[] __initconst = { static const struct of_device_id msm_dt_gic_match[] __initconst = {
{ .compatible = "qcom,msm-qgic2", .data = gic_of_init }, { .compatible = "qcom,msm-qgic2", .data = gic_of_init },
...@@ -40,6 +41,7 @@ static const char * const msm8960_dt_match[] __initconst = { ...@@ -40,6 +41,7 @@ static const char * const msm8960_dt_match[] __initconst = {
}; };
DT_MACHINE_START(MSM8960_DT, "Qualcomm MSM (Flattened Device Tree)") DT_MACHINE_START(MSM8960_DT, "Qualcomm MSM (Flattened Device Tree)")
.smp = smp_ops(msm_smp_ops),
.map_io = msm_map_msm8960_io, .map_io = msm_map_msm8960_io,
.init_irq = msm_dt_init_irq, .init_irq = msm_dt_init_irq,
.timer = &msm_dt_timer, .timer = &msm_dt_timer,
......
extern struct smp_operations msm_smp_ops;
extern void msm_cpu_die(unsigned int cpu);
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/smp_plat.h> #include <asm/smp_plat.h>
extern volatile int pen_release; #include "core.h"
static inline void cpu_enter_lowpower(void) static inline void cpu_enter_lowpower(void)
{ {
...@@ -57,17 +57,12 @@ static inline void platform_do_lowpower(unsigned int cpu) ...@@ -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 * platform-specific code to shutdown a CPU
* *
* Called with IRQs disabled * 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 * we're ready for shutdown now, so do it
...@@ -81,12 +76,3 @@ void platform_cpu_die(unsigned int cpu) ...@@ -81,12 +76,3 @@ void platform_cpu_die(unsigned int cpu)
*/ */
cpu_leave_lowpower(); 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;
}
...@@ -23,17 +23,13 @@ ...@@ -23,17 +23,13 @@
#include <asm/smp_plat.h> #include <asm/smp_plat.h>
#include "scm-boot.h" #include "scm-boot.h"
#include "core.h"
#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x15A0 #define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x15A0
#define SCSS_CPU1CORE_RESET 0xD80 #define SCSS_CPU1CORE_RESET 0xD80
#define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64 #define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64
extern void msm_secondary_startup(void); 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); static DEFINE_SPINLOCK(boot_lock);
...@@ -43,7 +39,7 @@ static inline int get_core_count(void) ...@@ -43,7 +39,7 @@ static inline int get_core_count(void)
return ((read_cpuid_id() >> 4) & 3) + 1; 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 * if any interrupts are already enabled for the primary
...@@ -85,7 +81,7 @@ static __cpuinit void prepare_cold_cpu(unsigned int cpu) ...@@ -85,7 +81,7 @@ static __cpuinit void prepare_cold_cpu(unsigned int cpu)
"address\n"); "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; unsigned long timeout;
static int cold_boot_done; static int cold_boot_done;
...@@ -145,7 +141,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) ...@@ -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 * does not support the ARM SCU, so just set the possible cpu mask to
* NR_CPUS. * NR_CPUS.
*/ */
void __init smp_init_cpus(void) static void __init msm_smp_init_cpus(void)
{ {
unsigned int i, ncores = get_core_count(); unsigned int i, ncores = get_core_count();
...@@ -161,6 +157,16 @@ void __init smp_init_cpus(void) ...@@ -161,6 +157,16 @@ void __init smp_init_cpus(void)
set_smp_cross_call(gic_raise_softirq); 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
};
...@@ -907,6 +907,7 @@ static void __init omap_4430sdp_init(void) ...@@ -907,6 +907,7 @@ static void __init omap_4430sdp_init(void)
MACHINE_START(OMAP_4430SDP, "OMAP4430 4430SDP board") MACHINE_START(OMAP_4430SDP, "OMAP4430 4430SDP board")
/* Maintainer: Santosh Shilimkar - Texas Instruments Inc */ /* Maintainer: Santosh Shilimkar - Texas Instruments Inc */
.atag_offset = 0x100, .atag_offset = 0x100,
.smp = smp_ops(omap4_smp_ops),
.reserve = omap_reserve, .reserve = omap_reserve,
.map_io = omap4_map_io, .map_io = omap4_map_io,
.init_early = omap4430_init_early, .init_early = omap4430_init_early,
......
...@@ -125,6 +125,7 @@ static const char *omap4_boards_compat[] __initdata = { ...@@ -125,6 +125,7 @@ static const char *omap4_boards_compat[] __initdata = {
DT_MACHINE_START(OMAP4_DT, "Generic OMAP4 (Flattened Device Tree)") DT_MACHINE_START(OMAP4_DT, "Generic OMAP4 (Flattened Device Tree)")
.reserve = omap_reserve, .reserve = omap_reserve,
.smp = smp_ops(omap4_smp_ops),
.map_io = omap4_map_io, .map_io = omap4_map_io,
.init_early = omap4430_init_early, .init_early = omap4430_init_early,
.init_irq = omap_gic_of_init, .init_irq = omap_gic_of_init,
...@@ -145,6 +146,7 @@ static const char *omap5_boards_compat[] __initdata = { ...@@ -145,6 +146,7 @@ static const char *omap5_boards_compat[] __initdata = {
DT_MACHINE_START(OMAP5_DT, "Generic OMAP5 (Flattened Device Tree)") DT_MACHINE_START(OMAP5_DT, "Generic OMAP5 (Flattened Device Tree)")
.reserve = omap_reserve, .reserve = omap_reserve,
.smp = smp_ops(omap4_smp_ops),
.map_io = omap5_map_io, .map_io = omap5_map_io,
.init_early = omap5_init_early, .init_early = omap5_init_early,
.init_irq = omap_gic_of_init, .init_irq = omap_gic_of_init,
......
...@@ -516,6 +516,7 @@ static void __init omap4_panda_init(void) ...@@ -516,6 +516,7 @@ static void __init omap4_panda_init(void)
MACHINE_START(OMAP4_PANDA, "OMAP4 Panda board") MACHINE_START(OMAP4_PANDA, "OMAP4 Panda board")
/* Maintainer: David Anders - Texas Instruments Inc */ /* Maintainer: David Anders - Texas Instruments Inc */
.atag_offset = 0x100, .atag_offset = 0x100,
.smp = smp_ops(omap4_smp_ops),
.reserve = omap_reserve, .reserve = omap_reserve,
.map_io = omap4_map_io, .map_io = omap4_map_io,
.init_early = omap4430_init_early, .init_early = omap4430_init_early,
......
...@@ -285,6 +285,11 @@ extern void omap_secondary_startup(void); ...@@ -285,6 +285,11 @@ extern void omap_secondary_startup(void);
extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask); extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask);
extern void omap_auxcoreboot_addr(u32 cpu_addr); extern void omap_auxcoreboot_addr(u32 cpu_addr);
extern u32 omap_read_auxcoreboot0(void); 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); extern void omap5_secondary_startup(void);
#endif #endif
......
...@@ -26,16 +26,11 @@ ...@@ -26,16 +26,11 @@
#include "powerdomain.h" #include "powerdomain.h"
int platform_cpu_kill(unsigned int cpu)
{
return 1;
}
/* /*
* platform-specific code to shutdown a CPU * platform-specific code to shutdown a CPU
* Called with IRQs disabled * 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; unsigned int boot_cpu = 0;
void __iomem *base = omap_get_wakeupgen_base(); void __iomem *base = omap_get_wakeupgen_base();
...@@ -75,12 +70,3 @@ void __ref platform_cpu_die(unsigned int cpu) ...@@ -75,12 +70,3 @@ void __ref platform_cpu_die(unsigned int cpu)
pr_debug("CPU%u: spurious wakeup call\n", 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;
}
...@@ -49,7 +49,7 @@ void __iomem *omap4_get_scu_base(void) ...@@ -49,7 +49,7 @@ void __iomem *omap4_get_scu_base(void)
return scu_base; 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. * 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) ...@@ -77,7 +77,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
spin_unlock(&boot_lock); 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 struct clockdomain *cpu1_clkdm;
static bool booted; static bool booted;
...@@ -165,7 +165,7 @@ static void __init wakeup_secondary(void) ...@@ -165,7 +165,7 @@ static void __init wakeup_secondary(void)
* Initialise the CPU possible map early - this describes the CPUs * Initialise the CPU possible map early - this describes the CPUs
* which may be present or become present in the system. * 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; unsigned int i = 0, ncores = 1, cpu_id;
...@@ -196,7 +196,7 @@ void __init smp_init_cpus(void) ...@@ -196,7 +196,7 @@ void __init smp_init_cpus(void)
set_smp_cross_call(gic_raise_softirq); 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) ...@@ -207,3 +207,13 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
scu_enable(scu_base); scu_enable(scu_base);
wakeup_secondary(); 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
};
...@@ -56,4 +56,7 @@ extern void realview_init_early(void); ...@@ -56,4 +56,7 @@ extern void realview_init_early(void);
extern void realview_fixup(struct tag *tags, char **from, extern void realview_fixup(struct tag *tags, char **from,
struct meminfo *meminfo); struct meminfo *meminfo);
extern struct smp_operations realview_smp_ops;
extern void realview_cpu_die(unsigned int cpu);
#endif #endif
...@@ -16,8 +16,6 @@ ...@@ -16,8 +16,6 @@
#include <asm/cp15.h> #include <asm/cp15.h>
#include <asm/smp_plat.h> #include <asm/smp_plat.h>
extern volatile int pen_release;
static inline void cpu_enter_lowpower(void) static inline void cpu_enter_lowpower(void)
{ {
unsigned int v; unsigned int v;
...@@ -89,17 +87,12 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious) ...@@ -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 * platform-specific code to shutdown a CPU
* *
* Called with IRQs disabled * Called with IRQs disabled
*/ */
void platform_cpu_die(unsigned int cpu) void __ref realview_cpu_die(unsigned int cpu)
{ {
int spurious = 0; int spurious = 0;
...@@ -118,12 +111,3 @@ void platform_cpu_die(unsigned int cpu) ...@@ -118,12 +111,3 @@ void platform_cpu_die(unsigned int cpu)
if (spurious) if (spurious)
pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, 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;
}
...@@ -22,9 +22,9 @@ ...@@ -22,9 +22,9 @@
#include <mach/board-pb11mp.h> #include <mach/board-pb11mp.h>
#include <mach/board-pbx.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) static void __iomem *scu_base_addr(void)
{ {
...@@ -43,7 +43,7 @@ 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 * Initialise the CPU possible map early - this describes the CPUs
* which may be present or become present in the system. * 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(); void __iomem *scu_base = scu_base_addr();
unsigned int i, ncores; unsigned int i, ncores;
...@@ -63,7 +63,7 @@ void __init smp_init_cpus(void) ...@@ -63,7 +63,7 @@ void __init smp_init_cpus(void)
set_smp_cross_call(gic_raise_softirq); 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()); scu_enable(scu_base_addr());
...@@ -77,3 +77,13 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus) ...@@ -77,3 +77,13 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
__raw_writel(virt_to_phys(versatile_secondary_startup), __raw_writel(virt_to_phys(versatile_secondary_startup),
__io_address(REALVIEW_SYS_FLAGSSET)); __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
};
...@@ -367,6 +367,7 @@ static void __init realview_pb11mp_init(void) ...@@ -367,6 +367,7 @@ static void __init realview_pb11mp_init(void)
MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore") MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
.atag_offset = 0x100, .atag_offset = 0x100,
.smp = smp_ops(realview_smp_ops),
.fixup = realview_fixup, .fixup = realview_fixup,
.map_io = realview_pb11mp_map_io, .map_io = realview_pb11mp_map_io,
.init_early = realview_init_early, .init_early = realview_init_early,
......
...@@ -404,6 +404,7 @@ static void __init realview_pbx_init(void) ...@@ -404,6 +404,7 @@ static void __init realview_pbx_init(void)
MACHINE_START(REALVIEW_PBX, "ARM-RealView PBX") MACHINE_START(REALVIEW_PBX, "ARM-RealView PBX")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
.atag_offset = 0x100, .atag_offset = 0x100,
.smp = smp_ops(realview_smp_ops),
.fixup = realview_pbx_fixup, .fixup = realview_pbx_fixup,
.map_io = realview_pbx_map_io, .map_io = realview_pbx_map_io,
.init_early = realview_init_early, .init_early = realview_init_early,
......
...@@ -649,6 +649,7 @@ static void __init ag5evm_init(void) ...@@ -649,6 +649,7 @@ static void __init ag5evm_init(void)
} }
MACHINE_START(AG5EVM, "ag5evm") MACHINE_START(AG5EVM, "ag5evm")
.smp = smp_ops(sh73a0_smp_ops),
.map_io = sh73a0_map_io, .map_io = sh73a0_map_io,
.init_early = sh73a0_add_early_devices, .init_early = sh73a0_add_early_devices,
.nr_irqs = NR_IRQS_LEGACY, .nr_irqs = NR_IRQS_LEGACY,
......
...@@ -545,6 +545,7 @@ static void __init kota2_init(void) ...@@ -545,6 +545,7 @@ static void __init kota2_init(void)
} }
MACHINE_START(KOTA2, "kota2") MACHINE_START(KOTA2, "kota2")
.smp = smp_ops(sh73a0_smp_ops),
.map_io = sh73a0_map_io, .map_io = sh73a0_map_io,
.init_early = sh73a0_add_early_devices, .init_early = sh73a0_add_early_devices,
.nr_irqs = NR_IRQS_LEGACY, .nr_irqs = NR_IRQS_LEGACY,
......
...@@ -84,6 +84,7 @@ static const char *kzm9d_boards_compat_dt[] __initdata = { ...@@ -84,6 +84,7 @@ static const char *kzm9d_boards_compat_dt[] __initdata = {
}; };
DT_MACHINE_START(KZM9D_DT, "kzm9d") DT_MACHINE_START(KZM9D_DT, "kzm9d")
.smp = smp_ops(emev2_smp_ops),
.map_io = emev2_map_io, .map_io = emev2_map_io,
.init_early = emev2_add_early_devices, .init_early = emev2_add_early_devices,
.nr_irqs = NR_IRQS_LEGACY, .nr_irqs = NR_IRQS_LEGACY,
......
...@@ -776,6 +776,7 @@ static const char *kzm9g_boards_compat_dt[] __initdata = { ...@@ -776,6 +776,7 @@ static const char *kzm9g_boards_compat_dt[] __initdata = {
}; };
DT_MACHINE_START(KZM9G_DT, "kzm9g") DT_MACHINE_START(KZM9G_DT, "kzm9g")
.smp = smp_ops(sh73a0_smp_ops),
.map_io = sh73a0_map_io, .map_io = sh73a0_map_io,
.init_early = sh73a0_add_early_devices, .init_early = sh73a0_add_early_devices,
.nr_irqs = NR_IRQS_LEGACY, .nr_irqs = NR_IRQS_LEGACY,
......
...@@ -102,6 +102,7 @@ static void __init marzen_init(void) ...@@ -102,6 +102,7 @@ static void __init marzen_init(void)
} }
MACHINE_START(MARZEN, "marzen") MACHINE_START(MARZEN, "marzen")
.smp = smp_ops(r8a7779_smp_ops),
.map_io = r8a7779_map_io, .map_io = r8a7779_map_io,
.init_early = r8a7779_add_early_devices, .init_early = r8a7779_add_early_devices,
.nr_irqs = NR_IRQS_LEGACY, .nr_irqs = NR_IRQS_LEGACY,
......
...@@ -14,30 +14,16 @@ ...@@ -14,30 +14,16 @@
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/cpumask.h> #include <linux/cpumask.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/of.h>
#include <mach/common.h> #include <mach/common.h>
#include <mach/r8a7779.h>
#include <mach/emev2.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/mach-types.h>
static cpumask_t dead_cpus; static cpumask_t dead_cpus;
int platform_cpu_kill(unsigned int cpu) void shmobile_cpu_die(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)
{ {
/* hardware shutdown code running on the CPU that is being offlined */ /* hardware shutdown code running on the CPU that is being offlined */
flush_cache_all(); flush_cache_all();
...@@ -60,7 +46,7 @@ void platform_cpu_die(unsigned int cpu) ...@@ -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); cpumask_clear_cpu(cpu, &dead_cpus);
/* /*
...@@ -69,3 +55,8 @@ int platform_cpu_disable(unsigned int cpu) ...@@ -69,3 +55,8 @@ int platform_cpu_disable(unsigned int cpu)
*/ */
return cpu == 0 ? -EPERM : 0; return cpu == 0 ? -EPERM : 0;
} }
int shmobile_cpu_is_dead(unsigned int cpu)
{
return cpumask_test_cpu(cpu, &dead_cpus);
}
...@@ -4,11 +4,10 @@ ...@@ -4,11 +4,10 @@
extern void shmobile_earlytimer_init(void); extern void shmobile_earlytimer_init(void);
extern struct sys_timer shmobile_timer; extern struct sys_timer shmobile_timer;
extern void shmobile_setup_delay(unsigned int max_cpu_core_mhz, 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; struct twd_local_timer;
extern void shmobile_setup_console(void); extern void shmobile_setup_console(void);
extern void shmobile_secondary_vector(void); extern void shmobile_secondary_vector(void);
extern int shmobile_platform_cpu_kill(unsigned int cpu);
struct clk; struct clk;
extern int shmobile_clk_init(void); extern int shmobile_clk_init(void);
extern void shmobile_handle_irq_intc(struct pt_regs *); extern void shmobile_handle_irq_intc(struct pt_regs *);
...@@ -58,11 +57,6 @@ extern struct clk sh73a0_extal2_clk; ...@@ -58,11 +57,6 @@ extern struct clk sh73a0_extal2_clk;
extern struct clk sh73a0_extcki_clk; extern struct clk sh73a0_extcki_clk;
extern struct clk sh73a0_extalr_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_init_irq(void);
extern void r8a7740_map_io(void); extern void r8a7740_map_io(void);
extern void r8a7740_add_early_devices(void); extern void r8a7740_add_early_devices(void);
...@@ -79,11 +73,6 @@ extern void r8a7779_pinmux_init(void); ...@@ -79,11 +73,6 @@ extern void r8a7779_pinmux_init(void);
extern void r8a7779_pm_init(void); extern void r8a7779_pm_init(void);
extern void r8a7740_meram_workaround(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 r8a7779_register_twd(void);
extern void shmobile_init_late(void); extern void shmobile_init_late(void);
...@@ -100,4 +89,15 @@ int shmobile_cpuidle_init(void); ...@@ -100,4 +89,15 @@ int shmobile_cpuidle_init(void);
static inline int shmobile_cpuidle_init(void) { return 0; } static inline int shmobile_cpuidle_init(void) { return 0; }
#endif #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 */ #endif /* __ARCH_MACH_COMMON_H */
...@@ -7,13 +7,10 @@ extern void emev2_add_early_devices(void); ...@@ -7,13 +7,10 @@ extern void emev2_add_early_devices(void);
extern void emev2_add_standard_devices(void); extern void emev2_add_standard_devices(void);
extern void emev2_clock_init(void); extern void emev2_clock_init(void);
extern void emev2_set_boot_vector(unsigned long value); 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_BASE 200
#define EMEV2_GPIO_IRQ(n) (EMEV2_GPIO_BASE + (n)) #define EMEV2_GPIO_IRQ(n) (EMEV2_GPIO_BASE + (n))
extern struct smp_operations emev2_smp_ops;
#endif /* __ASM_EMEV2_H__ */ #endif /* __ASM_EMEV2_H__ */
...@@ -360,4 +360,6 @@ extern void r8a7779_add_device_to_domain(struct r8a7779_pm_domain *r8a7779_pd, ...@@ -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) #define r8a7779_add_device_to_domain(pd, pdev) do { } while (0)
#endif /* CONFIG_PM */ #endif /* CONFIG_PM */
extern struct smp_operations r8a7779_smp_ops;
#endif /* __ASM_R8A7779_H__ */ #endif /* __ASM_R8A7779_H__ */
...@@ -557,4 +557,6 @@ enum { ...@@ -557,4 +557,6 @@ enum {
#define SH73A0_PINT0_IRQ(irq) ((irq) + 700) #define SH73A0_PINT0_IRQ(irq) ((irq) + 700)
#define SH73A0_PINT1_IRQ(irq) ((irq) + 732) #define SH73A0_PINT1_IRQ(irq) ((irq) + 732)
extern struct smp_operations sh73a0_smp_ops;
#endif /* __ASM_SH73A0_H__ */ #endif /* __ASM_SH73A0_H__ */
...@@ -11,100 +11,11 @@ ...@@ -11,100 +11,11 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/io.h>
#include <linux/of.h>
#include <asm/hardware/gic.h> #include <asm/hardware/gic.h>
#include <asm/mach-types.h>
#include <mach/common.h>
#include <mach/emev2.h>
#ifdef CONFIG_ARCH_SH73A0 void __init shmobile_smp_init_cpus(unsigned int ncores)
#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)
{ {
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; unsigned int i;
if (ncores > nr_cpu_ids) { if (ncores > nr_cpu_ids) {
...@@ -118,8 +29,3 @@ void __init smp_init_cpus(void) ...@@ -118,8 +29,3 @@ void __init smp_init_cpus(void)
set_smp_cross_call(gic_raise_softirq); set_smp_cross_call(gic_raise_softirq);
} }
void __init platform_smp_prepare_cpus(unsigned int max_cpus)
{
shmobile_smp_prepare_cpus();
}
...@@ -461,6 +461,7 @@ void __init emev2_init_irq_dt(void) ...@@ -461,6 +461,7 @@ void __init emev2_init_irq_dt(void)
} }
DT_MACHINE_START(EMEV2_DT, "Generic Emma Mobile EV2 (Flattened Device Tree)") DT_MACHINE_START(EMEV2_DT, "Generic Emma Mobile EV2 (Flattened Device Tree)")
.smp = smp_ops(emev2_smp_ops),
.init_early = emev2_init_delay, .init_early = emev2_init_delay,
.nr_irqs = NR_IRQS_LEGACY, .nr_irqs = NR_IRQS_LEGACY,
.init_irq = emev2_init_irq_dt, .init_irq = emev2_init_irq_dt,
......
...@@ -50,7 +50,7 @@ static void modify_scu_cpu_psr(unsigned long set, unsigned long clr) ...@@ -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) { if (!scu_base) {
scu_base = ioremap(EMEV2_SCU_BASE, PAGE_SIZE); scu_base = ioremap(EMEV2_SCU_BASE, PAGE_SIZE);
...@@ -62,17 +62,35 @@ unsigned int __init emev2_get_core_count(void) ...@@ -62,17 +62,35 @@ unsigned int __init emev2_get_core_count(void)
return scu_base ? scu_get_core_count(scu_base) : 1; 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 */ 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); 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); cpu = cpu_logical_map(cpu);
...@@ -86,7 +104,7 @@ int __cpuinit emev2_boot_secondary(unsigned int cpu) ...@@ -86,7 +104,7 @@ int __cpuinit emev2_boot_secondary(unsigned int cpu)
return 0; 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); int cpu = cpu_logical_map(0);
...@@ -95,3 +113,22 @@ void __init emev2_smp_prepare_cpus(void) ...@@ -95,3 +113,22 @@ void __init emev2_smp_prepare_cpus(void)
/* enable cache coherency on CPU0 */ /* enable cache coherency on CPU0 */
modify_scu_cpu_psr(0, 3 << (cpu * 8)); 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
};
...@@ -87,14 +87,14 @@ static void modify_scu_cpu_psr(unsigned long set, unsigned long clr) ...@@ -87,14 +87,14 @@ static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
__raw_writel(tmp, scu_base + 8); __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(); void __iomem *scu_base = scu_base_addr();
return scu_get_core_count(scu_base); 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; struct r8a7779_pm_ch *ch = NULL;
int ret = -EIO; int ret = -EIO;
...@@ -113,12 +113,31 @@ int r8a7779_platform_cpu_kill(unsigned int cpu) ...@@ -113,12 +113,31 @@ int r8a7779_platform_cpu_kill(unsigned int cpu)
return ret ? ret : 1; 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); 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; struct r8a7779_pm_ch *ch = NULL;
int ret = -EIO; int ret = -EIO;
...@@ -137,7 +156,7 @@ int __cpuinit r8a7779_boot_secondary(unsigned int cpu) ...@@ -137,7 +156,7 @@ int __cpuinit r8a7779_boot_secondary(unsigned int cpu)
return ret; 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); int cpu = cpu_logical_map(0);
...@@ -156,3 +175,22 @@ void __init r8a7779_smp_prepare_cpus(void) ...@@ -156,3 +175,22 @@ void __init r8a7779_smp_prepare_cpus(void)
r8a7779_platform_cpu_kill(2); r8a7779_platform_cpu_kill(2);
r8a7779_platform_cpu_kill(3); 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
};
...@@ -22,8 +22,10 @@ ...@@ -22,8 +22,10 @@
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/delay.h>
#include <mach/common.h> #include <mach/common.h>
#include <asm/smp_plat.h> #include <asm/smp_plat.h>
#include <mach/sh73a0.h>
#include <asm/smp_scu.h> #include <asm/smp_scu.h>
#include <asm/smp_twd.h> #include <asm/smp_twd.h>
#include <asm/hardware/gic.h> #include <asm/hardware/gic.h>
...@@ -64,19 +66,19 @@ static void modify_scu_cpu_psr(unsigned long set, unsigned long clr) ...@@ -64,19 +66,19 @@ static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
__raw_writel(tmp, scu_base + 8); __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(); void __iomem *scu_base = scu_base_addr();
return scu_get_core_count(scu_base); 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); 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); cpu = cpu_logical_map(cpu);
...@@ -91,7 +93,7 @@ int __cpuinit sh73a0_boot_secondary(unsigned int cpu) ...@@ -91,7 +93,7 @@ int __cpuinit sh73a0_boot_secondary(unsigned int cpu)
return 0; 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); int cpu = cpu_logical_map(0);
...@@ -104,3 +106,41 @@ void __init sh73a0_smp_prepare_cpus(void) ...@@ -104,3 +106,41 @@ void __init sh73a0_smp_prepare_cpus(void)
/* enable cache coherency on CPU0 */ /* enable cache coherency on CPU0 */
modify_scu_cpu_psr(0, 3 << (cpu * 8)); 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
};
...@@ -17,8 +17,6 @@ ...@@ -17,8 +17,6 @@
#include <asm/cp15.h> #include <asm/cp15.h>
#include <asm/smp_plat.h> #include <asm/smp_plat.h>
extern volatile int pen_release;
static inline void cpu_enter_lowpower(void) static inline void cpu_enter_lowpower(void)
{ {
unsigned int v; unsigned int v;
...@@ -56,7 +54,7 @@ static inline void cpu_leave_lowpower(void) ...@@ -56,7 +54,7 @@ static inline void cpu_leave_lowpower(void)
: "cc"); : "cc");
} }
static inline void platform_do_lowpower(unsigned int cpu, int *spurious) static inline void spear13xx_do_lowpower(unsigned int cpu, int *spurious)
{ {
for (;;) { for (;;) {
wfi(); wfi();
...@@ -79,17 +77,12 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious) ...@@ -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 * platform-specific code to shutdown a CPU
* *
* Called with IRQs disabled * Called with IRQs disabled
*/ */
void __cpuinit platform_cpu_die(unsigned int cpu) void __ref spear13xx_cpu_die(unsigned int cpu)
{ {
int spurious = 0; int spurious = 0;
...@@ -97,7 +90,7 @@ void __cpuinit platform_cpu_die(unsigned int cpu) ...@@ -97,7 +90,7 @@ void __cpuinit platform_cpu_die(unsigned int cpu)
* we're ready for shutdown now, so do it * we're ready for shutdown now, so do it
*/ */
cpu_enter_lowpower(); cpu_enter_lowpower();
platform_do_lowpower(cpu, &spurious); spear13xx_do_lowpower(cpu, &spurious);
/* /*
* bring this CPU back into the world of cache * bring this CPU back into the world of cache
...@@ -108,12 +101,3 @@ void __cpuinit platform_cpu_die(unsigned int cpu) ...@@ -108,12 +101,3 @@ void __cpuinit platform_cpu_die(unsigned int cpu)
if (spurious) if (spurious)
pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, 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;
}
...@@ -33,6 +33,9 @@ void __init spear13xx_l2x0_init(void); ...@@ -33,6 +33,9 @@ void __init spear13xx_l2x0_init(void);
bool dw_dma_filter(struct dma_chan *chan, void *slave); bool dw_dma_filter(struct dma_chan *chan, void *slave);
void spear_restart(char, const char *); void spear_restart(char, const char *);
void spear13xx_secondary_startup(void); void spear13xx_secondary_startup(void);
void __cpuinit spear13xx_cpu_die(unsigned int cpu);
extern struct smp_operations spear13xx_smp_ops;
#ifdef CONFIG_MACH_SPEAR1310 #ifdef CONFIG_MACH_SPEAR1310
void __init spear1310_clk_init(void); void __init spear1310_clk_init(void);
......
...@@ -19,18 +19,13 @@ ...@@ -19,18 +19,13 @@
#include <asm/hardware/gic.h> #include <asm/hardware/gic.h>
#include <asm/smp_scu.h> #include <asm/smp_scu.h>
#include <mach/spear.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 DEFINE_SPINLOCK(boot_lock);
static void __iomem *scu_base = IOMEM(VA_SCU_BASE); 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 * if any interrupts are already enabled for the primary
...@@ -53,7 +48,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu) ...@@ -53,7 +48,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
spin_unlock(&boot_lock); 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; unsigned long timeout;
...@@ -97,7 +92,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) ...@@ -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 * Initialise the CPU possible map early - this describes the CPUs
* which may be present or become present in the system. * 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); unsigned int i, ncores = scu_get_core_count(scu_base);
...@@ -113,7 +108,7 @@ void __init smp_init_cpus(void) ...@@ -113,7 +108,7 @@ void __init smp_init_cpus(void)
set_smp_cross_call(gic_raise_softirq); 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); scu_enable(scu_base);
...@@ -125,3 +120,13 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus) ...@@ -125,3 +120,13 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
*/ */
__raw_writel(virt_to_phys(spear13xx_secondary_startup), SYS_LOCATION); __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
};
...@@ -78,6 +78,7 @@ static void __init spear1310_map_io(void) ...@@ -78,6 +78,7 @@ static void __init spear1310_map_io(void)
} }
DT_MACHINE_START(SPEAR1310_DT, "ST SPEAr1310 SoC with Flattened Device Tree") DT_MACHINE_START(SPEAR1310_DT, "ST SPEAr1310 SoC with Flattened Device Tree")
.smp = smp_ops(spear13xx_smp_ops),
.map_io = spear1310_map_io, .map_io = spear1310_map_io,
.init_irq = spear13xx_dt_init_irq, .init_irq = spear13xx_dt_init_irq,
.handle_irq = gic_handle_irq, .handle_irq = gic_handle_irq,
......
...@@ -182,6 +182,7 @@ static const char * const spear1340_dt_board_compat[] = { ...@@ -182,6 +182,7 @@ static const char * const spear1340_dt_board_compat[] = {
}; };
DT_MACHINE_START(SPEAR1340_DT, "ST SPEAr1340 SoC with Flattened Device Tree") DT_MACHINE_START(SPEAR1340_DT, "ST SPEAr1340 SoC with Flattened Device Tree")
.smp = smp_ops(spear13xx_smp_ops),
.map_io = spear13xx_map_io, .map_io = spear13xx_map_io,
.init_irq = spear13xx_dt_init_irq, .init_irq = spear13xx_dt_init_irq,
.handle_irq = gic_handle_irq, .handle_irq = gic_handle_irq,
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include "board.h" #include "board.h"
#include "clock.h" #include "clock.h"
#include "devices.h" #include "devices.h"
#include "common.h"
struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = { struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC1_BASE, "sdhci-tegra.0", NULL), OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC1_BASE, "sdhci-tegra.0", NULL),
...@@ -152,6 +153,7 @@ static const char *tegra20_dt_board_compat[] = { ...@@ -152,6 +153,7 @@ static const char *tegra20_dt_board_compat[] = {
DT_MACHINE_START(TEGRA_DT, "nVidia Tegra20 (Flattened Device Tree)") DT_MACHINE_START(TEGRA_DT, "nVidia Tegra20 (Flattened Device Tree)")
.map_io = tegra_map_common_io, .map_io = tegra_map_common_io,
.smp = smp_ops(tegra_smp_ops),
.init_early = tegra20_init_early, .init_early = tegra20_init_early,
.init_irq = tegra_dt_init_irq, .init_irq = tegra_dt_init_irq,
.handle_irq = gic_handle_irq, .handle_irq = gic_handle_irq,
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include "board.h" #include "board.h"
#include "clock.h" #include "clock.h"
#include "common.h"
struct of_dev_auxdata tegra30_auxdata_lookup[] __initdata = { struct of_dev_auxdata tegra30_auxdata_lookup[] __initdata = {
OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000000, "sdhci-tegra.0", NULL), OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000000, "sdhci-tegra.0", NULL),
...@@ -83,6 +84,7 @@ static const char *tegra30_dt_board_compat[] = { ...@@ -83,6 +84,7 @@ static const char *tegra30_dt_board_compat[] = {
}; };
DT_MACHINE_START(TEGRA30_DT, "NVIDIA Tegra30 (Flattened Device Tree)") DT_MACHINE_START(TEGRA30_DT, "NVIDIA Tegra30 (Flattened Device Tree)")
.smp = smp_ops(tegra_smp_ops),
.map_io = tegra_map_common_io, .map_io = tegra_map_common_io,
.init_early = tegra30_init_early, .init_early = tegra30_init_early,
.init_irq = tegra_dt_init_irq, .init_irq = tegra_dt_init_irq,
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "board.h" #include "board.h"
#include "clock.h" #include "clock.h"
#include "common.h"
#include "fuse.h" #include "fuse.h"
#include "pmc.h" #include "pmc.h"
#include "apbio.h" #include "apbio.h"
......
extern struct smp_operations tegra_smp_ops;
extern void tegra_cpu_die(unsigned int cpu);
extern int tegra_cpu_disable(unsigned int cpu);
...@@ -19,17 +19,12 @@ ...@@ -19,17 +19,12 @@
static void (*tegra_hotplug_shutdown)(void); static void (*tegra_hotplug_shutdown)(void);
int platform_cpu_kill(unsigned int cpu)
{
return 1;
}
/* /*
* platform-specific code to shutdown a CPU * platform-specific code to shutdown a CPU
* *
* Called with IRQs disabled * Called with IRQs disabled
*/ */
void platform_cpu_die(unsigned int cpu) void __ref tegra_cpu_die(unsigned int cpu)
{ {
cpu = cpu_logical_map(cpu); cpu = cpu_logical_map(cpu);
...@@ -47,7 +42,7 @@ void platform_cpu_die(unsigned int cpu) ...@@ -47,7 +42,7 @@ void platform_cpu_die(unsigned int cpu)
BUG(); 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 * we don't allow CPU 0 to be shutdown (it is still too special
......
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
#include "reset.h" #include "reset.h"
#include "tegra_cpu_car.h" #include "tegra_cpu_car.h"
#include "common.h"
extern void tegra_secondary_startup(void); extern void tegra_secondary_startup(void);
static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE); 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); ...@@ -40,7 +42,7 @@ static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE);
#define EVP_CPU_RESET_VECTOR \ #define EVP_CPU_RESET_VECTOR \
(IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100) (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 * if any interrupts are already enabled for the primary
...@@ -100,7 +102,7 @@ static int tegra30_power_up_cpu(unsigned int cpu) ...@@ -100,7 +102,7 @@ static int tegra30_power_up_cpu(unsigned int cpu)
return 0; 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; int status;
...@@ -146,7 +148,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) ...@@ -146,7 +148,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
* Initialise the CPU possible map early - this describes the CPUs * Initialise the CPU possible map early - this describes the CPUs
* which may be present or become present in the system. * 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); unsigned int i, ncores = scu_get_core_count(scu_base);
...@@ -162,8 +164,19 @@ void __init smp_init_cpus(void) ...@@ -162,8 +164,19 @@ void __init smp_init_cpus(void)
set_smp_cross_call(gic_raise_softirq); 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(); tegra_cpu_reset_handler_init();
scu_enable(scu_base); 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
};
...@@ -673,6 +673,7 @@ static void __init hrefv60_init_machine(void) ...@@ -673,6 +673,7 @@ static void __init hrefv60_init_machine(void)
MACHINE_START(U8500, "ST-Ericsson MOP500 platform") MACHINE_START(U8500, "ST-Ericsson MOP500 platform")
/* Maintainer: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> */ /* Maintainer: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> */
.atag_offset = 0x100, .atag_offset = 0x100,
.smp = smp_ops(ux500_smp_ops),
.map_io = u8500_map_io, .map_io = u8500_map_io,
.init_irq = ux500_init_irq, .init_irq = ux500_init_irq,
/* we re-use nomadik timer here */ /* we re-use nomadik timer here */
...@@ -684,6 +685,7 @@ MACHINE_END ...@@ -684,6 +685,7 @@ MACHINE_END
MACHINE_START(HREFV60, "ST-Ericsson U8500 Platform HREFv60+") MACHINE_START(HREFV60, "ST-Ericsson U8500 Platform HREFv60+")
.atag_offset = 0x100, .atag_offset = 0x100,
.smp = smp_ops(ux500_smp_ops),
.map_io = u8500_map_io, .map_io = u8500_map_io,
.init_irq = ux500_init_irq, .init_irq = ux500_init_irq,
.timer = &ux500_timer, .timer = &ux500_timer,
...@@ -694,6 +696,7 @@ MACHINE_END ...@@ -694,6 +696,7 @@ MACHINE_END
MACHINE_START(SNOWBALL, "Calao Systems Snowball platform") MACHINE_START(SNOWBALL, "Calao Systems Snowball platform")
.atag_offset = 0x100, .atag_offset = 0x100,
.smp = smp_ops(ux500_smp_ops),
.map_io = u8500_map_io, .map_io = u8500_map_io,
.init_irq = ux500_init_irq, .init_irq = ux500_init_irq,
/* we re-use nomadik timer here */ /* we re-use nomadik timer here */
...@@ -823,6 +826,7 @@ static const char * u8500_dt_board_compat[] = { ...@@ -823,6 +826,7 @@ static const char * u8500_dt_board_compat[] = {
DT_MACHINE_START(U8500_DT, "ST-Ericsson U8500 platform (Device Tree Support)") DT_MACHINE_START(U8500_DT, "ST-Ericsson U8500 platform (Device Tree Support)")
.smp = smp_ops(ux500_smp_ops),
.map_io = u8500_map_io, .map_io = u8500_map_io,
.init_irq = ux500_init_irq, .init_irq = ux500_init_irq,
/* we re-use nomadik timer here */ /* we re-use nomadik timer here */
......
...@@ -15,13 +15,18 @@ ...@@ -15,13 +15,18 @@
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/smp_plat.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(); flush_cache_all();
/* we put the platform to just WFI */ /* directly enter low power state, skipping secure registers */
for (;;) { for (;;) {
__asm__ __volatile__("dsb\n\t" "wfi\n\t" __asm__ __volatile__("dsb\n\t" "wfi\n\t"
: : : "memory"); : : : "memory");
...@@ -33,28 +38,3 @@ static inline void platform_do_lowpower(unsigned int cpu) ...@@ -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;
}
...@@ -45,4 +45,7 @@ extern struct sys_timer ux500_timer; ...@@ -45,4 +45,7 @@ extern struct sys_timer ux500_timer;
.type = MT_MEMORY, \ .type = MT_MEMORY, \
} }
extern struct smp_operations ux500_smp_ops;
extern void ux500_cpu_die(unsigned int cpu);
#endif /* __ASM_ARCH_SETUP_H */ #endif /* __ASM_ARCH_SETUP_H */
...@@ -27,12 +27,6 @@ ...@@ -27,12 +27,6 @@
/* This is called from headsmp.S to wakeup the secondary core */ /* This is called from headsmp.S to wakeup the secondary core */
extern void u8500_secondary_startup(void); 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 * Write pen_release in a way that is guaranteed to be visible to all
* observers, irrespective of whether they're taking part in coherency * observers, irrespective of whether they're taking part in coherency
...@@ -58,7 +52,7 @@ static void __iomem *scu_base_addr(void) ...@@ -58,7 +52,7 @@ static void __iomem *scu_base_addr(void)
static DEFINE_SPINLOCK(boot_lock); 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 * if any interrupts are already enabled for the primary
...@@ -80,7 +74,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu) ...@@ -80,7 +74,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
spin_unlock(&boot_lock); 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; unsigned long timeout;
...@@ -145,7 +139,7 @@ static void __init wakeup_secondary(void) ...@@ -145,7 +139,7 @@ static void __init wakeup_secondary(void)
* Initialise the CPU possible map early - this describes the CPUs * Initialise the CPU possible map early - this describes the CPUs
* which may be present or become present in the system. * 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(); void __iomem *scu_base = scu_base_addr();
unsigned int i, ncores; unsigned int i, ncores;
...@@ -165,9 +159,19 @@ void __init smp_init_cpus(void) ...@@ -165,9 +159,19 @@ void __init smp_init_cpus(void)
set_smp_cross_call(gic_raise_softirq); 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()); scu_enable(scu_base_addr());
wakeup_secondary(); 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
};
...@@ -5,3 +5,7 @@ ...@@ -5,3 +5,7 @@
#define V2T_PERIPH 0xf8200000 #define V2T_PERIPH 0xf8200000
void vexpress_dt_smp_map_io(void); void vexpress_dt_smp_map_io(void);
extern struct smp_operations vexpress_smp_ops;
extern void vexpress_cpu_die(unsigned int cpu);
...@@ -16,8 +16,6 @@ ...@@ -16,8 +16,6 @@
#include <asm/smp_plat.h> #include <asm/smp_plat.h>
#include <asm/cp15.h> #include <asm/cp15.h>
extern volatile int pen_release;
static inline void cpu_enter_lowpower(void) static inline void cpu_enter_lowpower(void)
{ {
unsigned int v; unsigned int v;
...@@ -84,17 +82,12 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious) ...@@ -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 * platform-specific code to shutdown a CPU
* *
* Called with IRQs disabled * Called with IRQs disabled
*/ */
void platform_cpu_die(unsigned int cpu) void __ref vexpress_cpu_die(unsigned int cpu)
{ {
int spurious = 0; int spurious = 0;
...@@ -113,12 +106,3 @@ void platform_cpu_die(unsigned int cpu) ...@@ -113,12 +106,3 @@ void platform_cpu_die(unsigned int cpu)
if (spurious) if (spurious)
pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, 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;
}
...@@ -20,9 +20,9 @@ ...@@ -20,9 +20,9 @@
#include <mach/motherboard.h> #include <mach/motherboard.h>
#include "core.h" #include <plat/platsmp.h>
extern void versatile_secondary_startup(void); #include "core.h"
#if defined(CONFIG_OF) #if defined(CONFIG_OF)
...@@ -167,7 +167,7 @@ void __init vexpress_dt_smp_prepare_cpus(unsigned int max_cpus) ...@@ -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 * Initialise the CPU possible map early - this describes the CPUs
* which may be present or become present in the system. * 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) if (ct_desc)
ct_desc->init_cpu_map(); ct_desc->init_cpu_map();
...@@ -176,7 +176,7 @@ void __init smp_init_cpus(void) ...@@ -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 * Initialise the present map, which describes the set of CPUs
...@@ -195,3 +195,13 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus) ...@@ -195,3 +195,13 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
*/ */
v2m_flags_set(virt_to_phys(versatile_secondary_startup)); 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
};
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <linux/amba/bus.h> #include <linux/amba/bus.h>
#include <linux/amba/mmci.h> #include <linux/amba/mmci.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/smp.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/of_fdt.h> #include <linux/of_fdt.h>
...@@ -38,6 +39,7 @@ ...@@ -38,6 +39,7 @@
#include <mach/motherboard.h> #include <mach/motherboard.h>
#include <plat/sched_clock.h> #include <plat/sched_clock.h>
#include <plat/platsmp.h>
#include "core.h" #include "core.h"
...@@ -530,6 +532,7 @@ static void __init v2m_init(void) ...@@ -530,6 +532,7 @@ static void __init v2m_init(void)
MACHINE_START(VEXPRESS, "ARM-Versatile Express") MACHINE_START(VEXPRESS, "ARM-Versatile Express")
.atag_offset = 0x100, .atag_offset = 0x100,
.smp = smp_ops(vexpress_smp_ops),
.map_io = v2m_map_io, .map_io = v2m_map_io,
.init_early = v2m_init_early, .init_early = v2m_init_early,
.init_irq = v2m_init_irq, .init_irq = v2m_init_irq,
...@@ -661,6 +664,7 @@ const static char *v2m_dt_match[] __initconst = { ...@@ -661,6 +664,7 @@ const static char *v2m_dt_match[] __initconst = {
DT_MACHINE_START(VEXPRESS_DT, "ARM-Versatile Express") DT_MACHINE_START(VEXPRESS_DT, "ARM-Versatile Express")
.dt_compat = v2m_dt_match, .dt_compat = v2m_dt_match,
.smp = smp_ops(vexpress_smp_ops),
.map_io = v2m_dt_map_io, .map_io = v2m_dt_map_io,
.init_early = v2m_dt_init_early, .init_early = v2m_dt_init_early,
.init_irq = v2m_dt_init_irq, .init_irq = v2m_dt_init_irq,
......
...@@ -139,6 +139,8 @@ extern void imx_gpc_post_resume(void); ...@@ -139,6 +139,8 @@ extern void imx_gpc_post_resume(void);
extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode); extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);
extern void imx6q_clock_map_io(void); extern void imx6q_clock_map_io(void);
extern void imx_cpu_die(unsigned int cpu);
#ifdef CONFIG_PM #ifdef CONFIG_PM
extern void imx6q_pm_init(void); extern void imx6q_pm_init(void);
extern void imx51_pm_init(void); extern void imx51_pm_init(void);
...@@ -155,4 +157,6 @@ extern int mx51_neon_fixup(void); ...@@ -155,4 +157,6 @@ extern int mx51_neon_fixup(void);
static inline int mx51_neon_fixup(void) { return 0; } static inline int mx51_neon_fixup(void) { return 0; }
#endif #endif
extern struct smp_operations imx_smp_ops;
#endif #endif
/*
* 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);
...@@ -19,12 +19,6 @@ ...@@ -19,12 +19,6 @@
#include <asm/smp_plat.h> #include <asm/smp_plat.h>
#include <asm/hardware/gic.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 * Write pen_release in a way that is guaranteed to be visible to all
* observers, irrespective of whether they're taking part in coherency * observers, irrespective of whether they're taking part in coherency
...@@ -40,7 +34,7 @@ static void __cpuinit write_pen_release(int val) ...@@ -40,7 +34,7 @@ static void __cpuinit write_pen_release(int val)
static DEFINE_SPINLOCK(boot_lock); 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 * if any interrupts are already enabled for the primary
...@@ -62,7 +56,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu) ...@@ -62,7 +56,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
spin_unlock(&boot_lock); 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; unsigned long timeout;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment