kernel: update 4.4 to 4.4.86
[openwrt/openwrt.git] / target / linux / bcm53xx / patches-4.4 / 022-ARM-BCM-Clean-up-SMP-support-for-Broadcom-Kona.patch
1 From b5989f783de046577067fe356b1bb76cae07e867 Mon Sep 17 00:00:00 2001
2 From: Kapil Hali <kapilh@broadcom.com>
3 Date: Sat, 5 Dec 2015 06:53:41 -0500
4 Subject: [PATCH] ARM: BCM: Clean up SMP support for Broadcom Kona
5
6 These changes cleans up SMP implementaion for Broadcom's
7 Kona SoC which are required for handling SMP for iProc
8 family of SoCs at a single place for BCM NSP and BCM Kona.
9
10 Signed-off-by: Kapil Hali <kapilh@broadcom.com>
11 Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
12 ---
13 .../bindings/arm/bcm/brcm,bcm11351-cpu-method.txt | 12 ++--
14 arch/arm/boot/dts/bcm11351.dtsi | 4 +-
15 arch/arm/boot/dts/bcm21664.dtsi | 4 +-
16 arch/arm/mach-bcm/kona_smp.c | 82 ++++++++++++++--------
17 4 files changed, 64 insertions(+), 38 deletions(-)
18
19 --- a/Documentation/devicetree/bindings/arm/bcm/brcm,bcm11351-cpu-method.txt
20 +++ b/Documentation/devicetree/bindings/arm/bcm/brcm,bcm11351-cpu-method.txt
21 @@ -1,17 +1,17 @@
22 Broadcom Kona Family CPU Enable Method
23 --------------------------------------
24 This binding defines the enable method used for starting secondary
25 -CPUs in the following Broadcom SoCs:
26 +CPU in the following Broadcom SoCs:
27 BCM11130, BCM11140, BCM11351, BCM28145, BCM28155, BCM21664
28
29 The enable method is specified by defining the following required
30 -properties in the "cpus" device tree node:
31 +properties in the corresponding secondary "cpu" device tree node:
32 - enable-method = "brcm,bcm11351-cpu-method";
33 - secondary-boot-reg = <...>;
34
35 The secondary-boot-reg property is a u32 value that specifies the
36 -physical address of the register used to request the ROM holding pen
37 -code release a secondary CPU. The value written to the register is
38 +physical address of the register used to request the ROM code
39 +release a secondary CPU. The value written to the register is
40 formed by encoding the target CPU id into the low bits of the
41 physical start address it should jump to.
42
43 @@ -19,8 +19,6 @@ Example:
44 cpus {
45 #address-cells = <1>;
46 #size-cells = <0>;
47 - enable-method = "brcm,bcm11351-cpu-method";
48 - secondary-boot-reg = <0x3500417c>;
49
50 cpu0: cpu@0 {
51 device_type = "cpu";
52 @@ -31,6 +29,8 @@ Example:
53 cpu1: cpu@1 {
54 device_type = "cpu";
55 compatible = "arm,cortex-a9";
56 + enable-method = "brcm,bcm11351-cpu-method";
57 + secondary-boot-reg = <0x3500417c>;
58 reg = <1>;
59 };
60 };
61 --- a/arch/arm/boot/dts/bcm11351.dtsi
62 +++ b/arch/arm/boot/dts/bcm11351.dtsi
63 @@ -30,8 +30,6 @@
64 cpus {
65 #address-cells = <1>;
66 #size-cells = <0>;
67 - enable-method = "brcm,bcm11351-cpu-method";
68 - secondary-boot-reg = <0x3500417c>;
69
70 cpu0: cpu@0 {
71 device_type = "cpu";
72 @@ -42,6 +40,8 @@
73 cpu1: cpu@1 {
74 device_type = "cpu";
75 compatible = "arm,cortex-a9";
76 + enable-method = "brcm,bcm11351-cpu-method";
77 + secondary-boot-reg = <0x3500417c>;
78 reg = <1>;
79 };
80 };
81 --- a/arch/arm/boot/dts/bcm21664.dtsi
82 +++ b/arch/arm/boot/dts/bcm21664.dtsi
83 @@ -30,8 +30,6 @@
84 cpus {
85 #address-cells = <1>;
86 #size-cells = <0>;
87 - enable-method = "brcm,bcm11351-cpu-method";
88 - secondary-boot-reg = <0x35004178>;
89
90 cpu0: cpu@0 {
91 device_type = "cpu";
92 @@ -42,6 +40,8 @@
93 cpu1: cpu@1 {
94 device_type = "cpu";
95 compatible = "arm,cortex-a9";
96 + enable-method = "brcm,bcm11351-cpu-method";
97 + secondary-boot-reg = <0x35004178>;
98 reg = <1>;
99 };
100 };
101 --- a/arch/arm/mach-bcm/kona_smp.c
102 +++ b/arch/arm/mach-bcm/kona_smp.c
103 @@ -1,5 +1,5 @@
104 /*
105 - * Copyright (C) 2014 Broadcom Corporation
106 + * Copyright (C) 2014-2015 Broadcom Corporation
107 * Copyright 2014 Linaro Limited
108 *
109 * This program is free software; you can redistribute it and/or
110 @@ -30,9 +30,10 @@
111
112 /* Name of device node property defining secondary boot register location */
113 #define OF_SECONDARY_BOOT "secondary-boot-reg"
114 +#define MPIDR_CPUID_BITMASK 0x3
115
116 /* I/O address of register used to coordinate secondary core startup */
117 -static u32 secondary_boot;
118 +static u32 secondary_boot_addr;
119
120 /*
121 * Enable the Cortex A9 Snoop Control Unit
122 @@ -78,44 +79,68 @@ static int __init scu_a9_enable(void)
123 static void __init bcm_smp_prepare_cpus(unsigned int max_cpus)
124 {
125 static cpumask_t only_cpu_0 = { CPU_BITS_CPU0 };
126 - struct device_node *node;
127 + struct device_node *cpus_node = NULL;
128 + struct device_node *cpu_node = NULL;
129 int ret;
130
131 - BUG_ON(secondary_boot); /* We're called only once */
132 -
133 /*
134 * This function is only called via smp_ops->smp_prepare_cpu().
135 * That only happens if a "/cpus" device tree node exists
136 * and has an "enable-method" property that selects the SMP
137 * operations defined herein.
138 */
139 - node = of_find_node_by_path("/cpus");
140 - BUG_ON(!node);
141 -
142 - /*
143 - * Our secondary enable method requires a "secondary-boot-reg"
144 - * property to specify a register address used to request the
145 - * ROM code boot a secondary code. If we have any trouble
146 - * getting this we fall back to uniprocessor mode.
147 - */
148 - if (of_property_read_u32(node, OF_SECONDARY_BOOT, &secondary_boot)) {
149 - pr_err("%s: missing/invalid " OF_SECONDARY_BOOT " property\n",
150 - node->name);
151 - ret = -ENOENT; /* Arrange to disable SMP */
152 - goto out;
153 + cpus_node = of_find_node_by_path("/cpus");
154 + if (!cpus_node)
155 + return;
156 +
157 + for_each_child_of_node(cpus_node, cpu_node) {
158 + u32 cpuid;
159 +
160 + if (of_node_cmp(cpu_node->type, "cpu"))
161 + continue;
162 +
163 + if (of_property_read_u32(cpu_node, "reg", &cpuid)) {
164 + pr_debug("%s: missing reg property\n",
165 + cpu_node->full_name);
166 + ret = -ENOENT;
167 + goto out;
168 + }
169 +
170 + /*
171 + * "secondary-boot-reg" property should be defined only
172 + * for secondary cpu
173 + */
174 + if ((cpuid & MPIDR_CPUID_BITMASK) == 1) {
175 + /*
176 + * Our secondary enable method requires a
177 + * "secondary-boot-reg" property to specify a register
178 + * address used to request the ROM code boot a secondary
179 + * core. If we have any trouble getting this we fall
180 + * back to uniprocessor mode.
181 + */
182 + if (of_property_read_u32(cpu_node,
183 + OF_SECONDARY_BOOT,
184 + &secondary_boot_addr)) {
185 + pr_warn("%s: no" OF_SECONDARY_BOOT "property\n",
186 + cpu_node->name);
187 + ret = -ENOENT;
188 + goto out;
189 + }
190 + }
191 }
192
193 /*
194 - * Enable the SCU on Cortex A9 based SoCs. If -ENOENT is
195 + * Enable the SCU on Cortex A9 based SoCs. If -ENOENT is
196 * returned, the SoC reported a uniprocessor configuration.
197 * We bail on any other error.
198 */
199 ret = scu_a9_enable();
200 out:
201 - of_node_put(node);
202 + of_node_put(cpu_node);
203 + of_node_put(cpus_node);
204 +
205 if (ret) {
206 /* Update the CPU present map to reflect uniprocessor mode */
207 - BUG_ON(ret != -ENOENT);
208 pr_warn("disabling SMP\n");
209 init_cpu_present(&only_cpu_0);
210 }
211 @@ -139,7 +164,7 @@ out:
212 * - Wait for the secondary boot register to be re-written, which
213 * indicates the secondary core has started.
214 */
215 -static int bcm_boot_secondary(unsigned int cpu, struct task_struct *idle)
216 +static int kona_boot_secondary(unsigned int cpu, struct task_struct *idle)
217 {
218 void __iomem *boot_reg;
219 phys_addr_t boot_func;
220 @@ -154,15 +179,16 @@ static int bcm_boot_secondary(unsigned i
221 return -EINVAL;
222 }
223
224 - if (!secondary_boot) {
225 + if (!secondary_boot_addr) {
226 pr_err("required secondary boot register not specified\n");
227 return -EINVAL;
228 }
229
230 - boot_reg = ioremap_nocache((phys_addr_t)secondary_boot, sizeof(u32));
231 + boot_reg = ioremap_nocache(
232 + (phys_addr_t)secondary_boot_addr, sizeof(u32));
233 if (!boot_reg) {
234 pr_err("unable to map boot register for cpu %u\n", cpu_id);
235 - return -ENOSYS;
236 + return -ENOMEM;
237 }
238
239 /*
240 @@ -191,12 +217,12 @@ static int bcm_boot_secondary(unsigned i
241
242 pr_err("timeout waiting for cpu %u to start\n", cpu_id);
243
244 - return -ENOSYS;
245 + return -ENXIO;
246 }
247
248 static struct smp_operations bcm_smp_ops __initdata = {
249 .smp_prepare_cpus = bcm_smp_prepare_cpus,
250 - .smp_boot_secondary = bcm_boot_secondary,
251 + .smp_boot_secondary = kona_boot_secondary,
252 };
253 CPU_METHOD_OF_DECLARE(bcm_smp_bcm281xx, "brcm,bcm11351-cpu-method",
254 &bcm_smp_ops);