[linux-yocto] [PATCH 43/94] arm/mach-axxia: Clean up the sequence of starting other cores.

Paul Butler butler.paul at gmail.com
Thu Nov 7 17:12:57 PST 2013


From: John Jacques <john.jacques at lsi.com>

Signed-off-by: John Jacques <john.jacques at lsi.com>
---
 arch/arm/mach-axxia/platsmp.c | 58 ++++++++++++++++++++++++++++++-------------
 1 file changed, 41 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-axxia/platsmp.c b/arch/arm/mach-axxia/platsmp.c
index 8d6dbd8..bad6e67 100644
--- a/arch/arm/mach-axxia/platsmp.c
+++ b/arch/arm/mach-axxia/platsmp.c
@@ -35,6 +35,16 @@ extern void axxia_secondary_startup(void);
 #define APB2_SER3_ADDR_SIZE   0x10000
 
 /*
+  flush_l3
+*/
+
+static void
+flush_l3(void)
+{
+	return;
+}
+
+/*
  * Write pen_release in a way that is guaranteed to be visible to all
  * observers, irrespective of whether they're taking part in coherency
  * or not.  This is necessary for the hotplug code to work reliably.
@@ -45,6 +55,7 @@ static void __cpuinit write_pen_release(int val)
 	smp_wmb();
 	__cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
 	outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
+	flush_l3();
 }
 
 static DEFINE_RAW_SPINLOCK(boot_lock);
@@ -191,7 +202,7 @@ platform_smp_prepare_cpus(unsigned int max_cpus)
 	int i;
 	void __iomem *apb2_ser3_base;
 	unsigned long resetVal;
-	int phys_cpu, cpu_count=0;
+	int phys_cpu, cpu_count = 0;
 	struct device_node *np;
 	unsigned long release_addr[NR_CPUS] = {0};
 	unsigned long release;
@@ -216,25 +227,33 @@ platform_smp_prepare_cpus(unsigned int max_cpus)
 		 * actually populated at the present time.
 		 */
 
-		apb2_ser3_base = ioremap(APB2_SER3_PHY_ADDR, APB2_SER3_ADDR_SIZE);
+		apb2_ser3_base =
+			ioremap(APB2_SER3_PHY_ADDR, APB2_SER3_ADDR_SIZE);
 
-		for (i = 0; i < NR_CPUS; i++) {	
+		for (i = 0; i < NR_CPUS; i++) {
 			/* check if this is a possible CPU and
 			   it is within max_cpus range */
 			if ((cpu_possible(i)) &&
 			    (cpu_count < max_cpus) &&
 			    (0 != release_addr[i])) {
-				resetVal = readl(apb2_ser3_base + 0x1010);
-				phys_cpu = cpu_logical_map(i);
 				set_cpu_present(cpu_count, true);
-				if (phys_cpu != 0) {
-					writel(0xab, apb2_ser3_base+0x1000);
-					resetVal &= ~(1 << phys_cpu);
-					writel(resetVal, apb2_ser3_base+0x1010);
-					udelay(1000);
-				}
 				cpu_count++;
 			}
+
+			/* Release all physical cpu:s since we might want to
+			 * bring them online later. Also we need to get the
+			 * execution into kernel code (it's currently executing
+			 * in u-boot).
+			 */
+			phys_cpu = cpu_logical_map(i);
+
+			if (phys_cpu != 0) {
+				resetVal = readl(apb2_ser3_base + 0x1010);
+				writel(0xab, apb2_ser3_base+0x1000);
+				resetVal &= ~(1 << phys_cpu);
+				writel(resetVal, apb2_ser3_base+0x1010);
+				udelay(1000);
+			}
 		}
 
 		iounmap(apb2_ser3_base);
@@ -244,14 +263,19 @@ platform_smp_prepare_cpus(unsigned int max_cpus)
 		 * cores will execute once they are released from their
 		 * "holding pen".
 		 */
-		*(u32 *)phys_to_virt(release) =
-			virt_to_phys(axxia_secondary_startup);
-		smp_wmb();
-		__cpuc_flush_dcache_area((void *)phys_to_virt(release),
-					 sizeof(u32));
+		for (i = 0; i < NR_CPUS; i++) {
+			if (release_addr[i] != 0) {
+				u32 *vrel_addr =
+					(u32 *)phys_to_virt(release_addr[i]);
+				*vrel_addr =
+					virt_to_phys(axxia_secondary_startup);
+				smp_wmb();
+				__cpuc_flush_dcache_area(vrel_addr, sizeof(u32));
+			}
+		}
 	} else if (of_find_compatible_node(NULL, NULL, "lsi,axm5516-sim")) {
 		for (i = 0; i < max_cpus; i++)
-                	set_cpu_present(i, true);
+			set_cpu_present(i, true);
 
 		/*
 		 * This is the entry point of the routine that the secondary
-- 
1.8.3.4




More information about the linux-yocto mailing list