aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mn10300/mm/cache-inv-icache.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mn10300/mm/cache-inv-icache.c')
-rw-r--r--arch/mn10300/mm/cache-inv-icache.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/arch/mn10300/mm/cache-inv-icache.c b/arch/mn10300/mm/cache-inv-icache.c
index 4a3f7afcfe5..a8933a60b2d 100644
--- a/arch/mn10300/mm/cache-inv-icache.c
+++ b/arch/mn10300/mm/cache-inv-icache.c
@@ -12,6 +12,8 @@
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/mm.h> 13#include <linux/mm.h>
14#include <asm/cacheflush.h> 14#include <asm/cacheflush.h>
15#include <asm/smp.h>
16#include "cache-smp.h"
15 17
16/** 18/**
17 * flush_icache_page_range - Flush dcache and invalidate icache for part of a 19 * flush_icache_page_range - Flush dcache and invalidate icache for part of a
@@ -66,7 +68,8 @@ static void flush_icache_page_range(unsigned long start, unsigned long end)
66 addr = page_to_phys(page); 68 addr = page_to_phys(page);
67 69
68 /* invalidate the icache coverage on that region */ 70 /* invalidate the icache coverage on that region */
69 mn10300_icache_inv_range2(addr + off, size); 71 mn10300_local_icache_inv_range2(addr + off, size);
72 smp_cache_call(SMP_ICACHE_INV_FLUSH_RANGE, start, end);
70} 73}
71 74
72/** 75/**
@@ -81,28 +84,31 @@ static void flush_icache_page_range(unsigned long start, unsigned long end)
81void flush_icache_range(unsigned long start, unsigned long end) 84void flush_icache_range(unsigned long start, unsigned long end)
82{ 85{
83 unsigned long start_page, end_page; 86 unsigned long start_page, end_page;
87 unsigned long flags;
88
89 flags = smp_lock_cache();
84 90
85 if (end > 0x80000000UL) { 91 if (end > 0x80000000UL) {
86 /* addresses above 0xa0000000 do not go through the cache */ 92 /* addresses above 0xa0000000 do not go through the cache */
87 if (end > 0xa0000000UL) { 93 if (end > 0xa0000000UL) {
88 end = 0xa0000000UL; 94 end = 0xa0000000UL;
89 if (start >= end) 95 if (start >= end)
90 return; 96 goto done;
91 } 97 }
92 98
93 /* kernel addresses between 0x80000000 and 0x9fffffff do not 99 /* kernel addresses between 0x80000000 and 0x9fffffff do not
94 * require page tables, so we just map such addresses 100 * require page tables, so we just map such addresses
95 * directly */ 101 * directly */
96 start_page = (start >= 0x80000000UL) ? start : 0x80000000UL; 102 start_page = (start >= 0x80000000UL) ? start : 0x80000000UL;
97 mn10300_dcache_flush_range(start_page, end);
98 mn10300_icache_inv_range(start_page, end); 103 mn10300_icache_inv_range(start_page, end);
104 smp_cache_call(SMP_ICACHE_INV_FLUSH_RANGE, start, end);
99 if (start_page == start) 105 if (start_page == start)
100 return; 106 goto done;
101 end = start_page; 107 end = start_page;
102 } 108 }
103 109
104 start_page = start & PAGE_MASK; 110 start_page = start & PAGE_MASK;
105 end_page = end & PAGE_MASK; 111 end_page = (end - 1) & PAGE_MASK;
106 112
107 if (start_page == end_page) { 113 if (start_page == end_page) {
108 /* the first and last bytes are on the same page */ 114 /* the first and last bytes are on the same page */
@@ -113,7 +119,11 @@ void flush_icache_range(unsigned long start, unsigned long end)
113 flush_icache_page_range(end_page, end); 119 flush_icache_page_range(end_page, end);
114 } else { 120 } else {
115 /* more than 2 pages; just flush the entire cache */ 121 /* more than 2 pages; just flush the entire cache */
116 mn10300_icache_inv(); 122 mn10300_local_icache_inv();
123 smp_cache_call(SMP_ICACHE_INV, 0, 0);
117 } 124 }
125
126done:
127 smp_unlock_cache(flags);
118} 128}
119EXPORT_SYMBOL(flush_icache_range); 129EXPORT_SYMBOL(flush_icache_range);