sh: default to extended TLB support.
[safe/jmp/linux-2.6] / arch / sh / mm / cache-sh7705.c
index 31f8deb..f527fb7 100644 (file)
@@ -3,15 +3,16 @@
  *
  * Copyright (C) 1999, 2000  Niibe Yutaka
  * Copyright (C) 2004  Alex Song
- * Copyright (C) 2006  Paul Mundt
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
+ *
  */
 #include <linux/init.h>
 #include <linux/mman.h>
 #include <linux/mm.h>
+#include <linux/fs.h>
 #include <linux/threads.h>
 #include <asm/addrspace.h>
 #include <asm/page.h>
@@ -51,6 +52,7 @@ static inline void cache_wback_all(void)
 
                        if ((data & v) == v)
                                ctrl_outl(data & ~v, addr);
+
                }
 
                addrstart += current_cpu_data.dcache.way_incr;
@@ -62,15 +64,21 @@ static inline void cache_wback_all(void)
  *
  * Called from kernel/module.c:sys_init_module and routine for a.out format.
  */
-void flush_icache_range(unsigned long start, unsigned long end)
+static void sh7705_flush_icache_range(void *args)
 {
+       struct flusher_data *data = args;
+       unsigned long start, end;
+
+       start = data->addr1;
+       end = data->addr2;
+
        __flush_wback_region((void *)start, end - start);
 }
 
 /*
  * Writeback&Invalidate the D-cache of the page
  */
-static void __flush_dcache_page(unsigned long phys)
+static void __uses_jump_to_uncached __flush_dcache_page(unsigned long phys)
 {
        unsigned long ways, waysize, addrstart;
        unsigned long flags;
@@ -91,7 +99,7 @@ static void __flush_dcache_page(unsigned long phys)
         * possible.
         */
        local_irq_save(flags);
-       jump_to_P2();
+       jump_to_uncached();
 
        ways = current_cpu_data.dcache.ways;
        waysize = current_cpu_data.dcache.sets;
@@ -117,7 +125,7 @@ static void __flush_dcache_page(unsigned long phys)
                addrstart += current_cpu_data.dcache.way_incr;
        } while (--ways);
 
-       back_to_P1();
+       back_to_cached();
        local_irq_restore(flags);
 }
 
@@ -125,66 +133,39 @@ static void __flush_dcache_page(unsigned long phys)
  * Write back & invalidate the D-cache of the page.
  * (To avoid "alias" issues)
  */
-void flush_dcache_page(struct page *page)
+static void sh7705_flush_dcache_page(void *arg)
 {
+       struct page *page = arg;
        struct address_space *mapping = page_mapping(page);
 
        if (mapping && !mapping_mapped(mapping))
                set_bit(PG_dcache_dirty, &page->flags);
        else
-               __flush_dcache_page(PHYSADDR(page_address(page)));
+               __flush_dcache_page(__pa(page_address(page)));
 }
 
-void flush_cache_all(void)
+static void __uses_jump_to_uncached sh7705_flush_cache_all(void *args)
 {
        unsigned long flags;
 
        local_irq_save(flags);
-       jump_to_P2();
+       jump_to_uncached();
 
        cache_wback_all();
-       back_to_P1();
+       back_to_cached();
        local_irq_restore(flags);
 }
 
-void flush_cache_mm(struct mm_struct *mm)
-{
-       /* Is there any good way? */
-       /* XXX: possibly call flush_cache_range for each vm area */
-       flush_cache_all();
-}
-
-/*
- * Write back and invalidate D-caches.
- *
- * START, END: Virtual Address (U0 address)
- *
- * NOTE: We need to flush the _physical_ page entry.
- * Flushing the cache lines for U0 only isn't enough.
- * We need to flush for P1 too, which may contain aliases.
- */
-void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
-                      unsigned long end)
-{
-
-       /*
-        * We could call flush_cache_page for the pages of these range,
-        * but it's not efficient (scan the caches all the time...).
-        *
-        * We can't use A-bit magic, as there's the case we don't have
-        * valid entry on TLB.
-        */
-       flush_cache_all();
-}
-
 /*
  * Write back and invalidate I/D-caches for the page.
  *
  * ADDRESS: Virtual Address (U0 address)
  */
-void flush_cache_page(struct vm_area_struct *vma, unsigned long address,
-                     unsigned long pfn)
+static void sh7705_flush_cache_page(void *args)
 {
+       struct flusher_data *data = args;
+       unsigned long pfn = data->addr2;
+
        __flush_dcache_page(pfn << PAGE_SHIFT);
 }
 
@@ -196,7 +177,19 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long address,
  * Not entirely sure why this is necessary on SH3 with 32K cache but
  * without it we get occasional "Memory fault" when loading a program.
  */
-void flush_icache_page(struct vm_area_struct *vma, struct page *page)
+static void sh7705_flush_icache_page(void *page)
 {
        __flush_purge_region(page_address(page), PAGE_SIZE);
 }
+
+void __init sh7705_cache_init(void)
+{
+       local_flush_icache_range        = sh7705_flush_icache_range;
+       local_flush_dcache_page         = sh7705_flush_dcache_page;
+       local_flush_cache_all           = sh7705_flush_cache_all;
+       local_flush_cache_mm            = sh7705_flush_cache_all;
+       local_flush_cache_dup_mm        = sh7705_flush_cache_all;
+       local_flush_cache_range         = sh7705_flush_cache_all;
+       local_flush_cache_page          = sh7705_flush_cache_page;
+       local_flush_icache_page         = sh7705_flush_icache_page;
+}