Merge branches 'clk-imx', 'clk-samsung', 'clk-ti', 'clk-uniphier-gear' and 'clk-mmp2...
[linux-2.6-microblaze.git] / arch / csky / mm / ioremap.c
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
3
4 #include <linux/export.h>
5 #include <linux/mm.h>
6 #include <linux/vmalloc.h>
7 #include <linux/io.h>
8
9 #include <asm/pgtable.h>
10
11 void __iomem *ioremap(phys_addr_t addr, size_t size)
12 {
13         phys_addr_t last_addr;
14         unsigned long offset, vaddr;
15         struct vm_struct *area;
16         pgprot_t prot;
17
18         last_addr = addr + size - 1;
19         if (!size || last_addr < addr)
20                 return NULL;
21
22         offset = addr & (~PAGE_MASK);
23         addr &= PAGE_MASK;
24         size = PAGE_ALIGN(size + offset);
25
26         area = get_vm_area_caller(size, VM_ALLOC, __builtin_return_address(0));
27         if (!area)
28                 return NULL;
29
30         vaddr = (unsigned long)area->addr;
31
32         prot = __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE |
33                         _PAGE_GLOBAL | _CACHE_UNCACHED | _PAGE_SO);
34
35         if (ioremap_page_range(vaddr, vaddr + size, addr, prot)) {
36                 free_vm_area(area);
37                 return NULL;
38         }
39
40         return (void __iomem *)(vaddr + offset);
41 }
42 EXPORT_SYMBOL(ioremap);
43
44 void iounmap(void __iomem *addr)
45 {
46         vunmap((void *)((unsigned long)addr & PAGE_MASK));
47 }
48 EXPORT_SYMBOL(iounmap);
49
50 pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
51                               unsigned long size, pgprot_t vma_prot)
52 {
53         if (!pfn_valid(pfn)) {
54                 vma_prot.pgprot |= _PAGE_SO;
55                 return pgprot_noncached(vma_prot);
56         } else if (file->f_flags & O_SYNC) {
57                 return pgprot_noncached(vma_prot);
58         }
59
60         return vma_prot;
61 }
62 EXPORT_SYMBOL(phys_mem_access_prot);