[linux-yocto] [PATCH 028/161] arm/mach-axxia: Clean up the sequence of starting other cores.
Cristian Bercaru
cristian.bercaru at windriver.com
Thu May 21 12:20:10 PDT 2015
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.7.9.5
More information about the linux-yocto
mailing list