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.4.3 _______________________________________________ linux-yocto mailing list linux-yocto@yoctoproject.org https://lists.yoctoproject.org/listinfo/linux-yocto