aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-bcm/Makefile5
-rw-r--r--arch/arm/mach-bcm/board_bcm2835.c6
-rw-r--r--arch/arm/mach-bcm/platsmp.c35
-rw-r--r--arch/arm/mach-bcm/platsmp.h10
-rw-r--r--drivers/irqchip/irq-bcm2836.c79
-rw-r--r--include/linux/irqchip/irq-bcm2836.h70
6 files changed, 127 insertions, 78 deletions
diff --git a/arch/arm/mach-bcm/Makefile b/arch/arm/mach-bcm/Makefile
index 980f5850097c..62a59008c5a8 100644
--- a/arch/arm/mach-bcm/Makefile
+++ b/arch/arm/mach-bcm/Makefile
@@ -43,6 +43,11 @@ endif
43 43
44# BCM2835 44# BCM2835
45obj-$(CONFIG_ARCH_BCM2835) += board_bcm2835.o 45obj-$(CONFIG_ARCH_BCM2835) += board_bcm2835.o
46ifeq ($(CONFIG_ARCH_BCM2835),y)
47ifeq ($(CONFIG_ARM),y)
48obj-$(CONFIG_SMP) += platsmp.o
49endif
50endif
46 51
47# BCM5301X 52# BCM5301X
48obj-$(CONFIG_ARCH_BCM_5301X) += bcm_5301x.o 53obj-$(CONFIG_ARCH_BCM_5301X) += bcm_5301x.o
diff --git a/arch/arm/mach-bcm/board_bcm2835.c b/arch/arm/mach-bcm/board_bcm2835.c
index 24af33f91705..8cff865ace04 100644
--- a/arch/arm/mach-bcm/board_bcm2835.c
+++ b/arch/arm/mach-bcm/board_bcm2835.c
@@ -19,16 +19,20 @@
19#include <asm/mach/arch.h> 19#include <asm/mach/arch.h>
20#include <asm/mach/map.h> 20#include <asm/mach/map.h>
21 21
22#include "platsmp.h"
23
22static const char * const bcm2835_compat[] = { 24static const char * const bcm2835_compat[] = {
23#ifdef CONFIG_ARCH_MULTI_V6 25#ifdef CONFIG_ARCH_MULTI_V6
24 "brcm,bcm2835", 26 "brcm,bcm2835",
25#endif 27#endif
26#ifdef CONFIG_ARCH_MULTI_V7 28#ifdef CONFIG_ARCH_MULTI_V7
27 "brcm,bcm2836", 29 "brcm,bcm2836",
30 "brcm,bcm2837",
28#endif 31#endif
29 NULL 32 NULL
30}; 33};
31 34
32DT_MACHINE_START(BCM2835, "BCM2835") 35DT_MACHINE_START(BCM2835, "BCM2835")
33 .dt_compat = bcm2835_compat 36 .dt_compat = bcm2835_compat,
37 .smp = smp_ops(bcm2836_smp_ops),
34MACHINE_END 38MACHINE_END
diff --git a/arch/arm/mach-bcm/platsmp.c b/arch/arm/mach-bcm/platsmp.c
index 9e3f275934eb..34506a608fea 100644
--- a/arch/arm/mach-bcm/platsmp.c
+++ b/arch/arm/mach-bcm/platsmp.c
@@ -17,6 +17,7 @@
17#include <linux/errno.h> 17#include <linux/errno.h>
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/io.h> 19#include <linux/io.h>
20#include <linux/irqchip/irq-bcm2836.h>
20#include <linux/jiffies.h> 21#include <linux/jiffies.h>
21#include <linux/of.h> 22#include <linux/of.h>
22#include <linux/of_address.h> 23#include <linux/of_address.h>
@@ -287,6 +288,35 @@ out:
287 return ret; 288 return ret;
288} 289}
289 290
291static int bcm2836_boot_secondary(unsigned int cpu, struct task_struct *idle)
292{
293 void __iomem *intc_base;
294 struct device_node *dn;
295 char *name;
296
297 name = "brcm,bcm2836-l1-intc";
298 dn = of_find_compatible_node(NULL, NULL, name);
299 if (!dn) {
300 pr_err("unable to find intc node\n");
301 return -ENODEV;
302 }
303
304 intc_base = of_iomap(dn, 0);
305 of_node_put(dn);
306
307 if (!intc_base) {
308 pr_err("unable to remap intc base register\n");
309 return -ENOMEM;
310 }
311
312 writel(virt_to_phys(secondary_startup),
313 intc_base + LOCAL_MAILBOX3_SET0 + 16 * cpu);
314
315 iounmap(intc_base);
316
317 return 0;
318}
319
290static const struct smp_operations kona_smp_ops __initconst = { 320static const struct smp_operations kona_smp_ops __initconst = {
291 .smp_prepare_cpus = bcm_smp_prepare_cpus, 321 .smp_prepare_cpus = bcm_smp_prepare_cpus,
292 .smp_boot_secondary = kona_boot_secondary, 322 .smp_boot_secondary = kona_boot_secondary,
@@ -305,3 +335,8 @@ static const struct smp_operations nsp_smp_ops __initconst = {
305 .smp_boot_secondary = nsp_boot_secondary, 335 .smp_boot_secondary = nsp_boot_secondary,
306}; 336};
307CPU_METHOD_OF_DECLARE(bcm_smp_nsp, "brcm,bcm-nsp-smp", &nsp_smp_ops); 337CPU_METHOD_OF_DECLARE(bcm_smp_nsp, "brcm,bcm-nsp-smp", &nsp_smp_ops);
338
339const struct smp_operations bcm2836_smp_ops __initconst = {
340 .smp_boot_secondary = bcm2836_boot_secondary,
341};
342CPU_METHOD_OF_DECLARE(bcm_smp_bcm2836, "brcm,bcm2836-smp", &bcm2836_smp_ops);
diff --git a/arch/arm/mach-bcm/platsmp.h b/arch/arm/mach-bcm/platsmp.h
new file mode 100644
index 000000000000..b8b8b3fa350d
--- /dev/null
+++ b/arch/arm/mach-bcm/platsmp.h
@@ -0,0 +1,10 @@
1/*
2 * Copyright (C) 2017 Stefan Wahren <stefan.wahren@i2se.com>
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 */
9
10extern const struct smp_operations bcm2836_smp_ops;
diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c
index dc8c1e3eafe7..667b9e14b032 100644
--- a/drivers/irqchip/irq-bcm2836.c
+++ b/drivers/irqchip/irq-bcm2836.c
@@ -19,62 +19,9 @@
19#include <linux/of_irq.h> 19#include <linux/of_irq.h>
20#include <linux/irqchip.h> 20#include <linux/irqchip.h>
21#include <linux/irqdomain.h> 21#include <linux/irqdomain.h>
22#include <asm/exception.h> 22#include <linux/irqchip/irq-bcm2836.h>
23
24#define LOCAL_CONTROL 0x000
25#define LOCAL_PRESCALER 0x008
26 23
27/* 24#include <asm/exception.h>
28 * The low 2 bits identify the CPU that the GPU IRQ goes to, and the
29 * next 2 bits identify the CPU that the GPU FIQ goes to.
30 */
31#define LOCAL_GPU_ROUTING 0x00c
32/* When setting bits 0-3, enables PMU interrupts on that CPU. */
33#define LOCAL_PM_ROUTING_SET 0x010
34/* When setting bits 0-3, disables PMU interrupts on that CPU. */
35#define LOCAL_PM_ROUTING_CLR 0x014
36/*
37 * The low 4 bits of this are the CPU's timer IRQ enables, and the
38 * next 4 bits are the CPU's timer FIQ enables (which override the IRQ
39 * bits).
40 */
41#define LOCAL_TIMER_INT_CONTROL0 0x040
42/*
43 * The low 4 bits of this are the CPU's per-mailbox IRQ enables, and
44 * the next 4 bits are the CPU's per-mailbox FIQ enables (which
45 * override the IRQ bits).
46 */
47#define LOCAL_MAILBOX_INT_CONTROL0 0x050
48/*
49 * The CPU's interrupt status register. Bits are defined by the the
50 * LOCAL_IRQ_* bits below.
51 */
52#define LOCAL_IRQ_PENDING0 0x060
53/* Same status bits as above, but for FIQ. */
54#define LOCAL_FIQ_PENDING0 0x070
55/*
56 * Mailbox write-to-set bits. There are 16 mailboxes, 4 per CPU, and
57 * these bits are organized by mailbox number and then CPU number. We
58 * use mailbox 0 for IPIs. The mailbox's interrupt is raised while
59 * any bit is set.
60 */
61#define LOCAL_MAILBOX0_SET0 0x080
62#define LOCAL_MAILBOX3_SET0 0x08c
63/* Mailbox write-to-clear bits. */
64#define LOCAL_MAILBOX0_CLR0 0x0c0
65#define LOCAL_MAILBOX3_CLR0 0x0cc
66
67#define LOCAL_IRQ_CNTPSIRQ 0
68#define LOCAL_IRQ_CNTPNSIRQ 1
69#define LOCAL_IRQ_CNTHPIRQ 2
70#define LOCAL_IRQ_CNTVIRQ 3
71#define LOCAL_IRQ_MAILBOX0 4
72#define LOCAL_IRQ_MAILBOX1 5
73#define LOCAL_IRQ_MAILBOX2 6
74#define LOCAL_IRQ_MAILBOX3 7
75#define LOCAL_IRQ_GPU_FAST 8
76#define LOCAL_IRQ_PMU_FAST 9
77#define LAST_IRQ LOCAL_IRQ_PMU_FAST
78 25
79struct bcm2836_arm_irqchip_intc { 26struct bcm2836_arm_irqchip_intc {
80 struct irq_domain *domain; 27 struct irq_domain *domain;
@@ -215,24 +162,6 @@ static int bcm2836_cpu_dying(unsigned int cpu)
215 cpu); 162 cpu);
216 return 0; 163 return 0;
217} 164}
218
219#ifdef CONFIG_ARM
220static int __init bcm2836_smp_boot_secondary(unsigned int cpu,
221 struct task_struct *idle)
222{
223 unsigned long secondary_startup_phys =
224 (unsigned long)virt_to_phys((void *)secondary_startup);
225
226 writel(secondary_startup_phys,
227 intc.base + LOCAL_MAILBOX3_SET0 + 16 * cpu);
228
229 return 0;
230}
231
232static const struct smp_operations bcm2836_smp_ops __initconst = {
233 .smp_boot_secondary = bcm2836_smp_boot_secondary,
234};
235#endif
236#endif 165#endif
237 166
238static const struct irq_domain_ops bcm2836_arm_irqchip_intc_ops = { 167static const struct irq_domain_ops bcm2836_arm_irqchip_intc_ops = {
@@ -249,10 +178,6 @@ bcm2836_arm_irqchip_smp_init(void)
249 bcm2836_cpu_dying); 178 bcm2836_cpu_dying);
250 179
251 set_smp_cross_call(bcm2836_arm_irqchip_send_ipi); 180 set_smp_cross_call(bcm2836_arm_irqchip_send_ipi);
252
253#ifdef CONFIG_ARM
254 smp_set_ops(&bcm2836_smp_ops);
255#endif
256#endif 181#endif
257} 182}
258 183
diff --git a/include/linux/irqchip/irq-bcm2836.h b/include/linux/irqchip/irq-bcm2836.h
new file mode 100644
index 000000000000..218a6e1b18d8
--- /dev/null
+++ b/include/linux/irqchip/irq-bcm2836.h
@@ -0,0 +1,70 @@
1/*
2 * Root interrupt controller for the BCM2836 (Raspberry Pi 2).
3 *
4 * Copyright 2015 Broadcom
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#define LOCAL_CONTROL 0x000
18#define LOCAL_PRESCALER 0x008
19
20/*
21 * The low 2 bits identify the CPU that the GPU IRQ goes to, and the
22 * next 2 bits identify the CPU that the GPU FIQ goes to.
23 */
24#define LOCAL_GPU_ROUTING 0x00c
25/* When setting bits 0-3, enables PMU interrupts on that CPU. */
26#define LOCAL_PM_ROUTING_SET 0x010
27/* When setting bits 0-3, disables PMU interrupts on that CPU. */
28#define LOCAL_PM_ROUTING_CLR 0x014
29/*
30 * The low 4 bits of this are the CPU's timer IRQ enables, and the
31 * next 4 bits are the CPU's timer FIQ enables (which override the IRQ
32 * bits).
33 */
34#define LOCAL_TIMER_INT_CONTROL0 0x040
35/*
36 * The low 4 bits of this are the CPU's per-mailbox IRQ enables, and
37 * the next 4 bits are the CPU's per-mailbox FIQ enables (which
38 * override the IRQ bits).
39 */
40#define LOCAL_MAILBOX_INT_CONTROL0 0x050
41/*
42 * The CPU's interrupt status register. Bits are defined by the the
43 * LOCAL_IRQ_* bits below.
44 */
45#define LOCAL_IRQ_PENDING0 0x060
46/* Same status bits as above, but for FIQ. */
47#define LOCAL_FIQ_PENDING0 0x070
48/*
49 * Mailbox write-to-set bits. There are 16 mailboxes, 4 per CPU, and
50 * these bits are organized by mailbox number and then CPU number. We
51 * use mailbox 0 for IPIs. The mailbox's interrupt is raised while
52 * any bit is set.
53 */
54#define LOCAL_MAILBOX0_SET0 0x080
55#define LOCAL_MAILBOX3_SET0 0x08c
56/* Mailbox write-to-clear bits. */
57#define LOCAL_MAILBOX0_CLR0 0x0c0
58#define LOCAL_MAILBOX3_CLR0 0x0cc
59
60#define LOCAL_IRQ_CNTPSIRQ 0
61#define LOCAL_IRQ_CNTPNSIRQ 1
62#define LOCAL_IRQ_CNTHPIRQ 2
63#define LOCAL_IRQ_CNTVIRQ 3
64#define LOCAL_IRQ_MAILBOX0 4
65#define LOCAL_IRQ_MAILBOX1 5
66#define LOCAL_IRQ_MAILBOX2 6
67#define LOCAL_IRQ_MAILBOX3 7
68#define LOCAL_IRQ_GPU_FAST 8
69#define LOCAL_IRQ_PMU_FAST 9
70#define LAST_IRQ LOCAL_IRQ_PMU_FAST