m68k: fix ColdFire clear cache operation
authorGreg Ungerer <gerg@uclinux.org>
Tue, 10 Jul 2012 03:33:24 +0000 (13:33 +1000)
committerGreg Ungerer <gerg@uclinux.org>
Tue, 17 Jul 2012 05:49:34 +0000 (15:49 +1000)
The code for clearing (invalidating) the ColdFire cache is actually performing
a push operation. Add functions to clear the cache, and fix cache_clear() to
call the appropriate clear cache function.

Signed-off-by: Greg Ungerer <gerg@uclinux.org>
arch/m68k/include/asm/cacheflush_mm.h
arch/m68k/mm/memory.c

index 8104bd874649560e607689b3240d9c64487b2be3..fa2c3d681d84cb5d0abcd562fcd64642cbcdcb2a 100644 (file)
 #define DCACHE_MAX_ADDR        0
 #define DCACHE_SETMASK 0
 #endif
+#ifndef CACHE_MODE
+#define        CACHE_MODE      0
+#define        CACR_ICINVA     0
+#define        CACR_DCINVA     0
+#define        CACR_BCINVA     0
+#endif
+
+/*
+ * ColdFire architecture has no way to clear individual cache lines, so we
+ * are stuck invalidating all the cache entries when we want a clear operation.
+ */
+static inline void clear_cf_icache(unsigned long start, unsigned long end)
+{
+       __asm__ __volatile__ (
+               "movec  %0,%%cacr\n\t"
+               "nop"
+               :
+               : "r" (CACHE_MODE | CACR_ICINVA | CACR_BCINVA));
+}
+
+static inline void clear_cf_dcache(unsigned long start, unsigned long end)
+{
+       __asm__ __volatile__ (
+               "movec  %0,%%cacr\n\t"
+               "nop"
+               :
+               : "r" (CACHE_MODE | CACR_DCINVA));
+}
 
+static inline void clear_cf_bcache(unsigned long start, unsigned long end)
+{
+       __asm__ __volatile__ (
+               "movec  %0,%%cacr\n\t"
+               "nop"
+               :
+               : "r" (CACHE_MODE | CACR_ICINVA | CACR_BCINVA | CACR_DCINVA));
+}
+
+/*
+ * Use the ColdFire cpushl instruction to push (and invalidate) cache lines.
+ * The start and end addresses are cache line numbers not memory addresses.
+ */
 static inline void flush_cf_icache(unsigned long start, unsigned long end)
 {
        unsigned long set;
index 250b8b786f4f344e70298722340e1c07b83cc5c6..51bc9d258ede39b8e9dd244b2a493974ed6ed552 100644 (file)
@@ -203,7 +203,7 @@ static inline void pushcl040(unsigned long paddr)
 void cache_clear (unsigned long paddr, int len)
 {
     if (CPU_IS_COLDFIRE) {
-       flush_cf_bcache(0, DCACHE_MAX_ADDR);
+       clear_cf_bcache(0, DCACHE_MAX_ADDR);
     } else if (CPU_IS_040_OR_060) {
        int tmp;