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 #include <asm/fixmap.h>
29 #include <asm/tlbflush.h>
30 #include <asm/pgalloc.h>
32 static void __iomem
*__ioremap_caller(phys_addr_t phys_addr
, size_t size
,
33 pgprot_t prot
, void *caller
)
35 unsigned long last_addr
;
36 unsigned long offset
= phys_addr
& ~PAGE_MASK
;
39 struct vm_struct
*area
;
42 * Page align the mapping address and size, taking account of any
45 phys_addr
&= PAGE_MASK
;
46 size
= PAGE_ALIGN(size
+ offset
);
49 * Don't allow wraparound, zero size or outside PHYS_MASK.
51 last_addr
= phys_addr
+ size
- 1;
52 if (!size
|| last_addr
< phys_addr
|| (last_addr
& ~PHYS_MASK
))
56 * Don't allow RAM to be mapped.
58 if (WARN_ON(pfn_valid(__phys_to_pfn(phys_addr
))))
61 area
= get_vm_area_caller(size
, VM_IOREMAP
, caller
);
64 addr
= (unsigned long)area
->addr
;
65 area
->phys_addr
= phys_addr
;
67 err
= ioremap_page_range(addr
, addr
+ size
, phys_addr
, prot
);
73 return (void __iomem
*)(offset
+ addr
);
76 void __iomem
*__ioremap(phys_addr_t phys_addr
, size_t size
, pgprot_t prot
)
78 return __ioremap_caller(phys_addr
, size
, prot
,
79 __builtin_return_address(0));
81 EXPORT_SYMBOL(__ioremap
);
83 void __iounmap(volatile void __iomem
*io_addr
)
85 unsigned long addr
= (unsigned long)io_addr
& PAGE_MASK
;
88 * We could get an address outside vmalloc range in case
89 * of ioremap_cache() reusing a RAM mapping.
91 if (VMALLOC_START
<= addr
&& addr
< VMALLOC_END
)
94 EXPORT_SYMBOL(__iounmap
);
96 void __iomem
*ioremap_cache(phys_addr_t phys_addr
, size_t size
)
98 /* For normal memory we already have a cacheable mapping. */
99 if (pfn_valid(__phys_to_pfn(phys_addr
)))
100 return (void __iomem
*)__phys_to_virt(phys_addr
);
102 return __ioremap_caller(phys_addr
, size
, __pgprot(PROT_NORMAL
),
103 __builtin_return_address(0));
105 EXPORT_SYMBOL(ioremap_cache
);
108 * Must be called after early_fixmap_init
110 void __init
early_ioremap_init(void)
112 early_ioremap_setup();