From: Greg Ungerer <g...@uclinux.org>

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 <g...@uclinux.org>
---
 arch/m68k/include/asm/cacheflush_mm.h |   41 +++++++++++++++++++++++++++++++++
 arch/m68k/mm/memory.c                 |    2 +-
 2 files changed, 42 insertions(+), 1 deletions(-)

diff --git a/arch/m68k/include/asm/cacheflush_mm.h 
b/arch/m68k/include/asm/cacheflush_mm.h
index 8104bd8..a32ffc9 100644
--- a/arch/m68k/include/asm/cacheflush_mm.h
+++ b/arch/m68k/include/asm/cacheflush_mm.h
@@ -17,6 +17,47 @@
 #define DCACHE_SETMASK 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__ (
+               "movel  %0,%%d0\n\t"
+               "movec  %%d0,%%cacr\n\t"
+               "nop\n\t"
+               :
+               : "i" (CACHE_MODE | CACR_ICINVA | CACR_BCINVA)
+               : "d0");
+}
+
+static inline void clear_cf_dcache(unsigned long start, unsigned long end)
+{
+       __asm__ __volatile__ (
+               "movel  %0,%%d0\n\t"
+               "movec  %%d0,%%cacr\n\t"
+               "nop\n\t"
+               :
+               : "i" (CACHE_MODE | CACR_DCINVA)
+               : "d0");
+}
+
+static inline void clear_cf_bcache(unsigned long start, unsigned long end)
+{
+       __asm__ __volatile__ (
+               "movel  %0,%%d0\n\t"
+               "movec  %%d0,%%cacr\n\t"
+               "nop\n\t"
+               :
+               : "i" (CACHE_MODE | CACR_ICINVA | CACR_BCINVA | CACR_DCINVA)
+               : "d0");
+}
+
+/*
+ * 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;
diff --git a/arch/m68k/mm/memory.c b/arch/m68k/mm/memory.c
index 250b8b7..51bc9d2 100644
--- a/arch/m68k/mm/memory.c
+++ b/arch/m68k/mm/memory.c
@@ -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;
 
-- 
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-m68k" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to