ARM: uniphier: insert dsb barrier to ensure visibility of store
authorMasahiro Yamada <yamada.masahiro@socionext.com>
Wed, 8 Jun 2016 09:02:32 +0000 (18:02 +0900)
committerMasahiro Yamada <yamada.masahiro@socionext.com>
Wed, 8 Jun 2016 23:19:13 +0000 (08:19 +0900)
I noticed secondary CPUs sometimes fail to wake up, and the root
cause is that the sev instruction wakes up slave CPUs before the
preceding the register write is observed by them.

The read-back of the accessed register does not guarantee the order.
In order to ensure the order between the register write and the sev
instruction, a dsb instruction should be executed prior to the sev.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
arch/arm/mach-uniphier/arm64/smp_kick_cpus.c

index 64412e0ecce009ce19e13d7009f33bd49968e106..5971ad256b8b055db4bead72cb088c97dce8dcba 100644 (file)
@@ -21,11 +21,11 @@ void uniphier_smp_kick_all_cpus(void)
        rom_boot_rsv0 = map_sysmem(UNIPHIER_SMPCTRL_ROM_RSV0, SZ_8);
 
        writeq((u64)uniphier_secondary_startup, rom_boot_rsv0);
-       readq(rom_boot_rsv0);   /* relax */
 
        unmap_sysmem(rom_boot_rsv0);
 
        uniphier_smp_setup();
 
-       asm("sev"); /* Bring up all secondary CPUs from Boot ROM into U-Boot */
+       asm("dsb        ishst\n" /* Ensure the write to ROM_RSV0 is visible */
+           "sev"); /* Bring up all secondary CPUs from Boot ROM into U-Boot */
 }