5fc584f1b13818a128cf0368668bfdf0902ca222
[openwrt/staging/luka.git] /
1 From 827d93b06aefb4fd03f9a6a0c3774a14fd5bd291 Mon Sep 17 00:00:00 2001
2 From: Stefan Wahren <stefan.wahren@i2se.com>
3 Date: Sun, 6 Aug 2017 17:52:02 +0200
4 Subject: [PATCH 245/454] irqchip: bcm2836: Move SMP startup code to arch/arm
5 (v2)
6
7 commit 88bbe85dcd37aa2662c1a83962c15009fc12503e upstream.
8
9 In order to easily provide SMP for BCM2837 on 32-bit and 64-bit
10 the SMP startup code was placed in irq-bcm2836. That's not the
11 right approach. So move this code where it belongs.
12
13 Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
14 Fixes: 41f4988cc287 ("irqchip/bcm2836: Add SMP support for the 2836")
15 Tested-by: Eric Anholt <eric@anholt.net>
16 Acked-by: Marc Zyngier <marc.zyngier@arm.com>
17 ---
18 arch/arm/mach-bcm/Makefile | 5 ++
19 arch/arm/mach-bcm/board_bcm2835.c | 5 +-
20 arch/arm/mach-bcm/platsmp.c | 35 ++++++++++++
21 arch/arm/mach-bcm/platsmp.h | 10 ++++
22 drivers/irqchip/irq-bcm2836.c | 82 +----------------------------
23 include/linux/irqchip/irq-bcm2836.h | 70 ++++++++++++++++++++++++
24 6 files changed, 126 insertions(+), 81 deletions(-)
25 create mode 100644 arch/arm/mach-bcm/platsmp.h
26 create mode 100644 include/linux/irqchip/irq-bcm2836.h
27
28 --- a/arch/arm/mach-bcm/Makefile
29 +++ b/arch/arm/mach-bcm/Makefile
30 @@ -43,6 +43,11 @@ endif
31
32 # BCM2835
33 obj-$(CONFIG_ARCH_BCM2835) += board_bcm2835.o
34 +ifeq ($(CONFIG_ARCH_BCM2835),y)
35 +ifeq ($(CONFIG_ARM),y)
36 +obj-$(CONFIG_SMP) += platsmp.o
37 +endif
38 +endif
39
40 # BCM5301X
41 obj-$(CONFIG_ARCH_BCM_5301X) += bcm_5301x.o
42 --- a/arch/arm/mach-bcm/board_bcm2835.c
43 +++ b/arch/arm/mach-bcm/board_bcm2835.c
44 @@ -21,6 +21,7 @@
45 #include <asm/mach/arch.h>
46 #include <asm/mach/map.h>
47
48 +#include "platsmp.h"
49 #include <linux/dma-mapping.h>
50
51 static void __init bcm2835_init(void)
52 @@ -49,6 +50,7 @@ static const char * const bcm2835_compat
53 #endif
54 #ifdef CONFIG_ARCH_MULTI_V7
55 "brcm,bcm2836",
56 + "brcm,bcm2837",
57 #endif
58 NULL
59 };
60 @@ -56,5 +58,6 @@ static const char * const bcm2835_compat
61 DT_MACHINE_START(BCM2835, "BCM2835")
62 .init_machine = bcm2835_init,
63 .init_early = bcm2835_init_early,
64 - .dt_compat = bcm2835_compat
65 + .dt_compat = bcm2835_compat,
66 + .smp = smp_ops(bcm2836_smp_ops),
67 MACHINE_END
68 --- a/arch/arm/mach-bcm/platsmp.c
69 +++ b/arch/arm/mach-bcm/platsmp.c
70 @@ -17,6 +17,7 @@
71 #include <linux/errno.h>
72 #include <linux/init.h>
73 #include <linux/io.h>
74 +#include <linux/irqchip/irq-bcm2836.h>
75 #include <linux/jiffies.h>
76 #include <linux/of.h>
77 #include <linux/of_address.h>
78 @@ -287,6 +288,35 @@ out:
79 return ret;
80 }
81
82 +static int bcm2836_boot_secondary(unsigned int cpu, struct task_struct *idle)
83 +{
84 + void __iomem *intc_base;
85 + struct device_node *dn;
86 + char *name;
87 +
88 + name = "brcm,bcm2836-l1-intc";
89 + dn = of_find_compatible_node(NULL, NULL, name);
90 + if (!dn) {
91 + pr_err("unable to find intc node\n");
92 + return -ENODEV;
93 + }
94 +
95 + intc_base = of_iomap(dn, 0);
96 + of_node_put(dn);
97 +
98 + if (!intc_base) {
99 + pr_err("unable to remap intc base register\n");
100 + return -ENOMEM;
101 + }
102 +
103 + writel(virt_to_phys(secondary_startup),
104 + intc_base + LOCAL_MAILBOX3_SET0 + 16 * cpu);
105 +
106 + iounmap(intc_base);
107 +
108 + return 0;
109 +}
110 +
111 static const struct smp_operations kona_smp_ops __initconst = {
112 .smp_prepare_cpus = bcm_smp_prepare_cpus,
113 .smp_boot_secondary = kona_boot_secondary,
114 @@ -305,3 +335,8 @@ static const struct smp_operations nsp_s
115 .smp_boot_secondary = nsp_boot_secondary,
116 };
117 CPU_METHOD_OF_DECLARE(bcm_smp_nsp, "brcm,bcm-nsp-smp", &nsp_smp_ops);
118 +
119 +const struct smp_operations bcm2836_smp_ops __initconst = {
120 + .smp_boot_secondary = bcm2836_boot_secondary,
121 +};
122 +CPU_METHOD_OF_DECLARE(bcm_smp_bcm2836, "brcm,bcm2836-smp", &bcm2836_smp_ops);
123 --- /dev/null
124 +++ b/arch/arm/mach-bcm/platsmp.h
125 @@ -0,0 +1,10 @@
126 +/*
127 + * Copyright (C) 2017 Stefan Wahren <stefan.wahren@i2se.com>
128 + *
129 + * This program is free software; you can redistribute it and/or
130 + * modify it under the terms of the GNU General Public License as
131 + * published by the Free Software Foundation version 2.
132 + *
133 + */
134 +
135 +extern const struct smp_operations bcm2836_smp_ops;
136 --- a/drivers/irqchip/irq-bcm2836.c
137 +++ b/drivers/irqchip/irq-bcm2836.c
138 @@ -19,62 +19,9 @@
139 #include <linux/of_irq.h>
140 #include <linux/irqchip.h>
141 #include <linux/irqdomain.h>
142 -#include <asm/exception.h>
143 -
144 -#define LOCAL_CONTROL 0x000
145 -#define LOCAL_PRESCALER 0x008
146 +#include <linux/irqchip/irq-bcm2836.h>
147
148 -/*
149 - * The low 2 bits identify the CPU that the GPU IRQ goes to, and the
150 - * next 2 bits identify the CPU that the GPU FIQ goes to.
151 - */
152 -#define LOCAL_GPU_ROUTING 0x00c
153 -/* When setting bits 0-3, enables PMU interrupts on that CPU. */
154 -#define LOCAL_PM_ROUTING_SET 0x010
155 -/* When setting bits 0-3, disables PMU interrupts on that CPU. */
156 -#define LOCAL_PM_ROUTING_CLR 0x014
157 -/*
158 - * The low 4 bits of this are the CPU's timer IRQ enables, and the
159 - * next 4 bits are the CPU's timer FIQ enables (which override the IRQ
160 - * bits).
161 - */
162 -#define LOCAL_TIMER_INT_CONTROL0 0x040
163 -/*
164 - * The low 4 bits of this are the CPU's per-mailbox IRQ enables, and
165 - * the next 4 bits are the CPU's per-mailbox FIQ enables (which
166 - * override the IRQ bits).
167 - */
168 -#define LOCAL_MAILBOX_INT_CONTROL0 0x050
169 -/*
170 - * The CPU's interrupt status register. Bits are defined by the the
171 - * LOCAL_IRQ_* bits below.
172 - */
173 -#define LOCAL_IRQ_PENDING0 0x060
174 -/* Same status bits as above, but for FIQ. */
175 -#define LOCAL_FIQ_PENDING0 0x070
176 -/*
177 - * Mailbox write-to-set bits. There are 16 mailboxes, 4 per CPU, and
178 - * these bits are organized by mailbox number and then CPU number. We
179 - * use mailbox 0 for IPIs. The mailbox's interrupt is raised while
180 - * any bit is set.
181 - */
182 -#define LOCAL_MAILBOX0_SET0 0x080
183 -#define LOCAL_MAILBOX3_SET0 0x08c
184 -/* Mailbox write-to-clear bits. */
185 -#define LOCAL_MAILBOX0_CLR0 0x0c0
186 -#define LOCAL_MAILBOX3_CLR0 0x0cc
187 -
188 -#define LOCAL_IRQ_CNTPSIRQ 0
189 -#define LOCAL_IRQ_CNTPNSIRQ 1
190 -#define LOCAL_IRQ_CNTHPIRQ 2
191 -#define LOCAL_IRQ_CNTVIRQ 3
192 -#define LOCAL_IRQ_MAILBOX0 4
193 -#define LOCAL_IRQ_MAILBOX1 5
194 -#define LOCAL_IRQ_MAILBOX2 6
195 -#define LOCAL_IRQ_MAILBOX3 7
196 -#define LOCAL_IRQ_GPU_FAST 8
197 -#define LOCAL_IRQ_PMU_FAST 9
198 -#define LAST_IRQ LOCAL_IRQ_PMU_FAST
199 +#include <asm/exception.h>
200
201 struct bcm2836_arm_irqchip_intc {
202 struct irq_domain *domain;
203 @@ -240,27 +187,6 @@ static int bcm2836_cpu_dying(unsigned in
204 cpu);
205 return 0;
206 }
207 -
208 -#ifdef CONFIG_ARM
209 -static int __init bcm2836_smp_boot_secondary(unsigned int cpu,
210 - struct task_struct *idle)
211 -{
212 - unsigned long secondary_startup_phys =
213 - (unsigned long)virt_to_phys((void *)secondary_startup);
214 -
215 - writel(secondary_startup_phys,
216 - intc.base + LOCAL_MAILBOX3_SET0 + 16 * cpu);
217 -
218 - dsb(sy); /* Ensure write has completed before waking the other CPUs */
219 - sev();
220 -
221 - return 0;
222 -}
223 -
224 -static const struct smp_operations bcm2836_smp_ops __initconst = {
225 - .smp_boot_secondary = bcm2836_smp_boot_secondary,
226 -};
227 -#endif
228 #endif
229
230 static const struct irq_domain_ops bcm2836_arm_irqchip_intc_ops = {
231 @@ -277,10 +203,6 @@ bcm2836_arm_irqchip_smp_init(void)
232 bcm2836_cpu_dying);
233
234 set_smp_cross_call(bcm2836_arm_irqchip_send_ipi);
235 -
236 -#ifdef CONFIG_ARM
237 - smp_set_ops(&bcm2836_smp_ops);
238 -#endif
239 #endif
240 }
241
242 --- /dev/null
243 +++ b/include/linux/irqchip/irq-bcm2836.h
244 @@ -0,0 +1,70 @@
245 +/*
246 + * Root interrupt controller for the BCM2836 (Raspberry Pi 2).
247 + *
248 + * Copyright 2015 Broadcom
249 + *
250 + * This program is free software; you can redistribute it and/or modify
251 + * it under the terms of the GNU General Public License as published by
252 + * the Free Software Foundation; either version 2 of the License, or
253 + * (at your option) any later version.
254 + *
255 + * This program is distributed in the hope that it will be useful,
256 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
257 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
258 + * GNU General Public License for more details.
259 + */
260 +
261 +#define LOCAL_CONTROL 0x000
262 +#define LOCAL_PRESCALER 0x008
263 +
264 +/*
265 + * The low 2 bits identify the CPU that the GPU IRQ goes to, and the
266 + * next 2 bits identify the CPU that the GPU FIQ goes to.
267 + */
268 +#define LOCAL_GPU_ROUTING 0x00c
269 +/* When setting bits 0-3, enables PMU interrupts on that CPU. */
270 +#define LOCAL_PM_ROUTING_SET 0x010
271 +/* When setting bits 0-3, disables PMU interrupts on that CPU. */
272 +#define LOCAL_PM_ROUTING_CLR 0x014
273 +/*
274 + * The low 4 bits of this are the CPU's timer IRQ enables, and the
275 + * next 4 bits are the CPU's timer FIQ enables (which override the IRQ
276 + * bits).
277 + */
278 +#define LOCAL_TIMER_INT_CONTROL0 0x040
279 +/*
280 + * The low 4 bits of this are the CPU's per-mailbox IRQ enables, and
281 + * the next 4 bits are the CPU's per-mailbox FIQ enables (which
282 + * override the IRQ bits).
283 + */
284 +#define LOCAL_MAILBOX_INT_CONTROL0 0x050
285 +/*
286 + * The CPU's interrupt status register. Bits are defined by the the
287 + * LOCAL_IRQ_* bits below.
288 + */
289 +#define LOCAL_IRQ_PENDING0 0x060
290 +/* Same status bits as above, but for FIQ. */
291 +#define LOCAL_FIQ_PENDING0 0x070
292 +/*
293 + * Mailbox write-to-set bits. There are 16 mailboxes, 4 per CPU, and
294 + * these bits are organized by mailbox number and then CPU number. We
295 + * use mailbox 0 for IPIs. The mailbox's interrupt is raised while
296 + * any bit is set.
297 + */
298 +#define LOCAL_MAILBOX0_SET0 0x080
299 +#define LOCAL_MAILBOX3_SET0 0x08c
300 +/* Mailbox write-to-clear bits. */
301 +#define LOCAL_MAILBOX0_CLR0 0x0c0
302 +#define LOCAL_MAILBOX3_CLR0 0x0cc
303 +
304 +#define LOCAL_IRQ_CNTPSIRQ 0
305 +#define LOCAL_IRQ_CNTPNSIRQ 1
306 +#define LOCAL_IRQ_CNTHPIRQ 2
307 +#define LOCAL_IRQ_CNTVIRQ 3
308 +#define LOCAL_IRQ_MAILBOX0 4
309 +#define LOCAL_IRQ_MAILBOX1 5
310 +#define LOCAL_IRQ_MAILBOX2 6
311 +#define LOCAL_IRQ_MAILBOX3 7
312 +#define LOCAL_IRQ_GPU_FAST 8
313 +#define LOCAL_IRQ_PMU_FAST 9
314 +#define LAST_IRQ LOCAL_IRQ_PMU_FAST