diff options
author | Paul Mundt <lethal@linux-sh.org> | 2009-08-21 04:23:14 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-08-21 04:23:14 -0400 |
commit | f26b2a562b46ab186c8383993ab1332673ac4a47 (patch) | |
tree | 5cf52089da5ca762c07cf6c1364a6aa411fb3038 /arch/sh/mm/cache.c | |
parent | f9bd71f255b4349c4f9f596863161fd5182f67fa (diff) |
sh: Make cache flushers SMP-aware.
This does a bit of rework for making the cache flushers SMP-aware. The
function pointer-based flushers are renamed to local variants with the
exported interface being commonly implemented and wrapping as necessary.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/mm/cache.c')
-rw-r--r-- | arch/sh/mm/cache.c | 137 |
1 files changed, 78 insertions, 59 deletions
diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c index d60239460436..411fe6058429 100644 --- a/arch/sh/mm/cache.c +++ b/arch/sh/mm/cache.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * arch/sh/mm/pg-mmu.c | 2 | * arch/sh/mm/cache.c |
3 | * | 3 | * |
4 | * Copyright (C) 1999, 2000, 2002 Niibe Yutaka | 4 | * Copyright (C) 1999, 2000, 2002 Niibe Yutaka |
5 | * Copyright (C) 2002 - 2009 Paul Mundt | 5 | * Copyright (C) 2002 - 2009 Paul Mundt |
@@ -10,63 +10,26 @@ | |||
10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
11 | #include <linux/mutex.h> | 11 | #include <linux/mutex.h> |
12 | #include <linux/fs.h> | 12 | #include <linux/fs.h> |
13 | #include <linux/smp.h> | ||
13 | #include <linux/highmem.h> | 14 | #include <linux/highmem.h> |
14 | #include <linux/module.h> | 15 | #include <linux/module.h> |
15 | #include <asm/mmu_context.h> | 16 | #include <asm/mmu_context.h> |
16 | #include <asm/cacheflush.h> | 17 | #include <asm/cacheflush.h> |
17 | 18 | ||
18 | void (*flush_cache_all)(void); | 19 | void (*local_flush_cache_all)(void *args) = cache_noop; |
19 | void (*flush_cache_mm)(struct mm_struct *mm); | 20 | void (*local_flush_cache_mm)(void *args) = cache_noop; |
20 | void (*flush_cache_dup_mm)(struct mm_struct *mm); | 21 | void (*local_flush_cache_dup_mm)(void *args) = cache_noop; |
21 | void (*flush_cache_page)(struct vm_area_struct *vma, | 22 | void (*local_flush_cache_page)(void *args) = cache_noop; |
22 | unsigned long addr, unsigned long pfn); | 23 | void (*local_flush_cache_range)(void *args) = cache_noop; |
23 | void (*flush_cache_range)(struct vm_area_struct *vma, | 24 | void (*local_flush_dcache_page)(void *args) = cache_noop; |
24 | unsigned long start, unsigned long end); | 25 | void (*local_flush_icache_range)(void *args) = cache_noop; |
25 | void (*flush_dcache_page)(struct page *page); | 26 | void (*local_flush_icache_page)(void *args) = cache_noop; |
26 | void (*flush_icache_range)(unsigned long start, unsigned long end); | 27 | void (*local_flush_cache_sigtramp)(void *args) = cache_noop; |
27 | void (*flush_icache_page)(struct vm_area_struct *vma, | 28 | |
28 | struct page *page); | ||
29 | void (*flush_cache_sigtramp)(unsigned long address); | ||
30 | void (*__flush_wback_region)(void *start, int size); | 29 | void (*__flush_wback_region)(void *start, int size); |
31 | void (*__flush_purge_region)(void *start, int size); | 30 | void (*__flush_purge_region)(void *start, int size); |
32 | void (*__flush_invalidate_region)(void *start, int size); | 31 | void (*__flush_invalidate_region)(void *start, int size); |
33 | 32 | ||
34 | static inline void noop_flush_cache_all(void) | ||
35 | { | ||
36 | } | ||
37 | |||
38 | static inline void noop_flush_cache_mm(struct mm_struct *mm) | ||
39 | { | ||
40 | } | ||
41 | |||
42 | static inline void noop_flush_cache_page(struct vm_area_struct *vma, | ||
43 | unsigned long addr, unsigned long pfn) | ||
44 | { | ||
45 | } | ||
46 | |||
47 | static inline void noop_flush_cache_range(struct vm_area_struct *vma, | ||
48 | unsigned long start, unsigned long end) | ||
49 | { | ||
50 | } | ||
51 | |||
52 | static inline void noop_flush_dcache_page(struct page *page) | ||
53 | { | ||
54 | } | ||
55 | |||
56 | static inline void noop_flush_icache_range(unsigned long start, | ||
57 | unsigned long end) | ||
58 | { | ||
59 | } | ||
60 | |||
61 | static inline void noop_flush_icache_page(struct vm_area_struct *vma, | ||
62 | struct page *page) | ||
63 | { | ||
64 | } | ||
65 | |||
66 | static inline void noop_flush_cache_sigtramp(unsigned long address) | ||
67 | { | ||
68 | } | ||
69 | |||
70 | static inline void noop__flush_region(void *start, int size) | 33 | static inline void noop__flush_region(void *start, int size) |
71 | { | 34 | { |
72 | } | 35 | } |
@@ -184,6 +147,72 @@ void __flush_anon_page(struct page *page, unsigned long vmaddr) | |||
184 | } | 147 | } |
185 | } | 148 | } |
186 | 149 | ||
150 | void flush_cache_all(void) | ||
151 | { | ||
152 | on_each_cpu(local_flush_cache_all, NULL, 1); | ||
153 | } | ||
154 | |||
155 | void flush_cache_mm(struct mm_struct *mm) | ||
156 | { | ||
157 | on_each_cpu(local_flush_cache_mm, mm, 1); | ||
158 | } | ||
159 | |||
160 | void flush_cache_dup_mm(struct mm_struct *mm) | ||
161 | { | ||
162 | on_each_cpu(local_flush_cache_dup_mm, mm, 1); | ||
163 | } | ||
164 | |||
165 | void flush_cache_page(struct vm_area_struct *vma, unsigned long addr, | ||
166 | unsigned long pfn) | ||
167 | { | ||
168 | struct flusher_data data; | ||
169 | |||
170 | data.vma = vma; | ||
171 | data.addr1 = addr; | ||
172 | data.addr2 = pfn; | ||
173 | |||
174 | on_each_cpu(local_flush_cache_page, (void *)&data, 1); | ||
175 | } | ||
176 | |||
177 | void flush_cache_range(struct vm_area_struct *vma, unsigned long start, | ||
178 | unsigned long end) | ||
179 | { | ||
180 | struct flusher_data data; | ||
181 | |||
182 | data.vma = vma; | ||
183 | data.addr1 = start; | ||
184 | data.addr2 = end; | ||
185 | |||
186 | on_each_cpu(local_flush_cache_range, (void *)&data, 1); | ||
187 | } | ||
188 | |||
189 | void flush_dcache_page(struct page *page) | ||
190 | { | ||
191 | on_each_cpu(local_flush_dcache_page, page, 1); | ||
192 | } | ||
193 | |||
194 | void flush_icache_range(unsigned long start, unsigned long end) | ||
195 | { | ||
196 | struct flusher_data data; | ||
197 | |||
198 | data.vma = NULL; | ||
199 | data.addr1 = start; | ||
200 | data.addr2 = end; | ||
201 | |||
202 | on_each_cpu(local_flush_icache_range, (void *)&data, 1); | ||
203 | } | ||
204 | |||
205 | void flush_icache_page(struct vm_area_struct *vma, struct page *page) | ||
206 | { | ||
207 | /* Nothing uses the VMA, so just pass the struct page along */ | ||
208 | on_each_cpu(local_flush_icache_page, page, 1); | ||
209 | } | ||
210 | |||
211 | void flush_cache_sigtramp(unsigned long address) | ||
212 | { | ||
213 | on_each_cpu(local_flush_cache_sigtramp, (void *)address, 1); | ||
214 | } | ||
215 | |||
187 | static void compute_alias(struct cache_info *c) | 216 | static void compute_alias(struct cache_info *c) |
188 | { | 217 | { |
189 | c->alias_mask = ((c->sets - 1) << c->entry_shift) & ~(PAGE_SIZE - 1); | 218 | c->alias_mask = ((c->sets - 1) << c->entry_shift) & ~(PAGE_SIZE - 1); |
@@ -230,16 +259,6 @@ void __init cpu_cache_init(void) | |||
230 | compute_alias(&boot_cpu_data.dcache); | 259 | compute_alias(&boot_cpu_data.dcache); |
231 | compute_alias(&boot_cpu_data.scache); | 260 | compute_alias(&boot_cpu_data.scache); |
232 | 261 | ||
233 | flush_cache_all = noop_flush_cache_all; | ||
234 | flush_cache_mm = noop_flush_cache_mm; | ||
235 | flush_cache_dup_mm = noop_flush_cache_mm; | ||
236 | flush_cache_page = noop_flush_cache_page; | ||
237 | flush_cache_range = noop_flush_cache_range; | ||
238 | flush_dcache_page = noop_flush_dcache_page; | ||
239 | flush_icache_range = noop_flush_icache_range; | ||
240 | flush_icache_page = noop_flush_icache_page; | ||
241 | flush_cache_sigtramp = noop_flush_cache_sigtramp; | ||
242 | |||
243 | __flush_wback_region = noop__flush_region; | 262 | __flush_wback_region = noop__flush_region; |
244 | __flush_purge_region = noop__flush_region; | 263 | __flush_purge_region = noop__flush_region; |
245 | __flush_invalidate_region = noop__flush_region; | 264 | __flush_invalidate_region = noop__flush_region; |