Commit ea023be7 authored by Florian Fainelli's avatar Florian Fainelli

Merge tag 'bcm2835-soc-next-2017-08-24' into soc/next

This pull request brings in a move of the bcm2836/7 SMP init code from
the irqchip driver to platsmp.c (general move acked by the maintainer,
v2 of the patch including a squashed in fix to prevent a dependency on
updated DT compatibles) and an added sev() to wake up the secondary
CPUs on newer firmware.  It also garbage collects some stub clock code
from before we had a proper clock driver, which has been acked by the
clk maintainers to go through the ARM trees.
Signed-off-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
parents 2bd6bf03 968f7641
...@@ -43,6 +43,11 @@ endif ...@@ -43,6 +43,11 @@ endif
# BCM2835 # BCM2835
obj-$(CONFIG_ARCH_BCM2835) += board_bcm2835.o obj-$(CONFIG_ARCH_BCM2835) += board_bcm2835.o
ifeq ($(CONFIG_ARCH_BCM2835),y)
ifeq ($(CONFIG_ARM),y)
obj-$(CONFIG_SMP) += platsmp.o
endif
endif
# BCM5301X # BCM5301X
obj-$(CONFIG_ARCH_BCM_5301X) += bcm_5301x.o obj-$(CONFIG_ARCH_BCM_5301X) += bcm_5301x.o
......
...@@ -15,15 +15,11 @@ ...@@ -15,15 +15,11 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/irqchip.h> #include <linux/irqchip.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/clk/bcm2835.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/map.h> #include <asm/mach/map.h>
static void __init bcm2835_init(void) #include "platsmp.h"
{
bcm2835_init_clocks();
}
static const char * const bcm2835_compat[] = { static const char * const bcm2835_compat[] = {
#ifdef CONFIG_ARCH_MULTI_V6 #ifdef CONFIG_ARCH_MULTI_V6
...@@ -31,11 +27,12 @@ static const char * const bcm2835_compat[] = { ...@@ -31,11 +27,12 @@ static const char * const bcm2835_compat[] = {
#endif #endif
#ifdef CONFIG_ARCH_MULTI_V7 #ifdef CONFIG_ARCH_MULTI_V7
"brcm,bcm2836", "brcm,bcm2836",
"brcm,bcm2837",
#endif #endif
NULL NULL
}; };
DT_MACHINE_START(BCM2835, "BCM2835") DT_MACHINE_START(BCM2835, "BCM2835")
.init_machine = bcm2835_init, .dt_compat = bcm2835_compat,
.dt_compat = bcm2835_compat .smp = smp_ops(bcm2836_smp_ops),
MACHINE_END MACHINE_END
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/irqchip/irq-bcm2836.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_address.h> #include <linux/of_address.h>
...@@ -287,6 +288,38 @@ static int nsp_boot_secondary(unsigned int cpu, struct task_struct *idle) ...@@ -287,6 +288,38 @@ static int nsp_boot_secondary(unsigned int cpu, struct task_struct *idle)
return ret; return ret;
} }
static int bcm2836_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
void __iomem *intc_base;
struct device_node *dn;
char *name;
name = "brcm,bcm2836-l1-intc";
dn = of_find_compatible_node(NULL, NULL, name);
if (!dn) {
pr_err("unable to find intc node\n");
return -ENODEV;
}
intc_base = of_iomap(dn, 0);
of_node_put(dn);
if (!intc_base) {
pr_err("unable to remap intc base register\n");
return -ENOMEM;
}
writel(virt_to_phys(secondary_startup),
intc_base + LOCAL_MAILBOX3_SET0 + 16 * cpu);
dsb(sy);
sev();
iounmap(intc_base);
return 0;
}
static const struct smp_operations kona_smp_ops __initconst = { static const struct smp_operations kona_smp_ops __initconst = {
.smp_prepare_cpus = bcm_smp_prepare_cpus, .smp_prepare_cpus = bcm_smp_prepare_cpus,
.smp_boot_secondary = kona_boot_secondary, .smp_boot_secondary = kona_boot_secondary,
...@@ -305,3 +338,8 @@ static const struct smp_operations nsp_smp_ops __initconst = { ...@@ -305,3 +338,8 @@ static const struct smp_operations nsp_smp_ops __initconst = {
.smp_boot_secondary = nsp_boot_secondary, .smp_boot_secondary = nsp_boot_secondary,
}; };
CPU_METHOD_OF_DECLARE(bcm_smp_nsp, "brcm,bcm-nsp-smp", &nsp_smp_ops); CPU_METHOD_OF_DECLARE(bcm_smp_nsp, "brcm,bcm-nsp-smp", &nsp_smp_ops);
const struct smp_operations bcm2836_smp_ops __initconst = {
.smp_boot_secondary = bcm2836_boot_secondary,
};
CPU_METHOD_OF_DECLARE(bcm_smp_bcm2836, "brcm,bcm2836-smp", &bcm2836_smp_ops);
/*
* Copyright (C) 2017 Stefan Wahren <stefan.wahren@i2se.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
*/
extern const struct smp_operations bcm2836_smp_ops;
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/clk-provider.h> #include <linux/clk-provider.h>
#include <linux/clk/bcm2835.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <dt-bindings/clock/bcm2835-aux.h> #include <dt-bindings/clock/bcm2835-aux.h>
......
...@@ -37,7 +37,6 @@ ...@@ -37,7 +37,6 @@
#include <linux/clk-provider.h> #include <linux/clk-provider.h>
#include <linux/clkdev.h> #include <linux/clkdev.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/clk/bcm2835.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -416,35 +415,6 @@ static int bcm2835_debugfs_regset(struct bcm2835_cprman *cprman, u32 base, ...@@ -416,35 +415,6 @@ static int bcm2835_debugfs_regset(struct bcm2835_cprman *cprman, u32 base,
return regdump ? 0 : -ENOMEM; return regdump ? 0 : -ENOMEM;
} }
/*
* These are fixed clocks. They're probably not all root clocks and it may
* be possible to turn them on and off but until this is mapped out better
* it's the only way they can be used.
*/
void __init bcm2835_init_clocks(void)
{
struct clk_hw *hw;
int ret;
hw = clk_hw_register_fixed_rate(NULL, "apb_pclk", NULL, 0, 126000000);
if (IS_ERR(hw))
pr_err("apb_pclk not registered\n");
hw = clk_hw_register_fixed_rate(NULL, "uart0_pclk", NULL, 0, 3000000);
if (IS_ERR(hw))
pr_err("uart0_pclk not registered\n");
ret = clk_hw_register_clkdev(hw, NULL, "20201000.uart");
if (ret)
pr_err("uart0_pclk alias not registered\n");
hw = clk_hw_register_fixed_rate(NULL, "uart1_pclk", NULL, 0, 125000000);
if (IS_ERR(hw))
pr_err("uart1_pclk not registered\n");
ret = clk_hw_register_clkdev(hw, NULL, "20215000.uart");
if (ret)
pr_err("uart1_pclk alias not registered\n");
}
struct bcm2835_pll_data { struct bcm2835_pll_data {
const char *name; const char *name;
u32 cm_ctrl_reg; u32 cm_ctrl_reg;
......
...@@ -19,62 +19,9 @@ ...@@ -19,62 +19,9 @@
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/irqchip.h> #include <linux/irqchip.h>
#include <linux/irqdomain.h> #include <linux/irqdomain.h>
#include <asm/exception.h> #include <linux/irqchip/irq-bcm2836.h>
#define LOCAL_CONTROL 0x000
#define LOCAL_PRESCALER 0x008
/* #include <asm/exception.h>
* The low 2 bits identify the CPU that the GPU IRQ goes to, and the
* next 2 bits identify the CPU that the GPU FIQ goes to.
*/
#define LOCAL_GPU_ROUTING 0x00c
/* When setting bits 0-3, enables PMU interrupts on that CPU. */
#define LOCAL_PM_ROUTING_SET 0x010
/* When setting bits 0-3, disables PMU interrupts on that CPU. */
#define LOCAL_PM_ROUTING_CLR 0x014
/*
* The low 4 bits of this are the CPU's timer IRQ enables, and the
* next 4 bits are the CPU's timer FIQ enables (which override the IRQ
* bits).
*/
#define LOCAL_TIMER_INT_CONTROL0 0x040
/*
* The low 4 bits of this are the CPU's per-mailbox IRQ enables, and
* the next 4 bits are the CPU's per-mailbox FIQ enables (which
* override the IRQ bits).
*/
#define LOCAL_MAILBOX_INT_CONTROL0 0x050
/*
* The CPU's interrupt status register. Bits are defined by the the
* LOCAL_IRQ_* bits below.
*/
#define LOCAL_IRQ_PENDING0 0x060
/* Same status bits as above, but for FIQ. */
#define LOCAL_FIQ_PENDING0 0x070
/*
* Mailbox write-to-set bits. There are 16 mailboxes, 4 per CPU, and
* these bits are organized by mailbox number and then CPU number. We
* use mailbox 0 for IPIs. The mailbox's interrupt is raised while
* any bit is set.
*/
#define LOCAL_MAILBOX0_SET0 0x080
#define LOCAL_MAILBOX3_SET0 0x08c
/* Mailbox write-to-clear bits. */
#define LOCAL_MAILBOX0_CLR0 0x0c0
#define LOCAL_MAILBOX3_CLR0 0x0cc
#define LOCAL_IRQ_CNTPSIRQ 0
#define LOCAL_IRQ_CNTPNSIRQ 1
#define LOCAL_IRQ_CNTHPIRQ 2
#define LOCAL_IRQ_CNTVIRQ 3
#define LOCAL_IRQ_MAILBOX0 4
#define LOCAL_IRQ_MAILBOX1 5
#define LOCAL_IRQ_MAILBOX2 6
#define LOCAL_IRQ_MAILBOX3 7
#define LOCAL_IRQ_GPU_FAST 8
#define LOCAL_IRQ_PMU_FAST 9
#define LAST_IRQ LOCAL_IRQ_PMU_FAST
struct bcm2836_arm_irqchip_intc { struct bcm2836_arm_irqchip_intc {
struct irq_domain *domain; struct irq_domain *domain;
...@@ -215,24 +162,6 @@ static int bcm2836_cpu_dying(unsigned int cpu) ...@@ -215,24 +162,6 @@ static int bcm2836_cpu_dying(unsigned int cpu)
cpu); cpu);
return 0; return 0;
} }
#ifdef CONFIG_ARM
static int __init bcm2836_smp_boot_secondary(unsigned int cpu,
struct task_struct *idle)
{
unsigned long secondary_startup_phys =
(unsigned long)virt_to_phys((void *)secondary_startup);
writel(secondary_startup_phys,
intc.base + LOCAL_MAILBOX3_SET0 + 16 * cpu);
return 0;
}
static const struct smp_operations bcm2836_smp_ops __initconst = {
.smp_boot_secondary = bcm2836_smp_boot_secondary,
};
#endif
#endif #endif
static const struct irq_domain_ops bcm2836_arm_irqchip_intc_ops = { static const struct irq_domain_ops bcm2836_arm_irqchip_intc_ops = {
...@@ -249,10 +178,6 @@ bcm2836_arm_irqchip_smp_init(void) ...@@ -249,10 +178,6 @@ bcm2836_arm_irqchip_smp_init(void)
bcm2836_cpu_dying); bcm2836_cpu_dying);
set_smp_cross_call(bcm2836_arm_irqchip_send_ipi); set_smp_cross_call(bcm2836_arm_irqchip_send_ipi);
#ifdef CONFIG_ARM
smp_set_ops(&bcm2836_smp_ops);
#endif
#endif #endif
} }
......
/*
* Copyright (C) 2010 Broadcom
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __LINUX_CLK_BCM2835_H_
#define __LINUX_CLK_BCM2835_H_
void __init bcm2835_init_clocks(void);
#endif
/*
* Root interrupt controller for the BCM2836 (Raspberry Pi 2).
*
* Copyright 2015 Broadcom
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#define LOCAL_CONTROL 0x000
#define LOCAL_PRESCALER 0x008
/*
* The low 2 bits identify the CPU that the GPU IRQ goes to, and the
* next 2 bits identify the CPU that the GPU FIQ goes to.
*/
#define LOCAL_GPU_ROUTING 0x00c
/* When setting bits 0-3, enables PMU interrupts on that CPU. */
#define LOCAL_PM_ROUTING_SET 0x010
/* When setting bits 0-3, disables PMU interrupts on that CPU. */
#define LOCAL_PM_ROUTING_CLR 0x014
/*
* The low 4 bits of this are the CPU's timer IRQ enables, and the
* next 4 bits are the CPU's timer FIQ enables (which override the IRQ
* bits).
*/
#define LOCAL_TIMER_INT_CONTROL0 0x040
/*
* The low 4 bits of this are the CPU's per-mailbox IRQ enables, and
* the next 4 bits are the CPU's per-mailbox FIQ enables (which
* override the IRQ bits).
*/
#define LOCAL_MAILBOX_INT_CONTROL0 0x050
/*
* The CPU's interrupt status register. Bits are defined by the the
* LOCAL_IRQ_* bits below.
*/
#define LOCAL_IRQ_PENDING0 0x060
/* Same status bits as above, but for FIQ. */
#define LOCAL_FIQ_PENDING0 0x070
/*
* Mailbox write-to-set bits. There are 16 mailboxes, 4 per CPU, and
* these bits are organized by mailbox number and then CPU number. We
* use mailbox 0 for IPIs. The mailbox's interrupt is raised while
* any bit is set.
*/
#define LOCAL_MAILBOX0_SET0 0x080
#define LOCAL_MAILBOX3_SET0 0x08c
/* Mailbox write-to-clear bits. */
#define LOCAL_MAILBOX0_CLR0 0x0c0
#define LOCAL_MAILBOX3_CLR0 0x0cc
#define LOCAL_IRQ_CNTPSIRQ 0
#define LOCAL_IRQ_CNTPNSIRQ 1
#define LOCAL_IRQ_CNTHPIRQ 2
#define LOCAL_IRQ_CNTVIRQ 3
#define LOCAL_IRQ_MAILBOX0 4
#define LOCAL_IRQ_MAILBOX1 5
#define LOCAL_IRQ_MAILBOX2 6
#define LOCAL_IRQ_MAILBOX3 7
#define LOCAL_IRQ_GPU_FAST 8
#define LOCAL_IRQ_PMU_FAST 9
#define LAST_IRQ LOCAL_IRQ_PMU_FAST
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment