aboutsummaryrefslogtreecommitdiffstats
path: root/arch/avr32/mm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/avr32/mm')
-rw-r--r--arch/avr32/mm/cache.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/arch/avr32/mm/cache.c b/arch/avr32/mm/cache.c
index 450515b245a0..fb13f72e9a02 100644
--- a/arch/avr32/mm/cache.c
+++ b/arch/avr32/mm/cache.c
@@ -22,18 +22,34 @@
22 22
23void invalidate_dcache_region(void *start, size_t size) 23void invalidate_dcache_region(void *start, size_t size)
24{ 24{
25 unsigned long v, begin, end, linesz; 25 unsigned long v, begin, end, linesz, mask;
26 int flush = 0;
26 27
27 linesz = boot_cpu_data.dcache.linesz; 28 linesz = boot_cpu_data.dcache.linesz;
29 mask = linesz - 1;
30
31 /* when first and/or last cachelines are shared, flush them
32 * instead of invalidating ... never discard valid data!
33 */
34 begin = (unsigned long)start;
35 end = begin + size - 1;
36
37 if (begin & mask) {
38 flush_dcache_line(start);
39 begin += linesz;
40 flush = 1;
41 }
42 if ((end & mask) != mask) {
43 flush_dcache_line((void *)end);
44 end -= linesz;
45 flush = 1;
46 }
28 47
29 //printk("invalidate dcache: %p + %u\n", start, size); 48 /* remaining cachelines only need invalidation */
30 49 for (v = begin; v <= end; v += linesz)
31 /* You asked for it, you got it */
32 begin = (unsigned long)start & ~(linesz - 1);
33 end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);
34
35 for (v = begin; v < end; v += linesz)
36 invalidate_dcache_line((void *)v); 50 invalidate_dcache_line((void *)v);
51 if (flush)
52 flush_write_buffer();
37} 53}
38 54
39void clean_dcache_region(void *start, size_t size) 55void clean_dcache_region(void *start, size_t size)