Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

irqchip: bcm2836: Move SMP startup code to arch/arm (v2)

In order to easily provide SMP for BCM2837 on 32-bit and 64-bit
the SMP startup code was placed in irq-bcm2836. That's not the
right approach. So move this code where it belongs.

Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
Fixes: 41f4988cc287 ("irqchip/bcm2836: Add SMP support for the 2836")
Tested-by: Eric Anholt <eric@anholt.net>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>

authored by

Stefan Wahren and committed by
Florian Fainelli
88bbe85d 1d66af81

+127 -78
+5
arch/arm/mach-bcm/Makefile
··· 43 43 44 44 # BCM2835 45 45 obj-$(CONFIG_ARCH_BCM2835) += board_bcm2835.o 46 + ifeq ($(CONFIG_ARCH_BCM2835),y) 47 + ifeq ($(CONFIG_ARM),y) 48 + obj-$(CONFIG_SMP) += platsmp.o 49 + endif 50 + endif 46 51 47 52 # BCM5301X 48 53 obj-$(CONFIG_ARCH_BCM_5301X) += bcm_5301x.o
+5 -1
arch/arm/mach-bcm/board_bcm2835.c
··· 19 19 #include <asm/mach/arch.h> 20 20 #include <asm/mach/map.h> 21 21 22 + #include "platsmp.h" 23 + 22 24 static const char * const bcm2835_compat[] = { 23 25 #ifdef CONFIG_ARCH_MULTI_V6 24 26 "brcm,bcm2835", 25 27 #endif 26 28 #ifdef CONFIG_ARCH_MULTI_V7 27 29 "brcm,bcm2836", 30 + "brcm,bcm2837", 28 31 #endif 29 32 NULL 30 33 }; 31 34 32 35 DT_MACHINE_START(BCM2835, "BCM2835") 33 - .dt_compat = bcm2835_compat 36 + .dt_compat = bcm2835_compat, 37 + .smp = smp_ops(bcm2836_smp_ops), 34 38 MACHINE_END
+35
arch/arm/mach-bcm/platsmp.c
··· 17 17 #include <linux/errno.h> 18 18 #include <linux/init.h> 19 19 #include <linux/io.h> 20 + #include <linux/irqchip/irq-bcm2836.h> 20 21 #include <linux/jiffies.h> 21 22 #include <linux/of.h> 22 23 #include <linux/of_address.h> ··· 288 287 return ret; 289 288 } 290 289 290 + static int bcm2836_boot_secondary(unsigned int cpu, struct task_struct *idle) 291 + { 292 + void __iomem *intc_base; 293 + struct device_node *dn; 294 + char *name; 295 + 296 + name = "brcm,bcm2836-l1-intc"; 297 + dn = of_find_compatible_node(NULL, NULL, name); 298 + if (!dn) { 299 + pr_err("unable to find intc node\n"); 300 + return -ENODEV; 301 + } 302 + 303 + intc_base = of_iomap(dn, 0); 304 + of_node_put(dn); 305 + 306 + if (!intc_base) { 307 + pr_err("unable to remap intc base register\n"); 308 + return -ENOMEM; 309 + } 310 + 311 + writel(virt_to_phys(secondary_startup), 312 + intc_base + LOCAL_MAILBOX3_SET0 + 16 * cpu); 313 + 314 + iounmap(intc_base); 315 + 316 + return 0; 317 + } 318 + 291 319 static const struct smp_operations kona_smp_ops __initconst = { 292 320 .smp_prepare_cpus = bcm_smp_prepare_cpus, 293 321 .smp_boot_secondary = kona_boot_secondary, ··· 335 305 .smp_boot_secondary = nsp_boot_secondary, 336 306 }; 337 307 CPU_METHOD_OF_DECLARE(bcm_smp_nsp, "brcm,bcm-nsp-smp", &nsp_smp_ops); 308 + 309 + const struct smp_operations bcm2836_smp_ops __initconst = { 310 + .smp_boot_secondary = bcm2836_boot_secondary, 311 + }; 312 + CPU_METHOD_OF_DECLARE(bcm_smp_bcm2836, "brcm,bcm2836-smp", &bcm2836_smp_ops);
+10
arch/arm/mach-bcm/platsmp.h
··· 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 + 10 + extern const struct smp_operations bcm2836_smp_ops;
+2 -77
drivers/irqchip/irq-bcm2836.c
··· 19 19 #include <linux/of_irq.h> 20 20 #include <linux/irqchip.h> 21 21 #include <linux/irqdomain.h> 22 + #include <linux/irqchip/irq-bcm2836.h> 23 + 22 24 #include <asm/exception.h> 23 - 24 - #define LOCAL_CONTROL 0x000 25 - #define LOCAL_PRESCALER 0x008 26 - 27 - /* 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 79 26 struct bcm2836_arm_irqchip_intc { 80 27 struct irq_domain *domain; ··· 162 215 cpu); 163 216 return 0; 164 217 } 165 - 166 - #ifdef CONFIG_ARM 167 - static int __init bcm2836_smp_boot_secondary(unsigned int cpu, 168 - struct task_struct *idle) 169 - { 170 - unsigned long secondary_startup_phys = 171 - (unsigned long)virt_to_phys((void *)secondary_startup); 172 - 173 - writel(secondary_startup_phys, 174 - intc.base + LOCAL_MAILBOX3_SET0 + 16 * cpu); 175 - 176 - return 0; 177 - } 178 - 179 - static const struct smp_operations bcm2836_smp_ops __initconst = { 180 - .smp_boot_secondary = bcm2836_smp_boot_secondary, 181 - }; 182 - #endif 183 218 #endif 184 219 185 220 static const struct irq_domain_ops bcm2836_arm_irqchip_intc_ops = { ··· 178 249 bcm2836_cpu_dying); 179 250 180 251 set_smp_cross_call(bcm2836_arm_irqchip_send_ipi); 181 - 182 - #ifdef CONFIG_ARM 183 - smp_set_ops(&bcm2836_smp_ops); 184 - #endif 185 252 #endif 186 253 } 187 254
+70
include/linux/irqchip/irq-bcm2836.h
··· 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