131-ARM-BCM-Clean-up-SMP-support-for-Broadcom-Kona.patch 6.0 KB

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