ARM: l2c: avoid calling outer_flush_all() unnecessarily (Spear)
authorRussell King <rmk+kernel@arm.linux.org.uk>
Sat, 15 Mar 2014 16:47:47 +0000 (16:47 +0000)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Thu, 22 May 2014 15:38:38 +0000 (16:38 +0100)
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>
arch/arm/mach-spear/platsmp.c

index c19751fff2c60d3737b3b2c98688b0dd48d85c44..fd4297713d679c477b6b623c1162eff03c402f82 100644 (file)
 #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)) {