aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/devtree.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel/devtree.c')
-rw-r--r--arch/arm/kernel/devtree.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c
index f751714d52c1..c7419a585ddc 100644
--- a/arch/arm/kernel/devtree.c
+++ b/arch/arm/kernel/devtree.c
@@ -18,6 +18,7 @@
18#include <linux/of_fdt.h> 18#include <linux/of_fdt.h>
19#include <linux/of_irq.h> 19#include <linux/of_irq.h>
20#include <linux/of_platform.h> 20#include <linux/of_platform.h>
21#include <linux/smp.h>
21 22
22#include <asm/cputype.h> 23#include <asm/cputype.h>
23#include <asm/setup.h> 24#include <asm/setup.h>
@@ -63,6 +64,34 @@ void __init arm_dt_memblock_reserve(void)
63 } 64 }
64} 65}
65 66
67#ifdef CONFIG_SMP
68extern struct of_cpu_method __cpu_method_of_table_begin[];
69extern struct of_cpu_method __cpu_method_of_table_end[];
70
71static int __init set_smp_ops_by_method(struct device_node *node)
72{
73 const char *method;
74 struct of_cpu_method *m = __cpu_method_of_table_begin;
75
76 if (of_property_read_string(node, "enable-method", &method))
77 return 0;
78
79 for (; m < __cpu_method_of_table_end; m++)
80 if (!strcmp(m->method, method)) {
81 smp_set_ops(m->ops);
82 return 1;
83 }
84
85 return 0;
86}
87#else
88static inline int set_smp_ops_by_method(struct device_node *node)
89{
90 return 1;
91}
92#endif
93
94
66/* 95/*
67 * arm_dt_init_cpu_maps - Function retrieves cpu nodes from the device tree 96 * arm_dt_init_cpu_maps - Function retrieves cpu nodes from the device tree
68 * and builds the cpu logical map array containing MPIDR values related to 97 * and builds the cpu logical map array containing MPIDR values related to
@@ -79,6 +108,7 @@ void __init arm_dt_init_cpu_maps(void)
79 * read as 0. 108 * read as 0.
80 */ 109 */
81 struct device_node *cpu, *cpus; 110 struct device_node *cpu, *cpus;
111 int found_method = 0;
82 u32 i, j, cpuidx = 1; 112 u32 i, j, cpuidx = 1;
83 u32 mpidr = is_smp() ? read_cpuid_mpidr() & MPIDR_HWID_BITMASK : 0; 113 u32 mpidr = is_smp() ? read_cpuid_mpidr() & MPIDR_HWID_BITMASK : 0;
84 114
@@ -150,8 +180,18 @@ void __init arm_dt_init_cpu_maps(void)
150 } 180 }
151 181
152 tmp_map[i] = hwid; 182 tmp_map[i] = hwid;
183
184 if (!found_method)
185 found_method = set_smp_ops_by_method(cpu);
153 } 186 }
154 187
188 /*
189 * Fallback to an enable-method in the cpus node if nothing found in
190 * a cpu node.
191 */
192 if (!found_method)
193 set_smp_ops_by_method(cpus);
194
155 if (!bootcpu_valid) { 195 if (!bootcpu_valid) {
156 pr_warn("DT missing boot CPU MPIDR[23:0], fall back to default cpu_logical_map\n"); 196 pr_warn("DT missing boot CPU MPIDR[23:0], fall back to default cpu_logical_map\n");
157 return; 197 return;