2 * (C) Copyright 1995 1996 Linus Torvalds
3 * (C) Copyright 2012 Regents of the University of California
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation, version 2.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
15 #include <linux/export.h>
17 #include <linux/vmalloc.h>
20 #include <asm/pgtable.h>
23 * Remap an arbitrary physical address space into the kernel virtual
24 * address space. Needed when the kernel wants to access high addresses
27 * NOTE! We need to allow non-page-aligned mappings too: we will obviously
28 * have to convert them into an offset in a page-aligned mapping, but the
29 * caller shouldn't need to know that small detail.
31 static void __iomem
*__ioremap_caller(phys_addr_t addr
, size_t size
,
32 pgprot_t prot
, void *caller
)
34 phys_addr_t last_addr
;
35 unsigned long offset
, vaddr
;
36 struct vm_struct
*area
;
38 /* Disallow wrap-around or zero size */
39 last_addr
= addr
+ size
- 1;
40 if (!size
|| last_addr
< addr
)
43 /* Page-align mappings */
44 offset
= addr
& (~PAGE_MASK
);
46 size
= PAGE_ALIGN(size
+ offset
);
48 area
= get_vm_area_caller(size
, VM_IOREMAP
, caller
);
51 vaddr
= (unsigned long)area
->addr
;
53 if (ioremap_page_range(vaddr
, vaddr
+ size
, addr
, prot
)) {
58 return (void __iomem
*)(vaddr
+ offset
);
62 * ioremap - map bus memory into CPU space
63 * @offset: bus address of the memory
64 * @size: size of the resource to map
66 * ioremap performs a platform specific sequence of operations to
67 * make bus memory CPU accessible via the readb/readw/readl/writeb/
68 * writew/writel functions and the other mmio helpers. The returned
69 * address is not guaranteed to be usable directly as a virtual
72 * Must be freed with iounmap.
74 void __iomem
*ioremap(phys_addr_t offset
, unsigned long size
)
76 return __ioremap_caller(offset
, size
, PAGE_KERNEL
,
77 __builtin_return_address(0));
79 EXPORT_SYMBOL(ioremap
);
83 * iounmap - Free a IO remapping
84 * @addr: virtual address from ioremap_*
86 * Caller must ensure there is only one unmapping for the same pointer.
88 void iounmap(volatile void __iomem
*addr
)
90 vunmap((void *)((unsigned long)addr
& PAGE_MASK
));
92 EXPORT_SYMBOL(iounmap
);