5fc584f1b13818a128cf0368668bfdf0902ca222
[oweals/openwrt.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