diff options
author | Greg Ungerer <gerg@uclinux.org> | 2012-07-09 23:33:24 -0400 |
---|---|---|
committer | Greg Ungerer <gerg@uclinux.org> | 2012-07-17 01:49:34 -0400 |
commit | f3ff6432dde9c0800754f1f144f6e864ac228214 (patch) | |
tree | 16739657a2a113ceda333e428b393caf0e6774f1 /arch/m68k | |
parent | b60f187fecee5d9dceb89773e15f976fe21d893a (diff) |
m68k: fix ColdFire clear cache operation
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>
Diffstat (limited to 'arch/m68k')
-rw-r--r-- | arch/m68k/include/asm/cacheflush_mm.h | 41 | ||||
-rw-r--r-- | 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 8104bd874649..fa2c3d681d84 100644 --- a/arch/m68k/include/asm/cacheflush_mm.h +++ b/arch/m68k/include/asm/cacheflush_mm.h | |||
@@ -16,7 +16,48 @@ | |||
16 | #define DCACHE_MAX_ADDR 0 | 16 | #define DCACHE_MAX_ADDR 0 |
17 | #define DCACHE_SETMASK 0 | 17 | #define DCACHE_SETMASK 0 |
18 | #endif | 18 | #endif |
19 | #ifndef CACHE_MODE | ||
20 | #define CACHE_MODE 0 | ||
21 | #define CACR_ICINVA 0 | ||
22 | #define CACR_DCINVA 0 | ||
23 | #define CACR_BCINVA 0 | ||
24 | #endif | ||
25 | |||
26 | /* | ||
27 | * ColdFire architecture has no way to clear individual cache lines, so we | ||
28 | * are stuck invalidating all the cache entries when we want a clear operation. | ||
29 | */ | ||
30 | static inline void clear_cf_icache(unsigned long start, unsigned long end) | ||
31 | { | ||
32 | __asm__ __volatile__ ( | ||
33 | "movec %0,%%cacr\n\t" | ||
34 | "nop" | ||
35 | : | ||
36 | : "r" (CACHE_MODE | CACR_ICINVA | CACR_BCINVA)); | ||
37 | } | ||
38 | |||
39 | static inline void clear_cf_dcache(unsigned long start, unsigned long end) | ||
40 | { | ||
41 | __asm__ __volatile__ ( | ||
42 | "movec %0,%%cacr\n\t" | ||
43 | "nop" | ||
44 | : | ||
45 | : "r" (CACHE_MODE | CACR_DCINVA)); | ||
46 | } | ||
19 | 47 | ||
48 | static inline void clear_cf_bcache(unsigned long start, unsigned long end) | ||
49 | { | ||
50 | __asm__ __volatile__ ( | ||
51 | "movec %0,%%cacr\n\t" | ||
52 | "nop" | ||
53 | : | ||
54 | : "r" (CACHE_MODE | CACR_ICINVA | CACR_BCINVA | CACR_DCINVA)); | ||
55 | } | ||
56 | |||
57 | /* | ||
58 | * Use the ColdFire cpushl instruction to push (and invalidate) cache lines. | ||
59 | * The start and end addresses are cache line numbers not memory addresses. | ||
60 | */ | ||
20 | static inline void flush_cf_icache(unsigned long start, unsigned long end) | 61 | static inline void flush_cf_icache(unsigned long start, unsigned long end) |
21 | { | 62 | { |
22 | unsigned long set; | 63 | unsigned long set; |
diff --git a/arch/m68k/mm/memory.c b/arch/m68k/mm/memory.c index 250b8b786f4f..51bc9d258ede 100644 --- a/arch/m68k/mm/memory.c +++ b/arch/m68k/mm/memory.c | |||
@@ -203,7 +203,7 @@ static inline void pushcl040(unsigned long paddr) | |||
203 | void cache_clear (unsigned long paddr, int len) | 203 | void cache_clear (unsigned long paddr, int len) |
204 | { | 204 | { |
205 | if (CPU_IS_COLDFIRE) { | 205 | if (CPU_IS_COLDFIRE) { |
206 | flush_cf_bcache(0, DCACHE_MAX_ADDR); | 206 | clear_cf_bcache(0, DCACHE_MAX_ADDR); |
207 | } else if (CPU_IS_040_OR_060) { | 207 | } else if (CPU_IS_040_OR_060) { |
208 | int tmp; | 208 | int tmp; |
209 | 209 | ||