On Sat, Dec 05, 2015 at 06:53:41AM -0500, Kapil Hali wrote: > 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@xxxxxxxxxxxx> > --- > .../bindings/arm/bcm/brcm,bcm11351-cpu-method.txt | 12 ++-- > arch/arm/boot/dts/bcm11351.dtsi | 4 +- > arch/arm/boot/dts/bcm21664.dtsi | 4 +- For the bindings: Acked-by: Rob Herring <robh@xxxxxxxxxx> > arch/arm/mach-bcm/kona_smp.c | 82 ++++++++++++++-------- > 4 files changed, 64 insertions(+), 38 deletions(-) > > diff --git a/Documentation/devicetree/bindings/arm/bcm/brcm,bcm11351-cpu-method.txt b/Documentation/devicetree/bindings/arm/bcm/brcm,bcm11351-cpu-method.txt > index 8240c02..3c5fe4b 100644 > --- a/Documentation/devicetree/bindings/arm/bcm/brcm,bcm11351-cpu-method.txt > +++ b/Documentation/devicetree/bindings/arm/bcm/brcm,bcm11351-cpu-method.txt > @@ -1,17 +1,17 @@ > Broadcom Kona Family CPU Enable Method > -------------------------------------- > This binding defines the enable method used for starting secondary > -CPUs in the following Broadcom SoCs: > +CPU in the following Broadcom SoCs: > BCM11130, BCM11140, BCM11351, BCM28145, BCM28155, BCM21664 > > The enable method is specified by defining the following required > -properties in the "cpus" device tree node: > +properties in the corresponding secondary "cpu" device tree node: > - enable-method = "brcm,bcm11351-cpu-method"; > - secondary-boot-reg = <...>; > > The secondary-boot-reg property is a u32 value that specifies the > -physical address of the register used to request the ROM holding pen > -code release a secondary CPU. The value written to the register is > +physical address of the register used to request the ROM code > +release a secondary CPU. The value written to the register is > formed by encoding the target CPU id into the low bits of the > physical start address it should jump to. > > @@ -19,8 +19,6 @@ Example: > cpus { > #address-cells = <1>; > #size-cells = <0>; > - enable-method = "brcm,bcm11351-cpu-method"; > - secondary-boot-reg = <0x3500417c>; > > cpu0: cpu@0 { > device_type = "cpu"; > @@ -31,6 +29,8 @@ Example: > cpu1: cpu@1 { > device_type = "cpu"; > compatible = "arm,cortex-a9"; > + enable-method = "brcm,bcm11351-cpu-method"; > + secondary-boot-reg = <0x3500417c>; > reg = <1>; > }; > }; > diff --git a/arch/arm/boot/dts/bcm11351.dtsi b/arch/arm/boot/dts/bcm11351.dtsi > index 2ddaa51..18045c3 100644 > --- a/arch/arm/boot/dts/bcm11351.dtsi > +++ b/arch/arm/boot/dts/bcm11351.dtsi > @@ -30,8 +30,6 @@ > cpus { > #address-cells = <1>; > #size-cells = <0>; > - enable-method = "brcm,bcm11351-cpu-method"; > - secondary-boot-reg = <0x3500417c>; > > cpu0: cpu@0 { > device_type = "cpu"; > @@ -42,6 +40,8 @@ > cpu1: cpu@1 { > device_type = "cpu"; > compatible = "arm,cortex-a9"; > + enable-method = "brcm,bcm11351-cpu-method"; > + secondary-boot-reg = <0x3500417c>; > reg = <1>; > }; > }; > diff --git a/arch/arm/boot/dts/bcm21664.dtsi b/arch/arm/boot/dts/bcm21664.dtsi > index 2016b72..6dde95f 100644 > --- a/arch/arm/boot/dts/bcm21664.dtsi > +++ b/arch/arm/boot/dts/bcm21664.dtsi > @@ -30,8 +30,6 @@ > cpus { > #address-cells = <1>; > #size-cells = <0>; > - enable-method = "brcm,bcm11351-cpu-method"; > - secondary-boot-reg = <0x35004178>; > > cpu0: cpu@0 { > device_type = "cpu"; > @@ -42,6 +40,8 @@ > cpu1: cpu@1 { > device_type = "cpu"; > compatible = "arm,cortex-a9"; > + enable-method = "brcm,bcm11351-cpu-method"; > + secondary-boot-reg = <0x35004178>; > reg = <1>; > }; > }; > diff --git a/arch/arm/mach-bcm/kona_smp.c b/arch/arm/mach-bcm/kona_smp.c > index 66a0465..15af781 100644 > --- a/arch/arm/mach-bcm/kona_smp.c > +++ b/arch/arm/mach-bcm/kona_smp.c > @@ -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); > - > - /* > - * 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; > + cpus_node = of_find_node_by_path("/cpus"); > + if (!cpus_node) > + return; > + > + 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); > -- > 2.1.0 > -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html