sh: Support explicit L1 cache disabling.

This reworks the cache mode configuration in Kconfig, and allows for
explicit selection of write-back/write-through/off configurations.
All of the cache flushing routines are optimized away for the off
case.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
diff --git a/include/asm-sh/cacheflush.h b/include/asm-sh/cacheflush.h
index 07f62ec..aa558da 100644
--- a/include/asm-sh/cacheflush.h
+++ b/include/asm-sh/cacheflush.h
@@ -1,16 +1,47 @@
 #ifndef __ASM_SH_CACHEFLUSH_H
 #define __ASM_SH_CACHEFLUSH_H
+
 #ifdef __KERNEL__
 
-#include <linux/mm.h>
+#ifdef CONFIG_CACHE_OFF
+/*
+ * Nothing to do when the cache is disabled, initial flush and explicit
+ * disabling is handled at CPU init time.
+ *
+ * See arch/sh/kernel/cpu/init.c:cache_init().
+ */
+#define p3_cache_init()				do { } while (0)
+#define flush_cache_all()			do { } while (0)
+#define flush_cache_mm(mm)			do { } while (0)
+#define flush_cache_dup_mm(mm)			do { } while (0)
+#define flush_cache_range(vma, start, end)	do { } while (0)
+#define flush_cache_page(vma, vmaddr, pfn)	do { } while (0)
+#define flush_dcache_page(page)			do { } while (0)
+#define flush_icache_range(start, end)		do { } while (0)
+#define flush_icache_page(vma,pg)		do { } while (0)
+#define flush_dcache_mmap_lock(mapping)		do { } while (0)
+#define flush_dcache_mmap_unlock(mapping)	do { } while (0)
+#define flush_cache_sigtramp(vaddr)		do { } while (0)
+#define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
+#define __flush_wback_region(start, size)	do { (void)(start); } while (0)
+#define __flush_purge_region(start, size)	do { (void)(start); } while (0)
+#define __flush_invalidate_region(start, size)	do { (void)(start); } while (0)
+#else
 #include <asm/cpu/cacheflush.h>
 
+/*
+ * Consistent DMA requires that the __flush_xxx() primitives must be set
+ * for any of the enabled non-coherent caches (most of the UP CPUs),
+ * regardless of PIPT or VIPT cache configurations.
+ */
+
 /* Flush (write-back only) a region (smaller than a page) */
 extern void __flush_wback_region(void *start, int size);
 /* Flush (write-back & invalidate) a region (smaller than a page) */
 extern void __flush_purge_region(void *start, int size);
 /* Flush (invalidate only) a region (smaller than a page) */
 extern void __flush_invalidate_region(void *start, int size);
+#endif
 
 #define flush_cache_vmap(start, end)		flush_cache_all()
 #define flush_cache_vunmap(start, end)		flush_cache_all()
diff --git a/include/asm-sh/page.h b/include/asm-sh/page.h
index 6bc9bba..48b718e 100644
--- a/include/asm-sh/page.h
+++ b/include/asm-sh/page.h
@@ -70,14 +70,14 @@
 extern void copy_page_nommu(void *to, void *from);
 #endif
 
-#if defined(CONFIG_MMU) && (defined(CONFIG_CPU_SH4) || \
-	defined(CONFIG_SH7705_CACHE_32KB))
+#if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_MMU) && \
+	(defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB))
 struct page;
 extern void clear_user_page(void *to, unsigned long address, struct page *pg);
 extern void copy_user_page(void *to, void *from, unsigned long address, struct page *pg);
 extern void __clear_user_page(void *to, void *orig_to);
 extern void __copy_user_page(void *to, void *from, void *orig_to);
-#elif defined(CONFIG_CPU_SH2) || defined(CONFIG_CPU_SH3) || !defined(CONFIG_MMU)
+#else
 #define clear_user_page(page, vaddr, pg)	clear_page(page)
 #define copy_user_page(to, from, vaddr, pg)	copy_page(to, from)
 #endif
diff --git a/include/asm-sh/pgtable.h b/include/asm-sh/pgtable.h
index e3fae12..54ad503 100644
--- a/include/asm-sh/pgtable.h
+++ b/include/asm-sh/pgtable.h
@@ -563,7 +563,8 @@
 extern unsigned int kobjsize(const void *objp);
 #endif /* !CONFIG_MMU */
 
-#if defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB)
+#if !defined(CONFIG_CACHE_OFF) && (defined(CONFIG_CPU_SH4) || \
+	defined(CONFIG_SH7705_CACHE_32KB))
 #define __HAVE_ARCH_PTEP_GET_AND_CLEAR
 extern pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
 #endif