debugobjects: Make stack check warning more informative
[linux/fpc-iii.git] / arch / nds32 / mm / ioremap.c
blob690140bb23a2c4f4bfa0a4bcb5f1166dc39bb148
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2005-2017 Andes Technology Corporation
4 #include <linux/vmalloc.h>
5 #include <linux/io.h>
6 #include <linux/mm.h>
7 #include <asm/pgtable.h>
9 void __iomem *ioremap(phys_addr_t phys_addr, size_t size);
11 static void __iomem *__ioremap_caller(phys_addr_t phys_addr, size_t size,
12 void *caller)
14 struct vm_struct *area;
15 unsigned long addr, offset, last_addr;
16 pgprot_t prot;
18 /* Don't allow wraparound or zero size */
19 last_addr = phys_addr + size - 1;
20 if (!size || last_addr < phys_addr)
21 return NULL;
24 * Mappings have to be page-aligned
26 offset = phys_addr & ~PAGE_MASK;
27 phys_addr &= PAGE_MASK;
28 size = PAGE_ALIGN(last_addr + 1) - phys_addr;
31 * Ok, go for it..
33 area = get_vm_area_caller(size, VM_IOREMAP, caller);
34 if (!area)
35 return NULL;
37 area->phys_addr = phys_addr;
38 addr = (unsigned long)area->addr;
39 prot = __pgprot(_PAGE_V | _PAGE_M_KRW | _PAGE_D |
40 _PAGE_G | _PAGE_C_DEV);
41 if (ioremap_page_range(addr, addr + size, phys_addr, prot)) {
42 vunmap((void *)addr);
43 return NULL;
45 return (__force void __iomem *)(offset + (char *)addr);
49 void __iomem *ioremap(phys_addr_t phys_addr, size_t size)
51 return __ioremap_caller(phys_addr, size,
52 __builtin_return_address(0));
55 EXPORT_SYMBOL(ioremap);
57 void iounmap(volatile void __iomem * addr)
59 vunmap((void *)(PAGE_MASK & (unsigned long)addr));
62 EXPORT_SYMBOL(iounmap);