summaryrefslogtreecommitdiffstats
path: root/arch/sh/mm/cache-sh4.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/mm/cache-sh4.c')
-rw-r--r--arch/sh/mm/cache-sh4.c79
1 files changed, 18 insertions, 61 deletions
diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c
index 5cfe08dbb59..92f87a460a8 100644
--- a/arch/sh/mm/cache-sh4.c
+++ b/arch/sh/mm/cache-sh4.c
@@ -14,6 +14,7 @@
#include <linux/mm.h>
#include <linux/io.h>
#include <linux/mutex.h>
+#include <linux/fs.h>
#include <asm/mmu_context.h>
#include <asm/cacheflush.h>
@@ -118,66 +119,6 @@ void __init p3_cache_init(void)
}
/*
- * Write back the dirty D-caches, but not invalidate them.
- *
- * START: Virtual Address (U0, P1, or P3)
- * SIZE: Size of the region.
- */
-void __flush_wback_region(void *start, int size)
-{
- unsigned long v;
- unsigned long begin, end;
-
- begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
- end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
- & ~(L1_CACHE_BYTES-1);
- for (v = begin; v < end; v+=L1_CACHE_BYTES) {
- asm volatile("ocbwb %0"
- : /* no output */
- : "m" (__m(v)));
- }
-}
-
-/*
- * Write back the dirty D-caches and invalidate them.
- *
- * START: Virtual Address (U0, P1, or P3)
- * SIZE: Size of the region.
- */
-void __flush_purge_region(void *start, int size)
-{
- unsigned long v;
- unsigned long begin, end;
-
- begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
- end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
- & ~(L1_CACHE_BYTES-1);
- for (v = begin; v < end; v+=L1_CACHE_BYTES) {
- asm volatile("ocbp %0"
- : /* no output */
- : "m" (__m(v)));
- }
-}
-
-/*
- * No write back please
- */
-void __flush_invalidate_region(void *start, int size)
-{
- unsigned long v;
- unsigned long begin, end;
-
- begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
- end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
- & ~(L1_CACHE_BYTES-1);
- for (v = begin; v < end; v+=L1_CACHE_BYTES) {
- asm volatile("ocbi %0"
- : /* no output */
- : "m" (__m(v)));
- }
-}
-
-/*
* Write back the range of D-cache, and purge the I-cache.
*
* Called from kernel/module.c:sys_init_module and routine for a.out format,
@@ -246,7 +187,14 @@ static inline void flush_cache_4096(unsigned long start,
*/
void flush_dcache_page(struct page *page)
{
- if (test_bit(PG_mapped, &page->flags)) {
+ struct address_space *mapping = page_mapping(page);
+
+#ifndef CONFIG_SMP
+ if (mapping && !mapping_mapped(mapping))
+ set_bit(PG_dcache_dirty, &page->flags);
+ else
+#endif
+ {
unsigned long phys = PHYSADDR(page_address(page));
unsigned long addr = CACHE_OC_ADDRESS_ARRAY;
int i, n;
@@ -382,6 +330,9 @@ loop_exit:
*/
void flush_cache_mm(struct mm_struct *mm)
{
+ if (cpu_context(smp_processor_id(), mm) == NO_CONTEXT)
+ return;
+
/*
* If cache is only 4k-per-way, there are never any 'aliases'. Since
* the cache is physically tagged, the data can just be left in there.
@@ -423,6 +374,9 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long address,
unsigned long phys = pfn << PAGE_SHIFT;
unsigned int alias_mask;
+ if (cpu_context(smp_processor_id(), vma->vm_mm) == NO_CONTEXT)
+ return;
+
alias_mask = boot_cpu_data.dcache.alias_mask;
/* We only need to flush D-cache when we have alias */
@@ -465,6 +419,9 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long address,
void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
unsigned long end)
{
+ if (cpu_context(smp_processor_id(), vma->vm_mm) == NO_CONTEXT)
+ return;
+
/*
* If cache is only 4k-per-way, there are never any 'aliases'. Since
* the cache is physically tagged, the data can just be left in there.