ARM: BCM: Clean up SMP support for Broadcom Kona
These changes cleans up SMP implementaion for Broadcom's Kona SoC which are required for handling SMP for iProc family of SoCs at a single place for BCM NSP and BCM Kona. Signed-off-by: Kapil Hali <kapilh@broadcom.com> Acked-by: Rob Herring <robh@kernel.org> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
This commit is contained in:
parent
f4ce7effe2
commit
84320e1a63
|
@ -31,7 +31,6 @@
|
|||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
enable-method = "brcm,bcm11351-cpu-method";
|
||||
secondary-boot-reg = <0x3500417c>;
|
||||
|
||||
cpu0: cpu@0 {
|
||||
device_type = "cpu";
|
||||
|
@ -42,6 +41,7 @@
|
|||
cpu1: cpu@1 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a9";
|
||||
secondary-boot-reg = <0x3500417c>;
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
enable-method = "brcm,bcm11351-cpu-method";
|
||||
secondary-boot-reg = <0x35004178>;
|
||||
|
||||
cpu0: cpu@0 {
|
||||
device_type = "cpu";
|
||||
|
@ -42,6 +41,7 @@
|
|||
cpu1: cpu@1 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a9";
|
||||
secondary-boot-reg = <0x35004178>;
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2014 Broadcom Corporation
|
||||
* Copyright (C) 2014-2015 Broadcom Corporation
|
||||
* Copyright 2014 Linaro Limited
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -30,9 +30,10 @@
|
|||
|
||||
/* Name of device node property defining secondary boot register location */
|
||||
#define OF_SECONDARY_BOOT "secondary-boot-reg"
|
||||
#define MPIDR_CPUID_BITMASK 0x3
|
||||
|
||||
/* I/O address of register used to coordinate secondary core startup */
|
||||
static u32 secondary_boot;
|
||||
static u32 secondary_boot_addr;
|
||||
|
||||
/*
|
||||
* Enable the Cortex A9 Snoop Control Unit
|
||||
|
@ -78,44 +79,68 @@ static int __init scu_a9_enable(void)
|
|||
static void __init bcm_smp_prepare_cpus(unsigned int max_cpus)
|
||||
{
|
||||
static cpumask_t only_cpu_0 = { CPU_BITS_CPU0 };
|
||||
struct device_node *node;
|
||||
struct device_node *cpus_node = NULL;
|
||||
struct device_node *cpu_node = NULL;
|
||||
int ret;
|
||||
|
||||
BUG_ON(secondary_boot); /* We're called only once */
|
||||
|
||||
/*
|
||||
* This function is only called via smp_ops->smp_prepare_cpu().
|
||||
* That only happens if a "/cpus" device tree node exists
|
||||
* and has an "enable-method" property that selects the SMP
|
||||
* operations defined herein.
|
||||
*/
|
||||
node = of_find_node_by_path("/cpus");
|
||||
BUG_ON(!node);
|
||||
cpus_node = of_find_node_by_path("/cpus");
|
||||
if (!cpus_node)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Our secondary enable method requires a "secondary-boot-reg"
|
||||
* property to specify a register address used to request the
|
||||
* ROM code boot a secondary code. If we have any trouble
|
||||
* getting this we fall back to uniprocessor mode.
|
||||
*/
|
||||
if (of_property_read_u32(node, OF_SECONDARY_BOOT, &secondary_boot)) {
|
||||
pr_err("%s: missing/invalid " OF_SECONDARY_BOOT " property\n",
|
||||
node->name);
|
||||
ret = -ENOENT; /* Arrange to disable SMP */
|
||||
goto out;
|
||||
for_each_child_of_node(cpus_node, cpu_node) {
|
||||
u32 cpuid;
|
||||
|
||||
if (of_node_cmp(cpu_node->type, "cpu"))
|
||||
continue;
|
||||
|
||||
if (of_property_read_u32(cpu_node, "reg", &cpuid)) {
|
||||
pr_debug("%s: missing reg property\n",
|
||||
cpu_node->full_name);
|
||||
ret = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* "secondary-boot-reg" property should be defined only
|
||||
* for secondary cpu
|
||||
*/
|
||||
if ((cpuid & MPIDR_CPUID_BITMASK) == 1) {
|
||||
/*
|
||||
* Our secondary enable method requires a
|
||||
* "secondary-boot-reg" property to specify a register
|
||||
* address used to request the ROM code boot a secondary
|
||||
* core. If we have any trouble getting this we fall
|
||||
* back to uniprocessor mode.
|
||||
*/
|
||||
if (of_property_read_u32(cpu_node,
|
||||
OF_SECONDARY_BOOT,
|
||||
&secondary_boot_addr)) {
|
||||
pr_warn("%s: no" OF_SECONDARY_BOOT "property\n",
|
||||
cpu_node->name);
|
||||
ret = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable the SCU on Cortex A9 based SoCs. If -ENOENT is
|
||||
* Enable the SCU on Cortex A9 based SoCs. If -ENOENT is
|
||||
* returned, the SoC reported a uniprocessor configuration.
|
||||
* We bail on any other error.
|
||||
*/
|
||||
ret = scu_a9_enable();
|
||||
out:
|
||||
of_node_put(node);
|
||||
of_node_put(cpu_node);
|
||||
of_node_put(cpus_node);
|
||||
|
||||
if (ret) {
|
||||
/* Update the CPU present map to reflect uniprocessor mode */
|
||||
BUG_ON(ret != -ENOENT);
|
||||
pr_warn("disabling SMP\n");
|
||||
init_cpu_present(&only_cpu_0);
|
||||
}
|
||||
|
@ -139,7 +164,7 @@ out:
|
|||
* - Wait for the secondary boot register to be re-written, which
|
||||
* indicates the secondary core has started.
|
||||
*/
|
||||
static int bcm_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
||||
static int kona_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
||||
{
|
||||
void __iomem *boot_reg;
|
||||
phys_addr_t boot_func;
|
||||
|
@ -154,15 +179,16 @@ static int bcm_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!secondary_boot) {
|
||||
if (!secondary_boot_addr) {
|
||||
pr_err("required secondary boot register not specified\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
boot_reg = ioremap_nocache((phys_addr_t)secondary_boot, sizeof(u32));
|
||||
boot_reg = ioremap_nocache(
|
||||
(phys_addr_t)secondary_boot_addr, sizeof(u32));
|
||||
if (!boot_reg) {
|
||||
pr_err("unable to map boot register for cpu %u\n", cpu_id);
|
||||
return -ENOSYS;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -191,12 +217,12 @@ static int bcm_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
|||
|
||||
pr_err("timeout waiting for cpu %u to start\n", cpu_id);
|
||||
|
||||
return -ENOSYS;
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
static struct smp_operations bcm_smp_ops __initdata = {
|
||||
.smp_prepare_cpus = bcm_smp_prepare_cpus,
|
||||
.smp_boot_secondary = bcm_boot_secondary,
|
||||
.smp_boot_secondary = kona_boot_secondary,
|
||||
};
|
||||
CPU_METHOD_OF_DECLARE(bcm_smp_bcm281xx, "brcm,bcm11351-cpu-method",
|
||||
&bcm_smp_ops);
|
||||
|
|
Loading…
Reference in New Issue