diff options
author | Matt Fleming <matt@console-pimps.org> | 2009-10-06 17:22:33 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-10-10 08:52:34 -0400 |
commit | 20b5014b3e5fe7b874a3f6a1dc03b0c21cb222cd (patch) | |
tree | 7b14d3c6f7004ca86e444c7237a022a143405e7f /arch/sh | |
parent | ef269b32763b22100eda9c0bf99d462c6cd65377 (diff) |
sh: Fold fixed-PMB support into dynamic PMB support
The initialisation process differs for CONFIG_PMB and for
CONFIG_PMB_FIXED. For CONFIG_PMB_FIXED we need to register the PMB
entries that were allocated by the bootloader.
Signed-off-by: Matt Fleming <matt@console-pimps.org>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh')
-rw-r--r-- | arch/sh/include/asm/mmu.h | 2 | ||||
-rw-r--r-- | arch/sh/kernel/setup.c | 2 | ||||
-rw-r--r-- | arch/sh/mm/Makefile | 3 | ||||
-rw-r--r-- | arch/sh/mm/pmb-fixed.c | 45 | ||||
-rw-r--r-- | arch/sh/mm/pmb.c | 65 |
5 files changed, 64 insertions, 53 deletions
diff --git a/arch/sh/include/asm/mmu.h b/arch/sh/include/asm/mmu.h index 9c84b4546c8d..c7426ad9926e 100644 --- a/arch/sh/include/asm/mmu.h +++ b/arch/sh/include/asm/mmu.h | |||
@@ -15,6 +15,8 @@ | |||
15 | #define PMB_E_MASK 0x0000000f | 15 | #define PMB_E_MASK 0x0000000f |
16 | #define PMB_E_SHIFT 8 | 16 | #define PMB_E_SHIFT 8 |
17 | 17 | ||
18 | #define PMB_PFN_MASK 0xff000000 | ||
19 | |||
18 | #define PMB_SZ_16M 0x00000000 | 20 | #define PMB_SZ_16M 0x00000000 |
19 | #define PMB_SZ_64M 0x00000010 | 21 | #define PMB_SZ_64M 0x00000010 |
20 | #define PMB_SZ_128M 0x00000080 | 22 | #define PMB_SZ_128M 0x00000080 |
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 8fdd03a67680..df65fe2d43b8 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c | |||
@@ -453,7 +453,7 @@ void __init setup_arch(char **cmdline_p) | |||
453 | 453 | ||
454 | paging_init(); | 454 | paging_init(); |
455 | 455 | ||
456 | #ifdef CONFIG_PMB | 456 | #ifdef CONFIG_PMB_ENABLE |
457 | pmb_init(); | 457 | pmb_init(); |
458 | #endif | 458 | #endif |
459 | 459 | ||
diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile index 3759bf853293..8a70535fa7ce 100644 --- a/arch/sh/mm/Makefile +++ b/arch/sh/mm/Makefile | |||
@@ -33,8 +33,7 @@ obj-y += $(tlb-y) | |||
33 | endif | 33 | endif |
34 | 34 | ||
35 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o | 35 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o |
36 | obj-$(CONFIG_PMB) += pmb.o | 36 | obj-$(CONFIG_PMB_ENABLE) += pmb.o |
37 | obj-$(CONFIG_PMB_FIXED) += pmb-fixed.o | ||
38 | obj-$(CONFIG_NUMA) += numa.o | 37 | obj-$(CONFIG_NUMA) += numa.o |
39 | 38 | ||
40 | # Special flags for fault_64.o. This puts restrictions on the number of | 39 | # Special flags for fault_64.o. This puts restrictions on the number of |
diff --git a/arch/sh/mm/pmb-fixed.c b/arch/sh/mm/pmb-fixed.c deleted file mode 100644 index 43c8eac4d8a1..000000000000 --- a/arch/sh/mm/pmb-fixed.c +++ /dev/null | |||
@@ -1,45 +0,0 @@ | |||
1 | /* | ||
2 | * arch/sh/mm/fixed_pmb.c | ||
3 | * | ||
4 | * Copyright (C) 2009 Renesas Solutions Corp. | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License. See the file "COPYING" in the main directory of this archive | ||
8 | * for more details. | ||
9 | */ | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/mm.h> | ||
12 | #include <linux/io.h> | ||
13 | #include <asm/mmu.h> | ||
14 | #include <asm/mmu_context.h> | ||
15 | |||
16 | static int __uses_jump_to_uncached fixed_pmb_init(void) | ||
17 | { | ||
18 | int i; | ||
19 | unsigned long addr, data; | ||
20 | |||
21 | jump_to_uncached(); | ||
22 | |||
23 | for (i = 0; i < PMB_ENTRY_MAX; i++) { | ||
24 | addr = PMB_DATA + (i << PMB_E_SHIFT); | ||
25 | data = ctrl_inl(addr); | ||
26 | if (!(data & PMB_V)) | ||
27 | continue; | ||
28 | |||
29 | if (data & PMB_C) { | ||
30 | #if defined(CONFIG_CACHE_WRITETHROUGH) | ||
31 | data |= PMB_WT; | ||
32 | #elif defined(CONFIG_CACHE_WRITEBACK) | ||
33 | data &= ~PMB_WT; | ||
34 | #else | ||
35 | data &= ~(PMB_C | PMB_WT); | ||
36 | #endif | ||
37 | } | ||
38 | ctrl_outl(data, addr); | ||
39 | } | ||
40 | |||
41 | back_to_cached(); | ||
42 | |||
43 | return 0; | ||
44 | } | ||
45 | arch_initcall(fixed_pmb_init); | ||
diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index 7e64f6d960c5..280f6a166035 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c | |||
@@ -70,14 +70,20 @@ repeat: | |||
70 | } | 70 | } |
71 | 71 | ||
72 | static struct pmb_entry *pmb_alloc(unsigned long vpn, unsigned long ppn, | 72 | static struct pmb_entry *pmb_alloc(unsigned long vpn, unsigned long ppn, |
73 | unsigned long flags) | 73 | unsigned long flags, int entry) |
74 | { | 74 | { |
75 | struct pmb_entry *pmbe; | 75 | struct pmb_entry *pmbe; |
76 | int pos; | 76 | int pos; |
77 | 77 | ||
78 | pos = pmb_alloc_entry(); | 78 | if (entry == PMB_NO_ENTRY) { |
79 | if (pos < 0) | 79 | pos = pmb_alloc_entry(); |
80 | return ERR_PTR(pos); | 80 | if (pos < 0) |
81 | return ERR_PTR(pos); | ||
82 | } else { | ||
83 | if (test_bit(entry, &pmb_map)) | ||
84 | return ERR_PTR(-ENOSPC); | ||
85 | pos = entry; | ||
86 | } | ||
81 | 87 | ||
82 | pmbe = &pmb_entry_list[pos]; | 88 | pmbe = &pmb_entry_list[pos]; |
83 | if (!pmbe) | 89 | if (!pmbe) |
@@ -187,7 +193,8 @@ again: | |||
187 | if (size < pmb_sizes[i].size) | 193 | if (size < pmb_sizes[i].size) |
188 | continue; | 194 | continue; |
189 | 195 | ||
190 | pmbe = pmb_alloc(vaddr, phys, pmb_flags | pmb_sizes[i].flag); | 196 | pmbe = pmb_alloc(vaddr, phys, pmb_flags | pmb_sizes[i].flag, |
197 | PMB_NO_ENTRY); | ||
191 | if (IS_ERR(pmbe)) { | 198 | if (IS_ERR(pmbe)) { |
192 | err = PTR_ERR(pmbe); | 199 | err = PTR_ERR(pmbe); |
193 | goto out; | 200 | goto out; |
@@ -272,6 +279,7 @@ static void __pmb_unmap(struct pmb_entry *pmbe) | |||
272 | } while (pmbe); | 279 | } while (pmbe); |
273 | } | 280 | } |
274 | 281 | ||
282 | #ifdef CONFIG_PMB | ||
275 | int __uses_jump_to_uncached pmb_init(void) | 283 | int __uses_jump_to_uncached pmb_init(void) |
276 | { | 284 | { |
277 | unsigned int i; | 285 | unsigned int i; |
@@ -309,6 +317,53 @@ int __uses_jump_to_uncached pmb_init(void) | |||
309 | 317 | ||
310 | return 0; | 318 | return 0; |
311 | } | 319 | } |
320 | #else | ||
321 | int __uses_jump_to_uncached pmb_init(void) | ||
322 | { | ||
323 | int i; | ||
324 | unsigned long addr, data; | ||
325 | |||
326 | jump_to_uncached(); | ||
327 | |||
328 | for (i = 0; i < PMB_ENTRY_MAX; i++) { | ||
329 | struct pmb_entry *pmbe; | ||
330 | unsigned long vpn, ppn, flags; | ||
331 | |||
332 | addr = PMB_DATA + (i << PMB_E_SHIFT); | ||
333 | data = ctrl_inl(addr); | ||
334 | if (!(data & PMB_V)) | ||
335 | continue; | ||
336 | |||
337 | if (data & PMB_C) { | ||
338 | #if defined(CONFIG_CACHE_WRITETHROUGH) | ||
339 | data |= PMB_WT; | ||
340 | #elif defined(CONFIG_CACHE_WRITEBACK) | ||
341 | data &= ~PMB_WT; | ||
342 | #else | ||
343 | data &= ~(PMB_C | PMB_WT); | ||
344 | #endif | ||
345 | } | ||
346 | ctrl_outl(data, addr); | ||
347 | |||
348 | ppn = data & PMB_PFN_MASK; | ||
349 | |||
350 | flags = data & (PMB_C | PMB_WT | PMB_UB); | ||
351 | flags |= data & PMB_SZ_MASK; | ||
352 | |||
353 | addr = PMB_ADDR + (i << PMB_E_SHIFT); | ||
354 | data = ctrl_inl(addr); | ||
355 | |||
356 | vpn = data & PMB_PFN_MASK; | ||
357 | |||
358 | pmbe = pmb_alloc(vpn, ppn, flags, i); | ||
359 | WARN_ON(IS_ERR(pmbe)); | ||
360 | } | ||
361 | |||
362 | back_to_cached(); | ||
363 | |||
364 | return 0; | ||
365 | } | ||
366 | #endif /* CONFIG_PMB */ | ||
312 | 367 | ||
313 | static int pmb_seq_show(struct seq_file *file, void *iter) | 368 | static int pmb_seq_show(struct seq_file *file, void *iter) |
314 | { | 369 | { |