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
7 commit 88bbe85dcd37aa2662c1a83962c15009fc12503e upstream.
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.
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>
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
28 --- a/arch/arm/mach-bcm/Makefile
29 +++ b/arch/arm/mach-bcm/Makefile
30 @@ -43,6 +43,11 @@ endif
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
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
45 #include <asm/mach/arch.h>
46 #include <asm/mach/map.h>
49 #include <linux/dma-mapping.h>
51 static void __init bcm2835_init(void)
52 @@ -49,6 +50,7 @@ static const char * const bcm2835_compat
54 #ifdef CONFIG_ARCH_MULTI_V7
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),
68 --- a/arch/arm/mach-bcm/platsmp.c
69 +++ b/arch/arm/mach-bcm/platsmp.c
71 #include <linux/errno.h>
72 #include <linux/init.h>
74 +#include <linux/irqchip/irq-bcm2836.h>
75 #include <linux/jiffies.h>
77 #include <linux/of_address.h>
78 @@ -287,6 +288,35 @@ out:
82 +static int bcm2836_boot_secondary(unsigned int cpu, struct task_struct *idle)
84 + void __iomem *intc_base;
85 + struct device_node *dn;
88 + name = "brcm,bcm2836-l1-intc";
89 + dn = of_find_compatible_node(NULL, NULL, name);
91 + pr_err("unable to find intc node\n");
95 + intc_base = of_iomap(dn, 0);
99 + pr_err("unable to remap intc base register\n");
103 + writel(virt_to_phys(secondary_startup),
104 + intc_base + LOCAL_MAILBOX3_SET0 + 16 * cpu);
106 + iounmap(intc_base);
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,
117 CPU_METHOD_OF_DECLARE(bcm_smp_nsp, "brcm,bcm-nsp-smp", &nsp_smp_ops);
119 +const struct smp_operations bcm2836_smp_ops __initconst = {
120 + .smp_boot_secondary = bcm2836_boot_secondary,
122 +CPU_METHOD_OF_DECLARE(bcm_smp_bcm2836, "brcm,bcm2836-smp", &bcm2836_smp_ops);
124 +++ b/arch/arm/mach-bcm/platsmp.h
127 + * Copyright (C) 2017 Stefan Wahren <stefan.wahren@i2se.com>
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.
135 +extern const struct smp_operations bcm2836_smp_ops;
136 --- a/drivers/irqchip/irq-bcm2836.c
137 +++ b/drivers/irqchip/irq-bcm2836.c
139 #include <linux/of_irq.h>
140 #include <linux/irqchip.h>
141 #include <linux/irqdomain.h>
142 -#include <asm/exception.h>
144 -#define LOCAL_CONTROL 0x000
145 -#define LOCAL_PRESCALER 0x008
146 +#include <linux/irqchip/irq-bcm2836.h>
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.
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
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
162 -#define LOCAL_TIMER_INT_CONTROL0 0x040
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).
168 -#define LOCAL_MAILBOX_INT_CONTROL0 0x050
170 - * The CPU's interrupt status register. Bits are defined by the the
171 - * LOCAL_IRQ_* bits below.
173 -#define LOCAL_IRQ_PENDING0 0x060
174 -/* Same status bits as above, but for FIQ. */
175 -#define LOCAL_FIQ_PENDING0 0x070
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
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
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>
201 struct bcm2836_arm_irqchip_intc {
202 struct irq_domain *domain;
203 @@ -240,27 +187,6 @@ static int bcm2836_cpu_dying(unsigned in
209 -static int __init bcm2836_smp_boot_secondary(unsigned int cpu,
210 - struct task_struct *idle)
212 - unsigned long secondary_startup_phys =
213 - (unsigned long)virt_to_phys((void *)secondary_startup);
215 - writel(secondary_startup_phys,
216 - intc.base + LOCAL_MAILBOX3_SET0 + 16 * cpu);
218 - dsb(sy); /* Ensure write has completed before waking the other CPUs */
224 -static const struct smp_operations bcm2836_smp_ops __initconst = {
225 - .smp_boot_secondary = bcm2836_smp_boot_secondary,
230 static const struct irq_domain_ops bcm2836_arm_irqchip_intc_ops = {
231 @@ -277,10 +203,6 @@ bcm2836_arm_irqchip_smp_init(void)
234 set_smp_cross_call(bcm2836_arm_irqchip_send_ipi);
237 - smp_set_ops(&bcm2836_smp_ops);
243 +++ b/include/linux/irqchip/irq-bcm2836.h
246 + * Root interrupt controller for the BCM2836 (Raspberry Pi 2).
248 + * Copyright 2015 Broadcom
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.
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.
261 +#define LOCAL_CONTROL 0x000
262 +#define LOCAL_PRESCALER 0x008
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.
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
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
278 +#define LOCAL_TIMER_INT_CONTROL0 0x040
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).
284 +#define LOCAL_MAILBOX_INT_CONTROL0 0x050
286 + * The CPU's interrupt status register. Bits are defined by the the
287 + * LOCAL_IRQ_* bits below.
289 +#define LOCAL_IRQ_PENDING0 0x060
290 +/* Same status bits as above, but for FIQ. */
291 +#define LOCAL_FIQ_PENDING0 0x070
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
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
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