]>
Commit | Line | Data |
---|---|---|
59fd53cd GH |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | // Copyright (C) 2005-2017 Andes Technology Corporation | |
3 | ||
4 | #include <linux/export.h> | |
5 | #include <linux/highmem.h> | |
6 | #include <linux/sched.h> | |
7 | #include <linux/smp.h> | |
8 | #include <linux/interrupt.h> | |
9 | #include <linux/bootmem.h> | |
10 | #include <asm/fixmap.h> | |
11 | #include <asm/tlbflush.h> | |
12 | ||
13 | void *kmap(struct page *page) | |
14 | { | |
15 | unsigned long vaddr; | |
16 | might_sleep(); | |
17 | if (!PageHighMem(page)) | |
18 | return page_address(page); | |
19 | vaddr = (unsigned long)kmap_high(page); | |
20 | return (void *)vaddr; | |
21 | } | |
22 | ||
23 | EXPORT_SYMBOL(kmap); | |
24 | ||
25 | void kunmap(struct page *page) | |
26 | { | |
27 | BUG_ON(in_interrupt()); | |
28 | if (!PageHighMem(page)) | |
29 | return; | |
30 | kunmap_high(page); | |
31 | } | |
32 | ||
33 | EXPORT_SYMBOL(kunmap); | |
34 | ||
35 | void *kmap_atomic(struct page *page) | |
36 | { | |
37 | unsigned int idx; | |
38 | unsigned long vaddr, pte; | |
39 | int type; | |
40 | pte_t *ptep; | |
41 | ||
42 | preempt_disable(); | |
43 | pagefault_disable(); | |
44 | if (!PageHighMem(page)) | |
45 | return page_address(page); | |
46 | ||
47 | type = kmap_atomic_idx_push(); | |
48 | ||
49 | idx = type + KM_TYPE_NR * smp_processor_id(); | |
50 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | |
51 | pte = (page_to_pfn(page) << PAGE_SHIFT) | (PAGE_KERNEL); | |
52 | ptep = pte_offset_kernel(pmd_off_k(vaddr), vaddr); | |
53 | set_pte(ptep, pte); | |
54 | ||
55 | __nds32__tlbop_inv(vaddr); | |
56 | __nds32__mtsr_dsb(vaddr, NDS32_SR_TLB_VPN); | |
57 | __nds32__tlbop_rwr(pte); | |
58 | __nds32__isb(); | |
59 | return (void *)vaddr; | |
60 | } | |
61 | ||
62 | EXPORT_SYMBOL(kmap_atomic); | |
63 | ||
64 | void __kunmap_atomic(void *kvaddr) | |
65 | { | |
66 | if (kvaddr >= (void *)FIXADDR_START) { | |
67 | unsigned long vaddr = (unsigned long)kvaddr; | |
68 | pte_t *ptep; | |
69 | kmap_atomic_idx_pop(); | |
70 | __nds32__tlbop_inv(vaddr); | |
71 | __nds32__isb(); | |
72 | ptep = pte_offset_kernel(pmd_off_k(vaddr), vaddr); | |
73 | set_pte(ptep, 0); | |
74 | } | |
75 | pagefault_enable(); | |
76 | preempt_enable(); | |
77 | } | |
78 | ||
79 | EXPORT_SYMBOL(__kunmap_atomic); |