summaryrefslogtreecommitdiffstats
path: root/arch/sh/mm
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2007-07-31 17:07:28 +0900
committerPaul Mundt <lethal@linux-sh.org>2007-09-21 11:57:46 +0900
commite7bd34a15b85655f24d1b45edbe3bdfebf9d027e (patch)
tree051647273266582fe95dcc5cf008534c264be5ae /arch/sh/mm
parentac919986d7dfc5d1d9f5585521307f222a8ebeaf (diff)
downloadlinux-e7bd34a15b85655f24d1b45edbe3bdfebf9d027e.tar.bz2
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>
Diffstat (limited to 'arch/sh/mm')
-rw-r--r--arch/sh/mm/Kconfig19
-rw-r--r--arch/sh/mm/Makefile11
-rw-r--r--arch/sh/mm/pmb.c2
-rw-r--r--arch/sh/mm/tlb-sh4.c25
4 files changed, 38 insertions, 19 deletions
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig
index 093d491424fd..c2777555003e 100644
--- a/arch/sh/mm/Kconfig
+++ b/arch/sh/mm/Kconfig
@@ -2,7 +2,6 @@
# Processor families
#
config CPU_SH2
- select SH_WRITETHROUGH if !CPU_SH2A
bool
config CPU_SH2A
@@ -414,8 +413,17 @@ config SH_DIRECT_MAPPED
Turn this option off for platforms that do not have a direct-mapped
cache, and you have no need to run the caches in such a configuration.
-config SH_WRITETHROUGH
- bool "Use write-through caching"
+choice
+ prompt "Cache mode"
+ default CACHE_WRITEBACK if CPU_SH2A || CPU_SH3 || CPU_SH4
+ default CACHE_WRITETHROUGH if (CPU_SH2 && !CPU_SH2A)
+
+config CACHE_WRITEBACK
+ bool "Write-back"
+ depends on CPU_SH2A || CPU_SH3 || CPU_SH4
+
+config CACHE_WRITETHROUGH
+ bool "Write-through"
help
Selecting this option will configure the caches in write-through
mode, as opposed to the default write-back configuration.
@@ -426,4 +434,9 @@ config SH_WRITETHROUGH
If unsure, say N.
+config CACHE_OFF
+ bool "Off"
+
+endchoice
+
endmenu
diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile
index 4061e89d84d0..e73d7f970ce0 100644
--- a/arch/sh/mm/Makefile
+++ b/arch/sh/mm/Makefile
@@ -4,9 +4,10 @@
obj-y := init.o extable.o consistent.o
-obj-$(CONFIG_CPU_SH2) += cache-sh2.o
-obj-$(CONFIG_CPU_SH3) += cache-sh3.o
-obj-$(CONFIG_CPU_SH4) += cache-sh4.o
+cache-$(CONFIG_CPU_SH2) := cache-sh2.o
+cache-$(CONFIG_CPU_SH3) := cache-sh3.o
+cache-$(CONFIG_CPU_SH4) := cache-sh4.o pg-sh4.o
+cache-$(CONFIG_CACHE_OFF) :=
mmu-y := tlb-nommu.o pg-nommu.o
mmu-$(CONFIG_CPU_SH3) += fault-nommu.o
@@ -14,7 +15,7 @@ mmu-$(CONFIG_CPU_SH4) += fault-nommu.o
mmu-$(CONFIG_MMU) := fault.o clear_page.o copy_page.o tlb-flush.o \
ioremap.o
-obj-y += $(mmu-y)
+obj-y += $(cache-y) $(mmu-y)
ifdef CONFIG_DEBUG_FS
obj-$(CONFIG_CPU_SH4) += cache-debugfs.o
@@ -22,7 +23,7 @@ endif
ifdef CONFIG_MMU
obj-$(CONFIG_CPU_SH3) += tlb-sh3.o
-obj-$(CONFIG_CPU_SH4) += tlb-sh4.o pg-sh4.o
+obj-$(CONFIG_CPU_SH4) += tlb-sh4.o
obj-$(CONFIG_SH7705_CACHE_32KB) += pg-sh7705.o
endif
diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c
index a08a4a958add..7d43758dc244 100644
--- a/arch/sh/mm/pmb.c
+++ b/arch/sh/mm/pmb.c
@@ -145,7 +145,7 @@ repeat:
ctrl_outl(vpn | PMB_V, mk_pmb_addr(pos));
-#ifdef CONFIG_SH_WRITETHROUGH
+#ifdef CONFIG_CACHE_WRITETHROUGH
/*
* When we are in 32-bit address extended mode, CCR.CB becomes
* invalid, so care must be taken to manually adjust cacheable
diff --git a/arch/sh/mm/tlb-sh4.c b/arch/sh/mm/tlb-sh4.c
index f74cf667c8fa..13fde8cc7179 100644
--- a/arch/sh/mm/tlb-sh4.c
+++ b/arch/sh/mm/tlb-sh4.c
@@ -34,22 +34,27 @@ void update_mmu_cache(struct vm_area_struct * vma,
unsigned long flags;
unsigned long pteval;
unsigned long vpn;
- struct page *page;
- unsigned long pfn;
/* Ptrace may call this routine. */
if (vma && current->active_mm != vma->vm_mm)
return;
- pfn = pte_pfn(pte);
- if (pfn_valid(pfn)) {
- page = pfn_to_page(pfn);
- if (!test_bit(PG_mapped, &page->flags)) {
- unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
- __flush_wback_region((void *)P1SEGADDR(phys), PAGE_SIZE);
- __set_bit(PG_mapped, &page->flags);
+#ifndef CONFIG_CACHE_OFF
+ {
+ unsigned long pfn = pte_pfn(pte);
+
+ if (pfn_valid(pfn)) {
+ struct page *page = pfn_to_page(pfn);
+
+ if (!test_bit(PG_mapped, &page->flags)) {
+ unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
+ __flush_wback_region((void *)P1SEGADDR(phys),
+ PAGE_SIZE);
+ __set_bit(PG_mapped, &page->flags);
+ }
}
}
+#endif
local_irq_save(flags);
@@ -66,7 +71,7 @@ void update_mmu_cache(struct vm_area_struct * vma,
/* Set PTEL register */
pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
-#ifdef CONFIG_SH_WRITETHROUGH
+#ifdef CONFIG_CACHE_WRITETHROUGH
pteval |= _PAGE_WT;
#endif
/* conveniently, we want all the software flags to be 0 anyway */