From b3e707a0f9a3bbb5274d6d306d1e06b93481f8e0 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 4 Aug 2009 16:02:43 +0900 Subject: [PATCH] --- yaml --- r: 163354 b: refs/heads/master c: c0fe478dbb14fd32e71d1383dbe302b54ce94134 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/sh/include/asm/cacheflush.h | 14 ++++++++++++++ trunk/arch/sh/mm/pg-mmu.c | 17 +++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 38e1c93969c1..b0587643a383 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: b5eb10ae901fa797c19accb684825f0e36ecbe0f +refs/heads/master: c0fe478dbb14fd32e71d1383dbe302b54ce94134 diff --git a/trunk/arch/sh/include/asm/cacheflush.h b/trunk/arch/sh/include/asm/cacheflush.h index 4c85d55847cc..5dffbd126e46 100644 --- a/trunk/arch/sh/include/asm/cacheflush.h +++ b/trunk/arch/sh/include/asm/cacheflush.h @@ -1,6 +1,8 @@ #ifndef __ASM_SH_CACHEFLUSH_H #define __ASM_SH_CACHEFLUSH_H +#include + #ifdef __KERNEL__ #ifdef CONFIG_CACHE_OFF @@ -43,6 +45,18 @@ extern void __flush_purge_region(void *start, int size); extern void __flush_invalidate_region(void *start, int size); #endif +#ifdef CONFIG_MMU +#define ARCH_HAS_FLUSH_ANON_PAGE +extern void __flush_anon_page(struct page *page, unsigned long); + +static inline void flush_anon_page(struct vm_area_struct *vma, + struct page *page, unsigned long vmaddr) +{ + if (boot_cpu_data.dcache.n_aliases && PageAnon(page)) + __flush_anon_page(page, vmaddr); +} +#endif + #define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE static inline void flush_kernel_dcache_page(struct page *page) { diff --git a/trunk/arch/sh/mm/pg-mmu.c b/trunk/arch/sh/mm/pg-mmu.c index a9ede7bae520..027c4d83fb8e 100644 --- a/trunk/arch/sh/mm/pg-mmu.c +++ b/trunk/arch/sh/mm/pg-mmu.c @@ -157,3 +157,20 @@ void __update_cache(struct vm_area_struct *vma, } } } + +void __flush_anon_page(struct page *page, unsigned long vmaddr) +{ + unsigned long addr = (unsigned long) page_address(page); + + if (pages_do_alias(addr, vmaddr)) { + if (boot_cpu_data.dcache.n_aliases && page_mapped(page) && + !test_bit(PG_dcache_dirty, &page->flags)) { + void *kaddr; + + kaddr = kmap_coherent(page, vmaddr); + __flush_wback_region((void *)kaddr, PAGE_SIZE); + kunmap_coherent(); + } else + __flush_wback_region((void *)addr, PAGE_SIZE); + } +}