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/mm/pmb.c | |
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/mm/pmb.c')
-rw-r--r-- | arch/sh/mm/pmb.c | 65 |
1 files changed, 60 insertions, 5 deletions
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 | { |