diff options
Diffstat (limited to 'arch/arm/mach-realview')
-rw-r--r-- | arch/arm/mach-realview/platsmp.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c index 226c63102a00..bb8d6c4e4315 100644 --- a/arch/arm/mach-realview/platsmp.c +++ b/arch/arm/mach-realview/platsmp.c @@ -36,6 +36,19 @@ extern void realview_secondary_startup(void); */ volatile int __cpuinitdata pen_release = -1; +/* + * 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. + */ +static void write_pen_release(int val) +{ + pen_release = val; + smp_wmb(); + __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release)); + outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1)); +} + static void __iomem *scu_base_addr(void) { if (machine_is_realview_eb_mp()) @@ -64,8 +77,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu) * let the primary processor know we're out of the * pen, then head off into the C entry point */ - pen_release = -1; - smp_wmb(); + write_pen_release(-1); /* * Synchronise with the boot thread. @@ -92,8 +104,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) * Note that "pen_release" is the hardware CPU ID, whereas * "cpu" is Linux's internal ID. */ - pen_release = cpu; - flush_cache_all(); + write_pen_release(cpu); /* * Send the secondary CPU a soft interrupt, thereby causing |