diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2014-03-15 16:47:47 +0000 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2014-05-22 16:38:38 +0100 |
commit | 03a166e22a49350010fc398a8cb9be3e93192fef (patch) | |
tree | 1e2a1286e8b1505530a636c09395ff52b1fe1cce /arch/arm/mach-spear/platsmp.c | |
parent | b13b9e98b80fa24460a011ba0378d3fe56137a31 (diff) | |
download | op-kernel-dev-03a166e22a49350010fc398a8cb9be3e93192fef.zip op-kernel-dev-03a166e22a49350010fc398a8cb9be3e93192fef.tar.gz |
ARM: l2c: avoid calling outer_flush_all() unnecessarily (Spear)
Spear calls outer_flush_all() from it's SMP bringup function. This
is potentially dangerous as the L2C set/way operations which implement
this don't take kindly to concurrent operations. Besides, there's
better solutions to this, as implemented on other platforms.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-spear/platsmp.c')
-rw-r--r-- | arch/arm/mach-spear/platsmp.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/arch/arm/mach-spear/platsmp.c b/arch/arm/mach-spear/platsmp.c index c19751f..fd42977 100644 --- a/arch/arm/mach-spear/platsmp.c +++ b/arch/arm/mach-spear/platsmp.c @@ -20,6 +20,18 @@ #include <mach/spear.h> #include "generic.h" +/* + * 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(); + sync_cache_w(&pen_release); +} + static DEFINE_SPINLOCK(boot_lock); static void __iomem *scu_base = IOMEM(VA_SCU_BASE); @@ -30,8 +42,7 @@ static void spear13xx_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. @@ -58,9 +69,7 @@ static int spear13xx_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(); - outer_flush_all(); + write_pen_release(cpu); timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { |