diff options
Diffstat (limited to 'arch/sh/mm/kmap.c')
-rw-r--r-- | arch/sh/mm/kmap.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/arch/sh/mm/kmap.c b/arch/sh/mm/kmap.c new file mode 100644 index 000000000000..16e01b5fed04 --- /dev/null +++ b/arch/sh/mm/kmap.c | |||
@@ -0,0 +1,65 @@ | |||
1 | /* | ||
2 | * arch/sh/mm/kmap.c | ||
3 | * | ||
4 | * Copyright (C) 1999, 2000, 2002 Niibe Yutaka | ||
5 | * Copyright (C) 2002 - 2009 Paul Mundt | ||
6 | * | ||
7 | * Released under the terms of the GNU GPL v2.0. | ||
8 | */ | ||
9 | #include <linux/mm.h> | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/mutex.h> | ||
12 | #include <linux/fs.h> | ||
13 | #include <linux/highmem.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <asm/mmu_context.h> | ||
16 | #include <asm/cacheflush.h> | ||
17 | |||
18 | #define kmap_get_fixmap_pte(vaddr) \ | ||
19 | pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr)) | ||
20 | |||
21 | static pte_t *kmap_coherent_pte; | ||
22 | |||
23 | void __init kmap_coherent_init(void) | ||
24 | { | ||
25 | unsigned long vaddr; | ||
26 | |||
27 | /* cache the first coherent kmap pte */ | ||
28 | vaddr = __fix_to_virt(FIX_CMAP_BEGIN); | ||
29 | kmap_coherent_pte = kmap_get_fixmap_pte(vaddr); | ||
30 | } | ||
31 | |||
32 | void *kmap_coherent(struct page *page, unsigned long addr) | ||
33 | { | ||
34 | enum fixed_addresses idx; | ||
35 | unsigned long vaddr; | ||
36 | |||
37 | BUG_ON(test_bit(PG_dcache_dirty, &page->flags)); | ||
38 | |||
39 | pagefault_disable(); | ||
40 | |||
41 | idx = FIX_CMAP_END - | ||
42 | ((addr & current_cpu_data.dcache.alias_mask) >> PAGE_SHIFT); | ||
43 | vaddr = __fix_to_virt(idx); | ||
44 | |||
45 | BUG_ON(!pte_none(*(kmap_coherent_pte - idx))); | ||
46 | set_pte(kmap_coherent_pte - idx, mk_pte(page, PAGE_KERNEL)); | ||
47 | |||
48 | return (void *)vaddr; | ||
49 | } | ||
50 | |||
51 | void kunmap_coherent(void *kvaddr) | ||
52 | { | ||
53 | if (kvaddr >= (void *)FIXADDR_START) { | ||
54 | unsigned long vaddr = (unsigned long)kvaddr & PAGE_MASK; | ||
55 | enum fixed_addresses idx = __virt_to_fix(vaddr); | ||
56 | |||
57 | /* XXX.. Kill this later, here for sanity at the moment.. */ | ||
58 | __flush_purge_region((void *)vaddr, PAGE_SIZE); | ||
59 | |||
60 | pte_clear(&init_mm, vaddr, kmap_coherent_pte - idx); | ||
61 | local_flush_tlb_one(get_asid(), vaddr); | ||
62 | } | ||
63 | |||
64 | pagefault_enable(); | ||
65 | } | ||