aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2012-09-22 03:06:21 -0400
committerOlof Johansson <olof@lixom.net>2012-09-22 03:16:04 -0400
commit25468fe89f88c4ceeef94526e94ae0db176f6999 (patch)
treed70a713525281276b5063c814413bb3141e6056c /arch
parenta283580c52d3aa24305985e945dfccfbcfc6f4f9 (diff)
parent28e8e29c616f947348cc66bea684d0035c76021a (diff)
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>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/include/asm/mach/arch.h7
-rw-r--r--arch/arm/include/asm/smp.h48
-rw-r--r--arch/arm/kernel/setup.c4
-rw-r--r--arch/arm/kernel/smp.c72
-rw-r--r--arch/arm/mach-exynos/common.h5
-rw-r--r--arch/arm/mach-exynos/hotplug.c18
-rw-r--r--arch/arm/mach-exynos/mach-armlex4210.c1
-rw-r--r--arch/arm/mach-exynos/mach-exynos5-dt.c1
-rw-r--r--arch/arm/mach-exynos/mach-nuri.c1
-rw-r--r--arch/arm/mach-exynos/mach-origen.c1
-rw-r--r--arch/arm/mach-exynos/mach-smdk4x12.c2
-rw-r--r--arch/arm/mach-exynos/mach-smdkv310.c2
-rw-r--r--arch/arm/mach-exynos/mach-universal_c210.c1
-rw-r--r--arch/arm/mach-exynos/platsmp.c27
-rw-r--r--arch/arm/mach-highbank/core.h3
-rw-r--r--arch/arm/mach-highbank/highbank.c1
-rw-r--r--arch/arm/mach-highbank/hotplug.c16
-rw-r--r--arch/arm/mach-highbank/platsmp.c18
-rw-r--r--arch/arm/mach-imx/hotplug.c16
-rw-r--r--arch/arm/mach-imx/mach-imx6q.c1
-rw-r--r--arch/arm/mach-imx/platsmp.c18
-rw-r--r--arch/arm/mach-msm/board-dt-8660.c2
-rw-r--r--arch/arm/mach-msm/board-dt-8960.c2
-rw-r--r--arch/arm/mach-msm/core.h2
-rw-r--r--arch/arm/mach-msm/hotplug.c18
-rw-r--r--arch/arm/mach-msm/platsmp.c24
-rw-r--r--arch/arm/mach-omap2/board-4430sdp.c1
-rw-r--r--arch/arm/mach-omap2/board-generic.c2
-rw-r--r--arch/arm/mach-omap2/board-omap4panda.c1
-rw-r--r--arch/arm/mach-omap2/common.h5
-rw-r--r--arch/arm/mach-omap2/omap-hotplug.c16
-rw-r--r--arch/arm/mach-omap2/omap-smp.c18
-rw-r--r--arch/arm/mach-realview/core.h3
-rw-r--r--arch/arm/mach-realview/hotplug.c18
-rw-r--r--arch/arm/mach-realview/platsmp.c18
-rw-r--r--arch/arm/mach-realview/realview_pb11mp.c1
-rw-r--r--arch/arm/mach-realview/realview_pbx.c1
-rw-r--r--arch/arm/mach-shmobile/board-ag5evm.c1
-rw-r--r--arch/arm/mach-shmobile/board-kota2.c1
-rw-r--r--arch/arm/mach-shmobile/board-kzm9d.c1
-rw-r--r--arch/arm/mach-shmobile/board-kzm9g.c1
-rw-r--r--arch/arm/mach-shmobile/board-marzen.c1
-rw-r--r--arch/arm/mach-shmobile/hotplug.c31
-rw-r--r--arch/arm/mach-shmobile/include/mach/common.h24
-rw-r--r--arch/arm/mach-shmobile/include/mach/emev2.h7
-rw-r--r--arch/arm/mach-shmobile/include/mach/r8a7779.h2
-rw-r--r--arch/arm/mach-shmobile/include/mach/sh73a0.h2
-rw-r--r--arch/arm/mach-shmobile/platsmp.c96
-rw-r--r--arch/arm/mach-shmobile/setup-emev2.c1
-rw-r--r--arch/arm/mach-shmobile/smp-emev2.c47
-rw-r--r--arch/arm/mach-shmobile/smp-r8a7779.c48
-rw-r--r--arch/arm/mach-shmobile/smp-sh73a0.c48
-rw-r--r--arch/arm/mach-spear13xx/hotplug.c22
-rw-r--r--arch/arm/mach-spear13xx/include/mach/generic.h3
-rw-r--r--arch/arm/mach-spear13xx/platsmp.c25
-rw-r--r--arch/arm/mach-spear13xx/spear1310.c1
-rw-r--r--arch/arm/mach-spear13xx/spear1340.c1
-rw-r--r--arch/arm/mach-tegra/board-dt-tegra20.c2
-rw-r--r--arch/arm/mach-tegra/board-dt-tegra30.c2
-rw-r--r--arch/arm/mach-tegra/common.c1
-rw-r--r--arch/arm/mach-tegra/common.h4
-rw-r--r--arch/arm/mach-tegra/hotplug.c9
-rw-r--r--arch/arm/mach-tegra/platsmp.c21
-rw-r--r--arch/arm/mach-ux500/board-mop500.c4
-rw-r--r--arch/arm/mach-ux500/hotplug.c36
-rw-r--r--arch/arm/mach-ux500/include/mach/setup.h3
-rw-r--r--arch/arm/mach-ux500/platsmp.c24
-rw-r--r--arch/arm/mach-vexpress/core.h4
-rw-r--r--arch/arm/mach-vexpress/hotplug.c18
-rw-r--r--arch/arm/mach-vexpress/platsmp.c18
-rw-r--r--arch/arm/mach-vexpress/v2m.c4
-rw-r--r--arch/arm/plat-mxc/include/mach/common.h4
-rw-r--r--arch/arm/plat-versatile/include/plat/platsmp.h14
-rw-r--r--arch/arm/plat-versatile/platsmp.c10
74 files changed, 535 insertions, 401 deletions
diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
index 0b1c94b8c652..917d4fcfd9b4 100644
--- a/arch/arm/include/asm/mach/arch.h
+++ b/arch/arm/include/asm/mach/arch.h
@@ -14,6 +14,12 @@ struct tag;
14struct meminfo; 14struct meminfo;
15struct sys_timer; 15struct sys_timer;
16struct pt_regs; 16struct pt_regs;
17struct smp_operations;
18#ifdef CONFIG_SMP
19#define smp_ops(ops) (&(ops))
20#else
21#define smp_ops(ops) (struct smp_operations *)NULL
22#endif
17 23
18struct machine_desc { 24struct machine_desc {
19 unsigned int nr; /* architecture number */ 25 unsigned int nr; /* architecture number */
@@ -35,6 +41,7 @@ struct machine_desc {
35 unsigned char reserve_lp1 :1; /* never has lp1 */ 41 unsigned char reserve_lp1 :1; /* never has lp1 */
36 unsigned char reserve_lp2 :1; /* never has lp2 */ 42 unsigned char reserve_lp2 :1; /* never has lp2 */
37 char restart_mode; /* default restart mode */ 43 char restart_mode; /* default restart mode */
44 struct smp_operations *smp; /* SMP operations */
38 void (*fixup)(struct tag *, char **, 45 void (*fixup)(struct tag *, char **,
39 struct meminfo *); 46 struct meminfo *);
40 void (*reserve)(void);/* reserve mem blocks */ 47 void (*reserve)(void);/* reserve mem blocks */
diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
index ae29293270a3..2e3be16c6766 100644
--- a/arch/arm/include/asm/smp.h
+++ b/arch/arm/include/asm/smp.h
@@ -60,15 +60,6 @@ extern int boot_secondary(unsigned int cpu, struct task_struct *);
60 */ 60 */
61asmlinkage void secondary_start_kernel(void); 61asmlinkage void secondary_start_kernel(void);
62 62
63/*
64 * Perform platform specific initialisation of the specified CPU.
65 */
66extern void platform_secondary_init(unsigned int cpu);
67
68/*
69 * Initialize cpu_possible map, and enable coherency
70 */
71extern void platform_smp_prepare_cpus(unsigned int);
72 63
73/* 64/*
74 * Initial data for bringing up a secondary CPU. 65 * Initial data for bringing up a secondary CPU.
@@ -79,18 +70,47 @@ struct secondary_data {
79 void *stack; 70 void *stack;
80}; 71};
81extern struct secondary_data secondary_data; 72extern struct secondary_data secondary_data;
73extern volatile int pen_release;
82 74
83extern int __cpu_disable(void); 75extern int __cpu_disable(void);
84extern int platform_cpu_disable(unsigned int cpu);
85 76
86extern void __cpu_die(unsigned int cpu); 77extern void __cpu_die(unsigned int cpu);
87extern void cpu_die(void); 78extern void cpu_die(void);
88 79
89extern void platform_cpu_die(unsigned int cpu);
90extern int platform_cpu_kill(unsigned int cpu);
91extern void platform_cpu_enable(unsigned int cpu);
92
93extern void arch_send_call_function_single_ipi(int cpu); 80extern void arch_send_call_function_single_ipi(int cpu);
94extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); 81extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
95 82
83struct smp_operations {
84#ifdef CONFIG_SMP
85 /*
86 * Setup the set of possible CPUs (via set_cpu_possible)
87 */
88 void (*smp_init_cpus)(void);
89 /*
90 * Initialize cpu_possible map, and enable coherency
91 */
92 void (*smp_prepare_cpus)(unsigned int max_cpus);
93
94 /*
95 * Perform platform specific initialisation of the specified CPU.
96 */
97 void (*smp_secondary_init)(unsigned int cpu);
98 /*
99 * Boot a secondary CPU, and assign it the specified idle task.
100 * This also gives us the initial stack to use for this CPU.
101 */
102 int (*smp_boot_secondary)(unsigned int cpu, struct task_struct *idle);
103#ifdef CONFIG_HOTPLUG_CPU
104 int (*cpu_kill)(unsigned int cpu);
105 void (*cpu_die)(unsigned int cpu);
106 int (*cpu_disable)(unsigned int cpu);
107#endif
108#endif
109};
110
111/*
112 * set platform specific SMP operations
113 */
114extern void smp_set_ops(struct smp_operations *);
115
96#endif /* ifndef __ASM_ARM_SMP_H */ 116#endif /* ifndef __ASM_ARM_SMP_H */
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index a81dcecc7343..725f9f2a9541 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -977,8 +977,10 @@ void __init setup_arch(char **cmdline_p)
977 unflatten_device_tree(); 977 unflatten_device_tree();
978 978
979#ifdef CONFIG_SMP 979#ifdef CONFIG_SMP
980 if (is_smp()) 980 if (is_smp()) {
981 smp_set_ops(mdesc->smp);
981 smp_init_cpus(); 982 smp_init_cpus();
983 }
982#endif 984#endif
983 reserve_crashkernel(); 985 reserve_crashkernel();
984 986
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index ebd8ad274d76..aa4ffe6e5ecf 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -19,7 +19,6 @@
19#include <linux/mm.h> 19#include <linux/mm.h>
20#include <linux/err.h> 20#include <linux/err.h>
21#include <linux/cpu.h> 21#include <linux/cpu.h>
22#include <linux/smp.h>
23#include <linux/seq_file.h> 22#include <linux/seq_file.h>
24#include <linux/irq.h> 23#include <linux/irq.h>
25#include <linux/percpu.h> 24#include <linux/percpu.h>
@@ -27,6 +26,7 @@
27#include <linux/completion.h> 26#include <linux/completion.h>
28 27
29#include <linux/atomic.h> 28#include <linux/atomic.h>
29#include <asm/smp.h>
30#include <asm/cacheflush.h> 30#include <asm/cacheflush.h>
31#include <asm/cpu.h> 31#include <asm/cpu.h>
32#include <asm/cputype.h> 32#include <asm/cputype.h>
@@ -42,6 +42,7 @@
42#include <asm/ptrace.h> 42#include <asm/ptrace.h>
43#include <asm/localtimer.h> 43#include <asm/localtimer.h>
44#include <asm/smp_plat.h> 44#include <asm/smp_plat.h>
45#include <asm/mach/arch.h>
45 46
46/* 47/*
47 * as from 2.5, kernels no longer have an init_tasks structure 48 * as from 2.5, kernels no longer have an init_tasks structure
@@ -50,6 +51,12 @@
50 */ 51 */
51struct secondary_data secondary_data; 52struct secondary_data secondary_data;
52 53
54/*
55 * control for which core is the next to come out of the secondary
56 * boot "holding pen"
57 */
58volatile int __cpuinitdata pen_release = -1;
59
53enum ipi_msg_type { 60enum ipi_msg_type {
54 IPI_TIMER = 2, 61 IPI_TIMER = 2,
55 IPI_RESCHEDULE, 62 IPI_RESCHEDULE,
@@ -60,6 +67,14 @@ enum ipi_msg_type {
60 67
61static DECLARE_COMPLETION(cpu_running); 68static DECLARE_COMPLETION(cpu_running);
62 69
70static struct smp_operations smp_ops;
71
72void __init smp_set_ops(struct smp_operations *ops)
73{
74 if (ops)
75 smp_ops = *ops;
76};
77
63int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle) 78int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
64{ 79{
65 int ret; 80 int ret;
@@ -100,13 +115,64 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
100 return ret; 115 return ret;
101} 116}
102 117
118/* platform specific SMP operations */
119void __init smp_init_cpus(void)
120{
121 if (smp_ops.smp_init_cpus)
122 smp_ops.smp_init_cpus();
123}
124
125static void __init platform_smp_prepare_cpus(unsigned int max_cpus)
126{
127 if (smp_ops.smp_prepare_cpus)
128 smp_ops.smp_prepare_cpus(max_cpus);
129}
130
131static void __cpuinit platform_secondary_init(unsigned int cpu)
132{
133 if (smp_ops.smp_secondary_init)
134 smp_ops.smp_secondary_init(cpu);
135}
136
137int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
138{
139 if (smp_ops.smp_boot_secondary)
140 return smp_ops.smp_boot_secondary(cpu, idle);
141 return -ENOSYS;
142}
143
103#ifdef CONFIG_HOTPLUG_CPU 144#ifdef CONFIG_HOTPLUG_CPU
104static void percpu_timer_stop(void); 145static void percpu_timer_stop(void);
105 146
147static int platform_cpu_kill(unsigned int cpu)
148{
149 if (smp_ops.cpu_kill)
150 return smp_ops.cpu_kill(cpu);
151 return 1;
152}
153
154static void platform_cpu_die(unsigned int cpu)
155{
156 if (smp_ops.cpu_die)
157 smp_ops.cpu_die(cpu);
158}
159
160static int platform_cpu_disable(unsigned int cpu)
161{
162 if (smp_ops.cpu_disable)
163 return smp_ops.cpu_disable(cpu);
164
165 /*
166 * By default, allow disabling all CPUs except the first one,
167 * since this is special on a lot of platforms, e.g. because
168 * of clock tick interrupts.
169 */
170 return cpu == 0 ? -EPERM : 0;
171}
106/* 172/*
107 * __cpu_disable runs on the processor to be shutdown. 173 * __cpu_disable runs on the processor to be shutdown.
108 */ 174 */
109int __cpu_disable(void) 175int __cpuinit __cpu_disable(void)
110{ 176{
111 unsigned int cpu = smp_processor_id(); 177 unsigned int cpu = smp_processor_id();
112 int ret; 178 int ret;
@@ -149,7 +215,7 @@ static DECLARE_COMPLETION(cpu_died);
149 * called on the thread which is asking for a CPU to be shutdown - 215 * called on the thread which is asking for a CPU to be shutdown -
150 * waits until shutdown has completed, or it is timed out. 216 * waits until shutdown has completed, or it is timed out.
151 */ 217 */
152void __cpu_die(unsigned int cpu) 218void __cpuinit __cpu_die(unsigned int cpu)
153{ 219{
154 if (!wait_for_completion_timeout(&cpu_died, msecs_to_jiffies(5000))) { 220 if (!wait_for_completion_timeout(&cpu_died, msecs_to_jiffies(5000))) {
155 pr_err("CPU%u: cpu didn't die\n", cpu); 221 pr_err("CPU%u: cpu didn't die\n", cpu);
diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
index aed2eeb06517..dac146df79ac 100644
--- a/arch/arm/mach-exynos/common.h
+++ b/arch/arm/mach-exynos/common.h
@@ -14,6 +14,7 @@
14 14
15extern struct sys_timer exynos4_timer; 15extern struct sys_timer exynos4_timer;
16 16
17struct map_desc;
17void exynos_init_io(struct map_desc *mach_desc, int size); 18void exynos_init_io(struct map_desc *mach_desc, int size);
18void exynos4_init_irq(void); 19void exynos4_init_irq(void);
19void exynos5_init_irq(void); 20void exynos5_init_irq(void);
@@ -59,4 +60,8 @@ void exynos4212_register_clocks(void);
59#define exynos4212_register_clocks() 60#define exynos4212_register_clocks()
60#endif 61#endif
61 62
63extern struct smp_operations exynos_smp_ops;
64
65extern void exynos_cpu_die(unsigned int cpu);
66
62#endif /* __ARCH_ARM_MACH_EXYNOS_COMMON_H */ 67#endif /* __ARCH_ARM_MACH_EXYNOS_COMMON_H */
diff --git a/arch/arm/mach-exynos/hotplug.c b/arch/arm/mach-exynos/hotplug.c
index 9c17a0a43858..f4d7dd20cdac 100644
--- a/arch/arm/mach-exynos/hotplug.c
+++ b/arch/arm/mach-exynos/hotplug.c
@@ -21,7 +21,7 @@
21 21
22#include <mach/regs-pmu.h> 22#include <mach/regs-pmu.h>
23 23
24extern volatile int pen_release; 24#include "common.h"
25 25
26static inline void cpu_enter_lowpower(void) 26static inline void cpu_enter_lowpower(void)
27{ 27{
@@ -95,17 +95,12 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
95 } 95 }
96} 96}
97 97
98int platform_cpu_kill(unsigned int cpu)
99{
100 return 1;
101}
102
103/* 98/*
104 * platform-specific code to shutdown a CPU 99 * platform-specific code to shutdown a CPU
105 * 100 *
106 * Called with IRQs disabled 101 * Called with IRQs disabled
107 */ 102 */
108void platform_cpu_die(unsigned int cpu) 103void __ref exynos_cpu_die(unsigned int cpu)
109{ 104{
110 int spurious = 0; 105 int spurious = 0;
111 106
@@ -124,12 +119,3 @@ void platform_cpu_die(unsigned int cpu)
124 if (spurious) 119 if (spurious)
125 pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious); 120 pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
126} 121}
127
128int platform_cpu_disable(unsigned int cpu)
129{
130 /*
131 * we don't allow CPU 0 to be shutdown (it is still too special
132 * e.g. clock tick interrupts)
133 */
134 return cpu == 0 ? -EPERM : 0;
135}
diff --git a/arch/arm/mach-exynos/mach-armlex4210.c b/arch/arm/mach-exynos/mach-armlex4210.c
index 5a3daa0168d8..3f37a5e8a1f4 100644
--- a/arch/arm/mach-exynos/mach-armlex4210.c
+++ b/arch/arm/mach-exynos/mach-armlex4210.c
@@ -199,6 +199,7 @@ static void __init armlex4210_machine_init(void)
199MACHINE_START(ARMLEX4210, "ARMLEX4210") 199MACHINE_START(ARMLEX4210, "ARMLEX4210")
200 /* Maintainer: Alim Akhtar <alim.akhtar@samsung.com> */ 200 /* Maintainer: Alim Akhtar <alim.akhtar@samsung.com> */
201 .atag_offset = 0x100, 201 .atag_offset = 0x100,
202 .smp = smp_ops(exynos_smp_ops),
202 .init_irq = exynos4_init_irq, 203 .init_irq = exynos4_init_irq,
203 .map_io = armlex4210_map_io, 204 .map_io = armlex4210_map_io,
204 .handle_irq = gic_handle_irq, 205 .handle_irq = gic_handle_irq,
diff --git a/arch/arm/mach-exynos/mach-exynos5-dt.c b/arch/arm/mach-exynos/mach-exynos5-dt.c
index ef770bc2318f..8833060f77e9 100644
--- a/arch/arm/mach-exynos/mach-exynos5-dt.c
+++ b/arch/arm/mach-exynos/mach-exynos5-dt.c
@@ -79,6 +79,7 @@ static char const *exynos5250_dt_compat[] __initdata = {
79DT_MACHINE_START(EXYNOS5_DT, "SAMSUNG EXYNOS5 (Flattened Device Tree)") 79DT_MACHINE_START(EXYNOS5_DT, "SAMSUNG EXYNOS5 (Flattened Device Tree)")
80 /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */ 80 /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
81 .init_irq = exynos5_init_irq, 81 .init_irq = exynos5_init_irq,
82 .smp = smp_ops(exynos_smp_ops),
82 .map_io = exynos5250_dt_map_io, 83 .map_io = exynos5250_dt_map_io,
83 .handle_irq = gic_handle_irq, 84 .handle_irq = gic_handle_irq,
84 .init_machine = exynos5250_dt_machine_init, 85 .init_machine = exynos5250_dt_machine_init,
diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c
index ea785fcaf6c3..ffaa355c1bde 100644
--- a/arch/arm/mach-exynos/mach-nuri.c
+++ b/arch/arm/mach-exynos/mach-nuri.c
@@ -1383,6 +1383,7 @@ static void __init nuri_machine_init(void)
1383MACHINE_START(NURI, "NURI") 1383MACHINE_START(NURI, "NURI")
1384 /* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */ 1384 /* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
1385 .atag_offset = 0x100, 1385 .atag_offset = 0x100,
1386 .smp = smp_ops(exynos_smp_ops),
1386 .init_irq = exynos4_init_irq, 1387 .init_irq = exynos4_init_irq,
1387 .map_io = nuri_map_io, 1388 .map_io = nuri_map_io,
1388 .handle_irq = gic_handle_irq, 1389 .handle_irq = gic_handle_irq,
diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c
index 4e574c24581c..abd0e6059ab3 100644
--- a/arch/arm/mach-exynos/mach-origen.c
+++ b/arch/arm/mach-exynos/mach-origen.c
@@ -806,6 +806,7 @@ static void __init origen_machine_init(void)
806MACHINE_START(ORIGEN, "ORIGEN") 806MACHINE_START(ORIGEN, "ORIGEN")
807 /* Maintainer: JeongHyeon Kim <jhkim@insignal.co.kr> */ 807 /* Maintainer: JeongHyeon Kim <jhkim@insignal.co.kr> */
808 .atag_offset = 0x100, 808 .atag_offset = 0x100,
809 .smp = smp_ops(exynos_smp_ops),
809 .init_irq = exynos4_init_irq, 810 .init_irq = exynos4_init_irq,
810 .map_io = origen_map_io, 811 .map_io = origen_map_io,
811 .handle_irq = gic_handle_irq, 812 .handle_irq = gic_handle_irq,
diff --git a/arch/arm/mach-exynos/mach-smdk4x12.c b/arch/arm/mach-exynos/mach-smdk4x12.c
index b26beb13ebef..964693bdc242 100644
--- a/arch/arm/mach-exynos/mach-smdk4x12.c
+++ b/arch/arm/mach-exynos/mach-smdk4x12.c
@@ -370,6 +370,7 @@ static void __init smdk4x12_machine_init(void)
370MACHINE_START(SMDK4212, "SMDK4212") 370MACHINE_START(SMDK4212, "SMDK4212")
371 /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */ 371 /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
372 .atag_offset = 0x100, 372 .atag_offset = 0x100,
373 .smp = smp_ops(exynos_smp_ops),
373 .init_irq = exynos4_init_irq, 374 .init_irq = exynos4_init_irq,
374 .map_io = smdk4x12_map_io, 375 .map_io = smdk4x12_map_io,
375 .handle_irq = gic_handle_irq, 376 .handle_irq = gic_handle_irq,
@@ -383,6 +384,7 @@ MACHINE_START(SMDK4412, "SMDK4412")
383 /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */ 384 /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
384 /* Maintainer: Changhwan Youn <chaos.youn@samsung.com> */ 385 /* Maintainer: Changhwan Youn <chaos.youn@samsung.com> */
385 .atag_offset = 0x100, 386 .atag_offset = 0x100,
387 .smp = smp_ops(exynos_smp_ops),
386 .init_irq = exynos4_init_irq, 388 .init_irq = exynos4_init_irq,
387 .map_io = smdk4x12_map_io, 389 .map_io = smdk4x12_map_io,
388 .handle_irq = gic_handle_irq, 390 .handle_irq = gic_handle_irq,
diff --git a/arch/arm/mach-exynos/mach-smdkv310.c b/arch/arm/mach-exynos/mach-smdkv310.c
index 73f2bce097e1..69b858ceefc5 100644
--- a/arch/arm/mach-exynos/mach-smdkv310.c
+++ b/arch/arm/mach-exynos/mach-smdkv310.c
@@ -417,6 +417,7 @@ MACHINE_START(SMDKV310, "SMDKV310")
417 /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */ 417 /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
418 /* Maintainer: Changhwan Youn <chaos.youn@samsung.com> */ 418 /* Maintainer: Changhwan Youn <chaos.youn@samsung.com> */
419 .atag_offset = 0x100, 419 .atag_offset = 0x100,
420 .smp = smp_ops(exynos_smp_ops),
420 .init_irq = exynos4_init_irq, 421 .init_irq = exynos4_init_irq,
421 .map_io = smdkv310_map_io, 422 .map_io = smdkv310_map_io,
422 .handle_irq = gic_handle_irq, 423 .handle_irq = gic_handle_irq,
@@ -429,6 +430,7 @@ MACHINE_END
429MACHINE_START(SMDKC210, "SMDKC210") 430MACHINE_START(SMDKC210, "SMDKC210")
430 /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */ 431 /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
431 .atag_offset = 0x100, 432 .atag_offset = 0x100,
433 .smp = smp_ops(exynos_smp_ops),
432 .init_irq = exynos4_init_irq, 434 .init_irq = exynos4_init_irq,
433 .map_io = smdkv310_map_io, 435 .map_io = smdkv310_map_io,
434 .handle_irq = gic_handle_irq, 436 .handle_irq = gic_handle_irq,
diff --git a/arch/arm/mach-exynos/mach-universal_c210.c b/arch/arm/mach-exynos/mach-universal_c210.c
index 4d1f40d44ed1..922ca0f11795 100644
--- a/arch/arm/mach-exynos/mach-universal_c210.c
+++ b/arch/arm/mach-exynos/mach-universal_c210.c
@@ -1155,6 +1155,7 @@ static void __init universal_machine_init(void)
1155MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210") 1155MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210")
1156 /* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */ 1156 /* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
1157 .atag_offset = 0x100, 1157 .atag_offset = 0x100,
1158 .smp = smp_ops(exynos_smp_ops),
1158 .init_irq = exynos4_init_irq, 1159 .init_irq = exynos4_init_irq,
1159 .map_io = universal_map_io, 1160 .map_io = universal_map_io,
1160 .handle_irq = gic_handle_irq, 1161 .handle_irq = gic_handle_irq,
diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index 36c3984aaa47..8d57e4223bdb 100644
--- a/arch/arm/mach-exynos/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -32,19 +32,14 @@
32 32
33#include <plat/cpu.h> 33#include <plat/cpu.h>
34 34
35#include "common.h"
36
35extern void exynos4_secondary_startup(void); 37extern void exynos4_secondary_startup(void);
36 38
37#define CPU1_BOOT_REG (samsung_rev() == EXYNOS4210_REV_1_1 ? \ 39#define CPU1_BOOT_REG (samsung_rev() == EXYNOS4210_REV_1_1 ? \
38 S5P_INFORM5 : S5P_VA_SYSRAM) 40 S5P_INFORM5 : S5P_VA_SYSRAM)
39 41
40/* 42/*
41 * control for which core is the next to come out of the secondary
42 * boot "holding pen"
43 */
44
45volatile int __cpuinitdata pen_release = -1;
46
47/*
48 * Write pen_release in a way that is guaranteed to be visible to all 43 * Write pen_release in a way that is guaranteed to be visible to all
49 * observers, irrespective of whether they're taking part in coherency 44 * observers, irrespective of whether they're taking part in coherency
50 * or not. This is necessary for the hotplug code to work reliably. 45 * or not. This is necessary for the hotplug code to work reliably.
@@ -64,7 +59,7 @@ static void __iomem *scu_base_addr(void)
64 59
65static DEFINE_SPINLOCK(boot_lock); 60static DEFINE_SPINLOCK(boot_lock);
66 61
67void __cpuinit platform_secondary_init(unsigned int cpu) 62static void __cpuinit exynos_secondary_init(unsigned int cpu)
68{ 63{
69 /* 64 /*
70 * if any interrupts are already enabled for the primary 65 * if any interrupts are already enabled for the primary
@@ -86,7 +81,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
86 spin_unlock(&boot_lock); 81 spin_unlock(&boot_lock);
87} 82}
88 83
89int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) 84static int __cpuinit exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
90{ 85{
91 unsigned long timeout; 86 unsigned long timeout;
92 87
@@ -161,7 +156,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
161 * which may be present or become present in the system. 156 * which may be present or become present in the system.
162 */ 157 */
163 158
164void __init smp_init_cpus(void) 159static void __init exynos_smp_init_cpus(void)
165{ 160{
166 void __iomem *scu_base = scu_base_addr(); 161 void __iomem *scu_base = scu_base_addr();
167 unsigned int i, ncores; 162 unsigned int i, ncores;
@@ -184,7 +179,7 @@ void __init smp_init_cpus(void)
184 set_smp_cross_call(gic_raise_softirq); 179 set_smp_cross_call(gic_raise_softirq);
185} 180}
186 181
187void __init platform_smp_prepare_cpus(unsigned int max_cpus) 182static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
188{ 183{
189 if (!soc_is_exynos5250()) 184 if (!soc_is_exynos5250())
190 scu_enable(scu_base_addr()); 185 scu_enable(scu_base_addr());
@@ -198,3 +193,13 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
198 __raw_writel(virt_to_phys(exynos4_secondary_startup), 193 __raw_writel(virt_to_phys(exynos4_secondary_startup),
199 CPU1_BOOT_REG); 194 CPU1_BOOT_REG);
200} 195}
196
197struct smp_operations exynos_smp_ops __initdata = {
198 .smp_init_cpus = exynos_smp_init_cpus,
199 .smp_prepare_cpus = exynos_smp_prepare_cpus,
200 .smp_secondary_init = exynos_secondary_init,
201 .smp_boot_secondary = exynos_boot_secondary,
202#ifdef CONFIG_HOTPLUG_CPU
203 .cpu_die = exynos_cpu_die,
204#endif
205};
diff --git a/arch/arm/mach-highbank/core.h b/arch/arm/mach-highbank/core.h
index 8b9fb1a46a91..286ec82a4f63 100644
--- a/arch/arm/mach-highbank/core.h
+++ b/arch/arm/mach-highbank/core.h
@@ -15,3 +15,6 @@ static inline void highbank_pm_init(void) {}
15#endif 15#endif
16 16
17extern void highbank_smc1(int fn, int arg); 17extern void highbank_smc1(int fn, int arg);
18extern void highbank_cpu_die(unsigned int cpu);
19
20extern struct smp_operations highbank_smp_ops;
diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c
index f376c26cb0e1..af1da34ccf9d 100644
--- a/arch/arm/mach-highbank/highbank.c
+++ b/arch/arm/mach-highbank/highbank.c
@@ -163,6 +163,7 @@ static const char *highbank_match[] __initconst = {
163}; 163};
164 164
165DT_MACHINE_START(HIGHBANK, "Highbank") 165DT_MACHINE_START(HIGHBANK, "Highbank")
166 .smp = smp_ops(highbank_smp_ops),
166 .map_io = highbank_map_io, 167 .map_io = highbank_map_io,
167 .init_irq = highbank_init_irq, 168 .init_irq = highbank_init_irq,
168 .timer = &highbank_timer, 169 .timer = &highbank_timer,
diff --git a/arch/arm/mach-highbank/hotplug.c b/arch/arm/mach-highbank/hotplug.c
index 977cebbea580..2c1b8c3c8e45 100644
--- a/arch/arm/mach-highbank/hotplug.c
+++ b/arch/arm/mach-highbank/hotplug.c
@@ -24,16 +24,11 @@
24 24
25extern void secondary_startup(void); 25extern void secondary_startup(void);
26 26
27int platform_cpu_kill(unsigned int cpu)
28{
29 return 1;
30}
31
32/* 27/*
33 * platform-specific code to shutdown a CPU 28 * platform-specific code to shutdown a CPU
34 * 29 *
35 */ 30 */
36void platform_cpu_die(unsigned int cpu) 31void __ref highbank_cpu_die(unsigned int cpu)
37{ 32{
38 flush_cache_all(); 33 flush_cache_all();
39 34
@@ -45,12 +40,3 @@ void platform_cpu_die(unsigned int cpu)
45 /* We should never return from idle */ 40 /* We should never return from idle */
46 panic("highbank: cpu %d unexpectedly exit from shutdown\n", cpu); 41 panic("highbank: cpu %d unexpectedly exit from shutdown\n", cpu);
47} 42}
48
49int platform_cpu_disable(unsigned int cpu)
50{
51 /*
52 * CPU0 should not be shut down via hotplug. cpu_idle can WFI
53 * or a proper shutdown or hibernate should be used.
54 */
55 return cpu == 0 ? -EPERM : 0;
56}
diff --git a/arch/arm/mach-highbank/platsmp.c b/arch/arm/mach-highbank/platsmp.c
index d01364c72b45..fa9560ec6e70 100644
--- a/arch/arm/mach-highbank/platsmp.c
+++ b/arch/arm/mach-highbank/platsmp.c
@@ -25,12 +25,12 @@
25 25
26extern void secondary_startup(void); 26extern void secondary_startup(void);
27 27
28void __cpuinit platform_secondary_init(unsigned int cpu) 28static void __cpuinit highbank_secondary_init(unsigned int cpu)
29{ 29{
30 gic_secondary_init(0); 30 gic_secondary_init(0);
31} 31}
32 32
33int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) 33static int __cpuinit highbank_boot_secondary(unsigned int cpu, struct task_struct *idle)
34{ 34{
35 gic_raise_softirq(cpumask_of(cpu), 0); 35 gic_raise_softirq(cpumask_of(cpu), 0);
36 return 0; 36 return 0;
@@ -40,7 +40,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
40 * Initialise the CPU possible map early - this describes the CPUs 40 * Initialise the CPU possible map early - this describes the CPUs
41 * which may be present or become present in the system. 41 * which may be present or become present in the system.
42 */ 42 */
43void __init smp_init_cpus(void) 43static void __init highbank_smp_init_cpus(void)
44{ 44{
45 unsigned int i, ncores; 45 unsigned int i, ncores;
46 46
@@ -61,7 +61,7 @@ void __init smp_init_cpus(void)
61 set_smp_cross_call(gic_raise_softirq); 61 set_smp_cross_call(gic_raise_softirq);
62} 62}
63 63
64void __init platform_smp_prepare_cpus(unsigned int max_cpus) 64static void __init highbank_smp_prepare_cpus(unsigned int max_cpus)
65{ 65{
66 int i; 66 int i;
67 67
@@ -76,3 +76,13 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
76 for (i = 1; i < max_cpus; i++) 76 for (i = 1; i < max_cpus; i++)
77 highbank_set_cpu_jump(i, secondary_startup); 77 highbank_set_cpu_jump(i, secondary_startup);
78} 78}
79
80struct smp_operations highbank_smp_ops __initdata = {
81 .smp_init_cpus = highbank_smp_init_cpus,
82 .smp_prepare_cpus = highbank_smp_prepare_cpus,
83 .smp_secondary_init = highbank_secondary_init,
84 .smp_boot_secondary = highbank_boot_secondary,
85#ifdef CONFIG_HOTPLUG_CPU
86 .cpu_die = highbank_cpu_die,
87#endif
88};
diff --git a/arch/arm/mach-imx/hotplug.c b/arch/arm/mach-imx/hotplug.c
index f8f7437c83b8..b07b778dc9a8 100644
--- a/arch/arm/mach-imx/hotplug.c
+++ b/arch/arm/mach-imx/hotplug.c
@@ -15,11 +15,6 @@
15#include <asm/cp15.h> 15#include <asm/cp15.h>
16#include <mach/common.h> 16#include <mach/common.h>
17 17
18int platform_cpu_kill(unsigned int cpu)
19{
20 return 1;
21}
22
23static inline void cpu_enter_lowpower(void) 18static inline void cpu_enter_lowpower(void)
24{ 19{
25 unsigned int v; 20 unsigned int v;
@@ -47,7 +42,7 @@ static inline void cpu_enter_lowpower(void)
47 * 42 *
48 * Called with IRQs disabled 43 * Called with IRQs disabled
49 */ 44 */
50void platform_cpu_die(unsigned int cpu) 45void imx_cpu_die(unsigned int cpu)
51{ 46{
52 cpu_enter_lowpower(); 47 cpu_enter_lowpower();
53 imx_enable_cpu(cpu, false); 48 imx_enable_cpu(cpu, false);
@@ -56,12 +51,3 @@ void platform_cpu_die(unsigned int cpu)
56 while (1) 51 while (1)
57 ; 52 ;
58} 53}
59
60int platform_cpu_disable(unsigned int cpu)
61{
62 /*
63 * we don't allow CPU 0 to be shutdown (it is still too special
64 * e.g. clock tick interrupts)
65 */
66 return cpu == 0 ? -EPERM : 0;
67}
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index 692b4b143bb1..36979d3dfe34 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -215,6 +215,7 @@ static const char *imx6q_dt_compat[] __initdata = {
215}; 215};
216 216
217DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad (Device Tree)") 217DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad (Device Tree)")
218 .smp = smp_ops(imx_smp_ops),
218 .map_io = imx6q_map_io, 219 .map_io = imx6q_map_io,
219 .init_irq = imx6q_init_irq, 220 .init_irq = imx6q_init_irq,
220 .handle_irq = imx6q_handle_irq, 221 .handle_irq = imx6q_handle_irq,
diff --git a/arch/arm/mach-imx/platsmp.c b/arch/arm/mach-imx/platsmp.c
index ab98c6fec9eb..2ac43e1a2dfd 100644
--- a/arch/arm/mach-imx/platsmp.c
+++ b/arch/arm/mach-imx/platsmp.c
@@ -41,7 +41,7 @@ void __init imx_scu_map_io(void)
41 scu_base = IMX_IO_ADDRESS(base); 41 scu_base = IMX_IO_ADDRESS(base);
42} 42}
43 43
44void __cpuinit platform_secondary_init(unsigned int cpu) 44static void __cpuinit imx_secondary_init(unsigned int cpu)
45{ 45{
46 /* 46 /*
47 * if any interrupts are already enabled for the primary 47 * if any interrupts are already enabled for the primary
@@ -51,7 +51,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
51 gic_secondary_init(0); 51 gic_secondary_init(0);
52} 52}
53 53
54int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) 54static int __cpuinit imx_boot_secondary(unsigned int cpu, struct task_struct *idle)
55{ 55{
56 imx_set_cpu_jump(cpu, v7_secondary_startup); 56 imx_set_cpu_jump(cpu, v7_secondary_startup);
57 imx_enable_cpu(cpu, true); 57 imx_enable_cpu(cpu, true);
@@ -62,7 +62,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
62 * Initialise the CPU possible map early - this describes the CPUs 62 * Initialise the CPU possible map early - this describes the CPUs
63 * which may be present or become present in the system. 63 * which may be present or become present in the system.
64 */ 64 */
65void __init smp_init_cpus(void) 65static void __init imx_smp_init_cpus(void)
66{ 66{
67 int i, ncores; 67 int i, ncores;
68 68
@@ -79,7 +79,17 @@ void imx_smp_prepare(void)
79 scu_enable(scu_base); 79 scu_enable(scu_base);
80} 80}
81 81
82void __init platform_smp_prepare_cpus(unsigned int max_cpus) 82static void __init imx_smp_prepare_cpus(unsigned int max_cpus)
83{ 83{
84 imx_smp_prepare(); 84 imx_smp_prepare();
85} 85}
86
87struct smp_operations imx_smp_ops __initdata = {
88 .smp_init_cpus = imx_smp_init_cpus,
89 .smp_prepare_cpus = imx_smp_prepare_cpus,
90 .smp_secondary_init = imx_secondary_init,
91 .smp_boot_secondary = imx_boot_secondary,
92#ifdef CONFIG_HOTPLUG_CPU
93 .cpu_die = imx_cpu_die,
94#endif
95};
diff --git a/arch/arm/mach-msm/board-dt-8660.c b/arch/arm/mach-msm/board-dt-8660.c
index f77f57f39104..e5643f629dcd 100644
--- a/arch/arm/mach-msm/board-dt-8660.c
+++ b/arch/arm/mach-msm/board-dt-8660.c
@@ -20,6 +20,7 @@
20 20
21#include <mach/board.h> 21#include <mach/board.h>
22#include "common.h" 22#include "common.h"
23#include "core.h"
23 24
24static const struct of_device_id msm_dt_gic_match[] __initconst = { 25static const struct of_device_id msm_dt_gic_match[] __initconst = {
25 { .compatible = "qcom,msm-8660-qgic", .data = gic_of_init }, 26 { .compatible = "qcom,msm-8660-qgic", .data = gic_of_init },
@@ -53,6 +54,7 @@ static const char *msm8x60_fluid_match[] __initdata = {
53}; 54};
54 55
55DT_MACHINE_START(MSM_DT, "Qualcomm MSM (Flattened Device Tree)") 56DT_MACHINE_START(MSM_DT, "Qualcomm MSM (Flattened Device Tree)")
57 .smp = smp_ops(msm_smp_ops),
56 .map_io = msm_map_msm8x60_io, 58 .map_io = msm_map_msm8x60_io,
57 .init_irq = msm8x60_init_irq, 59 .init_irq = msm8x60_init_irq,
58 .handle_irq = gic_handle_irq, 60 .handle_irq = gic_handle_irq,
diff --git a/arch/arm/mach-msm/board-dt-8960.c b/arch/arm/mach-msm/board-dt-8960.c
index 8df99b8f3c92..139d61bbc8e7 100644
--- a/arch/arm/mach-msm/board-dt-8960.c
+++ b/arch/arm/mach-msm/board-dt-8960.c
@@ -18,6 +18,7 @@
18#include <asm/mach/arch.h> 18#include <asm/mach/arch.h>
19 19
20#include "common.h" 20#include "common.h"
21#include "core.h"
21 22
22static const struct of_device_id msm_dt_gic_match[] __initconst = { 23static const struct of_device_id msm_dt_gic_match[] __initconst = {
23 { .compatible = "qcom,msm-qgic2", .data = gic_of_init }, 24 { .compatible = "qcom,msm-qgic2", .data = gic_of_init },
@@ -40,6 +41,7 @@ static const char * const msm8960_dt_match[] __initconst = {
40}; 41};
41 42
42DT_MACHINE_START(MSM8960_DT, "Qualcomm MSM (Flattened Device Tree)") 43DT_MACHINE_START(MSM8960_DT, "Qualcomm MSM (Flattened Device Tree)")
44 .smp = smp_ops(msm_smp_ops),
43 .map_io = msm_map_msm8960_io, 45 .map_io = msm_map_msm8960_io,
44 .init_irq = msm_dt_init_irq, 46 .init_irq = msm_dt_init_irq,
45 .timer = &msm_dt_timer, 47 .timer = &msm_dt_timer,
diff --git a/arch/arm/mach-msm/core.h b/arch/arm/mach-msm/core.h
new file mode 100644
index 000000000000..a9bab53dddf4
--- /dev/null
+++ b/arch/arm/mach-msm/core.h
@@ -0,0 +1,2 @@
1extern struct smp_operations msm_smp_ops;
2extern void msm_cpu_die(unsigned int cpu);
diff --git a/arch/arm/mach-msm/hotplug.c b/arch/arm/mach-msm/hotplug.c
index a446fc14221f..002ac1e47235 100644
--- a/arch/arm/mach-msm/hotplug.c
+++ b/arch/arm/mach-msm/hotplug.c
@@ -13,7 +13,7 @@
13#include <asm/cacheflush.h> 13#include <asm/cacheflush.h>
14#include <asm/smp_plat.h> 14#include <asm/smp_plat.h>
15 15
16extern volatile int pen_release; 16#include "core.h"
17 17
18static inline void cpu_enter_lowpower(void) 18static inline void cpu_enter_lowpower(void)
19{ 19{
@@ -57,17 +57,12 @@ static inline void platform_do_lowpower(unsigned int cpu)
57 } 57 }
58} 58}
59 59
60int platform_cpu_kill(unsigned int cpu)
61{
62 return 1;
63}
64
65/* 60/*
66 * platform-specific code to shutdown a CPU 61 * platform-specific code to shutdown a CPU
67 * 62 *
68 * Called with IRQs disabled 63 * Called with IRQs disabled
69 */ 64 */
70void platform_cpu_die(unsigned int cpu) 65void __ref msm_cpu_die(unsigned int cpu)
71{ 66{
72 /* 67 /*
73 * we're ready for shutdown now, so do it 68 * we're ready for shutdown now, so do it
@@ -81,12 +76,3 @@ void platform_cpu_die(unsigned int cpu)
81 */ 76 */
82 cpu_leave_lowpower(); 77 cpu_leave_lowpower();
83} 78}
84
85int platform_cpu_disable(unsigned int cpu)
86{
87 /*
88 * we don't allow CPU 0 to be shutdown (it is still too special
89 * e.g. clock tick interrupts)
90 */
91 return cpu == 0 ? -EPERM : 0;
92}
diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
index 2d791e6b4ad1..637021c0d8af 100644
--- a/arch/arm/mach-msm/platsmp.c
+++ b/arch/arm/mach-msm/platsmp.c
@@ -23,17 +23,13 @@
23#include <asm/smp_plat.h> 23#include <asm/smp_plat.h>
24 24
25#include "scm-boot.h" 25#include "scm-boot.h"
26#include "core.h"
26 27
27#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x15A0 28#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x15A0
28#define SCSS_CPU1CORE_RESET 0xD80 29#define SCSS_CPU1CORE_RESET 0xD80
29#define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64 30#define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64
30 31
31extern void msm_secondary_startup(void); 32extern void msm_secondary_startup(void);
32/*
33 * control for which core is the next to come out of the secondary
34 * boot "holding pen".
35 */
36volatile int pen_release = -1;
37 33
38static DEFINE_SPINLOCK(boot_lock); 34static DEFINE_SPINLOCK(boot_lock);
39 35
@@ -43,7 +39,7 @@ static inline int get_core_count(void)
43 return ((read_cpuid_id() >> 4) & 3) + 1; 39 return ((read_cpuid_id() >> 4) & 3) + 1;
44} 40}
45 41
46void __cpuinit platform_secondary_init(unsigned int cpu) 42static void __cpuinit msm_secondary_init(unsigned int cpu)
47{ 43{
48 /* 44 /*
49 * if any interrupts are already enabled for the primary 45 * if any interrupts are already enabled for the primary
@@ -85,7 +81,7 @@ static __cpuinit void prepare_cold_cpu(unsigned int cpu)
85 "address\n"); 81 "address\n");
86} 82}
87 83
88int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) 84static int __cpuinit msm_boot_secondary(unsigned int cpu, struct task_struct *idle)
89{ 85{
90 unsigned long timeout; 86 unsigned long timeout;
91 static int cold_boot_done; 87 static int cold_boot_done;
@@ -145,7 +141,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
145 * does not support the ARM SCU, so just set the possible cpu mask to 141 * does not support the ARM SCU, so just set the possible cpu mask to
146 * NR_CPUS. 142 * NR_CPUS.
147 */ 143 */
148void __init smp_init_cpus(void) 144static void __init msm_smp_init_cpus(void)
149{ 145{
150 unsigned int i, ncores = get_core_count(); 146 unsigned int i, ncores = get_core_count();
151 147
@@ -161,6 +157,16 @@ void __init smp_init_cpus(void)
161 set_smp_cross_call(gic_raise_softirq); 157 set_smp_cross_call(gic_raise_softirq);
162} 158}
163 159
164void __init platform_smp_prepare_cpus(unsigned int max_cpus) 160static void __init msm_smp_prepare_cpus(unsigned int max_cpus)
165{ 161{
166} 162}
163
164struct smp_operations msm_smp_ops __initdata = {
165 .smp_init_cpus = msm_smp_init_cpus,
166 .smp_prepare_cpus = msm_smp_prepare_cpus,
167 .smp_secondary_init = msm_secondary_init,
168 .smp_boot_secondary = msm_boot_secondary,
169#ifdef CONFIG_HOTPLUG_CPU
170 .cpu_die = msm_cpu_die,
171#endif
172};
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index e82098fbedd6..6fe90796d462 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -907,6 +907,7 @@ static void __init omap_4430sdp_init(void)
907MACHINE_START(OMAP_4430SDP, "OMAP4430 4430SDP board") 907MACHINE_START(OMAP_4430SDP, "OMAP4430 4430SDP board")
908 /* Maintainer: Santosh Shilimkar - Texas Instruments Inc */ 908 /* Maintainer: Santosh Shilimkar - Texas Instruments Inc */
909 .atag_offset = 0x100, 909 .atag_offset = 0x100,
910 .smp = smp_ops(omap4_smp_ops),
910 .reserve = omap_reserve, 911 .reserve = omap_reserve,
911 .map_io = omap4_map_io, 912 .map_io = omap4_map_io,
912 .init_early = omap4430_init_early, 913 .init_early = omap4430_init_early,
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 2ea7c577b295..601ecdfb1cf9 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -125,6 +125,7 @@ static const char *omap4_boards_compat[] __initdata = {
125 125
126DT_MACHINE_START(OMAP4_DT, "Generic OMAP4 (Flattened Device Tree)") 126DT_MACHINE_START(OMAP4_DT, "Generic OMAP4 (Flattened Device Tree)")
127 .reserve = omap_reserve, 127 .reserve = omap_reserve,
128 .smp = smp_ops(omap4_smp_ops),
128 .map_io = omap4_map_io, 129 .map_io = omap4_map_io,
129 .init_early = omap4430_init_early, 130 .init_early = omap4430_init_early,
130 .init_irq = omap_gic_of_init, 131 .init_irq = omap_gic_of_init,
@@ -145,6 +146,7 @@ static const char *omap5_boards_compat[] __initdata = {
145 146
146DT_MACHINE_START(OMAP5_DT, "Generic OMAP5 (Flattened Device Tree)") 147DT_MACHINE_START(OMAP5_DT, "Generic OMAP5 (Flattened Device Tree)")
147 .reserve = omap_reserve, 148 .reserve = omap_reserve,
149 .smp = smp_ops(omap4_smp_ops),
148 .map_io = omap5_map_io, 150 .map_io = omap5_map_io,
149 .init_early = omap5_init_early, 151 .init_early = omap5_init_early,
150 .init_irq = omap_gic_of_init, 152 .init_irq = omap_gic_of_init,
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 45fe2d3f59b1..8ebb16c5182e 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -516,6 +516,7 @@ static void __init omap4_panda_init(void)
516MACHINE_START(OMAP4_PANDA, "OMAP4 Panda board") 516MACHINE_START(OMAP4_PANDA, "OMAP4 Panda board")
517 /* Maintainer: David Anders - Texas Instruments Inc */ 517 /* Maintainer: David Anders - Texas Instruments Inc */
518 .atag_offset = 0x100, 518 .atag_offset = 0x100,
519 .smp = smp_ops(omap4_smp_ops),
519 .reserve = omap_reserve, 520 .reserve = omap_reserve,
520 .map_io = omap4_map_io, 521 .map_io = omap4_map_io,
521 .init_early = omap4430_init_early, 522 .init_early = omap4430_init_early,
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
index da0f5c187353..7045e4d61ac3 100644
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -285,6 +285,11 @@ extern void omap_secondary_startup(void);
285extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask); 285extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask);
286extern void omap_auxcoreboot_addr(u32 cpu_addr); 286extern void omap_auxcoreboot_addr(u32 cpu_addr);
287extern u32 omap_read_auxcoreboot0(void); 287extern u32 omap_read_auxcoreboot0(void);
288
289extern void omap4_cpu_die(unsigned int cpu);
290
291extern struct smp_operations omap4_smp_ops;
292
288extern void omap5_secondary_startup(void); 293extern void omap5_secondary_startup(void);
289#endif 294#endif
290 295
diff --git a/arch/arm/mach-omap2/omap-hotplug.c b/arch/arm/mach-omap2/omap-hotplug.c
index 765a2aceb665..e712d1725a8b 100644
--- a/arch/arm/mach-omap2/omap-hotplug.c
+++ b/arch/arm/mach-omap2/omap-hotplug.c
@@ -26,16 +26,11 @@
26 26
27#include "powerdomain.h" 27#include "powerdomain.h"
28 28
29int platform_cpu_kill(unsigned int cpu)
30{
31 return 1;
32}
33
34/* 29/*
35 * platform-specific code to shutdown a CPU 30 * platform-specific code to shutdown a CPU
36 * Called with IRQs disabled 31 * Called with IRQs disabled
37 */ 32 */
38void __ref platform_cpu_die(unsigned int cpu) 33void __ref omap4_cpu_die(unsigned int cpu)
39{ 34{
40 unsigned int boot_cpu = 0; 35 unsigned int boot_cpu = 0;
41 void __iomem *base = omap_get_wakeupgen_base(); 36 void __iomem *base = omap_get_wakeupgen_base();
@@ -75,12 +70,3 @@ void __ref platform_cpu_die(unsigned int cpu)
75 pr_debug("CPU%u: spurious wakeup call\n", cpu); 70 pr_debug("CPU%u: spurious wakeup call\n", cpu);
76 } 71 }
77} 72}
78
79int platform_cpu_disable(unsigned int cpu)
80{
81 /*
82 * we don't allow CPU 0 to be shutdown (it is still too special
83 * e.g. clock tick interrupts)
84 */
85 return cpu == 0 ? -EPERM : 0;
86}
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
index 06d8bc3a8886..4d05fa8a4e48 100644
--- a/arch/arm/mach-omap2/omap-smp.c
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -49,7 +49,7 @@ void __iomem *omap4_get_scu_base(void)
49 return scu_base; 49 return scu_base;
50} 50}
51 51
52void __cpuinit platform_secondary_init(unsigned int cpu) 52static void __cpuinit omap4_secondary_init(unsigned int cpu)
53{ 53{
54 /* 54 /*
55 * Configure ACTRL and enable NS SMP bit access on CPU1 on HS device. 55 * 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 spin_unlock(&boot_lock); 77 spin_unlock(&boot_lock);
78} 78}
79 79
80int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) 80static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *idle)
81{ 81{
82 static struct clockdomain *cpu1_clkdm; 82 static struct clockdomain *cpu1_clkdm;
83 static bool booted; 83 static bool booted;
@@ -165,7 +165,7 @@ static void __init wakeup_secondary(void)
165 * Initialise the CPU possible map early - this describes the CPUs 165 * Initialise the CPU possible map early - this describes the CPUs
166 * which may be present or become present in the system. 166 * which may be present or become present in the system.
167 */ 167 */
168void __init smp_init_cpus(void) 168static void __init omap4_smp_init_cpus(void)
169{ 169{
170 unsigned int i = 0, ncores = 1, cpu_id; 170 unsigned int i = 0, ncores = 1, cpu_id;
171 171
@@ -196,7 +196,7 @@ void __init smp_init_cpus(void)
196 set_smp_cross_call(gic_raise_softirq); 196 set_smp_cross_call(gic_raise_softirq);
197} 197}
198 198
199void __init platform_smp_prepare_cpus(unsigned int max_cpus) 199static void __init omap4_smp_prepare_cpus(unsigned int max_cpus)
200{ 200{
201 201
202 /* 202 /*
@@ -207,3 +207,13 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
207 scu_enable(scu_base); 207 scu_enable(scu_base);
208 wakeup_secondary(); 208 wakeup_secondary();
209} 209}
210
211struct smp_operations omap4_smp_ops __initdata = {
212 .smp_init_cpus = omap4_smp_init_cpus,
213 .smp_prepare_cpus = omap4_smp_prepare_cpus,
214 .smp_secondary_init = omap4_secondary_init,
215 .smp_boot_secondary = omap4_boot_secondary,
216#ifdef CONFIG_HOTPLUG_CPU
217 .cpu_die = omap4_cpu_die,
218#endif
219};
diff --git a/arch/arm/mach-realview/core.h b/arch/arm/mach-realview/core.h
index f8f2c0ac4c01..78cd970c80f2 100644
--- a/arch/arm/mach-realview/core.h
+++ b/arch/arm/mach-realview/core.h
@@ -56,4 +56,7 @@ extern void realview_init_early(void);
56extern void realview_fixup(struct tag *tags, char **from, 56extern void realview_fixup(struct tag *tags, char **from,
57 struct meminfo *meminfo); 57 struct meminfo *meminfo);
58 58
59extern struct smp_operations realview_smp_ops;
60extern void realview_cpu_die(unsigned int cpu);
61
59#endif 62#endif
diff --git a/arch/arm/mach-realview/hotplug.c b/arch/arm/mach-realview/hotplug.c
index 57d9efba2956..53818e5cd3ad 100644
--- a/arch/arm/mach-realview/hotplug.c
+++ b/arch/arm/mach-realview/hotplug.c
@@ -16,8 +16,6 @@
16#include <asm/cp15.h> 16#include <asm/cp15.h>
17#include <asm/smp_plat.h> 17#include <asm/smp_plat.h>
18 18
19extern volatile int pen_release;
20
21static inline void cpu_enter_lowpower(void) 19static inline void cpu_enter_lowpower(void)
22{ 20{
23 unsigned int v; 21 unsigned int v;
@@ -89,17 +87,12 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
89 } 87 }
90} 88}
91 89
92int platform_cpu_kill(unsigned int cpu)
93{
94 return 1;
95}
96
97/* 90/*
98 * platform-specific code to shutdown a CPU 91 * platform-specific code to shutdown a CPU
99 * 92 *
100 * Called with IRQs disabled 93 * Called with IRQs disabled
101 */ 94 */
102void platform_cpu_die(unsigned int cpu) 95void __ref realview_cpu_die(unsigned int cpu)
103{ 96{
104 int spurious = 0; 97 int spurious = 0;
105 98
@@ -118,12 +111,3 @@ void platform_cpu_die(unsigned int cpu)
118 if (spurious) 111 if (spurious)
119 pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious); 112 pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
120} 113}
121
122int platform_cpu_disable(unsigned int cpu)
123{
124 /*
125 * we don't allow CPU 0 to be shutdown (it is still too special
126 * e.g. clock tick interrupts)
127 */
128 return cpu == 0 ? -EPERM : 0;
129}
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c
index 17c878ddbc70..300f7064465d 100644
--- a/arch/arm/mach-realview/platsmp.c
+++ b/arch/arm/mach-realview/platsmp.c
@@ -22,9 +22,9 @@
22#include <mach/board-pb11mp.h> 22#include <mach/board-pb11mp.h>
23#include <mach/board-pbx.h> 23#include <mach/board-pbx.h>
24 24
25#include "core.h" 25#include <plat/platsmp.h>
26 26
27extern void versatile_secondary_startup(void); 27#include "core.h"
28 28
29static void __iomem *scu_base_addr(void) 29static void __iomem *scu_base_addr(void)
30{ 30{
@@ -43,7 +43,7 @@ static void __iomem *scu_base_addr(void)
43 * Initialise the CPU possible map early - this describes the CPUs 43 * Initialise the CPU possible map early - this describes the CPUs
44 * which may be present or become present in the system. 44 * which may be present or become present in the system.
45 */ 45 */
46void __init smp_init_cpus(void) 46static void __init realview_smp_init_cpus(void)
47{ 47{
48 void __iomem *scu_base = scu_base_addr(); 48 void __iomem *scu_base = scu_base_addr();
49 unsigned int i, ncores; 49 unsigned int i, ncores;
@@ -63,7 +63,7 @@ void __init smp_init_cpus(void)
63 set_smp_cross_call(gic_raise_softirq); 63 set_smp_cross_call(gic_raise_softirq);
64} 64}
65 65
66void __init platform_smp_prepare_cpus(unsigned int max_cpus) 66static void __init realview_smp_prepare_cpus(unsigned int max_cpus)
67{ 67{
68 68
69 scu_enable(scu_base_addr()); 69 scu_enable(scu_base_addr());
@@ -77,3 +77,13 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
77 __raw_writel(virt_to_phys(versatile_secondary_startup), 77 __raw_writel(virt_to_phys(versatile_secondary_startup),
78 __io_address(REALVIEW_SYS_FLAGSSET)); 78 __io_address(REALVIEW_SYS_FLAGSSET));
79} 79}
80
81struct smp_operations realview_smp_ops __initdata = {
82 .smp_init_cpus = realview_smp_init_cpus,
83 .smp_prepare_cpus = realview_smp_prepare_cpus,
84 .smp_secondary_init = versatile_secondary_init,
85 .smp_boot_secondary = versatile_boot_secondary,
86#ifdef CONFIG_HOTPLUG_CPU
87 .cpu_die = realview_cpu_die,
88#endif
89};
diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c
index b442fb276d57..a80269981dd4 100644
--- a/arch/arm/mach-realview/realview_pb11mp.c
+++ b/arch/arm/mach-realview/realview_pb11mp.c
@@ -367,6 +367,7 @@ static void __init realview_pb11mp_init(void)
367MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore") 367MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore")
368 /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ 368 /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
369 .atag_offset = 0x100, 369 .atag_offset = 0x100,
370 .smp = smp_ops(realview_smp_ops),
370 .fixup = realview_fixup, 371 .fixup = realview_fixup,
371 .map_io = realview_pb11mp_map_io, 372 .map_io = realview_pb11mp_map_io,
372 .init_early = realview_init_early, 373 .init_early = realview_init_early,
diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c
index 5d2c8bebb069..a4b1aa93bb5a 100644
--- a/arch/arm/mach-realview/realview_pbx.c
+++ b/arch/arm/mach-realview/realview_pbx.c
@@ -404,6 +404,7 @@ static void __init realview_pbx_init(void)
404MACHINE_START(REALVIEW_PBX, "ARM-RealView PBX") 404MACHINE_START(REALVIEW_PBX, "ARM-RealView PBX")
405 /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ 405 /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
406 .atag_offset = 0x100, 406 .atag_offset = 0x100,
407 .smp = smp_ops(realview_smp_ops),
407 .fixup = realview_pbx_fixup, 408 .fixup = realview_pbx_fixup,
408 .map_io = realview_pbx_map_io, 409 .map_io = realview_pbx_map_io,
409 .init_early = realview_init_early, 410 .init_early = realview_init_early,
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c
index cfc3b5c43ba8..25eb88a923e6 100644
--- a/arch/arm/mach-shmobile/board-ag5evm.c
+++ b/arch/arm/mach-shmobile/board-ag5evm.c
@@ -649,6 +649,7 @@ static void __init ag5evm_init(void)
649} 649}
650 650
651MACHINE_START(AG5EVM, "ag5evm") 651MACHINE_START(AG5EVM, "ag5evm")
652 .smp = smp_ops(sh73a0_smp_ops),
652 .map_io = sh73a0_map_io, 653 .map_io = sh73a0_map_io,
653 .init_early = sh73a0_add_early_devices, 654 .init_early = sh73a0_add_early_devices,
654 .nr_irqs = NR_IRQS_LEGACY, 655 .nr_irqs = NR_IRQS_LEGACY,
diff --git a/arch/arm/mach-shmobile/board-kota2.c b/arch/arm/mach-shmobile/board-kota2.c
index 21dbe54304d5..bf88f9a8b7ac 100644
--- a/arch/arm/mach-shmobile/board-kota2.c
+++ b/arch/arm/mach-shmobile/board-kota2.c
@@ -545,6 +545,7 @@ static void __init kota2_init(void)
545} 545}
546 546
547MACHINE_START(KOTA2, "kota2") 547MACHINE_START(KOTA2, "kota2")
548 .smp = smp_ops(sh73a0_smp_ops),
548 .map_io = sh73a0_map_io, 549 .map_io = sh73a0_map_io,
549 .init_early = sh73a0_add_early_devices, 550 .init_early = sh73a0_add_early_devices,
550 .nr_irqs = NR_IRQS_LEGACY, 551 .nr_irqs = NR_IRQS_LEGACY,
diff --git a/arch/arm/mach-shmobile/board-kzm9d.c b/arch/arm/mach-shmobile/board-kzm9d.c
index 2c986eaae7b4..b52bc0d1273f 100644
--- a/arch/arm/mach-shmobile/board-kzm9d.c
+++ b/arch/arm/mach-shmobile/board-kzm9d.c
@@ -84,6 +84,7 @@ static const char *kzm9d_boards_compat_dt[] __initdata = {
84}; 84};
85 85
86DT_MACHINE_START(KZM9D_DT, "kzm9d") 86DT_MACHINE_START(KZM9D_DT, "kzm9d")
87 .smp = smp_ops(emev2_smp_ops),
87 .map_io = emev2_map_io, 88 .map_io = emev2_map_io,
88 .init_early = emev2_add_early_devices, 89 .init_early = emev2_add_early_devices,
89 .nr_irqs = NR_IRQS_LEGACY, 90 .nr_irqs = NR_IRQS_LEGACY,
diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c
index fd21fb6f9953..0a3d1f19077e 100644
--- a/arch/arm/mach-shmobile/board-kzm9g.c
+++ b/arch/arm/mach-shmobile/board-kzm9g.c
@@ -776,6 +776,7 @@ static const char *kzm9g_boards_compat_dt[] __initdata = {
776}; 776};
777 777
778DT_MACHINE_START(KZM9G_DT, "kzm9g") 778DT_MACHINE_START(KZM9G_DT, "kzm9g")
779 .smp = smp_ops(sh73a0_smp_ops),
779 .map_io = sh73a0_map_io, 780 .map_io = sh73a0_map_io,
780 .init_early = sh73a0_add_early_devices, 781 .init_early = sh73a0_add_early_devices,
781 .nr_irqs = NR_IRQS_LEGACY, 782 .nr_irqs = NR_IRQS_LEGACY,
diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c
index fcf5a47f4772..01ce3f15c6a3 100644
--- a/arch/arm/mach-shmobile/board-marzen.c
+++ b/arch/arm/mach-shmobile/board-marzen.c
@@ -102,6 +102,7 @@ static void __init marzen_init(void)
102} 102}
103 103
104MACHINE_START(MARZEN, "marzen") 104MACHINE_START(MARZEN, "marzen")
105 .smp = smp_ops(r8a7779_smp_ops),
105 .map_io = r8a7779_map_io, 106 .map_io = r8a7779_map_io,
106 .init_early = r8a7779_add_early_devices, 107 .init_early = r8a7779_add_early_devices,
107 .nr_irqs = NR_IRQS_LEGACY, 108 .nr_irqs = NR_IRQS_LEGACY,
diff --git a/arch/arm/mach-shmobile/hotplug.c b/arch/arm/mach-shmobile/hotplug.c
index 828d22f3af57..b09a0bdbf813 100644
--- a/arch/arm/mach-shmobile/hotplug.c
+++ b/arch/arm/mach-shmobile/hotplug.c
@@ -14,30 +14,16 @@
14#include <linux/smp.h> 14#include <linux/smp.h>
15#include <linux/cpumask.h> 15#include <linux/cpumask.h>
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/of.h>
17#include <mach/common.h> 18#include <mach/common.h>
19#include <mach/r8a7779.h>
20#include <mach/emev2.h>
18#include <asm/cacheflush.h> 21#include <asm/cacheflush.h>
22#include <asm/mach-types.h>
19 23
20static cpumask_t dead_cpus; 24static cpumask_t dead_cpus;
21 25
22int platform_cpu_kill(unsigned int cpu) 26void shmobile_cpu_die(unsigned int cpu)
23{
24 int k;
25
26 /* this function is running on another CPU than the offline target,
27 * here we need wait for shutdown code in platform_cpu_die() to
28 * finish before asking SoC-specific code to power off the CPU core.
29 */
30 for (k = 0; k < 1000; k++) {
31 if (cpumask_test_cpu(cpu, &dead_cpus))
32 return shmobile_platform_cpu_kill(cpu);
33
34 mdelay(1);
35 }
36
37 return 0;
38}
39
40void platform_cpu_die(unsigned int cpu)
41{ 27{
42 /* hardware shutdown code running on the CPU that is being offlined */ 28 /* hardware shutdown code running on the CPU that is being offlined */
43 flush_cache_all(); 29 flush_cache_all();
@@ -60,7 +46,7 @@ void platform_cpu_die(unsigned int cpu)
60 } 46 }
61} 47}
62 48
63int platform_cpu_disable(unsigned int cpu) 49int shmobile_cpu_disable(unsigned int cpu)
64{ 50{
65 cpumask_clear_cpu(cpu, &dead_cpus); 51 cpumask_clear_cpu(cpu, &dead_cpus);
66 /* 52 /*
@@ -69,3 +55,8 @@ int platform_cpu_disable(unsigned int cpu)
69 */ 55 */
70 return cpu == 0 ? -EPERM : 0; 56 return cpu == 0 ? -EPERM : 0;
71} 57}
58
59int shmobile_cpu_is_dead(unsigned int cpu)
60{
61 return cpumask_test_cpu(cpu, &dead_cpus);
62}
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h
index 45e61dada030..f80f9c549393 100644
--- a/arch/arm/mach-shmobile/include/mach/common.h
+++ b/arch/arm/mach-shmobile/include/mach/common.h
@@ -4,11 +4,10 @@
4extern void shmobile_earlytimer_init(void); 4extern void shmobile_earlytimer_init(void);
5extern struct sys_timer shmobile_timer; 5extern struct sys_timer shmobile_timer;
6extern void shmobile_setup_delay(unsigned int max_cpu_core_mhz, 6extern void shmobile_setup_delay(unsigned int max_cpu_core_mhz,
7 unsigned int mult, unsigned int div); 7 unsigned int mult, unsigned int div);
8struct twd_local_timer; 8struct twd_local_timer;
9extern void shmobile_setup_console(void); 9extern void shmobile_setup_console(void);
10extern void shmobile_secondary_vector(void); 10extern void shmobile_secondary_vector(void);
11extern int shmobile_platform_cpu_kill(unsigned int cpu);
12struct clk; 11struct clk;
13extern int shmobile_clk_init(void); 12extern int shmobile_clk_init(void);
14extern void shmobile_handle_irq_intc(struct pt_regs *); 13extern void shmobile_handle_irq_intc(struct pt_regs *);
@@ -58,11 +57,6 @@ extern struct clk sh73a0_extal2_clk;
58extern struct clk sh73a0_extcki_clk; 57extern struct clk sh73a0_extcki_clk;
59extern struct clk sh73a0_extalr_clk; 58extern struct clk sh73a0_extalr_clk;
60 59
61extern unsigned int sh73a0_get_core_count(void);
62extern void sh73a0_secondary_init(unsigned int cpu);
63extern int sh73a0_boot_secondary(unsigned int cpu);
64extern void sh73a0_smp_prepare_cpus(void);
65
66extern void r8a7740_init_irq(void); 60extern void r8a7740_init_irq(void);
67extern void r8a7740_map_io(void); 61extern void r8a7740_map_io(void);
68extern void r8a7740_add_early_devices(void); 62extern void r8a7740_add_early_devices(void);
@@ -79,11 +73,6 @@ extern void r8a7779_pinmux_init(void);
79extern void r8a7779_pm_init(void); 73extern void r8a7779_pm_init(void);
80extern void r8a7740_meram_workaround(void); 74extern void r8a7740_meram_workaround(void);
81 75
82extern unsigned int r8a7779_get_core_count(void);
83extern int r8a7779_platform_cpu_kill(unsigned int cpu);
84extern void r8a7779_secondary_init(unsigned int cpu);
85extern int r8a7779_boot_secondary(unsigned int cpu);
86extern void r8a7779_smp_prepare_cpus(void);
87extern void r8a7779_register_twd(void); 76extern void r8a7779_register_twd(void);
88 77
89extern void shmobile_init_late(void); 78extern void shmobile_init_late(void);
@@ -100,4 +89,15 @@ int shmobile_cpuidle_init(void);
100static inline int shmobile_cpuidle_init(void) { return 0; } 89static inline int shmobile_cpuidle_init(void) { return 0; }
101#endif 90#endif
102 91
92extern void shmobile_cpu_die(unsigned int cpu);
93extern int shmobile_cpu_disable(unsigned int cpu);
94
95#ifdef CONFIG_HOTPLUG_CPU
96extern int shmobile_cpu_is_dead(unsigned int cpu);
97#else
98static inline int shmobile_cpu_is_dead(unsigned int cpu) { return 1; }
99#endif
100
101extern void shmobile_smp_init_cpus(unsigned int ncores);
102
103#endif /* __ARCH_MACH_COMMON_H */ 103#endif /* __ARCH_MACH_COMMON_H */
diff --git a/arch/arm/mach-shmobile/include/mach/emev2.h b/arch/arm/mach-shmobile/include/mach/emev2.h
index e6b0c1bf4b7e..ac3751705cab 100644
--- a/arch/arm/mach-shmobile/include/mach/emev2.h
+++ b/arch/arm/mach-shmobile/include/mach/emev2.h
@@ -7,13 +7,10 @@ extern void emev2_add_early_devices(void);
7extern void emev2_add_standard_devices(void); 7extern void emev2_add_standard_devices(void);
8extern void emev2_clock_init(void); 8extern void emev2_clock_init(void);
9extern void emev2_set_boot_vector(unsigned long value); 9extern void emev2_set_boot_vector(unsigned long value);
10extern unsigned int emev2_get_core_count(void);
11extern int emev2_platform_cpu_kill(unsigned int cpu);
12extern void emev2_secondary_init(unsigned int cpu);
13extern int emev2_boot_secondary(unsigned int cpu);
14extern void emev2_smp_prepare_cpus(void);
15 10
16#define EMEV2_GPIO_BASE 200 11#define EMEV2_GPIO_BASE 200
17#define EMEV2_GPIO_IRQ(n) (EMEV2_GPIO_BASE + (n)) 12#define EMEV2_GPIO_IRQ(n) (EMEV2_GPIO_BASE + (n))
18 13
14extern struct smp_operations emev2_smp_ops;
15
19#endif /* __ASM_EMEV2_H__ */ 16#endif /* __ASM_EMEV2_H__ */
diff --git a/arch/arm/mach-shmobile/include/mach/r8a7779.h b/arch/arm/mach-shmobile/include/mach/r8a7779.h
index b07ad318eb2e..f504c5e81b47 100644
--- a/arch/arm/mach-shmobile/include/mach/r8a7779.h
+++ b/arch/arm/mach-shmobile/include/mach/r8a7779.h
@@ -360,4 +360,6 @@ extern void r8a7779_add_device_to_domain(struct r8a7779_pm_domain *r8a7779_pd,
360#define r8a7779_add_device_to_domain(pd, pdev) do { } while (0) 360#define r8a7779_add_device_to_domain(pd, pdev) do { } while (0)
361#endif /* CONFIG_PM */ 361#endif /* CONFIG_PM */
362 362
363extern struct smp_operations r8a7779_smp_ops;
364
363#endif /* __ASM_R8A7779_H__ */ 365#endif /* __ASM_R8A7779_H__ */
diff --git a/arch/arm/mach-shmobile/include/mach/sh73a0.h b/arch/arm/mach-shmobile/include/mach/sh73a0.h
index fe950f25d793..606d31d02a4e 100644
--- a/arch/arm/mach-shmobile/include/mach/sh73a0.h
+++ b/arch/arm/mach-shmobile/include/mach/sh73a0.h
@@ -557,4 +557,6 @@ enum {
557#define SH73A0_PINT0_IRQ(irq) ((irq) + 700) 557#define SH73A0_PINT0_IRQ(irq) ((irq) + 700)
558#define SH73A0_PINT1_IRQ(irq) ((irq) + 732) 558#define SH73A0_PINT1_IRQ(irq) ((irq) + 732)
559 559
560extern struct smp_operations sh73a0_smp_ops;
561
560#endif /* __ASM_SH73A0_H__ */ 562#endif /* __ASM_SH73A0_H__ */
diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c
index fde0d23121dc..ed8d2351915e 100644
--- a/arch/arm/mach-shmobile/platsmp.c
+++ b/arch/arm/mach-shmobile/platsmp.c
@@ -11,100 +11,11 @@
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
12 */ 12 */
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/errno.h>
15#include <linux/delay.h>
16#include <linux/device.h>
17#include <linux/smp.h> 14#include <linux/smp.h>
18#include <linux/io.h>
19#include <linux/of.h>
20#include <asm/hardware/gic.h> 15#include <asm/hardware/gic.h>
21#include <asm/mach-types.h>
22#include <mach/common.h>
23#include <mach/emev2.h>
24 16
25#ifdef CONFIG_ARCH_SH73A0 17void __init shmobile_smp_init_cpus(unsigned int ncores)
26#define is_sh73a0() (machine_is_ag5evm() || machine_is_kota2() || \
27 of_machine_is_compatible("renesas,sh73a0"))
28#else
29#define is_sh73a0() (0)
30#endif
31
32#define is_r8a7779() machine_is_marzen()
33
34#ifdef CONFIG_ARCH_EMEV2
35#define is_emev2() of_machine_is_compatible("renesas,emev2")
36#else
37#define is_emev2() (0)
38#endif
39
40static unsigned int __init shmobile_smp_get_core_count(void)
41{
42 if (is_sh73a0())
43 return sh73a0_get_core_count();
44
45 if (is_r8a7779())
46 return r8a7779_get_core_count();
47
48 if (is_emev2())
49 return emev2_get_core_count();
50
51 return 1;
52}
53
54static void __init shmobile_smp_prepare_cpus(void)
55{
56 if (is_sh73a0())
57 sh73a0_smp_prepare_cpus();
58
59 if (is_r8a7779())
60 r8a7779_smp_prepare_cpus();
61
62 if (is_emev2())
63 emev2_smp_prepare_cpus();
64}
65
66int shmobile_platform_cpu_kill(unsigned int cpu)
67{
68 if (is_r8a7779())
69 return r8a7779_platform_cpu_kill(cpu);
70
71 if (is_emev2())
72 return emev2_platform_cpu_kill(cpu);
73
74 return 1;
75}
76
77void __cpuinit platform_secondary_init(unsigned int cpu)
78{ 18{
79 trace_hardirqs_off();
80
81 if (is_sh73a0())
82 sh73a0_secondary_init(cpu);
83
84 if (is_r8a7779())
85 r8a7779_secondary_init(cpu);
86
87 if (is_emev2())
88 emev2_secondary_init(cpu);
89}
90
91int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
92{
93 if (is_sh73a0())
94 return sh73a0_boot_secondary(cpu);
95
96 if (is_r8a7779())
97 return r8a7779_boot_secondary(cpu);
98
99 if (is_emev2())
100 return emev2_boot_secondary(cpu);
101
102 return -ENOSYS;
103}
104
105void __init smp_init_cpus(void)
106{
107 unsigned int ncores = shmobile_smp_get_core_count();
108 unsigned int i; 19 unsigned int i;
109 20
110 if (ncores > nr_cpu_ids) { 21 if (ncores > nr_cpu_ids) {
@@ -118,8 +29,3 @@ void __init smp_init_cpus(void)
118 29
119 set_smp_cross_call(gic_raise_softirq); 30 set_smp_cross_call(gic_raise_softirq);
120} 31}
121
122void __init platform_smp_prepare_cpus(unsigned int max_cpus)
123{
124 shmobile_smp_prepare_cpus();
125}
diff --git a/arch/arm/mach-shmobile/setup-emev2.c b/arch/arm/mach-shmobile/setup-emev2.c
index 61446f30e397..a47beeb18283 100644
--- a/arch/arm/mach-shmobile/setup-emev2.c
+++ b/arch/arm/mach-shmobile/setup-emev2.c
@@ -461,6 +461,7 @@ void __init emev2_init_irq_dt(void)
461} 461}
462 462
463DT_MACHINE_START(EMEV2_DT, "Generic Emma Mobile EV2 (Flattened Device Tree)") 463DT_MACHINE_START(EMEV2_DT, "Generic Emma Mobile EV2 (Flattened Device Tree)")
464 .smp = smp_ops(emev2_smp_ops),
464 .init_early = emev2_init_delay, 465 .init_early = emev2_init_delay,
465 .nr_irqs = NR_IRQS_LEGACY, 466 .nr_irqs = NR_IRQS_LEGACY,
466 .init_irq = emev2_init_irq_dt, 467 .init_irq = emev2_init_irq_dt,
diff --git a/arch/arm/mach-shmobile/smp-emev2.c b/arch/arm/mach-shmobile/smp-emev2.c
index 6a35c4a31e6c..f978c5d0e1ae 100644
--- a/arch/arm/mach-shmobile/smp-emev2.c
+++ b/arch/arm/mach-shmobile/smp-emev2.c
@@ -50,7 +50,7 @@ static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
50 50
51} 51}
52 52
53unsigned int __init emev2_get_core_count(void) 53static unsigned int __init emev2_get_core_count(void)
54{ 54{
55 if (!scu_base) { 55 if (!scu_base) {
56 scu_base = ioremap(EMEV2_SCU_BASE, PAGE_SIZE); 56 scu_base = ioremap(EMEV2_SCU_BASE, PAGE_SIZE);
@@ -62,17 +62,35 @@ unsigned int __init emev2_get_core_count(void)
62 return scu_base ? scu_get_core_count(scu_base) : 1; 62 return scu_base ? scu_get_core_count(scu_base) : 1;
63} 63}
64 64
65int emev2_platform_cpu_kill(unsigned int cpu) 65static int emev2_platform_cpu_kill(unsigned int cpu)
66{ 66{
67 return 0; /* not supported yet */ 67 return 0; /* not supported yet */
68} 68}
69 69
70void __cpuinit emev2_secondary_init(unsigned int cpu) 70static int __maybe_unused emev2_cpu_kill(unsigned int cpu)
71{
72 int k;
73
74 /* this function is running on another CPU than the offline target,
75 * here we need wait for shutdown code in platform_cpu_die() to
76 * finish before asking SoC-specific code to power off the CPU core.
77 */
78 for (k = 0; k < 1000; k++) {
79 if (shmobile_cpu_is_dead(cpu))
80 return emev2_platform_cpu_kill(cpu);
81 mdelay(1);
82 }
83
84 return 0;
85}
86
87
88static void __cpuinit emev2_secondary_init(unsigned int cpu)
71{ 89{
72 gic_secondary_init(0); 90 gic_secondary_init(0);
73} 91}
74 92
75int __cpuinit emev2_boot_secondary(unsigned int cpu) 93static int __cpuinit emev2_boot_secondary(unsigned int cpu, struct task_struct *idle)
76{ 94{
77 cpu = cpu_logical_map(cpu); 95 cpu = cpu_logical_map(cpu);
78 96
@@ -86,7 +104,7 @@ int __cpuinit emev2_boot_secondary(unsigned int cpu)
86 return 0; 104 return 0;
87} 105}
88 106
89void __init emev2_smp_prepare_cpus(void) 107static void __init emev2_smp_prepare_cpus(unsigned int max_cpus)
90{ 108{
91 int cpu = cpu_logical_map(0); 109 int cpu = cpu_logical_map(0);
92 110
@@ -95,3 +113,22 @@ void __init emev2_smp_prepare_cpus(void)
95 /* enable cache coherency on CPU0 */ 113 /* enable cache coherency on CPU0 */
96 modify_scu_cpu_psr(0, 3 << (cpu * 8)); 114 modify_scu_cpu_psr(0, 3 << (cpu * 8));
97} 115}
116
117static void __init emev2_smp_init_cpus(void)
118{
119 unsigned int ncores = emev2_get_core_count();
120
121 shmobile_smp_init_cpus(ncores);
122}
123
124struct smp_operations emev2_smp_ops __initdata = {
125 .smp_init_cpus = emev2_smp_init_cpus,
126 .smp_prepare_cpus = emev2_smp_prepare_cpus,
127 .smp_secondary_init = emev2_secondary_init,
128 .smp_boot_secondary = emev2_boot_secondary,
129#ifdef CONFIG_HOTPLUG_CPU
130 .cpu_kill = emev2_cpu_kill,
131 .cpu_die = shmobile_cpu_die,
132 .cpu_disable = shmobile_cpu_disable,
133#endif
134};
diff --git a/arch/arm/mach-shmobile/smp-r8a7779.c b/arch/arm/mach-shmobile/smp-r8a7779.c
index 6d1d0238cbf7..2ce6af9a6a37 100644
--- a/arch/arm/mach-shmobile/smp-r8a7779.c
+++ b/arch/arm/mach-shmobile/smp-r8a7779.c
@@ -87,14 +87,14 @@ static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
87 __raw_writel(tmp, scu_base + 8); 87 __raw_writel(tmp, scu_base + 8);
88} 88}
89 89
90unsigned int __init r8a7779_get_core_count(void) 90static unsigned int __init r8a7779_get_core_count(void)
91{ 91{
92 void __iomem *scu_base = scu_base_addr(); 92 void __iomem *scu_base = scu_base_addr();
93 93
94 return scu_get_core_count(scu_base); 94 return scu_get_core_count(scu_base);
95} 95}
96 96
97int r8a7779_platform_cpu_kill(unsigned int cpu) 97static int r8a7779_platform_cpu_kill(unsigned int cpu)
98{ 98{
99 struct r8a7779_pm_ch *ch = NULL; 99 struct r8a7779_pm_ch *ch = NULL;
100 int ret = -EIO; 100 int ret = -EIO;
@@ -113,12 +113,31 @@ int r8a7779_platform_cpu_kill(unsigned int cpu)
113 return ret ? ret : 1; 113 return ret ? ret : 1;
114} 114}
115 115
116void __cpuinit r8a7779_secondary_init(unsigned int cpu) 116static int __maybe_unused r8a7779_cpu_kill(unsigned int cpu)
117{
118 int k;
119
120 /* this function is running on another CPU than the offline target,
121 * here we need wait for shutdown code in platform_cpu_die() to
122 * finish before asking SoC-specific code to power off the CPU core.
123 */
124 for (k = 0; k < 1000; k++) {
125 if (shmobile_cpu_is_dead(cpu))
126 return r8a7779_platform_cpu_kill(cpu);
127
128 mdelay(1);
129 }
130
131 return 0;
132}
133
134
135static void __cpuinit r8a7779_secondary_init(unsigned int cpu)
117{ 136{
118 gic_secondary_init(0); 137 gic_secondary_init(0);
119} 138}
120 139
121int __cpuinit r8a7779_boot_secondary(unsigned int cpu) 140static int __cpuinit r8a7779_boot_secondary(unsigned int cpu, struct task_struct *idle)
122{ 141{
123 struct r8a7779_pm_ch *ch = NULL; 142 struct r8a7779_pm_ch *ch = NULL;
124 int ret = -EIO; 143 int ret = -EIO;
@@ -137,7 +156,7 @@ int __cpuinit r8a7779_boot_secondary(unsigned int cpu)
137 return ret; 156 return ret;
138} 157}
139 158
140void __init r8a7779_smp_prepare_cpus(void) 159static void __init r8a7779_smp_prepare_cpus(unsigned int max_cpus)
141{ 160{
142 int cpu = cpu_logical_map(0); 161 int cpu = cpu_logical_map(0);
143 162
@@ -156,3 +175,22 @@ void __init r8a7779_smp_prepare_cpus(void)
156 r8a7779_platform_cpu_kill(2); 175 r8a7779_platform_cpu_kill(2);
157 r8a7779_platform_cpu_kill(3); 176 r8a7779_platform_cpu_kill(3);
158} 177}
178
179static void __init r8a7779_smp_init_cpus(void)
180{
181 unsigned int ncores = r8a7779_get_core_count();
182
183 shmobile_smp_init_cpus(ncores);
184}
185
186struct smp_operations r8a7779_smp_ops __initdata = {
187 .smp_init_cpus = r8a7779_smp_init_cpus,
188 .smp_prepare_cpus = r8a7779_smp_prepare_cpus,
189 .smp_secondary_init = r8a7779_secondary_init,
190 .smp_boot_secondary = r8a7779_boot_secondary,
191#ifdef CONFIG_HOTPLUG_CPU
192 .cpu_kill = r8a7779_cpu_kill,
193 .cpu_die = shmobile_cpu_die,
194 .cpu_disable = shmobile_cpu_disable,
195#endif
196};
diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c
index e36c41c4ab40..624f00f70abf 100644
--- a/arch/arm/mach-shmobile/smp-sh73a0.c
+++ b/arch/arm/mach-shmobile/smp-sh73a0.c
@@ -22,8 +22,10 @@
22#include <linux/smp.h> 22#include <linux/smp.h>
23#include <linux/spinlock.h> 23#include <linux/spinlock.h>
24#include <linux/io.h> 24#include <linux/io.h>
25#include <linux/delay.h>
25#include <mach/common.h> 26#include <mach/common.h>
26#include <asm/smp_plat.h> 27#include <asm/smp_plat.h>
28#include <mach/sh73a0.h>
27#include <asm/smp_scu.h> 29#include <asm/smp_scu.h>
28#include <asm/smp_twd.h> 30#include <asm/smp_twd.h>
29#include <asm/hardware/gic.h> 31#include <asm/hardware/gic.h>
@@ -64,19 +66,19 @@ static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
64 __raw_writel(tmp, scu_base + 8); 66 __raw_writel(tmp, scu_base + 8);
65} 67}
66 68
67unsigned int __init sh73a0_get_core_count(void) 69static unsigned int __init sh73a0_get_core_count(void)
68{ 70{
69 void __iomem *scu_base = scu_base_addr(); 71 void __iomem *scu_base = scu_base_addr();
70 72
71 return scu_get_core_count(scu_base); 73 return scu_get_core_count(scu_base);
72} 74}
73 75
74void __cpuinit sh73a0_secondary_init(unsigned int cpu) 76static void __cpuinit sh73a0_secondary_init(unsigned int cpu)
75{ 77{
76 gic_secondary_init(0); 78 gic_secondary_init(0);
77} 79}
78 80
79int __cpuinit sh73a0_boot_secondary(unsigned int cpu) 81static int __cpuinit sh73a0_boot_secondary(unsigned int cpu, struct task_struct *idle)
80{ 82{
81 cpu = cpu_logical_map(cpu); 83 cpu = cpu_logical_map(cpu);
82 84
@@ -91,7 +93,7 @@ int __cpuinit sh73a0_boot_secondary(unsigned int cpu)
91 return 0; 93 return 0;
92} 94}
93 95
94void __init sh73a0_smp_prepare_cpus(void) 96static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus)
95{ 97{
96 int cpu = cpu_logical_map(0); 98 int cpu = cpu_logical_map(0);
97 99
@@ -104,3 +106,41 @@ void __init sh73a0_smp_prepare_cpus(void)
104 /* enable cache coherency on CPU0 */ 106 /* enable cache coherency on CPU0 */
105 modify_scu_cpu_psr(0, 3 << (cpu * 8)); 107 modify_scu_cpu_psr(0, 3 << (cpu * 8));
106} 108}
109
110static void __init sh73a0_smp_init_cpus(void)
111{
112 unsigned int ncores = sh73a0_get_core_count();
113
114 shmobile_smp_init_cpus(ncores);
115}
116
117static int __maybe_unused sh73a0_cpu_kill(unsigned int cpu)
118{
119 int k;
120
121 /* this function is running on another CPU than the offline target,
122 * here we need wait for shutdown code in platform_cpu_die() to
123 * finish before asking SoC-specific code to power off the CPU core.
124 */
125 for (k = 0; k < 1000; k++) {
126 if (shmobile_cpu_is_dead(cpu))
127 return 1;
128
129 mdelay(1);
130 }
131
132 return 0;
133}
134
135
136struct smp_operations sh73a0_smp_ops __initdata = {
137 .smp_init_cpus = sh73a0_smp_init_cpus,
138 .smp_prepare_cpus = sh73a0_smp_prepare_cpus,
139 .smp_secondary_init = sh73a0_secondary_init,
140 .smp_boot_secondary = sh73a0_boot_secondary,
141#ifdef CONFIG_HOTPLUG_CPU
142 .cpu_kill = sh73a0_cpu_kill,
143 .cpu_die = shmobile_cpu_die,
144 .cpu_disable = shmobile_cpu_disable,
145#endif
146};
diff --git a/arch/arm/mach-spear13xx/hotplug.c b/arch/arm/mach-spear13xx/hotplug.c
index 5c6867b46d09..a7d2dd11a4f2 100644
--- a/arch/arm/mach-spear13xx/hotplug.c
+++ b/arch/arm/mach-spear13xx/hotplug.c
@@ -17,8 +17,6 @@
17#include <asm/cp15.h> 17#include <asm/cp15.h>
18#include <asm/smp_plat.h> 18#include <asm/smp_plat.h>
19 19
20extern volatile int pen_release;
21
22static inline void cpu_enter_lowpower(void) 20static inline void cpu_enter_lowpower(void)
23{ 21{
24 unsigned int v; 22 unsigned int v;
@@ -56,7 +54,7 @@ static inline void cpu_leave_lowpower(void)
56 : "cc"); 54 : "cc");
57} 55}
58 56
59static inline void platform_do_lowpower(unsigned int cpu, int *spurious) 57static inline void spear13xx_do_lowpower(unsigned int cpu, int *spurious)
60{ 58{
61 for (;;) { 59 for (;;) {
62 wfi(); 60 wfi();
@@ -79,17 +77,12 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
79 } 77 }
80} 78}
81 79
82int platform_cpu_kill(unsigned int cpu)
83{
84 return 1;
85}
86
87/* 80/*
88 * platform-specific code to shutdown a CPU 81 * platform-specific code to shutdown a CPU
89 * 82 *
90 * Called with IRQs disabled 83 * Called with IRQs disabled
91 */ 84 */
92void __cpuinit platform_cpu_die(unsigned int cpu) 85void __ref spear13xx_cpu_die(unsigned int cpu)
93{ 86{
94 int spurious = 0; 87 int spurious = 0;
95 88
@@ -97,7 +90,7 @@ void __cpuinit platform_cpu_die(unsigned int cpu)
97 * we're ready for shutdown now, so do it 90 * we're ready for shutdown now, so do it
98 */ 91 */
99 cpu_enter_lowpower(); 92 cpu_enter_lowpower();
100 platform_do_lowpower(cpu, &spurious); 93 spear13xx_do_lowpower(cpu, &spurious);
101 94
102 /* 95 /*
103 * bring this CPU back into the world of cache 96 * bring this CPU back into the world of cache
@@ -108,12 +101,3 @@ void __cpuinit platform_cpu_die(unsigned int cpu)
108 if (spurious) 101 if (spurious)
109 pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious); 102 pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
110} 103}
111
112int platform_cpu_disable(unsigned int cpu)
113{
114 /*
115 * we don't allow CPU 0 to be shutdown (it is still too special
116 * e.g. clock tick interrupts)
117 */
118 return cpu == 0 ? -EPERM : 0;
119}
diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
index dac57fd0cdfd..c33f4d9361bd 100644
--- a/arch/arm/mach-spear13xx/include/mach/generic.h
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -33,6 +33,9 @@ void __init spear13xx_l2x0_init(void);
33bool dw_dma_filter(struct dma_chan *chan, void *slave); 33bool dw_dma_filter(struct dma_chan *chan, void *slave);
34void spear_restart(char, const char *); 34void spear_restart(char, const char *);
35void spear13xx_secondary_startup(void); 35void spear13xx_secondary_startup(void);
36void __cpuinit spear13xx_cpu_die(unsigned int cpu);
37
38extern struct smp_operations spear13xx_smp_ops;
36 39
37#ifdef CONFIG_MACH_SPEAR1310 40#ifdef CONFIG_MACH_SPEAR1310
38void __init spear1310_clk_init(void); 41void __init spear1310_clk_init(void);
diff --git a/arch/arm/mach-spear13xx/platsmp.c b/arch/arm/mach-spear13xx/platsmp.c
index f5d07f2663d7..2eaa3fa7b432 100644
--- a/arch/arm/mach-spear13xx/platsmp.c
+++ b/arch/arm/mach-spear13xx/platsmp.c
@@ -19,18 +19,13 @@
19#include <asm/hardware/gic.h> 19#include <asm/hardware/gic.h>
20#include <asm/smp_scu.h> 20#include <asm/smp_scu.h>
21#include <mach/spear.h> 21#include <mach/spear.h>
22#include <mach/generic.h>
22 23
23/*
24 * control for which core is the next to come out of the secondary
25 * boot "holding pen"
26 */
27volatile int __cpuinitdata pen_release = -1;
28static DEFINE_SPINLOCK(boot_lock); 24static DEFINE_SPINLOCK(boot_lock);
29 25
30static void __iomem *scu_base = IOMEM(VA_SCU_BASE); 26static void __iomem *scu_base = IOMEM(VA_SCU_BASE);
31extern void spear13xx_secondary_startup(void);
32 27
33void __cpuinit platform_secondary_init(unsigned int cpu) 28static void __cpuinit spear13xx_secondary_init(unsigned int cpu)
34{ 29{
35 /* 30 /*
36 * if any interrupts are already enabled for the primary 31 * if any interrupts are already enabled for the primary
@@ -53,7 +48,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
53 spin_unlock(&boot_lock); 48 spin_unlock(&boot_lock);
54} 49}
55 50
56int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) 51static int __cpuinit spear13xx_boot_secondary(unsigned int cpu, struct task_struct *idle)
57{ 52{
58 unsigned long timeout; 53 unsigned long timeout;
59 54
@@ -97,7 +92,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
97 * Initialise the CPU possible map early - this describes the CPUs 92 * Initialise the CPU possible map early - this describes the CPUs
98 * which may be present or become present in the system. 93 * which may be present or become present in the system.
99 */ 94 */
100void __init smp_init_cpus(void) 95static void __init spear13xx_smp_init_cpus(void)
101{ 96{
102 unsigned int i, ncores = scu_get_core_count(scu_base); 97 unsigned int i, ncores = scu_get_core_count(scu_base);
103 98
@@ -113,7 +108,7 @@ void __init smp_init_cpus(void)
113 set_smp_cross_call(gic_raise_softirq); 108 set_smp_cross_call(gic_raise_softirq);
114} 109}
115 110
116void __init platform_smp_prepare_cpus(unsigned int max_cpus) 111static void __init spear13xx_smp_prepare_cpus(unsigned int max_cpus)
117{ 112{
118 113
119 scu_enable(scu_base); 114 scu_enable(scu_base);
@@ -125,3 +120,13 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
125 */ 120 */
126 __raw_writel(virt_to_phys(spear13xx_secondary_startup), SYS_LOCATION); 121 __raw_writel(virt_to_phys(spear13xx_secondary_startup), SYS_LOCATION);
127} 122}
123
124struct smp_operations spear13xx_smp_ops __initdata = {
125 .smp_init_cpus = spear13xx_smp_init_cpus,
126 .smp_prepare_cpus = spear13xx_smp_prepare_cpus,
127 .smp_secondary_init = spear13xx_secondary_init,
128 .smp_boot_secondary = spear13xx_boot_secondary,
129#ifdef CONFIG_HOTPLUG_CPU
130 .cpu_die = spear13xx_cpu_die,
131#endif
132};
diff --git a/arch/arm/mach-spear13xx/spear1310.c b/arch/arm/mach-spear13xx/spear1310.c
index 732d29bc7330..9fbbfc5650aa 100644
--- a/arch/arm/mach-spear13xx/spear1310.c
+++ b/arch/arm/mach-spear13xx/spear1310.c
@@ -78,6 +78,7 @@ static void __init spear1310_map_io(void)
78} 78}
79 79
80DT_MACHINE_START(SPEAR1310_DT, "ST SPEAr1310 SoC with Flattened Device Tree") 80DT_MACHINE_START(SPEAR1310_DT, "ST SPEAr1310 SoC with Flattened Device Tree")
81 .smp = smp_ops(spear13xx_smp_ops),
81 .map_io = spear1310_map_io, 82 .map_io = spear1310_map_io,
82 .init_irq = spear13xx_dt_init_irq, 83 .init_irq = spear13xx_dt_init_irq,
83 .handle_irq = gic_handle_irq, 84 .handle_irq = gic_handle_irq,
diff --git a/arch/arm/mach-spear13xx/spear1340.c b/arch/arm/mach-spear13xx/spear1340.c
index 81e4ed76ad06..081014fb314a 100644
--- a/arch/arm/mach-spear13xx/spear1340.c
+++ b/arch/arm/mach-spear13xx/spear1340.c
@@ -182,6 +182,7 @@ static const char * const spear1340_dt_board_compat[] = {
182}; 182};
183 183
184DT_MACHINE_START(SPEAR1340_DT, "ST SPEAr1340 SoC with Flattened Device Tree") 184DT_MACHINE_START(SPEAR1340_DT, "ST SPEAr1340 SoC with Flattened Device Tree")
185 .smp = smp_ops(spear13xx_smp_ops),
185 .map_io = spear13xx_map_io, 186 .map_io = spear13xx_map_io,
186 .init_irq = spear13xx_dt_init_irq, 187 .init_irq = spear13xx_dt_init_irq,
187 .handle_irq = gic_handle_irq, 188 .handle_irq = gic_handle_irq,
diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c
index 5957ffbd4af6..5d8c8fb060b0 100644
--- a/arch/arm/mach-tegra/board-dt-tegra20.c
+++ b/arch/arm/mach-tegra/board-dt-tegra20.c
@@ -44,6 +44,7 @@
44#include "board.h" 44#include "board.h"
45#include "clock.h" 45#include "clock.h"
46#include "devices.h" 46#include "devices.h"
47#include "common.h"
47 48
48struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = { 49struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
49 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC1_BASE, "sdhci-tegra.0", NULL), 50 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 153
153DT_MACHINE_START(TEGRA_DT, "nVidia Tegra20 (Flattened Device Tree)") 154DT_MACHINE_START(TEGRA_DT, "nVidia Tegra20 (Flattened Device Tree)")
154 .map_io = tegra_map_common_io, 155 .map_io = tegra_map_common_io,
156 .smp = smp_ops(tegra_smp_ops),
155 .init_early = tegra20_init_early, 157 .init_early = tegra20_init_early,
156 .init_irq = tegra_dt_init_irq, 158 .init_irq = tegra_dt_init_irq,
157 .handle_irq = gic_handle_irq, 159 .handle_irq = gic_handle_irq,
diff --git a/arch/arm/mach-tegra/board-dt-tegra30.c b/arch/arm/mach-tegra/board-dt-tegra30.c
index 53bf60f11580..e4a676d4ddf7 100644
--- a/arch/arm/mach-tegra/board-dt-tegra30.c
+++ b/arch/arm/mach-tegra/board-dt-tegra30.c
@@ -37,6 +37,7 @@
37 37
38#include "board.h" 38#include "board.h"
39#include "clock.h" 39#include "clock.h"
40#include "common.h"
40 41
41struct of_dev_auxdata tegra30_auxdata_lookup[] __initdata = { 42struct of_dev_auxdata tegra30_auxdata_lookup[] __initdata = {
42 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000000, "sdhci-tegra.0", NULL), 43 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000000, "sdhci-tegra.0", NULL),
@@ -83,6 +84,7 @@ static const char *tegra30_dt_board_compat[] = {
83}; 84};
84 85
85DT_MACHINE_START(TEGRA30_DT, "NVIDIA Tegra30 (Flattened Device Tree)") 86DT_MACHINE_START(TEGRA30_DT, "NVIDIA Tegra30 (Flattened Device Tree)")
87 .smp = smp_ops(tegra_smp_ops),
86 .map_io = tegra_map_common_io, 88 .map_io = tegra_map_common_io,
87 .init_early = tegra30_init_early, 89 .init_early = tegra30_init_early,
88 .init_irq = tegra_dt_init_irq, 90 .init_irq = tegra_dt_init_irq,
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
index 0560538bf598..0b0a5f556d34 100644
--- a/arch/arm/mach-tegra/common.c
+++ b/arch/arm/mach-tegra/common.c
@@ -31,6 +31,7 @@
31 31
32#include "board.h" 32#include "board.h"
33#include "clock.h" 33#include "clock.h"
34#include "common.h"
34#include "fuse.h" 35#include "fuse.h"
35#include "pmc.h" 36#include "pmc.h"
36#include "apbio.h" 37#include "apbio.h"
diff --git a/arch/arm/mach-tegra/common.h b/arch/arm/mach-tegra/common.h
new file mode 100644
index 000000000000..02f71b4f1e51
--- /dev/null
+++ b/arch/arm/mach-tegra/common.h
@@ -0,0 +1,4 @@
1extern struct smp_operations tegra_smp_ops;
2
3extern void tegra_cpu_die(unsigned int cpu);
4extern int tegra_cpu_disable(unsigned int cpu);
diff --git a/arch/arm/mach-tegra/hotplug.c b/arch/arm/mach-tegra/hotplug.c
index d02a35476135..dca5141a2c31 100644
--- a/arch/arm/mach-tegra/hotplug.c
+++ b/arch/arm/mach-tegra/hotplug.c
@@ -19,17 +19,12 @@
19 19
20static void (*tegra_hotplug_shutdown)(void); 20static void (*tegra_hotplug_shutdown)(void);
21 21
22int platform_cpu_kill(unsigned int cpu)
23{
24 return 1;
25}
26
27/* 22/*
28 * platform-specific code to shutdown a CPU 23 * platform-specific code to shutdown a CPU
29 * 24 *
30 * Called with IRQs disabled 25 * Called with IRQs disabled
31 */ 26 */
32void platform_cpu_die(unsigned int cpu) 27void __ref tegra_cpu_die(unsigned int cpu)
33{ 28{
34 cpu = cpu_logical_map(cpu); 29 cpu = cpu_logical_map(cpu);
35 30
@@ -47,7 +42,7 @@ void platform_cpu_die(unsigned int cpu)
47 BUG(); 42 BUG();
48} 43}
49 44
50int platform_cpu_disable(unsigned int cpu) 45int tegra_cpu_disable(unsigned int cpu)
51{ 46{
52 /* 47 /*
53 * we don't allow CPU 0 to be shutdown (it is still too special 48 * we don't allow CPU 0 to be shutdown (it is still too special
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
index 96ed1718eef0..81cb26591acf 100644
--- a/arch/arm/mach-tegra/platsmp.c
+++ b/arch/arm/mach-tegra/platsmp.c
@@ -33,6 +33,8 @@
33#include "reset.h" 33#include "reset.h"
34#include "tegra_cpu_car.h" 34#include "tegra_cpu_car.h"
35 35
36#include "common.h"
37
36extern void tegra_secondary_startup(void); 38extern void tegra_secondary_startup(void);
37 39
38static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE); 40static 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#define EVP_CPU_RESET_VECTOR \ 42#define EVP_CPU_RESET_VECTOR \
41 (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100) 43 (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100)
42 44
43void __cpuinit platform_secondary_init(unsigned int cpu) 45static void __cpuinit tegra_secondary_init(unsigned int cpu)
44{ 46{
45 /* 47 /*
46 * if any interrupts are already enabled for the primary 48 * if any interrupts are already enabled for the primary
@@ -100,7 +102,7 @@ static int tegra30_power_up_cpu(unsigned int cpu)
100 return 0; 102 return 0;
101} 103}
102 104
103int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) 105static int __cpuinit tegra_boot_secondary(unsigned int cpu, struct task_struct *idle)
104{ 106{
105 int status; 107 int status;
106 108
@@ -146,7 +148,7 @@ done:
146 * Initialise the CPU possible map early - this describes the CPUs 148 * Initialise the CPU possible map early - this describes the CPUs
147 * which may be present or become present in the system. 149 * which may be present or become present in the system.
148 */ 150 */
149void __init smp_init_cpus(void) 151static void __init tegra_smp_init_cpus(void)
150{ 152{
151 unsigned int i, ncores = scu_get_core_count(scu_base); 153 unsigned int i, ncores = scu_get_core_count(scu_base);
152 154
@@ -162,8 +164,19 @@ void __init smp_init_cpus(void)
162 set_smp_cross_call(gic_raise_softirq); 164 set_smp_cross_call(gic_raise_softirq);
163} 165}
164 166
165void __init platform_smp_prepare_cpus(unsigned int max_cpus) 167static void __init tegra_smp_prepare_cpus(unsigned int max_cpus)
166{ 168{
167 tegra_cpu_reset_handler_init(); 169 tegra_cpu_reset_handler_init();
168 scu_enable(scu_base); 170 scu_enable(scu_base);
169} 171}
172
173struct smp_operations tegra_smp_ops __initdata = {
174 .smp_init_cpus = tegra_smp_init_cpus,
175 .smp_prepare_cpus = tegra_smp_prepare_cpus,
176 .smp_secondary_init = tegra_secondary_init,
177 .smp_boot_secondary = tegra_boot_secondary,
178#ifdef CONFIG_HOTPLUG_CPU
179 .cpu_die = tegra_cpu_die,
180 .cpu_disable = tegra_cpu_disable,
181#endif
182};
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c
index 1d2e3c6f8b59..e783790c79cd 100644
--- a/arch/arm/mach-ux500/board-mop500.c
+++ b/arch/arm/mach-ux500/board-mop500.c
@@ -673,6 +673,7 @@ static void __init hrefv60_init_machine(void)
673MACHINE_START(U8500, "ST-Ericsson MOP500 platform") 673MACHINE_START(U8500, "ST-Ericsson MOP500 platform")
674 /* Maintainer: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> */ 674 /* Maintainer: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> */
675 .atag_offset = 0x100, 675 .atag_offset = 0x100,
676 .smp = smp_ops(ux500_smp_ops),
676 .map_io = u8500_map_io, 677 .map_io = u8500_map_io,
677 .init_irq = ux500_init_irq, 678 .init_irq = ux500_init_irq,
678 /* we re-use nomadik timer here */ 679 /* we re-use nomadik timer here */
@@ -684,6 +685,7 @@ MACHINE_END
684 685
685MACHINE_START(HREFV60, "ST-Ericsson U8500 Platform HREFv60+") 686MACHINE_START(HREFV60, "ST-Ericsson U8500 Platform HREFv60+")
686 .atag_offset = 0x100, 687 .atag_offset = 0x100,
688 .smp = smp_ops(ux500_smp_ops),
687 .map_io = u8500_map_io, 689 .map_io = u8500_map_io,
688 .init_irq = ux500_init_irq, 690 .init_irq = ux500_init_irq,
689 .timer = &ux500_timer, 691 .timer = &ux500_timer,
@@ -694,6 +696,7 @@ MACHINE_END
694 696
695MACHINE_START(SNOWBALL, "Calao Systems Snowball platform") 697MACHINE_START(SNOWBALL, "Calao Systems Snowball platform")
696 .atag_offset = 0x100, 698 .atag_offset = 0x100,
699 .smp = smp_ops(ux500_smp_ops),
697 .map_io = u8500_map_io, 700 .map_io = u8500_map_io,
698 .init_irq = ux500_init_irq, 701 .init_irq = ux500_init_irq,
699 /* we re-use nomadik timer here */ 702 /* we re-use nomadik timer here */
@@ -823,6 +826,7 @@ static const char * u8500_dt_board_compat[] = {
823 826
824 827
825DT_MACHINE_START(U8500_DT, "ST-Ericsson U8500 platform (Device Tree Support)") 828DT_MACHINE_START(U8500_DT, "ST-Ericsson U8500 platform (Device Tree Support)")
829 .smp = smp_ops(ux500_smp_ops),
826 .map_io = u8500_map_io, 830 .map_io = u8500_map_io,
827 .init_irq = ux500_init_irq, 831 .init_irq = ux500_init_irq,
828 /* we re-use nomadik timer here */ 832 /* we re-use nomadik timer here */
diff --git a/arch/arm/mach-ux500/hotplug.c b/arch/arm/mach-ux500/hotplug.c
index c76f0f456f04..2f6af259015d 100644
--- a/arch/arm/mach-ux500/hotplug.c
+++ b/arch/arm/mach-ux500/hotplug.c
@@ -15,13 +15,18 @@
15#include <asm/cacheflush.h> 15#include <asm/cacheflush.h>
16#include <asm/smp_plat.h> 16#include <asm/smp_plat.h>
17 17
18extern volatile int pen_release; 18#include <mach/setup.h>
19 19
20static inline void platform_do_lowpower(unsigned int cpu) 20/*
21 * platform-specific code to shutdown a CPU
22 *
23 * Called with IRQs disabled
24 */
25void __ref ux500_cpu_die(unsigned int cpu)
21{ 26{
22 flush_cache_all(); 27 flush_cache_all();
23 28
24 /* we put the platform to just WFI */ 29 /* directly enter low power state, skipping secure registers */
25 for (;;) { 30 for (;;) {
26 __asm__ __volatile__("dsb\n\t" "wfi\n\t" 31 __asm__ __volatile__("dsb\n\t" "wfi\n\t"
27 : : : "memory"); 32 : : : "memory");
@@ -33,28 +38,3 @@ static inline void platform_do_lowpower(unsigned int cpu)
33 } 38 }
34 } 39 }
35} 40}
36
37int platform_cpu_kill(unsigned int cpu)
38{
39 return 1;
40}
41
42/*
43 * platform-specific code to shutdown a CPU
44 *
45 * Called with IRQs disabled
46 */
47void platform_cpu_die(unsigned int cpu)
48{
49 /* directly enter low power state, skipping secure registers */
50 platform_do_lowpower(cpu);
51}
52
53int platform_cpu_disable(unsigned int cpu)
54{
55 /*
56 * we don't allow CPU 0 to be shutdown (it is still too special
57 * e.g. clock tick interrupts)
58 */
59 return cpu == 0 ? -EPERM : 0;
60}
diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h
index 7914e5eaa9c7..6be4c4d2ab88 100644
--- a/arch/arm/mach-ux500/include/mach/setup.h
+++ b/arch/arm/mach-ux500/include/mach/setup.h
@@ -45,4 +45,7 @@ extern struct sys_timer ux500_timer;
45 .type = MT_MEMORY, \ 45 .type = MT_MEMORY, \
46} 46}
47 47
48extern struct smp_operations ux500_smp_ops;
49extern void ux500_cpu_die(unsigned int cpu);
50
48#endif /* __ASM_ARCH_SETUP_H */ 51#endif /* __ASM_ARCH_SETUP_H */
diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c
index a5dda68444db..3db7782f3afb 100644
--- a/arch/arm/mach-ux500/platsmp.c
+++ b/arch/arm/mach-ux500/platsmp.c
@@ -28,12 +28,6 @@
28extern void u8500_secondary_startup(void); 28extern void u8500_secondary_startup(void);
29 29
30/* 30/*
31 * control for which core is the next to come out of the secondary
32 * boot "holding pen"
33 */
34volatile int pen_release = -1;
35
36/*
37 * Write pen_release in a way that is guaranteed to be visible to all 31 * Write pen_release in a way that is guaranteed to be visible to all
38 * observers, irrespective of whether they're taking part in coherency 32 * observers, irrespective of whether they're taking part in coherency
39 * or not. This is necessary for the hotplug code to work reliably. 33 * or not. This is necessary for the hotplug code to work reliably.
@@ -58,7 +52,7 @@ static void __iomem *scu_base_addr(void)
58 52
59static DEFINE_SPINLOCK(boot_lock); 53static DEFINE_SPINLOCK(boot_lock);
60 54
61void __cpuinit platform_secondary_init(unsigned int cpu) 55static void __cpuinit ux500_secondary_init(unsigned int cpu)
62{ 56{
63 /* 57 /*
64 * if any interrupts are already enabled for the primary 58 * if any interrupts are already enabled for the primary
@@ -80,7 +74,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
80 spin_unlock(&boot_lock); 74 spin_unlock(&boot_lock);
81} 75}
82 76
83int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) 77static int __cpuinit ux500_boot_secondary(unsigned int cpu, struct task_struct *idle)
84{ 78{
85 unsigned long timeout; 79 unsigned long timeout;
86 80
@@ -145,7 +139,7 @@ static void __init wakeup_secondary(void)
145 * Initialise the CPU possible map early - this describes the CPUs 139 * Initialise the CPU possible map early - this describes the CPUs
146 * which may be present or become present in the system. 140 * which may be present or become present in the system.
147 */ 141 */
148void __init smp_init_cpus(void) 142static void __init ux500_smp_init_cpus(void)
149{ 143{
150 void __iomem *scu_base = scu_base_addr(); 144 void __iomem *scu_base = scu_base_addr();
151 unsigned int i, ncores; 145 unsigned int i, ncores;
@@ -165,9 +159,19 @@ void __init smp_init_cpus(void)
165 set_smp_cross_call(gic_raise_softirq); 159 set_smp_cross_call(gic_raise_softirq);
166} 160}
167 161
168void __init platform_smp_prepare_cpus(unsigned int max_cpus) 162static void __init ux500_smp_prepare_cpus(unsigned int max_cpus)
169{ 163{
170 164
171 scu_enable(scu_base_addr()); 165 scu_enable(scu_base_addr());
172 wakeup_secondary(); 166 wakeup_secondary();
173} 167}
168
169struct smp_operations ux500_smp_ops __initdata = {
170 .smp_init_cpus = ux500_smp_init_cpus,
171 .smp_prepare_cpus = ux500_smp_prepare_cpus,
172 .smp_secondary_init = ux500_secondary_init,
173 .smp_boot_secondary = ux500_boot_secondary,
174#ifdef CONFIG_HOTPLUG_CPU
175 .cpu_die = ux500_cpu_die,
176#endif
177};
diff --git a/arch/arm/mach-vexpress/core.h b/arch/arm/mach-vexpress/core.h
index a3a4980770bd..f134cd4a85f1 100644
--- a/arch/arm/mach-vexpress/core.h
+++ b/arch/arm/mach-vexpress/core.h
@@ -5,3 +5,7 @@
5#define V2T_PERIPH 0xf8200000 5#define V2T_PERIPH 0xf8200000
6 6
7void vexpress_dt_smp_map_io(void); 7void vexpress_dt_smp_map_io(void);
8
9extern struct smp_operations vexpress_smp_ops;
10
11extern void vexpress_cpu_die(unsigned int cpu);
diff --git a/arch/arm/mach-vexpress/hotplug.c b/arch/arm/mach-vexpress/hotplug.c
index c504a72b94d6..a141b98d84fe 100644
--- a/arch/arm/mach-vexpress/hotplug.c
+++ b/arch/arm/mach-vexpress/hotplug.c
@@ -16,8 +16,6 @@
16#include <asm/smp_plat.h> 16#include <asm/smp_plat.h>
17#include <asm/cp15.h> 17#include <asm/cp15.h>
18 18
19extern volatile int pen_release;
20
21static inline void cpu_enter_lowpower(void) 19static inline void cpu_enter_lowpower(void)
22{ 20{
23 unsigned int v; 21 unsigned int v;
@@ -84,17 +82,12 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
84 } 82 }
85} 83}
86 84
87int platform_cpu_kill(unsigned int cpu)
88{
89 return 1;
90}
91
92/* 85/*
93 * platform-specific code to shutdown a CPU 86 * platform-specific code to shutdown a CPU
94 * 87 *
95 * Called with IRQs disabled 88 * Called with IRQs disabled
96 */ 89 */
97void platform_cpu_die(unsigned int cpu) 90void __ref vexpress_cpu_die(unsigned int cpu)
98{ 91{
99 int spurious = 0; 92 int spurious = 0;
100 93
@@ -113,12 +106,3 @@ void platform_cpu_die(unsigned int cpu)
113 if (spurious) 106 if (spurious)
114 pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious); 107 pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
115} 108}
116
117int platform_cpu_disable(unsigned int cpu)
118{
119 /*
120 * we don't allow CPU 0 to be shutdown (it is still too special
121 * e.g. clock tick interrupts)
122 */
123 return cpu == 0 ? -EPERM : 0;
124}
diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c
index 14ba1128ae8d..7db27c8c05cc 100644
--- a/arch/arm/mach-vexpress/platsmp.c
+++ b/arch/arm/mach-vexpress/platsmp.c
@@ -20,9 +20,9 @@
20 20
21#include <mach/motherboard.h> 21#include <mach/motherboard.h>
22 22
23#include "core.h" 23#include <plat/platsmp.h>
24 24
25extern void versatile_secondary_startup(void); 25#include "core.h"
26 26
27#if defined(CONFIG_OF) 27#if defined(CONFIG_OF)
28 28
@@ -167,7 +167,7 @@ void __init vexpress_dt_smp_prepare_cpus(unsigned int max_cpus)
167 * Initialise the CPU possible map early - this describes the CPUs 167 * Initialise the CPU possible map early - this describes the CPUs
168 * which may be present or become present in the system. 168 * which may be present or become present in the system.
169 */ 169 */
170void __init smp_init_cpus(void) 170static void __init vexpress_smp_init_cpus(void)
171{ 171{
172 if (ct_desc) 172 if (ct_desc)
173 ct_desc->init_cpu_map(); 173 ct_desc->init_cpu_map();
@@ -176,7 +176,7 @@ void __init smp_init_cpus(void)
176 176
177} 177}
178 178
179void __init platform_smp_prepare_cpus(unsigned int max_cpus) 179static void __init vexpress_smp_prepare_cpus(unsigned int max_cpus)
180{ 180{
181 /* 181 /*
182 * Initialise the present map, which describes the set of CPUs 182 * 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 */ 195 */
196 v2m_flags_set(virt_to_phys(versatile_secondary_startup)); 196 v2m_flags_set(virt_to_phys(versatile_secondary_startup));
197} 197}
198
199struct smp_operations __initdata vexpress_smp_ops = {
200 .smp_init_cpus = vexpress_smp_init_cpus,
201 .smp_prepare_cpus = vexpress_smp_prepare_cpus,
202 .smp_secondary_init = versatile_secondary_init,
203 .smp_boot_secondary = versatile_boot_secondary,
204#ifdef CONFIG_HOTPLUG_CPU
205 .cpu_die = vexpress_cpu_die,
206#endif
207};
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index 2ca86c50174d..5f6b7d543e55 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -5,6 +5,7 @@
5#include <linux/amba/bus.h> 5#include <linux/amba/bus.h>
6#include <linux/amba/mmci.h> 6#include <linux/amba/mmci.h>
7#include <linux/io.h> 7#include <linux/io.h>
8#include <linux/smp.h>
8#include <linux/init.h> 9#include <linux/init.h>
9#include <linux/of_address.h> 10#include <linux/of_address.h>
10#include <linux/of_fdt.h> 11#include <linux/of_fdt.h>
@@ -38,6 +39,7 @@
38#include <mach/motherboard.h> 39#include <mach/motherboard.h>
39 40
40#include <plat/sched_clock.h> 41#include <plat/sched_clock.h>
42#include <plat/platsmp.h>
41 43
42#include "core.h" 44#include "core.h"
43 45
@@ -530,6 +532,7 @@ static void __init v2m_init(void)
530 532
531MACHINE_START(VEXPRESS, "ARM-Versatile Express") 533MACHINE_START(VEXPRESS, "ARM-Versatile Express")
532 .atag_offset = 0x100, 534 .atag_offset = 0x100,
535 .smp = smp_ops(vexpress_smp_ops),
533 .map_io = v2m_map_io, 536 .map_io = v2m_map_io,
534 .init_early = v2m_init_early, 537 .init_early = v2m_init_early,
535 .init_irq = v2m_init_irq, 538 .init_irq = v2m_init_irq,
@@ -661,6 +664,7 @@ const static char *v2m_dt_match[] __initconst = {
661 664
662DT_MACHINE_START(VEXPRESS_DT, "ARM-Versatile Express") 665DT_MACHINE_START(VEXPRESS_DT, "ARM-Versatile Express")
663 .dt_compat = v2m_dt_match, 666 .dt_compat = v2m_dt_match,
667 .smp = smp_ops(vexpress_smp_ops),
664 .map_io = v2m_dt_map_io, 668 .map_io = v2m_dt_map_io,
665 .init_early = v2m_dt_init_early, 669 .init_early = v2m_dt_init_early,
666 .init_irq = v2m_dt_init_irq, 670 .init_irq = v2m_dt_init_irq,
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index 28ba09f4ebb9..ead901814c0d 100644
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -139,6 +139,8 @@ extern void imx_gpc_post_resume(void);
139extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode); 139extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);
140extern void imx6q_clock_map_io(void); 140extern void imx6q_clock_map_io(void);
141 141
142extern void imx_cpu_die(unsigned int cpu);
143
142#ifdef CONFIG_PM 144#ifdef CONFIG_PM
143extern void imx6q_pm_init(void); 145extern void imx6q_pm_init(void);
144extern void imx51_pm_init(void); 146extern void imx51_pm_init(void);
@@ -155,4 +157,6 @@ extern int mx51_neon_fixup(void);
155static inline int mx51_neon_fixup(void) { return 0; } 157static inline int mx51_neon_fixup(void) { return 0; }
156#endif 158#endif
157 159
160extern struct smp_operations imx_smp_ops;
161
158#endif 162#endif
diff --git a/arch/arm/plat-versatile/include/plat/platsmp.h b/arch/arm/plat-versatile/include/plat/platsmp.h
new file mode 100644
index 000000000000..50fb830192e0
--- /dev/null
+++ b/arch/arm/plat-versatile/include/plat/platsmp.h
@@ -0,0 +1,14 @@
1/*
2 * linux/arch/arm/plat-versatile/include/plat/platsmp.h
3 *
4 * Copyright (C) 2011 ARM Ltd.
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12extern void versatile_secondary_startup(void);
13extern void versatile_secondary_init(unsigned int cpu);
14extern int versatile_boot_secondary(unsigned int cpu, struct task_struct *idle);
diff --git a/arch/arm/plat-versatile/platsmp.c b/arch/arm/plat-versatile/platsmp.c
index d7c5c171f5aa..04ca4937d8ca 100644
--- a/arch/arm/plat-versatile/platsmp.c
+++ b/arch/arm/plat-versatile/platsmp.c
@@ -20,12 +20,6 @@
20#include <asm/hardware/gic.h> 20#include <asm/hardware/gic.h>
21 21
22/* 22/*
23 * control for which core is the next to come out of the secondary
24 * boot "holding pen"
25 */
26volatile int __cpuinitdata pen_release = -1;
27
28/*
29 * Write pen_release in a way that is guaranteed to be visible to all 23 * Write pen_release in a way that is guaranteed to be visible to all
30 * observers, irrespective of whether they're taking part in coherency 24 * observers, irrespective of whether they're taking part in coherency
31 * or not. This is necessary for the hotplug code to work reliably. 25 * or not. This is necessary for the hotplug code to work reliably.
@@ -40,7 +34,7 @@ static void __cpuinit write_pen_release(int val)
40 34
41static DEFINE_SPINLOCK(boot_lock); 35static DEFINE_SPINLOCK(boot_lock);
42 36
43void __cpuinit platform_secondary_init(unsigned int cpu) 37void __cpuinit versatile_secondary_init(unsigned int cpu)
44{ 38{
45 /* 39 /*
46 * if any interrupts are already enabled for the primary 40 * if any interrupts are already enabled for the primary
@@ -62,7 +56,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
62 spin_unlock(&boot_lock); 56 spin_unlock(&boot_lock);
63} 57}
64 58
65int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) 59int __cpuinit versatile_boot_secondary(unsigned int cpu, struct task_struct *idle)
66{ 60{
67 unsigned long timeout; 61 unsigned long timeout;
68 62