kernel: update kernel 3.18 to version 3.18.29
[openwrt.git] / target / linux / bcm53xx / patches-4.1 / 131-ARM-BCM-Clean-up-SMP-support-for-Broadcom-Kona.patch
1 From 8622d6da5d95293d474c156612fd819fdaf542ec Mon Sep 17 00:00:00 2001
2 From: Kapil Hali <kapilh@broadcom.com>
3 Date: Wed, 25 Nov 2015 08:58:53 -0500
4 Subject: [PATCH 131/134] ARM: BCM: Clean up SMP support for Broadcom Kona
5
6 These changes cleans up SMP implementaion for Broadcom's
7 Kona SoC which are required for handling SMP for iProc
8 family of SoCs at a single place for BCM NSP and BCM Kona.
9
10 Signed-off-by: Kapil Hali <kapilh@broadcom.com>
11 ---
12  arch/arm/boot/dts/bcm11351.dtsi |  2 +-
13  arch/arm/boot/dts/bcm21664.dtsi |  2 +-
14  arch/arm/mach-bcm/kona_smp.c    | 82 +++++++++++++++++++++++++++--------------
15  3 files changed, 56 insertions(+), 30 deletions(-)
16
17 --- a/arch/arm/boot/dts/bcm11351.dtsi
18 +++ b/arch/arm/boot/dts/bcm11351.dtsi
19 @@ -31,7 +31,6 @@
20                 #address-cells = <1>;
21                 #size-cells = <0>;
22                 enable-method = "brcm,bcm11351-cpu-method";
23 -               secondary-boot-reg = <0x3500417c>;
24  
25                 cpu0: cpu@0 {
26                         device_type = "cpu";
27 @@ -42,6 +41,7 @@
28                 cpu1: cpu@1 {
29                         device_type = "cpu";
30                         compatible = "arm,cortex-a9";
31 +                       secondary-boot-reg = <0x3500417c>;
32                         reg = <1>;
33                 };
34         };
35 --- a/arch/arm/boot/dts/bcm21664.dtsi
36 +++ b/arch/arm/boot/dts/bcm21664.dtsi
37 @@ -31,7 +31,6 @@
38                 #address-cells = <1>;
39                 #size-cells = <0>;
40                 enable-method = "brcm,bcm11351-cpu-method";
41 -               secondary-boot-reg = <0x35004178>;
42  
43                 cpu0: cpu@0 {
44                         device_type = "cpu";
45 @@ -42,6 +41,7 @@
46                 cpu1: cpu@1 {
47                         device_type = "cpu";
48                         compatible = "arm,cortex-a9";
49 +                       secondary-boot-reg = <0x35004178>;
50                         reg = <1>;
51                 };
52         };
53 --- a/arch/arm/mach-bcm/kona_smp.c
54 +++ b/arch/arm/mach-bcm/kona_smp.c
55 @@ -1,5 +1,5 @@
56  /*
57 - * Copyright (C) 2014 Broadcom Corporation
58 + * Copyright (C) 2014-2015 Broadcom Corporation
59   * Copyright 2014 Linaro Limited
60   *
61   * This program is free software; you can redistribute it and/or
62 @@ -30,9 +30,10 @@
63  
64  /* Name of device node property defining secondary boot register location */
65  #define OF_SECONDARY_BOOT      "secondary-boot-reg"
66 +#define MPIDR_CPUID_BITMASK    0x3
67  
68  /* I/O address of register used to coordinate secondary core startup */
69 -static u32     secondary_boot;
70 +static u32     secondary_boot_addr;
71  
72  /*
73   * Enable the Cortex A9 Snoop Control Unit
74 @@ -78,44 +79,68 @@ static int __init scu_a9_enable(void)
75  static void __init bcm_smp_prepare_cpus(unsigned int max_cpus)
76  {
77         static cpumask_t only_cpu_0 = { CPU_BITS_CPU0 };
78 -       struct device_node *node;
79 +       struct device_node *cpus_node = NULL;
80 +       struct device_node *cpu_node = NULL;
81         int ret;
82  
83 -       BUG_ON(secondary_boot);         /* We're called only once */
84 -
85         /*
86          * This function is only called via smp_ops->smp_prepare_cpu().
87          * That only happens if a "/cpus" device tree node exists
88          * and has an "enable-method" property that selects the SMP
89          * operations defined herein.
90          */
91 -       node = of_find_node_by_path("/cpus");
92 -       BUG_ON(!node);
93 -
94 -       /*
95 -        * Our secondary enable method requires a "secondary-boot-reg"
96 -        * property to specify a register address used to request the
97 -        * ROM code boot a secondary code.  If we have any trouble
98 -        * getting this we fall back to uniprocessor mode.
99 -        */
100 -       if (of_property_read_u32(node, OF_SECONDARY_BOOT, &secondary_boot)) {
101 -               pr_err("%s: missing/invalid " OF_SECONDARY_BOOT " property\n",
102 -                       node->name);
103 -               ret = -ENOENT;          /* Arrange to disable SMP */
104 -               goto out;
105 +       cpus_node = of_find_node_by_path("/cpus");
106 +       if (!cpus_node)
107 +               return;
108 +
109 +       for_each_child_of_node(cpus_node, cpu_node) {
110 +               u32 cpuid;
111 +
112 +               if (of_node_cmp(cpu_node->type, "cpu"))
113 +                       continue;
114 +
115 +               if (of_property_read_u32(cpu_node, "reg", &cpuid)) {
116 +                       pr_debug("%s: missing reg property\n",
117 +                                    cpu_node->full_name);
118 +                       ret = -ENOENT;
119 +                       goto out;
120 +               }
121 +
122 +               /*
123 +                * "secondary-boot-reg" property should be defined only
124 +                * for secondary cpu
125 +                */
126 +               if ((cpuid & MPIDR_CPUID_BITMASK) == 1) {
127 +                       /*
128 +                        * Our secondary enable method requires a
129 +                        * "secondary-boot-reg" property to specify a register
130 +                        * address used to request the ROM code boot a secondary
131 +                        * core. If we have any trouble getting this we fall
132 +                        * back to uniprocessor mode.
133 +                        */
134 +                       if (of_property_read_u32(cpu_node,
135 +                                               OF_SECONDARY_BOOT,
136 +                                               &secondary_boot_addr)) {
137 +                               pr_warn("%s: no" OF_SECONDARY_BOOT "property\n",
138 +                                       cpu_node->name);
139 +                               ret = -ENOENT;
140 +                               goto out;
141 +                       }
142 +               }
143         }
144  
145         /*
146 -        * Enable the SCU on Cortex A9 based SoCs.  If -ENOENT is
147 +        * Enable the SCU on Cortex A9 based SoCs. If -ENOENT is
148          * returned, the SoC reported a uniprocessor configuration.
149          * We bail on any other error.
150          */
151         ret = scu_a9_enable();
152  out:
153 -       of_node_put(node);
154 +       of_node_put(cpu_node);
155 +       of_node_put(cpus_node);
156 +
157         if (ret) {
158                 /* Update the CPU present map to reflect uniprocessor mode */
159 -               BUG_ON(ret != -ENOENT);
160                 pr_warn("disabling SMP\n");
161                 init_cpu_present(&only_cpu_0);
162         }
163 @@ -139,7 +164,7 @@ out:
164   * - Wait for the secondary boot register to be re-written, which
165   *   indicates the secondary core has started.
166   */
167 -static int bcm_boot_secondary(unsigned int cpu, struct task_struct *idle)
168 +static int kona_boot_secondary(unsigned int cpu, struct task_struct *idle)
169  {
170         void __iomem *boot_reg;
171         phys_addr_t boot_func;
172 @@ -154,15 +179,16 @@ static int bcm_boot_secondary(unsigned i
173                 return -EINVAL;
174         }
175  
176 -       if (!secondary_boot) {
177 +       if (!secondary_boot_addr) {
178                 pr_err("required secondary boot register not specified\n");
179                 return -EINVAL;
180         }
181  
182 -       boot_reg = ioremap_nocache((phys_addr_t)secondary_boot, sizeof(u32));
183 +       boot_reg = ioremap_nocache(
184 +                       (phys_addr_t)secondary_boot_addr, sizeof(u32));
185         if (!boot_reg) {
186                 pr_err("unable to map boot register for cpu %u\n", cpu_id);
187 -               return -ENOSYS;
188 +               return -ENOMEM;
189         }
190  
191         /*
192 @@ -191,12 +217,12 @@ static int bcm_boot_secondary(unsigned i
193  
194         pr_err("timeout waiting for cpu %u to start\n", cpu_id);
195  
196 -       return -ENOSYS;
197 +       return -ENXIO;
198  }
199  
200  static struct smp_operations bcm_smp_ops __initdata = {
201         .smp_prepare_cpus       = bcm_smp_prepare_cpus,
202 -       .smp_boot_secondary     = bcm_boot_secondary,
203 +       .smp_boot_secondary     = kona_boot_secondary,
204  };
205  CPU_METHOD_OF_DECLARE(bcm_smp_bcm281xx, "brcm,bcm11351-cpu-method",
206                         &bcm_smp_ops);