aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/mm
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2010-01-04 22:27:46 -0500
committerPaul Mundt <lethal@linux-sh.org>2010-01-04 22:27:46 -0500
commita7595fe7e8a93a73ce6199dace75a0caca7024c1 (patch)
treed8ed3959fe722ac5dad69285dea5537fc2535098 /arch/sh/mm
parent921a220857cdd3c553cde7c114f9f6757ac80cd5 (diff)
parent2a5eacca85d39d8b6dffae821d7d260f05584dc7 (diff)
Merge branch 'sh/pgtable' of git://github.com/mfleming/linux-2.6
Diffstat (limited to 'arch/sh/mm')
-rw-r--r--arch/sh/mm/Kconfig4
-rw-r--r--arch/sh/mm/Makefile2
-rw-r--r--arch/sh/mm/cache-sh4.c13
-rw-r--r--arch/sh/mm/pgtable.c57
4 files changed, 63 insertions, 13 deletions
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig
index a5dedf590a78..358c860aeb9b 100644
--- a/arch/sh/mm/Kconfig
+++ b/arch/sh/mm/Kconfig
@@ -219,7 +219,7 @@ config PAGE_SIZE_4KB
219 219
220config PAGE_SIZE_8KB 220config PAGE_SIZE_8KB
221 bool "8kB" 221 bool "8kB"
222 depends on !MMU || X2TLB && !PGTABLE_LEVELS_3 222 depends on !MMU || X2TLB
223 help 223 help
224 This enables 8kB pages as supported by SH-X2 and later MMUs. 224 This enables 8kB pages as supported by SH-X2 and later MMUs.
225 225
@@ -231,7 +231,7 @@ config PAGE_SIZE_16KB
231 231
232config PAGE_SIZE_64KB 232config PAGE_SIZE_64KB
233 bool "64kB" 233 bool "64kB"
234 depends on !MMU || CPU_SH4 && !PGTABLE_LEVELS_3 || CPU_SH5 234 depends on !MMU || CPU_SH4 || CPU_SH5
235 help 235 help
236 This enables support for 64kB pages, possible on all SH-4 236 This enables support for 64kB pages, possible on all SH-4
237 CPUs and later. 237 CPUs and later.
diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile
index 8a70535fa7ce..dd5010c708e0 100644
--- a/arch/sh/mm/Makefile
+++ b/arch/sh/mm/Makefile
@@ -15,7 +15,7 @@ obj-y += $(cacheops-y)
15 15
16mmu-y := nommu.o extable_32.o 16mmu-y := nommu.o extable_32.o
17mmu-$(CONFIG_MMU) := extable_$(BITS).o fault_$(BITS).o \ 17mmu-$(CONFIG_MMU) := extable_$(BITS).o fault_$(BITS).o \
18 ioremap_$(BITS).o kmap.o tlbflush_$(BITS).o 18 ioremap_$(BITS).o kmap.o pgtable.o tlbflush_$(BITS).o
19 19
20obj-y += $(mmu-y) 20obj-y += $(mmu-y)
21obj-$(CONFIG_DEBUG_FS) += asids-debugfs.o 21obj-$(CONFIG_DEBUG_FS) += asids-debugfs.o
diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c
index 560ddb6bc8a7..a2301daeefa3 100644
--- a/arch/sh/mm/cache-sh4.c
+++ b/arch/sh/mm/cache-sh4.c
@@ -109,6 +109,7 @@ static inline void flush_cache_one(unsigned long start, unsigned long phys)
109static void sh4_flush_dcache_page(void *arg) 109static void sh4_flush_dcache_page(void *arg)
110{ 110{
111 struct page *page = arg; 111 struct page *page = arg;
112 unsigned long addr = (unsigned long)page_address(page);
112#ifndef CONFIG_SMP 113#ifndef CONFIG_SMP
113 struct address_space *mapping = page_mapping(page); 114 struct address_space *mapping = page_mapping(page);
114 115
@@ -116,16 +117,8 @@ static void sh4_flush_dcache_page(void *arg)
116 set_bit(PG_dcache_dirty, &page->flags); 117 set_bit(PG_dcache_dirty, &page->flags);
117 else 118 else
118#endif 119#endif
119 { 120 flush_cache_one(CACHE_OC_ADDRESS_ARRAY |
120 unsigned long phys = page_to_phys(page); 121 (addr & shm_align_mask), page_to_phys(page));
121 unsigned long addr = CACHE_OC_ADDRESS_ARRAY;
122 int i, n;
123
124 /* Loop all the D-cache */
125 n = boot_cpu_data.dcache.n_aliases;
126 for (i = 0; i < n; i++, addr += PAGE_SIZE)
127 flush_cache_one(addr, phys);
128 }
129 122
130 wmb(); 123 wmb();
131} 124}
diff --git a/arch/sh/mm/pgtable.c b/arch/sh/mm/pgtable.c
new file mode 100644
index 000000000000..e1bc5483cc07
--- /dev/null
+++ b/arch/sh/mm/pgtable.c
@@ -0,0 +1,57 @@
1#include <linux/mm.h>
2
3#define PGALLOC_GFP GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO
4
5static struct kmem_cache *pgd_cachep;
6
7#ifdef CONFIG_PGTABLE_LEVELS_3
8static struct kmem_cache *pmd_cachep;
9#endif
10
11void pgd_ctor(void *x)
12{
13 pgd_t *pgd = x;
14
15 memcpy(pgd + USER_PTRS_PER_PGD,
16 swapper_pg_dir + USER_PTRS_PER_PGD,
17 (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
18}
19
20void pgtable_cache_init(void)
21{
22 pgd_cachep = kmem_cache_create("pgd_cache",
23 PTRS_PER_PGD * (1<<PTE_MAGNITUDE),
24 PAGE_SIZE, SLAB_PANIC, pgd_ctor);
25#ifdef CONFIG_PGTABLE_LEVELS_3
26 pmd_cachep = kmem_cache_create("pmd_cache",
27 PTRS_PER_PMD * (1<<PTE_MAGNITUDE),
28 PAGE_SIZE, SLAB_PANIC, NULL);
29#endif
30}
31
32pgd_t *pgd_alloc(struct mm_struct *mm)
33{
34 return kmem_cache_alloc(pgd_cachep, PGALLOC_GFP);
35}
36
37void pgd_free(struct mm_struct *mm, pgd_t *pgd)
38{
39 kmem_cache_free(pgd_cachep, pgd);
40}
41
42#ifdef CONFIG_PGTABLE_LEVELS_3
43void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
44{
45 set_pud(pud, __pud((unsigned long)pmd));
46}
47
48pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
49{
50 return kmem_cache_alloc(pmd_cachep, PGALLOC_GFP);
51}
52
53void pmd_free(struct mm_struct *mm, pmd_t *pmd)
54{
55 kmem_cache_free(pmd_cachep, pmd);
56}
57#endif /* CONFIG_PGTABLE_LEVELS_3 */