diff mbox

[v6,2/5] ARM: BCM: Clean up SMP support for Broadcom Kona

Message ID 1449316424-14549-3-git-send-email-kapilh@broadcom.com (mailing list archive)
State New, archived
Headers show

Commit Message

Kapil Hali Dec. 5, 2015, 11:53 a.m. UTC
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>
---
 .../bindings/arm/bcm/brcm,bcm11351-cpu-method.txt  | 12 ++--
 arch/arm/boot/dts/bcm11351.dtsi                    |  4 +-
 arch/arm/boot/dts/bcm21664.dtsi                    |  4 +-
 arch/arm/mach-bcm/kona_smp.c                       | 82 ++++++++++++++--------
 4 files changed, 64 insertions(+), 38 deletions(-)

Comments

Florian Fainelli Dec. 7, 2015, 3:50 a.m. UTC | #1
Le 05/12/2015 03:53, Kapil Hali a écrit :
> 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>

Applied to soc/next, thanks!
Rob Herring Dec. 7, 2015, 2:23 p.m. UTC | #2
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@broadcom.com>
> ---
>  .../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@kernel.org>

>  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
>
diff mbox

Patch

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);