aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64
diff options
context:
space:
mode:
authorMark Rutland <mark.rutland@arm.com>2013-10-24 15:30:15 -0400
committerCatalin Marinas <catalin.marinas@arm.com>2013-10-25 06:33:20 -0400
commitcd1aebf5277a3a154a9e4c0ea4b3acabb62e5cab (patch)
tree47876c066537a8c251ad483637c0f4d70dab5cf4 /arch/arm64
parent00ef54bb97389bfe8894272f48496f4191aae946 (diff)
arm64: reorganise smp_enable_ops
For hotplug support, we're going to want a place to store operations that do more than bring CPUs online, and it makes sense to group these with our current smp_enable_ops. For cpuidle support, we'll want to group additional functions, and we may want them even for UP kernels. This patch renames smp_enable_ops to the more general cpu_operations, and pulls the definitions out of smp code such that they can be used in UP kernels. While we're at it, fix up instances of the cpu parameter to be an unsigned int, drop the init markings and rename the *_cpu functions to cpu_* to reduce future churn when cpu_operations is extended. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm64')
-rw-r--r--arch/arm64/include/asm/cpu_ops.h33
-rw-r--r--arch/arm64/include/asm/smp.h11
-rw-r--r--arch/arm64/kernel/Makefile2
-rw-r--r--arch/arm64/kernel/cpu_ops.c47
-rw-r--r--arch/arm64/kernel/psci.c11
-rw-r--r--arch/arm64/kernel/smp.c39
-rw-r--r--arch/arm64/kernel/smp_spin_table.c11
7 files changed, 102 insertions, 52 deletions
diff --git a/arch/arm64/include/asm/cpu_ops.h b/arch/arm64/include/asm/cpu_ops.h
new file mode 100644
index 000000000000..3c60c8d1d928
--- /dev/null
+++ b/arch/arm64/include/asm/cpu_ops.h
@@ -0,0 +1,33 @@
1/*
2 * Copyright (C) 2013 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __ASM_CPU_OPS_H
17#define __ASM_CPU_OPS_H
18
19#include <linux/init.h>
20#include <linux/threads.h>
21
22struct device_node;
23
24struct cpu_operations {
25 const char *name;
26 int (*cpu_init)(struct device_node *, unsigned int);
27 int (*cpu_prepare)(unsigned int);
28};
29
30extern const struct cpu_operations *cpu_ops[NR_CPUS];
31extern const struct cpu_operations * __init cpu_get_ops(const char *name);
32
33#endif /* ifndef __ASM_CPU_OPS_H */
diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
index 4b8023c5d146..7e34295f78e3 100644
--- a/arch/arm64/include/asm/smp.h
+++ b/arch/arm64/include/asm/smp.h
@@ -66,15 +66,4 @@ extern volatile unsigned long secondary_holding_pen_release;
66extern void arch_send_call_function_single_ipi(int cpu); 66extern void arch_send_call_function_single_ipi(int cpu);
67extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); 67extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
68 68
69struct device_node;
70
71struct smp_enable_ops {
72 const char *name;
73 int (*init_cpu)(struct device_node *, int);
74 int (*prepare_cpu)(int);
75};
76
77extern const struct smp_enable_ops smp_spin_table_ops;
78extern const struct smp_enable_ops smp_psci_ops;
79
80#endif /* ifndef __ASM_SMP_H */ 69#endif /* ifndef __ASM_SMP_H */
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 75a90c15b30b..5ba2fd43a75b 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -9,7 +9,7 @@ AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
9arm64-obj-y := cputable.o debug-monitors.o entry.o irq.o fpsimd.o \ 9arm64-obj-y := cputable.o debug-monitors.o entry.o irq.o fpsimd.o \
10 entry-fpsimd.o process.o ptrace.o setup.o signal.o \ 10 entry-fpsimd.o process.o ptrace.o setup.o signal.o \
11 sys.o stacktrace.o time.o traps.o io.o vdso.o \ 11 sys.o stacktrace.o time.o traps.o io.o vdso.o \
12 hyp-stub.o psci.o 12 hyp-stub.o psci.o cpu_ops.o
13 13
14arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \ 14arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \
15 sys_compat.o 15 sys_compat.o
diff --git a/arch/arm64/kernel/cpu_ops.c b/arch/arm64/kernel/cpu_ops.c
new file mode 100644
index 000000000000..e2652aadd9ea
--- /dev/null
+++ b/arch/arm64/kernel/cpu_ops.c
@@ -0,0 +1,47 @@
1/*
2 * CPU kernel entry/exit control
3 *
4 * Copyright (C) 2013 ARM Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <asm/cpu_ops.h>
20#include <linux/string.h>
21
22extern const struct cpu_operations smp_spin_table_ops;
23extern const struct cpu_operations cpu_psci_ops;
24
25const struct cpu_operations *cpu_ops[NR_CPUS];
26
27static const struct cpu_operations *supported_cpu_ops[] __initconst = {
28#ifdef CONFIG_SMP
29 &smp_spin_table_ops,
30 &cpu_psci_ops,
31#endif
32 NULL,
33};
34
35const struct cpu_operations * __init cpu_get_ops(const char *name)
36{
37 const struct cpu_operations **ops = supported_cpu_ops;
38
39 while (*ops) {
40 if (!strcmp(name, (*ops)->name))
41 return *ops;
42
43 ops++;
44 }
45
46 return NULL;
47}
diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
index 368b78788cb5..ccec2ca67755 100644
--- a/arch/arm64/kernel/psci.c
+++ b/arch/arm64/kernel/psci.c
@@ -20,6 +20,7 @@
20#include <linux/smp.h> 20#include <linux/smp.h>
21 21
22#include <asm/compiler.h> 22#include <asm/compiler.h>
23#include <asm/cpu_ops.h>
23#include <asm/errno.h> 24#include <asm/errno.h>
24#include <asm/psci.h> 25#include <asm/psci.h>
25#include <asm/smp_plat.h> 26#include <asm/smp_plat.h>
@@ -231,12 +232,12 @@ out_put_node:
231 232
232#ifdef CONFIG_SMP 233#ifdef CONFIG_SMP
233 234
234static int __init smp_psci_init_cpu(struct device_node *dn, int cpu) 235static int __init cpu_psci_cpu_init(struct device_node *dn, unsigned int cpu)
235{ 236{
236 return 0; 237 return 0;
237} 238}
238 239
239static int __init smp_psci_prepare_cpu(int cpu) 240static int __init cpu_psci_cpu_prepare(unsigned int cpu)
240{ 241{
241 int err; 242 int err;
242 243
@@ -254,10 +255,10 @@ static int __init smp_psci_prepare_cpu(int cpu)
254 return 0; 255 return 0;
255} 256}
256 257
257const struct smp_enable_ops smp_psci_ops __initconst = { 258const struct cpu_operations cpu_psci_ops = {
258 .name = "psci", 259 .name = "psci",
259 .init_cpu = smp_psci_init_cpu, 260 .cpu_init = cpu_psci_cpu_init,
260 .prepare_cpu = smp_psci_prepare_cpu, 261 .cpu_prepare = cpu_psci_cpu_prepare,
261}; 262};
262 263
263#endif 264#endif
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 78db90dcc910..8965fb7dee89 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -39,6 +39,7 @@
39#include <asm/atomic.h> 39#include <asm/atomic.h>
40#include <asm/cacheflush.h> 40#include <asm/cacheflush.h>
41#include <asm/cputype.h> 41#include <asm/cputype.h>
42#include <asm/cpu_ops.h>
42#include <asm/mmu_context.h> 43#include <asm/mmu_context.h>
43#include <asm/pgtable.h> 44#include <asm/pgtable.h>
44#include <asm/pgalloc.h> 45#include <asm/pgalloc.h>
@@ -232,28 +233,6 @@ void __init smp_prepare_boot_cpu(void)
232 233
233static void (*smp_cross_call)(const struct cpumask *, unsigned int); 234static void (*smp_cross_call)(const struct cpumask *, unsigned int);
234 235
235static const struct smp_enable_ops *enable_ops[] __initconst = {
236 &smp_spin_table_ops,
237 &smp_psci_ops,
238 NULL,
239};
240
241static const struct smp_enable_ops *smp_enable_ops[NR_CPUS];
242
243static const struct smp_enable_ops * __init smp_get_enable_ops(const char *name)
244{
245 const struct smp_enable_ops **ops = enable_ops;
246
247 while (*ops) {
248 if (!strcmp(name, (*ops)->name))
249 return *ops;
250
251 ops++;
252 }
253
254 return NULL;
255}
256
257/* 236/*
258 * Enumerate the possible CPU set from the device tree and build the 237 * Enumerate the possible CPU set from the device tree and build the
259 * cpu logical map array containing MPIDR values related to logical 238 * cpu logical map array containing MPIDR values related to logical
@@ -263,7 +242,7 @@ void __init smp_init_cpus(void)
263{ 242{
264 const char *enable_method; 243 const char *enable_method;
265 struct device_node *dn = NULL; 244 struct device_node *dn = NULL;
266 int i, cpu = 1; 245 unsigned int i, cpu = 1;
267 bool bootcpu_valid = false; 246 bool bootcpu_valid = false;
268 247
269 while ((dn = of_find_node_by_type(dn, "cpu"))) { 248 while ((dn = of_find_node_by_type(dn, "cpu"))) {
@@ -342,15 +321,15 @@ void __init smp_init_cpus(void)
342 goto next; 321 goto next;
343 } 322 }
344 323
345 smp_enable_ops[cpu] = smp_get_enable_ops(enable_method); 324 cpu_ops[cpu] = cpu_get_ops(enable_method);
346 325
347 if (!smp_enable_ops[cpu]) { 326 if (!cpu_ops[cpu]) {
348 pr_err("%s: invalid enable-method property: %s\n", 327 pr_err("%s: invalid enable-method property: %s\n",
349 dn->full_name, enable_method); 328 dn->full_name, enable_method);
350 goto next; 329 goto next;
351 } 330 }
352 331
353 if (smp_enable_ops[cpu]->init_cpu(dn, cpu)) 332 if (cpu_ops[cpu]->cpu_init(dn, cpu))
354 goto next; 333 goto next;
355 334
356 pr_debug("cpu logical map 0x%llx\n", hwid); 335 pr_debug("cpu logical map 0x%llx\n", hwid);
@@ -380,8 +359,8 @@ next:
380 359
381void __init smp_prepare_cpus(unsigned int max_cpus) 360void __init smp_prepare_cpus(unsigned int max_cpus)
382{ 361{
383 int cpu, err; 362 int err;
384 unsigned int ncores = num_possible_cpus(); 363 unsigned int cpu, ncores = num_possible_cpus();
385 364
386 /* 365 /*
387 * are we trying to boot more cores than exist? 366 * are we trying to boot more cores than exist?
@@ -408,10 +387,10 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
408 if (cpu == smp_processor_id()) 387 if (cpu == smp_processor_id())
409 continue; 388 continue;
410 389
411 if (!smp_enable_ops[cpu]) 390 if (!cpu_ops[cpu])
412 continue; 391 continue;
413 392
414 err = smp_enable_ops[cpu]->prepare_cpu(cpu); 393 err = cpu_ops[cpu]->cpu_prepare(cpu);
415 if (err) 394 if (err)
416 continue; 395 continue;
417 396
diff --git a/arch/arm64/kernel/smp_spin_table.c b/arch/arm64/kernel/smp_spin_table.c
index 7c35fa682f76..a8b76e4eccff 100644
--- a/arch/arm64/kernel/smp_spin_table.c
+++ b/arch/arm64/kernel/smp_spin_table.c
@@ -21,10 +21,11 @@
21#include <linux/smp.h> 21#include <linux/smp.h>
22 22
23#include <asm/cacheflush.h> 23#include <asm/cacheflush.h>
24#include <asm/cpu_ops.h>
24 25
25static phys_addr_t cpu_release_addr[NR_CPUS]; 26static phys_addr_t cpu_release_addr[NR_CPUS];
26 27
27static int __init smp_spin_table_init_cpu(struct device_node *dn, int cpu) 28static int smp_spin_table_cpu_init(struct device_node *dn, unsigned int cpu)
28{ 29{
29 /* 30 /*
30 * Determine the address from which the CPU is polling. 31 * Determine the address from which the CPU is polling.
@@ -40,7 +41,7 @@ static int __init smp_spin_table_init_cpu(struct device_node *dn, int cpu)
40 return 0; 41 return 0;
41} 42}
42 43
43static int __init smp_spin_table_prepare_cpu(int cpu) 44static int smp_spin_table_cpu_prepare(unsigned int cpu)
44{ 45{
45 void **release_addr; 46 void **release_addr;
46 47
@@ -59,8 +60,8 @@ static int __init smp_spin_table_prepare_cpu(int cpu)
59 return 0; 60 return 0;
60} 61}
61 62
62const struct smp_enable_ops smp_spin_table_ops __initconst = { 63const struct cpu_operations smp_spin_table_ops = {
63 .name = "spin-table", 64 .name = "spin-table",
64 .init_cpu = smp_spin_table_init_cpu, 65 .cpu_init = smp_spin_table_cpu_init,
65 .prepare_cpu = smp_spin_table_prepare_cpu, 66 .cpu_prepare = smp_spin_table_cpu_prepare,
66}; 67};