aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/mm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/mm')
-rw-r--r--arch/sh/mm/Kconfig21
-rw-r--r--arch/sh/mm/Makefile_3211
-rw-r--r--arch/sh/mm/cache-debugfs.c2
-rw-r--r--arch/sh/mm/cache-sh2.c45
-rw-r--r--arch/sh/mm/cache-sh2a.c129
-rw-r--r--arch/sh/mm/cache-sh4.c67
-rw-r--r--arch/sh/mm/consistent.c128
-rw-r--r--arch/sh/mm/fault_32.c12
-rw-r--r--arch/sh/mm/fault_64.c2
-rw-r--r--arch/sh/mm/pg-sh4.c2
-rw-r--r--arch/sh/mm/pg-sh7705.c2
-rw-r--r--arch/sh/mm/pmb.c2
-rw-r--r--arch/sh/mm/tlb-sh5.c20
13 files changed, 277 insertions, 166 deletions
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig
index 5fd218430b19..9c131cac91a4 100644
--- a/arch/sh/mm/Kconfig
+++ b/arch/sh/mm/Kconfig
@@ -145,25 +145,39 @@ choice
145 145
146config PAGE_SIZE_4KB 146config PAGE_SIZE_4KB
147 bool "4kB" 147 bool "4kB"
148 depends on !X2TLB 148 depends on !MMU || !X2TLB
149 help 149 help
150 This is the default page size used by all SuperH CPUs. 150 This is the default page size used by all SuperH CPUs.
151 151
152config PAGE_SIZE_8KB 152config PAGE_SIZE_8KB
153 bool "8kB" 153 bool "8kB"
154 depends on X2TLB 154 depends on !MMU || X2TLB
155 help 155 help
156 This enables 8kB pages as supported by SH-X2 and later MMUs. 156 This enables 8kB pages as supported by SH-X2 and later MMUs.
157 157
158config PAGE_SIZE_16KB
159 bool "16kB"
160 depends on !MMU
161 help
162 This enables 16kB pages on MMU-less SH systems.
163
158config PAGE_SIZE_64KB 164config PAGE_SIZE_64KB
159 bool "64kB" 165 bool "64kB"
160 depends on CPU_SH4 || CPU_SH5 166 depends on !MMU || CPU_SH4 || CPU_SH5
161 help 167 help
162 This enables support for 64kB pages, possible on all SH-4 168 This enables support for 64kB pages, possible on all SH-4
163 CPUs and later. 169 CPUs and later.
164 170
165endchoice 171endchoice
166 172
173config ENTRY_OFFSET
174 hex
175 default "0x00001000" if PAGE_SIZE_4KB
176 default "0x00002000" if PAGE_SIZE_8KB
177 default "0x00004000" if PAGE_SIZE_16KB
178 default "0x00010000" if PAGE_SIZE_64KB
179 default "0x00000000"
180
167choice 181choice
168 prompt "HugeTLB page size" 182 prompt "HugeTLB page size"
169 depends on HUGETLB_PAGE && (CPU_SH4 || CPU_SH5) && MMU 183 depends on HUGETLB_PAGE && (CPU_SH4 || CPU_SH5) && MMU
@@ -223,7 +237,6 @@ choice
223 237
224config CACHE_WRITEBACK 238config CACHE_WRITEBACK
225 bool "Write-back" 239 bool "Write-back"
226 depends on CPU_SH2A || CPU_SH3 || CPU_SH4 || CPU_SH5
227 240
228config CACHE_WRITETHROUGH 241config CACHE_WRITETHROUGH
229 bool "Write-through" 242 bool "Write-through"
diff --git a/arch/sh/mm/Makefile_32 b/arch/sh/mm/Makefile_32
index e295db60b91b..70e0906023cc 100644
--- a/arch/sh/mm/Makefile_32
+++ b/arch/sh/mm/Makefile_32
@@ -5,12 +5,15 @@
5obj-y := init.o extable_32.o consistent.o 5obj-y := init.o extable_32.o consistent.o
6 6
7ifndef CONFIG_CACHE_OFF 7ifndef CONFIG_CACHE_OFF
8obj-$(CONFIG_CPU_SH2) += cache-sh2.o 8cache-$(CONFIG_CPU_SH2) := cache-sh2.o
9obj-$(CONFIG_CPU_SH3) += cache-sh3.o 9cache-$(CONFIG_CPU_SH2A) := cache-sh2a.o
10obj-$(CONFIG_CPU_SH4) += cache-sh4.o 10cache-$(CONFIG_CPU_SH3) := cache-sh3.o
11obj-$(CONFIG_SH7705_CACHE_32KB) += cache-sh7705.o 11cache-$(CONFIG_CPU_SH4) := cache-sh4.o
12cache-$(CONFIG_SH7705_CACHE_32KB) += cache-sh7705.o
12endif 13endif
13 14
15obj-y += $(cache-y)
16
14mmu-y := tlb-nommu.o pg-nommu.o 17mmu-y := tlb-nommu.o pg-nommu.o
15mmu-$(CONFIG_MMU) := fault_32.o tlbflush_32.o ioremap_32.o 18mmu-$(CONFIG_MMU) := fault_32.o tlbflush_32.o ioremap_32.o
16 19
diff --git a/arch/sh/mm/cache-debugfs.c b/arch/sh/mm/cache-debugfs.c
index c5b56d52b7d2..0e189ccd4a77 100644
--- a/arch/sh/mm/cache-debugfs.c
+++ b/arch/sh/mm/cache-debugfs.c
@@ -120,7 +120,7 @@ static const struct file_operations cache_debugfs_fops = {
120 .open = cache_debugfs_open, 120 .open = cache_debugfs_open,
121 .read = seq_read, 121 .read = seq_read,
122 .llseek = seq_lseek, 122 .llseek = seq_lseek,
123 .release = seq_release, 123 .release = single_release,
124}; 124};
125 125
126static int __init cache_debugfs_init(void) 126static int __init cache_debugfs_init(void)
diff --git a/arch/sh/mm/cache-sh2.c b/arch/sh/mm/cache-sh2.c
index 6614033f6be9..c4e80d2b764b 100644
--- a/arch/sh/mm/cache-sh2.c
+++ b/arch/sh/mm/cache-sh2.c
@@ -2,6 +2,7 @@
2 * arch/sh/mm/cache-sh2.c 2 * arch/sh/mm/cache-sh2.c
3 * 3 *
4 * Copyright (C) 2002 Paul Mundt 4 * Copyright (C) 2002 Paul Mundt
5 * Copyright (C) 2008 Yoshinori Sato
5 * 6 *
6 * Released under the terms of the GNU GPL v2.0. 7 * Released under the terms of the GNU GPL v2.0.
7 */ 8 */
@@ -24,8 +25,15 @@ void __flush_wback_region(void *start, int size)
24 end = ((unsigned long)start + size + L1_CACHE_BYTES-1) 25 end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
25 & ~(L1_CACHE_BYTES-1); 26 & ~(L1_CACHE_BYTES-1);
26 for (v = begin; v < end; v+=L1_CACHE_BYTES) { 27 for (v = begin; v < end; v+=L1_CACHE_BYTES) {
27 /* FIXME cache purge */ 28 unsigned long addr = CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0);
28 ctrl_outl((v & 0x1ffffc00), (v & 0x00000ff0) | 0x00000008); 29 int way;
30 for (way = 0; way < 4; way++) {
31 unsigned long data = ctrl_inl(addr | (way << 12));
32 if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) {
33 data &= ~SH_CACHE_UPDATED;
34 ctrl_outl(data, addr | (way << 12));
35 }
36 }
29 } 37 }
30} 38}
31 39
@@ -37,21 +45,40 @@ void __flush_purge_region(void *start, int size)
37 begin = (unsigned long)start & ~(L1_CACHE_BYTES-1); 45 begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
38 end = ((unsigned long)start + size + L1_CACHE_BYTES-1) 46 end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
39 & ~(L1_CACHE_BYTES-1); 47 & ~(L1_CACHE_BYTES-1);
40 for (v = begin; v < end; v+=L1_CACHE_BYTES) { 48
41 ctrl_outl((v & 0x1ffffc00), (v & 0x00000ff0) | 0x00000008); 49 for (v = begin; v < end; v+=L1_CACHE_BYTES)
42 } 50 ctrl_outl((v & CACHE_PHYSADDR_MASK),
51 CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0) | 0x00000008);
43} 52}
44 53
45void __flush_invalidate_region(void *start, int size) 54void __flush_invalidate_region(void *start, int size)
46{ 55{
56#ifdef CONFIG_CACHE_WRITEBACK
57 /*
58 * SH-2 does not support individual line invalidation, only a
59 * global invalidate.
60 */
61 unsigned long ccr;
62 unsigned long flags;
63 local_irq_save(flags);
64 jump_to_uncached();
65
66 ccr = ctrl_inl(CCR);
67 ccr |= CCR_CACHE_INVALIDATE;
68 ctrl_outl(ccr, CCR);
69
70 back_to_cached();
71 local_irq_restore(flags);
72#else
47 unsigned long v; 73 unsigned long v;
48 unsigned long begin, end; 74 unsigned long begin, end;
49 75
50 begin = (unsigned long)start & ~(L1_CACHE_BYTES-1); 76 begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
51 end = ((unsigned long)start + size + L1_CACHE_BYTES-1) 77 end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
52 & ~(L1_CACHE_BYTES-1); 78 & ~(L1_CACHE_BYTES-1);
53 for (v = begin; v < end; v+=L1_CACHE_BYTES) {
54 ctrl_outl((v & 0x1ffffc00), (v & 0x00000ff0) | 0x00000008);
55 }
56}
57 79
80 for (v = begin; v < end; v+=L1_CACHE_BYTES)
81 ctrl_outl((v & CACHE_PHYSADDR_MASK),
82 CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0) | 0x00000008);
83#endif
84}
diff --git a/arch/sh/mm/cache-sh2a.c b/arch/sh/mm/cache-sh2a.c
new file mode 100644
index 000000000000..62c0c5f35120
--- /dev/null
+++ b/arch/sh/mm/cache-sh2a.c
@@ -0,0 +1,129 @@
1/*
2 * arch/sh/mm/cache-sh2a.c
3 *
4 * Copyright (C) 2008 Yoshinori Sato
5 *
6 * Released under the terms of the GNU GPL v2.0.
7 */
8
9#include <linux/init.h>
10#include <linux/mm.h>
11
12#include <asm/cache.h>
13#include <asm/addrspace.h>
14#include <asm/processor.h>
15#include <asm/cacheflush.h>
16#include <asm/io.h>
17
18void __flush_wback_region(void *start, int size)
19{
20 unsigned long v;
21 unsigned long begin, end;
22 unsigned long flags;
23
24 begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
25 end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
26 & ~(L1_CACHE_BYTES-1);
27
28 local_irq_save(flags);
29 jump_to_uncached();
30
31 for (v = begin; v < end; v+=L1_CACHE_BYTES) {
32 unsigned long addr = CACHE_OC_ADDRESS_ARRAY | (v & 0x000007f0);
33 int way;
34 for (way = 0; way < 4; way++) {
35 unsigned long data = ctrl_inl(addr | (way << 11));
36 if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) {
37 data &= ~SH_CACHE_UPDATED;
38 ctrl_outl(data, addr | (way << 11));
39 }
40 }
41 }
42
43 back_to_cached();
44 local_irq_restore(flags);
45}
46
47void __flush_purge_region(void *start, int size)
48{
49 unsigned long v;
50 unsigned long begin, end;
51 unsigned long flags;
52
53 begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
54 end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
55 & ~(L1_CACHE_BYTES-1);
56
57 local_irq_save(flags);
58 jump_to_uncached();
59
60 for (v = begin; v < end; v+=L1_CACHE_BYTES) {
61 ctrl_outl((v & CACHE_PHYSADDR_MASK),
62 CACHE_OC_ADDRESS_ARRAY | (v & 0x000003f0) | 0x00000008);
63 }
64 back_to_cached();
65 local_irq_restore(flags);
66}
67
68void __flush_invalidate_region(void *start, int size)
69{
70 unsigned long v;
71 unsigned long begin, end;
72 unsigned long flags;
73
74 begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
75 end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
76 & ~(L1_CACHE_BYTES-1);
77 local_irq_save(flags);
78 jump_to_uncached();
79
80#ifdef CONFIG_CACHE_WRITEBACK
81 ctrl_outl(ctrl_inl(CCR) | CCR_OCACHE_INVALIDATE, CCR);
82 /* I-cache invalidate */
83 for (v = begin; v < end; v+=L1_CACHE_BYTES) {
84 ctrl_outl((v & CACHE_PHYSADDR_MASK),
85 CACHE_IC_ADDRESS_ARRAY | (v & 0x000003f0) | 0x00000008);
86 }
87#else
88 for (v = begin; v < end; v+=L1_CACHE_BYTES) {
89 ctrl_outl((v & CACHE_PHYSADDR_MASK),
90 CACHE_IC_ADDRESS_ARRAY | (v & 0x000003f0) | 0x00000008);
91 ctrl_outl((v & CACHE_PHYSADDR_MASK),
92 CACHE_OC_ADDRESS_ARRAY | (v & 0x000003f0) | 0x00000008);
93 }
94#endif
95 back_to_cached();
96 local_irq_restore(flags);
97}
98
99/* WBack O-Cache and flush I-Cache */
100void flush_icache_range(unsigned long start, unsigned long end)
101{
102 unsigned long v;
103 unsigned long flags;
104
105 start = start & ~(L1_CACHE_BYTES-1);
106 end = (end + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1);
107
108 local_irq_save(flags);
109 jump_to_uncached();
110
111 for (v = start; v < end; v+=L1_CACHE_BYTES) {
112 unsigned long addr = (v & 0x000007f0);
113 int way;
114 /* O-Cache writeback */
115 for (way = 0; way < 4; way++) {
116 unsigned long data = ctrl_inl(CACHE_OC_ADDRESS_ARRAY | addr | (way << 11));
117 if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) {
118 data &= ~SH_CACHE_UPDATED;
119 ctrl_outl(data, CACHE_OC_ADDRESS_ARRAY | addr | (way << 11));
120 }
121 }
122 /* I-Cache invalidate */
123 ctrl_outl(addr,
124 CACHE_IC_ADDRESS_ARRAY | addr | 0x00000008);
125 }
126
127 back_to_cached();
128 local_irq_restore(flags);
129}
diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c
index 43d7ff6b6ec7..1fdc8d90254a 100644
--- a/arch/sh/mm/cache-sh4.c
+++ b/arch/sh/mm/cache-sh4.c
@@ -4,6 +4,7 @@
4 * Copyright (C) 1999, 2000, 2002 Niibe Yutaka 4 * Copyright (C) 1999, 2000, 2002 Niibe Yutaka
5 * Copyright (C) 2001 - 2007 Paul Mundt 5 * Copyright (C) 2001 - 2007 Paul Mundt
6 * Copyright (C) 2003 Richard Curnow 6 * Copyright (C) 2003 Richard Curnow
7 * Copyright (c) 2007 STMicroelectronics (R&D) Ltd.
7 * 8 *
8 * This file is subject to the terms and conditions of the GNU General Public 9 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive 10 * License. See the file "COPYING" in the main directory of this archive
@@ -22,6 +23,7 @@
22 * entirety. 23 * entirety.
23 */ 24 */
24#define MAX_DCACHE_PAGES 64 /* XXX: Tune for ways */ 25#define MAX_DCACHE_PAGES 64 /* XXX: Tune for ways */
26#define MAX_ICACHE_PAGES 32
25 27
26static void __flush_dcache_segment_1way(unsigned long start, 28static void __flush_dcache_segment_1way(unsigned long start,
27 unsigned long extent); 29 unsigned long extent);
@@ -178,42 +180,45 @@ void __flush_invalidate_region(void *start, int size)
178/* 180/*
179 * Write back the range of D-cache, and purge the I-cache. 181 * Write back the range of D-cache, and purge the I-cache.
180 * 182 *
181 * Called from kernel/module.c:sys_init_module and routine for a.out format. 183 * Called from kernel/module.c:sys_init_module and routine for a.out format,
184 * signal handler code and kprobes code
182 */ 185 */
183void flush_icache_range(unsigned long start, unsigned long end) 186void flush_icache_range(unsigned long start, unsigned long end)
184{ 187{
185 flush_cache_all(); 188 int icacheaddr;
186} 189 unsigned long flags, v;
187
188/*
189 * Write back the D-cache and purge the I-cache for signal trampoline.
190 * .. which happens to be the same behavior as flush_icache_range().
191 * So, we simply flush out a line.
192 */
193void __uses_jump_to_uncached flush_cache_sigtramp(unsigned long addr)
194{
195 unsigned long v, index;
196 unsigned long flags;
197 int i; 190 int i;
198 191
199 v = addr & ~(L1_CACHE_BYTES-1); 192 /* If there are too many pages then just blow the caches */
200 asm volatile("ocbwb %0" 193 if (((end - start) >> PAGE_SHIFT) >= MAX_ICACHE_PAGES) {
201 : /* no output */ 194 flush_cache_all();
202 : "m" (__m(v))); 195 } else {
203 196 /* selectively flush d-cache then invalidate the i-cache */
204 index = CACHE_IC_ADDRESS_ARRAY | 197 /* this is inefficient, so only use for small ranges */
205 (v & boot_cpu_data.icache.entry_mask); 198 start &= ~(L1_CACHE_BYTES-1);
206 199 end += L1_CACHE_BYTES-1;
207 local_irq_save(flags); 200 end &= ~(L1_CACHE_BYTES-1);
208 jump_to_uncached(); 201
209 202 local_irq_save(flags);
210 for (i = 0; i < boot_cpu_data.icache.ways; 203 jump_to_uncached();
211 i++, index += boot_cpu_data.icache.way_incr) 204
212 ctrl_outl(0, index); /* Clear out Valid-bit */ 205 for (v = start; v < end; v+=L1_CACHE_BYTES) {
213 206 asm volatile("ocbwb %0"
214 back_to_cached(); 207 : /* no output */
215 wmb(); 208 : "m" (__m(v)));
216 local_irq_restore(flags); 209
210 icacheaddr = CACHE_IC_ADDRESS_ARRAY | (
211 v & cpu_data->icache.entry_mask);
212
213 for (i = 0; i < cpu_data->icache.ways;
214 i++, icacheaddr += cpu_data->icache.way_incr)
215 /* Clear i-cache line valid-bit */
216 ctrl_outl(0, icacheaddr);
217 }
218
219 back_to_cached();
220 local_irq_restore(flags);
221 }
217} 222}
218 223
219static inline void flush_cache_4096(unsigned long start, 224static inline void flush_cache_4096(unsigned long start,
diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c
index d3c33fc5b1c2..b2ce014401b5 100644
--- a/arch/sh/mm/consistent.c
+++ b/arch/sh/mm/consistent.c
@@ -10,6 +10,7 @@
10 * for more details. 10 * for more details.
11 */ 11 */
12#include <linux/mm.h> 12#include <linux/mm.h>
13#include <linux/platform_device.h>
13#include <linux/dma-mapping.h> 14#include <linux/dma-mapping.h>
14#include <asm/cacheflush.h> 15#include <asm/cacheflush.h>
15#include <asm/addrspace.h> 16#include <asm/addrspace.h>
@@ -27,21 +28,10 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
27 dma_addr_t *dma_handle, gfp_t gfp) 28 dma_addr_t *dma_handle, gfp_t gfp)
28{ 29{
29 void *ret, *ret_nocache; 30 void *ret, *ret_nocache;
30 struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
31 int order = get_order(size); 31 int order = get_order(size);
32 32
33 if (mem) { 33 if (dma_alloc_from_coherent(dev, size, dma_handle, &ret))
34 int page = bitmap_find_free_region(mem->bitmap, mem->size, 34 return ret;
35 order);
36 if (page >= 0) {
37 *dma_handle = mem->device_base + (page << PAGE_SHIFT);
38 ret = mem->virt_base + (page << PAGE_SHIFT);
39 memset(ret, 0, size);
40 return ret;
41 }
42 if (mem->flags & DMA_MEMORY_EXCLUSIVE)
43 return NULL;
44 }
45 35
46 ret = (void *)__get_free_pages(gfp, order); 36 ret = (void *)__get_free_pages(gfp, order);
47 if (!ret) 37 if (!ret)
@@ -71,11 +61,7 @@ void dma_free_coherent(struct device *dev, size_t size,
71 struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL; 61 struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
72 int order = get_order(size); 62 int order = get_order(size);
73 63
74 if (mem && vaddr >= mem->virt_base && vaddr < (mem->virt_base + (mem->size << PAGE_SHIFT))) { 64 if (!dma_release_from_coherent(dev, order, vaddr)) {
75 int page = (vaddr - mem->virt_base) >> PAGE_SHIFT;
76
77 bitmap_release_region(mem->bitmap, page, order);
78 } else {
79 WARN_ON(irqs_disabled()); /* for portability */ 65 WARN_ON(irqs_disabled()); /* for portability */
80 BUG_ON(mem && mem->flags & DMA_MEMORY_EXCLUSIVE); 66 BUG_ON(mem && mem->flags & DMA_MEMORY_EXCLUSIVE);
81 free_pages((unsigned long)phys_to_virt(dma_handle), order); 67 free_pages((unsigned long)phys_to_virt(dma_handle), order);
@@ -84,83 +70,6 @@ void dma_free_coherent(struct device *dev, size_t size,
84} 70}
85EXPORT_SYMBOL(dma_free_coherent); 71EXPORT_SYMBOL(dma_free_coherent);
86 72
87int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
88 dma_addr_t device_addr, size_t size, int flags)
89{
90 void __iomem *mem_base = NULL;
91 int pages = size >> PAGE_SHIFT;
92 int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
93
94 if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0)
95 goto out;
96 if (!size)
97 goto out;
98 if (dev->dma_mem)
99 goto out;
100
101 /* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */
102
103 mem_base = ioremap_nocache(bus_addr, size);
104 if (!mem_base)
105 goto out;
106
107 dev->dma_mem = kmalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL);
108 if (!dev->dma_mem)
109 goto out;
110 dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
111 if (!dev->dma_mem->bitmap)
112 goto free1_out;
113
114 dev->dma_mem->virt_base = mem_base;
115 dev->dma_mem->device_base = device_addr;
116 dev->dma_mem->size = pages;
117 dev->dma_mem->flags = flags;
118
119 if (flags & DMA_MEMORY_MAP)
120 return DMA_MEMORY_MAP;
121
122 return DMA_MEMORY_IO;
123
124 free1_out:
125 kfree(dev->dma_mem);
126 out:
127 if (mem_base)
128 iounmap(mem_base);
129 return 0;
130}
131EXPORT_SYMBOL(dma_declare_coherent_memory);
132
133void dma_release_declared_memory(struct device *dev)
134{
135 struct dma_coherent_mem *mem = dev->dma_mem;
136
137 if (!mem)
138 return;
139 dev->dma_mem = NULL;
140 iounmap(mem->virt_base);
141 kfree(mem->bitmap);
142 kfree(mem);
143}
144EXPORT_SYMBOL(dma_release_declared_memory);
145
146void *dma_mark_declared_memory_occupied(struct device *dev,
147 dma_addr_t device_addr, size_t size)
148{
149 struct dma_coherent_mem *mem = dev->dma_mem;
150 int pages = (size + (device_addr & ~PAGE_MASK) + PAGE_SIZE - 1) >> PAGE_SHIFT;
151 int pos, err;
152
153 if (!mem)
154 return ERR_PTR(-EINVAL);
155
156 pos = (device_addr - mem->device_base) >> PAGE_SHIFT;
157 err = bitmap_allocate_region(mem->bitmap, pos, get_order(pages));
158 if (err != 0)
159 return ERR_PTR(err);
160 return mem->virt_base + (pos << PAGE_SHIFT);
161}
162EXPORT_SYMBOL(dma_mark_declared_memory_occupied);
163
164void dma_cache_sync(struct device *dev, void *vaddr, size_t size, 73void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
165 enum dma_data_direction direction) 74 enum dma_data_direction direction)
166{ 75{
@@ -185,3 +94,32 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
185 } 94 }
186} 95}
187EXPORT_SYMBOL(dma_cache_sync); 96EXPORT_SYMBOL(dma_cache_sync);
97
98int platform_resource_setup_memory(struct platform_device *pdev,
99 char *name, unsigned long memsize)
100{
101 struct resource *r;
102 dma_addr_t dma_handle;
103 void *buf;
104
105 r = pdev->resource + pdev->num_resources - 1;
106 if (r->flags) {
107 pr_warning("%s: unable to find empty space for resource\n",
108 name);
109 return -EINVAL;
110 }
111
112 buf = dma_alloc_coherent(NULL, memsize, &dma_handle, GFP_KERNEL);
113 if (!buf) {
114 pr_warning("%s: unable to allocate memory\n", name);
115 return -ENOMEM;
116 }
117
118 memset(buf, 0, memsize);
119
120 r->flags = IORESOURCE_MEM;
121 r->start = dma_handle;
122 r->end = r->start + memsize - 1;
123 r->name = name;
124 return 0;
125}
diff --git a/arch/sh/mm/fault_32.c b/arch/sh/mm/fault_32.c
index d1fa27594c6e..0c776fdfbdda 100644
--- a/arch/sh/mm/fault_32.c
+++ b/arch/sh/mm/fault_32.c
@@ -37,16 +37,12 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
37 int fault; 37 int fault;
38 siginfo_t info; 38 siginfo_t info;
39 39
40 trace_hardirqs_on();
41 local_irq_enable();
42
43#ifdef CONFIG_SH_KGDB 40#ifdef CONFIG_SH_KGDB
44 if (kgdb_nofault && kgdb_bus_err_hook) 41 if (kgdb_nofault && kgdb_bus_err_hook)
45 kgdb_bus_err_hook(); 42 kgdb_bus_err_hook();
46#endif 43#endif
47 44
48 tsk = current; 45 tsk = current;
49 mm = tsk->mm;
50 si_code = SEGV_MAPERR; 46 si_code = SEGV_MAPERR;
51 47
52 if (unlikely(address >= TASK_SIZE)) { 48 if (unlikely(address >= TASK_SIZE)) {
@@ -88,6 +84,14 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
88 return; 84 return;
89 } 85 }
90 86
87 /* Only enable interrupts if they were on before the fault */
88 if ((regs->sr & SR_IMASK) != SR_IMASK) {
89 trace_hardirqs_on();
90 local_irq_enable();
91 }
92
93 mm = tsk->mm;
94
91 /* 95 /*
92 * If we're in an interrupt or have no user 96 * If we're in an interrupt or have no user
93 * context, we must not take the fault.. 97 * context, we must not take the fault..
diff --git a/arch/sh/mm/fault_64.c b/arch/sh/mm/fault_64.c
index 399d53710d2f..bd63b961b2a9 100644
--- a/arch/sh/mm/fault_64.c
+++ b/arch/sh/mm/fault_64.c
@@ -39,7 +39,7 @@
39#include <asm/uaccess.h> 39#include <asm/uaccess.h>
40#include <asm/pgalloc.h> 40#include <asm/pgalloc.h>
41#include <asm/mmu_context.h> 41#include <asm/mmu_context.h>
42#include <asm/cpu/registers.h> 42#include <cpu/registers.h>
43 43
44/* Callable from fault.c, so not static */ 44/* Callable from fault.c, so not static */
45inline void __do_tlb_refill(unsigned long address, 45inline void __do_tlb_refill(unsigned long address,
diff --git a/arch/sh/mm/pg-sh4.c b/arch/sh/mm/pg-sh4.c
index 8c7a9ca79879..38870e0fc182 100644
--- a/arch/sh/mm/pg-sh4.c
+++ b/arch/sh/mm/pg-sh4.c
@@ -111,7 +111,7 @@ EXPORT_SYMBOL(copy_user_highpage);
111/* 111/*
112 * For SH-4, we have our own implementation for ptep_get_and_clear 112 * For SH-4, we have our own implementation for ptep_get_and_clear
113 */ 113 */
114inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) 114pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
115{ 115{
116 pte_t pte = *ptep; 116 pte_t pte = *ptep;
117 117
diff --git a/arch/sh/mm/pg-sh7705.c b/arch/sh/mm/pg-sh7705.c
index 7f885b7f8aff..eaf25147194c 100644
--- a/arch/sh/mm/pg-sh7705.c
+++ b/arch/sh/mm/pg-sh7705.c
@@ -118,7 +118,7 @@ void copy_user_page(void *to, void *from, unsigned long address, struct page *pg
118 * For SH7705, we have our own implementation for ptep_get_and_clear 118 * For SH7705, we have our own implementation for ptep_get_and_clear
119 * Copied from pg-sh4.c 119 * Copied from pg-sh4.c
120 */ 120 */
121inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) 121pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
122{ 122{
123 pte_t pte = *ptep; 123 pte_t pte = *ptep;
124 124
diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c
index 46911bcbf17b..cef727669c87 100644
--- a/arch/sh/mm/pmb.c
+++ b/arch/sh/mm/pmb.c
@@ -385,7 +385,7 @@ static const struct file_operations pmb_debugfs_fops = {
385 .open = pmb_debugfs_open, 385 .open = pmb_debugfs_open,
386 .read = seq_read, 386 .read = seq_read,
387 .llseek = seq_lseek, 387 .llseek = seq_lseek,
388 .release = seq_release, 388 .release = single_release,
389}; 389};
390 390
391static int __init pmb_debugfs_init(void) 391static int __init pmb_debugfs_init(void)
diff --git a/arch/sh/mm/tlb-sh5.c b/arch/sh/mm/tlb-sh5.c
index f34274a1ded3..dae131243bcc 100644
--- a/arch/sh/mm/tlb-sh5.c
+++ b/arch/sh/mm/tlb-sh5.c
@@ -15,9 +15,7 @@
15#include <asm/mmu_context.h> 15#include <asm/mmu_context.h>
16 16
17/** 17/**
18 * sh64_tlb_init 18 * sh64_tlb_init - Perform initial setup for the DTLB and ITLB.
19 *
20 * Perform initial setup for the DTLB and ITLB.
21 */ 19 */
22int __init sh64_tlb_init(void) 20int __init sh64_tlb_init(void)
23{ 21{
@@ -46,9 +44,7 @@ int __init sh64_tlb_init(void)
46} 44}
47 45
48/** 46/**
49 * sh64_next_free_dtlb_entry 47 * sh64_next_free_dtlb_entry - Find the next available DTLB entry
50 *
51 * Find the next available DTLB entry
52 */ 48 */
53unsigned long long sh64_next_free_dtlb_entry(void) 49unsigned long long sh64_next_free_dtlb_entry(void)
54{ 50{
@@ -56,9 +52,7 @@ unsigned long long sh64_next_free_dtlb_entry(void)
56} 52}
57 53
58/** 54/**
59 * sh64_get_wired_dtlb_entry 55 * sh64_get_wired_dtlb_entry - Allocate a wired (locked-in) entry in the DTLB
60 *
61 * Allocate a wired (locked-in) entry in the DTLB
62 */ 56 */
63unsigned long long sh64_get_wired_dtlb_entry(void) 57unsigned long long sh64_get_wired_dtlb_entry(void)
64{ 58{
@@ -71,12 +65,10 @@ unsigned long long sh64_get_wired_dtlb_entry(void)
71} 65}
72 66
73/** 67/**
74 * sh64_put_wired_dtlb_entry 68 * sh64_put_wired_dtlb_entry - Free a wired (locked-in) entry in the DTLB.
75 * 69 *
76 * @entry: Address of TLB slot. 70 * @entry: Address of TLB slot.
77 * 71 *
78 * Free a wired (locked-in) entry in the DTLB.
79 *
80 * Works like a stack, last one to allocate must be first one to free. 72 * Works like a stack, last one to allocate must be first one to free.
81 */ 73 */
82int sh64_put_wired_dtlb_entry(unsigned long long entry) 74int sh64_put_wired_dtlb_entry(unsigned long long entry)
@@ -115,7 +107,7 @@ int sh64_put_wired_dtlb_entry(unsigned long long entry)
115} 107}
116 108
117/** 109/**
118 * sh64_setup_tlb_slot 110 * sh64_setup_tlb_slot - Load up a translation in a wired slot.
119 * 111 *
120 * @config_addr: Address of TLB slot. 112 * @config_addr: Address of TLB slot.
121 * @eaddr: Virtual address. 113 * @eaddr: Virtual address.
@@ -154,7 +146,7 @@ inline void sh64_setup_tlb_slot(unsigned long long config_addr,
154} 146}
155 147
156/** 148/**
157 * sh64_teardown_tlb_slot 149 * sh64_teardown_tlb_slot - Teardown a translation.
158 * 150 *
159 * @config_addr: Address of TLB slot. 151 * @config_addr: Address of TLB slot.
160 * 152 *