2 * Based on arch/arm/mm/ioremap.c
4 * (C) Copyright 1995 1996 Linus Torvalds
5 * Hacked for ARM by Phil Blundell <philb@gnu.org>
6 * Hacked to allow all architectures to build, and various cleanups
8 * Copyright (C) 2012 ARM Ltd.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include <linux/export.h>
25 #include <linux/vmalloc.h>
28 static void __iomem
*__ioremap_caller(phys_addr_t phys_addr
, size_t size
,
29 pgprot_t prot
, void *caller
)
31 unsigned long last_addr
;
32 unsigned long offset
= phys_addr
& ~PAGE_MASK
;
35 struct vm_struct
*area
;
38 * Page align the mapping address and size, taking account of any
41 phys_addr
&= PAGE_MASK
;
42 size
= PAGE_ALIGN(size
+ offset
);
45 * Don't allow wraparound, zero size or outside PHYS_MASK.
47 last_addr
= phys_addr
+ size
- 1;
48 if (!size
|| last_addr
< phys_addr
|| (last_addr
& ~PHYS_MASK
))
52 * Don't allow RAM to be mapped.
54 if (WARN_ON(pfn_valid(__phys_to_pfn(phys_addr
))))
57 area
= get_vm_area_caller(size
, VM_IOREMAP
, caller
);
60 addr
= (unsigned long)area
->addr
;
62 err
= ioremap_page_range(addr
, addr
+ size
, phys_addr
, prot
);
68 return (void __iomem
*)(offset
+ addr
);
71 void __iomem
*__ioremap(phys_addr_t phys_addr
, size_t size
, pgprot_t prot
)
73 return __ioremap_caller(phys_addr
, size
, prot
,
74 __builtin_return_address(0));
76 EXPORT_SYMBOL(__ioremap
);
78 void __iounmap(volatile void __iomem
*io_addr
)
80 void *addr
= (void *)(PAGE_MASK
& (unsigned long)io_addr
);
84 EXPORT_SYMBOL(__iounmap
);