summaryrefslogtreecommitdiff
path: root/arch/blackfin/mach-common/smp.c
diff options
context:
space:
mode:
authorSonic Zhang <sonic.zhang@analog.com>2011-04-12 12:16:04 +0400
committerMike Frysinger <vapier@gentoo.org>2011-04-14 03:34:06 +0400
commit8d50de9ee77b38a239dc5b1d6a63ad92a78f119d (patch)
tree43d24d6e0aadb9d75f196787819f6da9ef73aa07 /arch/blackfin/mach-common/smp.c
parent0bf02ce605b8780223b10739ab7c533de9eb10cc (diff)
downloadlinux-8d50de9ee77b38a239dc5b1d6a63ad92a78f119d.tar.xz
Blackfin: SMP: fix cache flush loop
The recent commit (10774912647781) wasn't entirely correct. While it fixed some issues, it introduced others. So pull in the fixes from the public cache flush functions, and document why we need to call things directly ourselves. Signed-off-by: Sonic Zhang <sonic.zhang@analog.com> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'arch/blackfin/mach-common/smp.c')
-rw-r--r--arch/blackfin/mach-common/smp.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c
index 6e17a265c4d3..8bce5ed031e4 100644
--- a/arch/blackfin/mach-common/smp.c
+++ b/arch/blackfin/mach-common/smp.c
@@ -109,10 +109,23 @@ static void ipi_flush_icache(void *info)
struct blackfin_flush_data *fdata = info;
/* Invalidate the memory holding the bounds of the flushed region. */
- invalidate_dcache_range((unsigned long)fdata,
- (unsigned long)fdata + sizeof(*fdata));
+ blackfin_dcache_invalidate_range((unsigned long)fdata,
+ (unsigned long)fdata + sizeof(*fdata));
+
+ /* Make sure all write buffers in the data side of the core
+ * are flushed before trying to invalidate the icache. This
+ * needs to be after the data flush and before the icache
+ * flush so that the SSYNC does the right thing in preventing
+ * the instruction prefetcher from hitting things in cached
+ * memory at the wrong time -- it runs much further ahead than
+ * the pipeline.
+ */
+ SSYNC();
- flush_icache_range(fdata->start, fdata->end);
+ /* ipi_flaush_icache is invoked by generic flush_icache_range,
+ * so call blackfin arch icache flush directly here.
+ */
+ blackfin_icache_flush_range(fdata->start, fdata->end);
}
static void ipi_call_function(unsigned int cpu, struct ipi_message *msg)