aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-bcm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-08-01 18:37:45 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-08-01 18:37:45 -0400
commit043248cd4e9603e2e8858c4e20810d8e40be7d9d (patch)
treee7efb8af3cbc9cf379cb5473a554d68c0ef30553 /arch/arm/mach-bcm
parent43a0a98aa8da71583f84b84fd72e265c24d4c5f8 (diff)
parentd95eabc7b8ee4c8ef471e8a97aa62d353b110880 (diff)
Merge tag 'armsoc-dt' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM DT updates from Olof Johansson: "Device tree contents continue to be the largest branches we submit. This time around, some of the contents worth pointing out is: New SoC platforms: - Freescale i.MX 7Solo - Broadcom BCM23550 - Cirrus Logic EP7209 and EP7211 (clps711x platforms)_ - Hisilicon HI3519 - Renesas R8A7792 Some of the other delta that is sticking out, line-count wise: - Exynos moves of IP blocks under an SoC bus, which causes a large delta due to indentation changes - a new Tegra K1 board: Apalis - a bunch of small updates to many Allwinner platforms; new hardware support, some cleanup, etc" * tag 'armsoc-dt' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (426 commits) ARM: dts: sun8i: Add dts file for inet86dz board ARM: dts: sun8i: Add dts file for Polaroid MID2407PXE03 tablet ARM: dts: sun8i: Use sun8i-reference-design-tablet for ga10h dts ARM: dts: sun8i: Use sun8i-reference-design-tablet for polaroid mid2809pxe04 ARM: dts: sun8i: reference-design-tablet: Add drivevbus-supply ARM: dts: Copy sun8i-q8-common.dtsi sun8i-reference-design-tablet.dtsi ARM: dts: sun5i: Use sun5i-reference-design-tablet.dtsi for utoo p66 dts ARM: dts: sun5i: Use sun5i-reference-design-tablet.dtsi for dit4350 dts ARM: dts: sun5i: reference-design-tablet: Remove mention of q8 ARM: dts: sun5i: reference-design-tablet: Set lradc vref to avcc ARM: dts: sun5i: Rename sun5i-q8-common.dtsi sun5i-reference-design-tablet.dtsi ARM: dts: sun5i: Move q8 display bits to sun5i-a13-q8-tablet.dts ARM: dts: sunxi: Rename sunxi-q8-common.dtsi sunxi-reference-design-tablet.dtsi ARM: dts: at91: Don't build unnecessary dtbs ARM: dts: at91: sama5d3x: separate motherboard gmac and emac definitions ARM: dts: at91: at91sam9g25ek: fix isi endpoint node ARM: dts: at91: move isi definition to at91sam9g25ek ARM: dts: at91: fix i2c-gpio node name ARM: dts: at91: vinco: fix regulator name ARM: dts: at91: ariag25 : fix onewire node ...
Diffstat (limited to 'arch/arm/mach-bcm')
-rw-r--r--arch/arm/mach-bcm/platsmp.c116
1 files changed, 37 insertions, 79 deletions
diff --git a/arch/arm/mach-bcm/platsmp.c b/arch/arm/mach-bcm/platsmp.c
index 33c4d8349f95..3ac3a9bc663c 100644
--- a/arch/arm/mach-bcm/platsmp.c
+++ b/arch/arm/mach-bcm/platsmp.c
@@ -38,9 +38,6 @@
38#define OF_SECONDARY_BOOT "secondary-boot-reg" 38#define OF_SECONDARY_BOOT "secondary-boot-reg"
39#define MPIDR_CPUID_BITMASK 0x3 39#define MPIDR_CPUID_BITMASK 0x3
40 40
41/* I/O address of register used to coordinate secondary core startup */
42static u32 secondary_boot_addr;
43
44/* 41/*
45 * Enable the Cortex A9 Snoop Control Unit 42 * Enable the Cortex A9 Snoop Control Unit
46 * 43 *
@@ -82,20 +79,40 @@ static int __init scu_a9_enable(void)
82 return 0; 79 return 0;
83} 80}
84 81
85static int nsp_write_lut(void) 82static u32 secondary_boot_addr_for(unsigned int cpu)
83{
84 u32 secondary_boot_addr = 0;
85 struct device_node *cpu_node = of_get_cpu_node(cpu, NULL);
86
87 if (!cpu_node) {
88 pr_err("Failed to find device tree node for CPU%u\n", cpu);
89 return 0;
90 }
91
92 if (of_property_read_u32(cpu_node,
93 OF_SECONDARY_BOOT,
94 &secondary_boot_addr))
95 pr_err("required secondary boot register not specified for CPU%u\n",
96 cpu);
97
98 of_node_put(cpu_node);
99
100 return secondary_boot_addr;
101}
102
103static int nsp_write_lut(unsigned int cpu)
86{ 104{
87 void __iomem *sku_rom_lut; 105 void __iomem *sku_rom_lut;
88 phys_addr_t secondary_startup_phy; 106 phys_addr_t secondary_startup_phy;
107 const u32 secondary_boot_addr = secondary_boot_addr_for(cpu);
89 108
90 if (!secondary_boot_addr) { 109 if (!secondary_boot_addr)
91 pr_warn("required secondary boot register not specified\n");
92 return -EINVAL; 110 return -EINVAL;
93 }
94 111
95 sku_rom_lut = ioremap_nocache((phys_addr_t)secondary_boot_addr, 112 sku_rom_lut = ioremap_nocache((phys_addr_t)secondary_boot_addr,
96 sizeof(secondary_boot_addr)); 113 sizeof(phys_addr_t));
97 if (!sku_rom_lut) { 114 if (!sku_rom_lut) {
98 pr_warn("unable to ioremap SKU-ROM LUT register\n"); 115 pr_warn("unable to ioremap SKU-ROM LUT register for cpu %u\n", cpu);
99 return -ENOMEM; 116 return -ENOMEM;
100 } 117 }
101 118
@@ -114,70 +131,12 @@ static int nsp_write_lut(void)
114 131
115static void __init bcm_smp_prepare_cpus(unsigned int max_cpus) 132static void __init bcm_smp_prepare_cpus(unsigned int max_cpus)
116{ 133{
117 static cpumask_t only_cpu_0 = { CPU_BITS_CPU0 }; 134 const cpumask_t only_cpu_0 = { CPU_BITS_CPU0 };
118 struct device_node *cpus_node = NULL;
119 struct device_node *cpu_node = NULL;
120 int ret;
121
122 /*
123 * This function is only called via smp_ops->smp_prepare_cpu().
124 * That only happens if a "/cpus" device tree node exists
125 * and has an "enable-method" property that selects the SMP
126 * operations defined herein.
127 */
128 cpus_node = of_find_node_by_path("/cpus");
129 if (!cpus_node)
130 return;
131
132 for_each_child_of_node(cpus_node, cpu_node) {
133 u32 cpuid;
134
135 if (of_node_cmp(cpu_node->type, "cpu"))
136 continue;
137
138 if (of_property_read_u32(cpu_node, "reg", &cpuid)) {
139 pr_debug("%s: missing reg property\n",
140 cpu_node->full_name);
141 ret = -ENOENT;
142 goto out;
143 }
144
145 /*
146 * "secondary-boot-reg" property should be defined only
147 * for secondary cpu
148 */
149 if ((cpuid & MPIDR_CPUID_BITMASK) == 1) {
150 /*
151 * Our secondary enable method requires a
152 * "secondary-boot-reg" property to specify a register
153 * address used to request the ROM code boot a secondary
154 * core. If we have any trouble getting this we fall
155 * back to uniprocessor mode.
156 */
157 if (of_property_read_u32(cpu_node,
158 OF_SECONDARY_BOOT,
159 &secondary_boot_addr)) {
160 pr_warn("%s: no" OF_SECONDARY_BOOT "property\n",
161 cpu_node->name);
162 ret = -ENOENT;
163 goto out;
164 }
165 }
166 }
167
168 /*
169 * Enable the SCU on Cortex A9 based SoCs. If -ENOENT is
170 * returned, the SoC reported a uniprocessor configuration.
171 * We bail on any other error.
172 */
173 ret = scu_a9_enable();
174out:
175 of_node_put(cpu_node);
176 of_node_put(cpus_node);
177 135
178 if (ret) { 136 /* Enable the SCU on Cortex A9 based SoCs */
137 if (scu_a9_enable()) {
179 /* Update the CPU present map to reflect uniprocessor mode */ 138 /* Update the CPU present map to reflect uniprocessor mode */
180 pr_warn("disabling SMP\n"); 139 pr_warn("failed to enable A9 SCU - disabling SMP\n");
181 init_cpu_present(&only_cpu_0); 140 init_cpu_present(&only_cpu_0);
182 } 141 }
183} 142}
@@ -208,6 +167,7 @@ static int kona_boot_secondary(unsigned int cpu, struct task_struct *idle)
208 u32 cpu_id; 167 u32 cpu_id;
209 u32 boot_val; 168 u32 boot_val;
210 bool timeout = false; 169 bool timeout = false;
170 const u32 secondary_boot_addr = secondary_boot_addr_for(cpu);
211 171
212 cpu_id = cpu_logical_map(cpu); 172 cpu_id = cpu_logical_map(cpu);
213 if (cpu_id & ~BOOT_ADDR_CPUID_MASK) { 173 if (cpu_id & ~BOOT_ADDR_CPUID_MASK) {
@@ -215,13 +175,11 @@ static int kona_boot_secondary(unsigned int cpu, struct task_struct *idle)
215 return -EINVAL; 175 return -EINVAL;
216 } 176 }
217 177
218 if (!secondary_boot_addr) { 178 if (!secondary_boot_addr)
219 pr_err("required secondary boot register not specified\n");
220 return -EINVAL; 179 return -EINVAL;
221 }
222 180
223 boot_reg = ioremap_nocache( 181 boot_reg = ioremap_nocache((phys_addr_t)secondary_boot_addr,
224 (phys_addr_t)secondary_boot_addr, sizeof(u32)); 182 sizeof(phys_addr_t));
225 if (!boot_reg) { 183 if (!boot_reg) {
226 pr_err("unable to map boot register for cpu %u\n", cpu_id); 184 pr_err("unable to map boot register for cpu %u\n", cpu_id);
227 return -ENOMEM; 185 return -ENOMEM;
@@ -315,7 +273,7 @@ static int nsp_boot_secondary(unsigned int cpu, struct task_struct *idle)
315 * After wake up, secondary core branches to the startup 273 * After wake up, secondary core branches to the startup
316 * address programmed at SKU ROM LUT location. 274 * address programmed at SKU ROM LUT location.
317 */ 275 */
318 ret = nsp_write_lut(); 276 ret = nsp_write_lut(cpu);
319 if (ret) { 277 if (ret) {
320 pr_err("unable to write startup addr to SKU ROM LUT\n"); 278 pr_err("unable to write startup addr to SKU ROM LUT\n");
321 goto out; 279 goto out;
@@ -328,12 +286,12 @@ out:
328 return ret; 286 return ret;
329} 287}
330 288
331static const struct smp_operations bcm_smp_ops __initconst = { 289static const struct smp_operations kona_smp_ops __initconst = {
332 .smp_prepare_cpus = bcm_smp_prepare_cpus, 290 .smp_prepare_cpus = bcm_smp_prepare_cpus,
333 .smp_boot_secondary = kona_boot_secondary, 291 .smp_boot_secondary = kona_boot_secondary,
334}; 292};
335CPU_METHOD_OF_DECLARE(bcm_smp_bcm281xx, "brcm,bcm11351-cpu-method", 293CPU_METHOD_OF_DECLARE(bcm_smp_bcm281xx, "brcm,bcm11351-cpu-method",
336 &bcm_smp_ops); 294 &kona_smp_ops);
337 295
338static const struct smp_operations bcm23550_smp_ops __initconst = { 296static const struct smp_operations bcm23550_smp_ops __initconst = {
339 .smp_boot_secondary = bcm23550_boot_secondary, 297 .smp_boot_secondary = bcm23550_boot_secondary,