aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-bcm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-bcm')
-rw-r--r--arch/arm/mach-bcm/Kconfig96
-rw-r--r--arch/arm/mach-bcm/Makefile5
-rw-r--r--arch/arm/mach-bcm/bcm_cygnus.c25
-rw-r--r--arch/arm/mach-bcm/brcmstb.h19
-rw-r--r--arch/arm/mach-bcm/headsmp-brcmstb.S33
-rw-r--r--arch/arm/mach-bcm/platsmp-brcmstb.c329
6 files changed, 468 insertions, 39 deletions
diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig
index 2abad742516d..1bd39b45d08b 100644
--- a/arch/arm/mach-bcm/Kconfig
+++ b/arch/arm/mach-bcm/Kconfig
@@ -5,8 +5,56 @@ menuconfig ARCH_BCM
5 5
6if ARCH_BCM 6if ARCH_BCM
7 7
8comment "IPROC architected SoCs"
9
10config ARCH_BCM_IPROC
11 bool
12 select ARM_GIC
13 select CACHE_L2X0
14 select HAVE_ARM_SCU if SMP
15 select HAVE_ARM_TWD if SMP
16 select ARM_GLOBAL_TIMER
17
18 select CLKSRC_MMIO
19 select ARCH_REQUIRE_GPIOLIB
20 select ARM_AMBA
21 select PINCTRL
22 help
23 This enables support for systems based on Broadcom IPROC architected SoCs.
24 The IPROC complex contains one or more ARM CPUs along with common
25 core periperals. Application specific SoCs are created by adding a
26 uArchitecture containing peripherals outside of the IPROC complex.
27 Currently supported SoCs are Cygnus.
28
29config ARCH_BCM_CYGNUS
30 bool "Broadcom Cygnus Support" if ARCH_MULTI_V7
31 select ARCH_BCM_IPROC
32 help
33 Enable support for the Cygnus family,
34 which includes the following variants:
35 BCM11300, BCM11320, BCM11350, BCM11360,
36 BCM58300, BCM58302, BCM58303, BCM58305.
37
38config ARCH_BCM_5301X
39 bool "Broadcom BCM470X / BCM5301X ARM SoC" if ARCH_MULTI_V7
40 select ARCH_BCM_IPROC
41 help
42 Support for Broadcom BCM470X and BCM5301X SoCs with ARM CPU cores.
43
44 This is a network SoC line mostly used in home routers and
45 wifi access points, it's internal name is Northstar.
46 This inclused the following SoC: BCM53010, BCM53011, BCM53012,
47 BCM53014, BCM53015, BCM53016, BCM53017, BCM53018, BCM4707,
48 BCM4708 and BCM4709.
49
50 Do not confuse this with the BCM4760 which is a totally
51 different SoC or with the older BCM47XX and BCM53XX based
52 network SoC using a MIPS CPU, they are supported by arch/mips/bcm47xx
53
54comment "KONA architected SoCs"
55
8config ARCH_BCM_MOBILE 56config ARCH_BCM_MOBILE
9 bool "Broadcom Mobile SoC Support" if ARCH_MULTI_V7 57 bool
10 select ARCH_REQUIRE_GPIOLIB 58 select ARCH_REQUIRE_GPIOLIB
11 select ARM_ERRATA_754322 59 select ARM_ERRATA_754322
12 select ARM_ERRATA_775420 60 select ARM_ERRATA_775420
@@ -15,16 +63,13 @@ config ARCH_BCM_MOBILE
15 select TICK_ONESHOT 63 select TICK_ONESHOT
16 select HAVE_ARM_ARCH_TIMER 64 select HAVE_ARM_ARCH_TIMER
17 select PINCTRL 65 select PINCTRL
66 select ARCH_BCM_MOBILE_SMP if SMP
18 help 67 help
19 This enables support for systems based on Broadcom mobile SoCs. 68 This enables support for systems based on Broadcom mobile SoCs.
20 69
21if ARCH_BCM_MOBILE
22
23menu "Broadcom Mobile SoC Selection"
24
25config ARCH_BCM_281XX 70config ARCH_BCM_281XX
26 bool "Broadcom BCM281XX SoC family" 71 bool "Broadcom BCM281XX SoC family"
27 default y 72 select ARCH_BCM_MOBILE
28 select HAVE_SMP 73 select HAVE_SMP
29 help 74 help
30 Enable support for the BCM281XX family, which includes 75 Enable support for the BCM281XX family, which includes
@@ -33,7 +78,7 @@ config ARCH_BCM_281XX
33 78
34config ARCH_BCM_21664 79config ARCH_BCM_21664
35 bool "Broadcom BCM21664 SoC family" 80 bool "Broadcom BCM21664 SoC family"
36 default y 81 select ARCH_BCM_MOBILE
37 select HAVE_SMP 82 select HAVE_SMP
38 help 83 help
39 Enable support for the BCM21664 family, which includes 84 Enable support for the BCM21664 family, which includes
@@ -41,19 +86,18 @@ config ARCH_BCM_21664
41 86
42config ARCH_BCM_MOBILE_L2_CACHE 87config ARCH_BCM_MOBILE_L2_CACHE
43 bool "Broadcom mobile SoC level 2 cache support" 88 bool "Broadcom mobile SoC level 2 cache support"
44 depends on (ARCH_BCM_281XX || ARCH_BCM_21664) 89 depends on ARCH_BCM_MOBILE
45 default y 90 default y
46 select CACHE_L2X0 91 select CACHE_L2X0
47 select ARCH_BCM_MOBILE_SMC 92 select ARCH_BCM_MOBILE_SMC
48 93
49config ARCH_BCM_MOBILE_SMC 94config ARCH_BCM_MOBILE_SMC
50 bool 95 bool
51 depends on ARCH_BCM_281XX || ARCH_BCM_21664 96 depends on ARCH_BCM_MOBILE
52 97
53config ARCH_BCM_MOBILE_SMP 98config ARCH_BCM_MOBILE_SMP
54 bool "Broadcom mobile SoC SMP support" 99 bool
55 depends on (ARCH_BCM_281XX || ARCH_BCM_21664) && SMP 100 depends on ARCH_BCM_MOBILE
56 default y
57 select HAVE_ARM_SCU 101 select HAVE_ARM_SCU
58 select ARM_ERRATA_764369 102 select ARM_ERRATA_764369
59 help 103 help
@@ -61,9 +105,7 @@ config ARCH_BCM_MOBILE_SMP
61 Provided as an option so SMP support for SoCs of this type 105 Provided as an option so SMP support for SoCs of this type
62 can be disabled for an SMP-enabled kernel. 106 can be disabled for an SMP-enabled kernel.
63 107
64endmenu 108comment "Other Architectures"
65
66endif
67 109
68config ARCH_BCM2835 110config ARCH_BCM2835
69 bool "Broadcom BCM2835 family" if ARCH_MULTI_V6 111 bool "Broadcom BCM2835 family" if ARCH_MULTI_V6
@@ -78,27 +120,6 @@ config ARCH_BCM2835
78 This enables support for the Broadcom BCM2835 SoC. This SoC is 120 This enables support for the Broadcom BCM2835 SoC. This SoC is
79 used in the Raspberry Pi and Roku 2 devices. 121 used in the Raspberry Pi and Roku 2 devices.
80 122
81config ARCH_BCM_5301X
82 bool "Broadcom BCM470X / BCM5301X ARM SoC" if ARCH_MULTI_V7
83 select ARM_GIC
84 select CACHE_L2X0
85 select HAVE_ARM_SCU if SMP
86 select HAVE_ARM_TWD if SMP
87 select ARM_GLOBAL_TIMER
88 select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
89 help
90 Support for Broadcom BCM470X and BCM5301X SoCs with ARM CPU cores.
91
92 This is a network SoC line mostly used in home routers and
93 wifi access points, it's internal name is Northstar.
94 This inclused the following SoC: BCM53010, BCM53011, BCM53012,
95 BCM53014, BCM53015, BCM53016, BCM53017, BCM53018, BCM4707,
96 BCM4708 and BCM4709.
97
98 Do not confuse this with the BCM4760 which is a totally
99 different SoC or with the older BCM47XX and BCM53XX based
100 network SoC using a MIPS CPU, they are supported by arch/mips/bcm47xx
101
102config ARCH_BCM_63XX 123config ARCH_BCM_63XX
103 bool "Broadcom BCM63xx DSL SoC" if ARCH_MULTI_V7 124 bool "Broadcom BCM63xx DSL SoC" if ARCH_MULTI_V7
104 depends on MMU 125 depends on MMU
@@ -118,10 +139,7 @@ config ARCH_BCM_63XX
118 139
119config ARCH_BRCMSTB 140config ARCH_BRCMSTB
120 bool "Broadcom BCM7XXX based boards" if ARCH_MULTI_V7 141 bool "Broadcom BCM7XXX based boards" if ARCH_MULTI_V7
121 depends on MMU
122 select ARM_GIC 142 select ARM_GIC
123 select MIGHT_HAVE_PCI
124 select HAVE_SMP
125 select HAVE_ARM_ARCH_TIMER 143 select HAVE_ARM_ARCH_TIMER
126 select BRCMSTB_GISB_ARB 144 select BRCMSTB_GISB_ARB
127 select BRCMSTB_L2_IRQ 145 select BRCMSTB_L2_IRQ
diff --git a/arch/arm/mach-bcm/Makefile b/arch/arm/mach-bcm/Makefile
index 300ae4b79ae6..4c38674c73ec 100644
--- a/arch/arm/mach-bcm/Makefile
+++ b/arch/arm/mach-bcm/Makefile
@@ -10,6 +10,9 @@
10# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details. 11# GNU General Public License for more details.
12 12
13# Cygnus
14obj-$(CONFIG_ARCH_BCM_CYGNUS) += bcm_cygnus.o
15
13# BCM281XX 16# BCM281XX
14obj-$(CONFIG_ARCH_BCM_281XX) += board_bcm281xx.o 17obj-$(CONFIG_ARCH_BCM_281XX) += board_bcm281xx.o
15 18
@@ -38,5 +41,7 @@ obj-$(CONFIG_ARCH_BCM_5301X) += bcm_5301x.o
38obj-$(CONFIG_ARCH_BCM_63XX) := bcm63xx.o 41obj-$(CONFIG_ARCH_BCM_63XX) := bcm63xx.o
39 42
40ifeq ($(CONFIG_ARCH_BRCMSTB),y) 43ifeq ($(CONFIG_ARCH_BRCMSTB),y)
44CFLAGS_platsmp-brcmstb.o += -march=armv7-a
41obj-y += brcmstb.o 45obj-y += brcmstb.o
46obj-$(CONFIG_SMP) += headsmp-brcmstb.o platsmp-brcmstb.o
42endif 47endif
diff --git a/arch/arm/mach-bcm/bcm_cygnus.c b/arch/arm/mach-bcm/bcm_cygnus.c
new file mode 100644
index 000000000000..30dc58be51b8
--- /dev/null
+++ b/arch/arm/mach-bcm/bcm_cygnus.c
@@ -0,0 +1,25 @@
1/*
2 * Copyright (C) 2014 Broadcom Corporation
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation version 2.
7 *
8 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
9 * kind, whether express or implied; without even the implied warranty
10 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <asm/mach/arch.h>
15
16static const char const *bcm_cygnus_dt_compat[] = {
17 "brcm,cygnus",
18 NULL,
19};
20
21DT_MACHINE_START(BCM_CYGNUS_DT, "Broadcom Cygnus SoC")
22 .l2c_aux_val = 0,
23 .l2c_aux_mask = ~0,
24 .dt_compat = bcm_cygnus_dt_compat,
25MACHINE_END
diff --git a/arch/arm/mach-bcm/brcmstb.h b/arch/arm/mach-bcm/brcmstb.h
new file mode 100644
index 000000000000..ec0c3d112b36
--- /dev/null
+++ b/arch/arm/mach-bcm/brcmstb.h
@@ -0,0 +1,19 @@
1/*
2 * Copyright (C) 2013-2014 Broadcom Corporation
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation version 2.
7 *
8 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
9 * kind, whether express or implied; without even the implied warranty
10 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#ifndef __BRCMSTB_H__
15#define __BRCMSTB_H__
16
17void brcmstb_secondary_startup(void);
18
19#endif /* __BRCMSTB_H__ */
diff --git a/arch/arm/mach-bcm/headsmp-brcmstb.S b/arch/arm/mach-bcm/headsmp-brcmstb.S
new file mode 100644
index 000000000000..199c1ea58248
--- /dev/null
+++ b/arch/arm/mach-bcm/headsmp-brcmstb.S
@@ -0,0 +1,33 @@
1/*
2 * SMP boot code for secondary CPUs
3 * Based on arch/arm/mach-tegra/headsmp.S
4 *
5 * Copyright (C) 2010 NVIDIA, Inc.
6 * Copyright (C) 2013-2014 Broadcom Corporation
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation version 2.
11 *
12 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
13 * kind, whether express or implied; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include <asm/assembler.h>
19#include <linux/linkage.h>
20#include <linux/init.h>
21
22 .section ".text.head", "ax"
23
24ENTRY(brcmstb_secondary_startup)
25 /*
26 * Ensure CPU is in a sane state by disabling all IRQs and switching
27 * into SVC mode.
28 */
29 setmode PSR_I_BIT | PSR_F_BIT | SVC_MODE, r0
30
31 bl v7_invalidate_l1
32 b secondary_startup
33ENDPROC(brcmstb_secondary_startup)
diff --git a/arch/arm/mach-bcm/platsmp-brcmstb.c b/arch/arm/mach-bcm/platsmp-brcmstb.c
new file mode 100644
index 000000000000..31c87a284a34
--- /dev/null
+++ b/arch/arm/mach-bcm/platsmp-brcmstb.c
@@ -0,0 +1,329 @@
1/*
2 * Broadcom STB CPU SMP and hotplug support for ARM
3 *
4 * Copyright (C) 2013-2014 Broadcom Corporation
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation version 2.
9 *
10 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
11 * kind, whether express or implied; without even the implied warranty
12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/delay.h>
17#include <linux/errno.h>
18#include <linux/init.h>
19#include <linux/io.h>
20#include <linux/of_address.h>
21#include <linux/of_platform.h>
22#include <linux/printk.h>
23#include <linux/regmap.h>
24#include <linux/smp.h>
25#include <linux/mfd/syscon.h>
26
27#include <asm/cacheflush.h>
28#include <asm/cp15.h>
29#include <asm/mach-types.h>
30#include <asm/smp_plat.h>
31
32#include "brcmstb.h"
33
34enum {
35 ZONE_MAN_CLKEN_MASK = BIT(0),
36 ZONE_MAN_RESET_CNTL_MASK = BIT(1),
37 ZONE_MAN_MEM_PWR_MASK = BIT(4),
38 ZONE_RESERVED_1_MASK = BIT(5),
39 ZONE_MAN_ISO_CNTL_MASK = BIT(6),
40 ZONE_MANUAL_CONTROL_MASK = BIT(7),
41 ZONE_PWR_DN_REQ_MASK = BIT(9),
42 ZONE_PWR_UP_REQ_MASK = BIT(10),
43 ZONE_BLK_RST_ASSERT_MASK = BIT(12),
44 ZONE_PWR_OFF_STATE_MASK = BIT(25),
45 ZONE_PWR_ON_STATE_MASK = BIT(26),
46 ZONE_DPG_PWR_STATE_MASK = BIT(28),
47 ZONE_MEM_PWR_STATE_MASK = BIT(29),
48 ZONE_RESET_STATE_MASK = BIT(31),
49 CPU0_PWR_ZONE_CTRL_REG = 1,
50 CPU_RESET_CONFIG_REG = 2,
51};
52
53static void __iomem *cpubiuctrl_block;
54static void __iomem *hif_cont_block;
55static u32 cpu0_pwr_zone_ctrl_reg;
56static u32 cpu_rst_cfg_reg;
57static u32 hif_cont_reg;
58
59#ifdef CONFIG_HOTPLUG_CPU
60/*
61 * We must quiesce a dying CPU before it can be killed by the boot CPU. Because
62 * one or more cache may be disabled, we must flush to ensure coherency. We
63 * cannot use traditionl completion structures or spinlocks as they rely on
64 * coherency.
65 */
66static DEFINE_PER_CPU_ALIGNED(int, per_cpu_sw_state);
67
68static int per_cpu_sw_state_rd(u32 cpu)
69{
70 sync_cache_r(SHIFT_PERCPU_PTR(&per_cpu_sw_state, per_cpu_offset(cpu)));
71 return per_cpu(per_cpu_sw_state, cpu);
72}
73
74static void per_cpu_sw_state_wr(u32 cpu, int val)
75{
76 dmb();
77 per_cpu(per_cpu_sw_state, cpu) = val;
78 sync_cache_w(SHIFT_PERCPU_PTR(&per_cpu_sw_state, per_cpu_offset(cpu)));
79}
80#else
81static inline void per_cpu_sw_state_wr(u32 cpu, int val) { }
82#endif
83
84static void __iomem *pwr_ctrl_get_base(u32 cpu)
85{
86 void __iomem *base = cpubiuctrl_block + cpu0_pwr_zone_ctrl_reg;
87 base += (cpu_logical_map(cpu) * 4);
88 return base;
89}
90
91static u32 pwr_ctrl_rd(u32 cpu)
92{
93 void __iomem *base = pwr_ctrl_get_base(cpu);
94 return readl_relaxed(base);
95}
96
97static void pwr_ctrl_wr(u32 cpu, u32 val)
98{
99 void __iomem *base = pwr_ctrl_get_base(cpu);
100 writel(val, base);
101}
102
103static void cpu_rst_cfg_set(u32 cpu, int set)
104{
105 u32 val;
106 val = readl_relaxed(cpubiuctrl_block + cpu_rst_cfg_reg);
107 if (set)
108 val |= BIT(cpu_logical_map(cpu));
109 else
110 val &= ~BIT(cpu_logical_map(cpu));
111 writel_relaxed(val, cpubiuctrl_block + cpu_rst_cfg_reg);
112}
113
114static void cpu_set_boot_addr(u32 cpu, unsigned long boot_addr)
115{
116 const int reg_ofs = cpu_logical_map(cpu) * 8;
117 writel_relaxed(0, hif_cont_block + hif_cont_reg + reg_ofs);
118 writel_relaxed(boot_addr, hif_cont_block + hif_cont_reg + 4 + reg_ofs);
119}
120
121static void brcmstb_cpu_boot(u32 cpu)
122{
123 /* Mark this CPU as "up" */
124 per_cpu_sw_state_wr(cpu, 1);
125
126 /*
127 * Set the reset vector to point to the secondary_startup
128 * routine
129 */
130 cpu_set_boot_addr(cpu, virt_to_phys(brcmstb_secondary_startup));
131
132 /* Unhalt the cpu */
133 cpu_rst_cfg_set(cpu, 0);
134}
135
136static void brcmstb_cpu_power_on(u32 cpu)
137{
138 /*
139 * The secondary cores power was cut, so we must go through
140 * power-on initialization.
141 */
142 u32 tmp;
143
144 /* Request zone power up */
145 pwr_ctrl_wr(cpu, ZONE_PWR_UP_REQ_MASK);
146
147 /* Wait for the power up FSM to complete */
148 do {
149 tmp = pwr_ctrl_rd(cpu);
150 } while (!(tmp & ZONE_PWR_ON_STATE_MASK));
151}
152
153static int brcmstb_cpu_get_power_state(u32 cpu)
154{
155 int tmp = pwr_ctrl_rd(cpu);
156 return (tmp & ZONE_RESET_STATE_MASK) ? 0 : 1;
157}
158
159#ifdef CONFIG_HOTPLUG_CPU
160
161static void brcmstb_cpu_die(u32 cpu)
162{
163 v7_exit_coherency_flush(all);
164
165 per_cpu_sw_state_wr(cpu, 0);
166
167 /* Sit and wait to die */
168 wfi();
169
170 /* We should never get here... */
171 while (1)
172 ;
173}
174
175static int brcmstb_cpu_kill(u32 cpu)
176{
177 u32 tmp;
178
179 while (per_cpu_sw_state_rd(cpu))
180 ;
181
182 /* Program zone reset */
183 pwr_ctrl_wr(cpu, ZONE_RESET_STATE_MASK | ZONE_BLK_RST_ASSERT_MASK |
184 ZONE_PWR_DN_REQ_MASK);
185
186 /* Verify zone reset */
187 tmp = pwr_ctrl_rd(cpu);
188 if (!(tmp & ZONE_RESET_STATE_MASK))
189 pr_err("%s: Zone reset bit for CPU %d not asserted!\n",
190 __func__, cpu);
191
192 /* Wait for power down */
193 do {
194 tmp = pwr_ctrl_rd(cpu);
195 } while (!(tmp & ZONE_PWR_OFF_STATE_MASK));
196
197 /* Flush pipeline before resetting CPU */
198 mb();
199
200 /* Assert reset on the CPU */
201 cpu_rst_cfg_set(cpu, 1);
202
203 return 1;
204}
205
206#endif /* CONFIG_HOTPLUG_CPU */
207
208static int __init setup_hifcpubiuctrl_regs(struct device_node *np)
209{
210 int rc = 0;
211 char *name;
212 struct device_node *syscon_np = NULL;
213
214 name = "syscon-cpu";
215
216 syscon_np = of_parse_phandle(np, name, 0);
217 if (!syscon_np) {
218 pr_err("can't find phandle %s\n", name);
219 rc = -EINVAL;
220 goto cleanup;
221 }
222
223 cpubiuctrl_block = of_iomap(syscon_np, 0);
224 if (!cpubiuctrl_block) {
225 pr_err("iomap failed for cpubiuctrl_block\n");
226 rc = -EINVAL;
227 goto cleanup;
228 }
229
230 rc = of_property_read_u32_index(np, name, CPU0_PWR_ZONE_CTRL_REG,
231 &cpu0_pwr_zone_ctrl_reg);
232 if (rc) {
233 pr_err("failed to read 1st entry from %s property (%d)\n", name,
234 rc);
235 rc = -EINVAL;
236 goto cleanup;
237 }
238
239 rc = of_property_read_u32_index(np, name, CPU_RESET_CONFIG_REG,
240 &cpu_rst_cfg_reg);
241 if (rc) {
242 pr_err("failed to read 2nd entry from %s property (%d)\n", name,
243 rc);
244 rc = -EINVAL;
245 goto cleanup;
246 }
247
248cleanup:
249 of_node_put(syscon_np);
250 return rc;
251}
252
253static int __init setup_hifcont_regs(struct device_node *np)
254{
255 int rc = 0;
256 char *name;
257 struct device_node *syscon_np = NULL;
258
259 name = "syscon-cont";
260
261 syscon_np = of_parse_phandle(np, name, 0);
262 if (!syscon_np) {
263 pr_err("can't find phandle %s\n", name);
264 rc = -EINVAL;
265 goto cleanup;
266 }
267
268 hif_cont_block = of_iomap(syscon_np, 0);
269 if (!hif_cont_block) {
270 pr_err("iomap failed for hif_cont_block\n");
271 rc = -EINVAL;
272 goto cleanup;
273 }
274
275 /* Offset is at top of hif_cont_block */
276 hif_cont_reg = 0;
277
278cleanup:
279 of_node_put(syscon_np);
280 return rc;
281}
282
283static void __init brcmstb_cpu_ctrl_setup(unsigned int max_cpus)
284{
285 int rc;
286 struct device_node *np;
287 char *name;
288
289 name = "brcm,brcmstb-smpboot";
290 np = of_find_compatible_node(NULL, NULL, name);
291 if (!np) {
292 pr_err("can't find compatible node %s\n", name);
293 return;
294 }
295
296 rc = setup_hifcpubiuctrl_regs(np);
297 if (rc)
298 return;
299
300 rc = setup_hifcont_regs(np);
301 if (rc)
302 return;
303}
304
305static int brcmstb_boot_secondary(unsigned int cpu, struct task_struct *idle)
306{
307 /* Missing the brcm,brcmstb-smpboot DT node? */
308 if (!cpubiuctrl_block || !hif_cont_block)
309 return -ENODEV;
310
311 /* Bring up power to the core if necessary */
312 if (brcmstb_cpu_get_power_state(cpu) == 0)
313 brcmstb_cpu_power_on(cpu);
314
315 brcmstb_cpu_boot(cpu);
316
317 return 0;
318}
319
320static struct smp_operations brcmstb_smp_ops __initdata = {
321 .smp_prepare_cpus = brcmstb_cpu_ctrl_setup,
322 .smp_boot_secondary = brcmstb_boot_secondary,
323#ifdef CONFIG_HOTPLUG_CPU
324 .cpu_kill = brcmstb_cpu_kill,
325 .cpu_die = brcmstb_cpu_die,
326#endif
327};
328
329CPU_METHOD_OF_DECLARE(brcmstb_smp, "brcm,brahma-b15", &brcmstb_smp_ops);