aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/mm/pmb.c
diff options
context:
space:
mode:
authorMatt Fleming <matt@console-pimps.org>2009-10-06 17:22:33 -0400
committerPaul Mundt <lethal@linux-sh.org>2009-10-10 08:52:34 -0400
commit20b5014b3e5fe7b874a3f6a1dc03b0c21cb222cd (patch)
tree7b14d3c6f7004ca86e444c7237a022a143405e7f /arch/sh/mm/pmb.c
parentef269b32763b22100eda9c0bf99d462c6cd65377 (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.c65
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
72static struct pmb_entry *pmb_alloc(unsigned long vpn, unsigned long ppn, 72static 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
275int __uses_jump_to_uncached pmb_init(void) 283int __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
321int __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
313static int pmb_seq_show(struct seq_file *file, void *iter) 368static int pmb_seq_show(struct seq_file *file, void *iter)
314{ 369{