aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/parisc/kernel/cache.c45
-rw-r--r--include/asm-parisc/cacheflush.h30
-rw-r--r--include/asm-parisc/page.h22
-rw-r--r--include/asm-parisc/processor.h13
4 files changed, 87 insertions, 23 deletions
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
index bc7c4a4e26a1..7e8d697aef36 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -91,7 +91,8 @@ update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
91 91
92 flush_kernel_dcache_page(page); 92 flush_kernel_dcache_page(page);
93 clear_bit(PG_dcache_dirty, &page->flags); 93 clear_bit(PG_dcache_dirty, &page->flags);
94 } 94 } else if (parisc_requires_coherency())
95 flush_kernel_dcache_page(page);
95} 96}
96 97
97void 98void
@@ -370,3 +371,45 @@ void parisc_setup_cache_timing(void)
370 371
371 printk(KERN_INFO "Setting cache flush threshold to %x (%d CPUs online)\n", parisc_cache_flush_threshold, num_online_cpus()); 372 printk(KERN_INFO "Setting cache flush threshold to %x (%d CPUs online)\n", parisc_cache_flush_threshold, num_online_cpus());
372} 373}
374
375extern void purge_kernel_dcache_page(unsigned long);
376extern void clear_user_page_asm(void *page, unsigned long vaddr);
377
378void
379clear_user_page(void *page, unsigned long vaddr, struct page *pg)
380{
381 purge_kernel_dcache_page((unsigned long)page);
382 purge_tlb_start();
383 pdtlb_kernel(page);
384 purge_tlb_end();
385 clear_user_page_asm(page, vaddr);
386}
387
388void flush_kernel_dcache_page_addr(void *addr)
389{
390 flush_kernel_dcache_page_asm(addr);
391 purge_tlb_start();
392 pdtlb_kernel(addr);
393 purge_tlb_end();
394}
395EXPORT_SYMBOL(flush_kernel_dcache_page_addr);
396
397void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
398 struct page *pg)
399{
400 /* no coherency needed (all in kmap/kunmap) */
401 copy_user_page_asm(vto, vfrom);
402 if (!parisc_requires_coherency())
403 flush_kernel_dcache_page_asm(vto);
404}
405EXPORT_SYMBOL(copy_user_page);
406
407#ifdef CONFIG_PA8X00
408
409void kunmap_parisc(void *addr)
410{
411 if (parisc_requires_coherency())
412 flush_kernel_dcache_page_addr(addr);
413}
414EXPORT_SYMBOL(kunmap_parisc);
415#endif
diff --git a/include/asm-parisc/cacheflush.h b/include/asm-parisc/cacheflush.h
index 0b459cdfbd6f..2bc41f2e0271 100644
--- a/include/asm-parisc/cacheflush.h
+++ b/include/asm-parisc/cacheflush.h
@@ -191,16 +191,38 @@ flush_anon_page(struct page *page, unsigned long vmaddr)
191} 191}
192#define ARCH_HAS_FLUSH_ANON_PAGE 192#define ARCH_HAS_FLUSH_ANON_PAGE
193 193
194static inline void 194#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
195flush_kernel_dcache_page(struct page *page) 195void flush_kernel_dcache_page_addr(void *addr);
196static inline void flush_kernel_dcache_page(struct page *page)
196{ 197{
197 flush_kernel_dcache_page_asm(page_address(page)); 198 flush_kernel_dcache_page_addr(page_address(page));
198} 199}
199#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
200 200
201#ifdef CONFIG_DEBUG_RODATA 201#ifdef CONFIG_DEBUG_RODATA
202void mark_rodata_ro(void); 202void mark_rodata_ro(void);
203#endif 203#endif
204 204
205#ifdef CONFIG_PA8X00
206/* Only pa8800, pa8900 needs this */
207#define ARCH_HAS_KMAP
208
209void kunmap_parisc(void *addr);
210
211static inline void *kmap(struct page *page)
212{
213 might_sleep();
214 return page_address(page);
215}
216
217#define kunmap(page) kunmap_parisc(page_address(page))
218
219#define kmap_atomic(page, idx) page_address(page)
220
221#define kunmap_atomic(addr, idx) kunmap_parisc(addr)
222
223#define kmap_atomic_pfn(pfn, idx) page_address(pfn_to_page(pfn))
224#define kmap_atomic_to_page(ptr) virt_to_page(ptr)
225#endif
226
205#endif /* _PARISC_CACHEFLUSH_H */ 227#endif /* _PARISC_CACHEFLUSH_H */
206 228
diff --git a/include/asm-parisc/page.h b/include/asm-parisc/page.h
index 57d6d82756dd..3567208191e3 100644
--- a/include/asm-parisc/page.h
+++ b/include/asm-parisc/page.h
@@ -26,24 +26,10 @@
26 26
27struct page; 27struct page;
28 28
29extern void purge_kernel_dcache_page(unsigned long); 29void copy_user_page_asm(void *to, void *from);
30extern void copy_user_page_asm(void *to, void *from); 30void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
31extern void clear_user_page_asm(void *page, unsigned long vaddr); 31 struct page *pg);
32 32void clear_user_page(void *page, unsigned long vaddr, struct page *pg);
33static inline void
34copy_user_page(void *vto, void *vfrom, unsigned long vaddr, struct page *pg)
35{
36 copy_user_page_asm(vto, vfrom);
37 flush_kernel_dcache_page_asm(vto);
38 /* XXX: ppc flushes icache too, should we? */
39}
40
41static inline void
42clear_user_page(void *page, unsigned long vaddr, struct page *pg)
43{
44 purge_kernel_dcache_page((unsigned long)page);
45 clear_user_page_asm(page, vaddr);
46}
47 33
48/* 34/*
49 * These are used to make use of C type-checking.. 35 * These are used to make use of C type-checking..
diff --git a/include/asm-parisc/processor.h b/include/asm-parisc/processor.h
index c72b8fa49686..4313618c98ee 100644
--- a/include/asm-parisc/processor.h
+++ b/include/asm-parisc/processor.h
@@ -332,6 +332,19 @@ extern unsigned long get_wchan(struct task_struct *p);
332 332
333#define cpu_relax() barrier() 333#define cpu_relax() barrier()
334 334
335/* Used as a macro to identify the combined VIPT/PIPT cached
336 * CPUs which require a guarantee of coherency (no inequivalent
337 * aliases with different data, whether clean or not) to operate */
338static inline int parisc_requires_coherency(void)
339{
340#ifdef CONFIG_PA8X00
341 /* FIXME: also pa8900 - when we see one */
342 return boot_cpu_data.cpu_type == mako;
343#else
344 return 0;
345#endif
346}
347
335#endif /* __ASSEMBLY__ */ 348#endif /* __ASSEMBLY__ */
336 349
337#endif /* __ASM_PARISC_PROCESSOR_H */ 350#endif /* __ASM_PARISC_PROCESSOR_H */