aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/smp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel/smp.c')
-rw-r--r--arch/arm/kernel/smp.c72
1 files changed, 69 insertions, 3 deletions
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);