From: John Jacques <john.jacq...@lsi.com>

Signed-off-by: John Jacques <john.jacq...@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

_______________________________________________
linux-yocto mailing list
linux-yocto@yoctoproject.org
https://lists.yoctoproject.org/listinfo/linux-yocto

Reply via email to