diff options
author | Rich Felker <dalias@libc.org> | 2016-02-15 13:30:50 -0500 |
---|---|---|
committer | Rich Felker <dalias@libc.org> | 2016-03-17 15:46:12 -0400 |
commit | 044b81f872169e9549b47ea2b6c94491e6d5f305 (patch) | |
tree | afe8eac4f0a66f6890f4795d8950d8d6abc671cb | |
parent | 7480e0aabd5f9e6c3e3b72ed206e89284e90f11f (diff) |
sh: add SMP method selection to device tree pseudo-board
Allow selection of plat_smp_ops based on the enable-method cpu
property from device tree and provide dummy ops for booting with a
device tree that does not enable SMP.
Signed-off-by: Rich Felker <dalias@libc.org>
-rw-r--r-- | arch/sh/boards/of-generic.c | 89 | ||||
-rw-r--r-- | arch/sh/include/asm/smp.h | 10 |
2 files changed, 96 insertions, 3 deletions
diff --git a/arch/sh/boards/of-generic.c b/arch/sh/boards/of-generic.c index 71d890932151..bf3a166a5407 100644 --- a/arch/sh/boards/of-generic.c +++ b/arch/sh/boards/of-generic.c | |||
@@ -18,6 +18,91 @@ | |||
18 | #include <asm/machvec.h> | 18 | #include <asm/machvec.h> |
19 | #include <asm/rtc.h> | 19 | #include <asm/rtc.h> |
20 | 20 | ||
21 | #ifdef CONFIG_SMP | ||
22 | |||
23 | static void dummy_smp_setup(void) | ||
24 | { | ||
25 | } | ||
26 | |||
27 | static void dummy_prepare_cpus(unsigned int max_cpus) | ||
28 | { | ||
29 | } | ||
30 | |||
31 | static void dummy_start_cpu(unsigned int cpu, unsigned long entry_point) | ||
32 | { | ||
33 | } | ||
34 | |||
35 | static unsigned int dummy_smp_processor_id(void) | ||
36 | { | ||
37 | return 0; | ||
38 | } | ||
39 | |||
40 | static void dummy_send_ipi(unsigned int cpu, unsigned int message) | ||
41 | { | ||
42 | } | ||
43 | |||
44 | static struct plat_smp_ops dummy_smp_ops = { | ||
45 | .smp_setup = dummy_smp_setup, | ||
46 | .prepare_cpus = dummy_prepare_cpus, | ||
47 | .start_cpu = dummy_start_cpu, | ||
48 | .smp_processor_id = dummy_smp_processor_id, | ||
49 | .send_ipi = dummy_send_ipi, | ||
50 | .cpu_die = native_cpu_die, | ||
51 | .cpu_disable = native_cpu_disable, | ||
52 | .play_dead = native_play_dead, | ||
53 | }; | ||
54 | |||
55 | extern const struct of_cpu_method __cpu_method_of_table[]; | ||
56 | const struct of_cpu_method __cpu_method_of_table_sentinel | ||
57 | __section(__cpu_method_of_table_end); | ||
58 | |||
59 | static void sh_of_smp_probe(void) | ||
60 | { | ||
61 | struct device_node *np = 0; | ||
62 | const char *method = 0; | ||
63 | const struct of_cpu_method *m = __cpu_method_of_table; | ||
64 | |||
65 | pr_info("SH generic board support: scanning for cpus\n"); | ||
66 | |||
67 | init_cpu_possible(cpumask_of(0)); | ||
68 | |||
69 | while ((np = of_find_node_by_type(np, "cpu"))) { | ||
70 | const __be32 *cell = of_get_property(np, "reg", NULL); | ||
71 | u64 id = -1; | ||
72 | if (cell) id = of_read_number(cell, of_n_addr_cells(np)); | ||
73 | if (id < NR_CPUS) { | ||
74 | if (!method) | ||
75 | of_property_read_string(np, "enable-method", &method); | ||
76 | set_cpu_possible(id, true); | ||
77 | set_cpu_present(id, true); | ||
78 | __cpu_number_map[id] = id; | ||
79 | __cpu_logical_map[id] = id; | ||
80 | } | ||
81 | } | ||
82 | if (!method) { | ||
83 | np = of_find_node_by_name(NULL, "cpus"); | ||
84 | of_property_read_string(np, "enable-method", &method); | ||
85 | } | ||
86 | |||
87 | pr_info("CPU enable method: %s\n", method); | ||
88 | if (method) | ||
89 | for (; m->method; m++) | ||
90 | if (!strcmp(m->method, method)) { | ||
91 | register_smp_ops(m->ops); | ||
92 | return; | ||
93 | } | ||
94 | |||
95 | register_smp_ops(&dummy_smp_ops); | ||
96 | } | ||
97 | |||
98 | #else | ||
99 | |||
100 | static void sh_of_smp_probe(void) | ||
101 | { | ||
102 | } | ||
103 | |||
104 | #endif | ||
105 | |||
21 | static void noop(void) | 106 | static void noop(void) |
22 | { | 107 | { |
23 | } | 108 | } |
@@ -49,9 +134,7 @@ static void __init sh_of_setup(char **cmdline_p) | |||
49 | if (!sh_mv.mv_name) | 134 | if (!sh_mv.mv_name) |
50 | sh_mv.mv_name = "Unknown SH model"; | 135 | sh_mv.mv_name = "Unknown SH model"; |
51 | 136 | ||
52 | /* FIXME: register smp ops to use dt to find cpus, use | 137 | sh_of_smp_probe(); |
53 | * cpu enable-method, and use irq controller's ipi | ||
54 | * functions. */ | ||
55 | } | 138 | } |
56 | 139 | ||
57 | static int sh_of_irq_demux(int irq) | 140 | static int sh_of_irq_demux(int irq) |
diff --git a/arch/sh/include/asm/smp.h b/arch/sh/include/asm/smp.h index 78b0d0f4b24b..1baf0ba96242 100644 --- a/arch/sh/include/asm/smp.h +++ b/arch/sh/include/asm/smp.h | |||
@@ -69,6 +69,16 @@ static inline int hard_smp_processor_id(void) | |||
69 | return mp_ops->smp_processor_id(); | 69 | return mp_ops->smp_processor_id(); |
70 | } | 70 | } |
71 | 71 | ||
72 | struct of_cpu_method { | ||
73 | const char *method; | ||
74 | struct plat_smp_ops *ops; | ||
75 | }; | ||
76 | |||
77 | #define CPU_METHOD_OF_DECLARE(name, _method, _ops) \ | ||
78 | static const struct of_cpu_method __cpu_method_of_table_##name \ | ||
79 | __used __section(__cpu_method_of_table) \ | ||
80 | = { .method = _method, .ops = _ops } | ||
81 | |||
72 | #else | 82 | #else |
73 | 83 | ||
74 | #define hard_smp_processor_id() (0) | 84 | #define hard_smp_processor_id() (0) |