Commit | Line | Data |
---|---|---|
2739742c PM |
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 | ||
2739742c PM |
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; | |
0906a3ad | 35 | unsigned long vaddr; |
2739742c | 36 | |
55661fc1 | 37 | BUG_ON(!test_bit(PG_dcache_clean, &page->flags)); |
2739742c | 38 | |
b15d53d0 | 39 | preempt_disable(); |
0906a3ad | 40 | pagefault_disable(); |
2739742c | 41 | |
0906a3ad | 42 | idx = FIX_CMAP_END - |
f9e2bdfd PM |
43 | (((addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1)) + |
44 | (FIX_N_COLOURS * smp_processor_id())); | |
45 | ||
0906a3ad | 46 | vaddr = __fix_to_virt(idx); |
2739742c | 47 | |
0906a3ad PM |
48 | BUG_ON(!pte_none(*(kmap_coherent_pte - idx))); |
49 | set_pte(kmap_coherent_pte - idx, mk_pte(page, PAGE_KERNEL)); | |
2739742c PM |
50 | |
51 | return (void *)vaddr; | |
52 | } | |
53 | ||
0906a3ad | 54 | void kunmap_coherent(void *kvaddr) |
2739742c | 55 | { |
0906a3ad PM |
56 | if (kvaddr >= (void *)FIXADDR_START) { |
57 | unsigned long vaddr = (unsigned long)kvaddr & PAGE_MASK; | |
58 | enum fixed_addresses idx = __virt_to_fix(vaddr); | |
59 | ||
6e4154d4 PM |
60 | /* XXX.. Kill this later, here for sanity at the moment.. */ |
61 | __flush_purge_region((void *)vaddr, PAGE_SIZE); | |
62 | ||
0906a3ad PM |
63 | pte_clear(&init_mm, vaddr, kmap_coherent_pte - idx); |
64 | local_flush_tlb_one(get_asid(), vaddr); | |
65 | } | |
66 | ||
67 | pagefault_enable(); | |
b15d53d0 | 68 | preempt_enable(); |
2739742c | 69 | } |