1 // SPDX-License-Identifier: GPL-2.0-only
3 * Based on arch/arm/mm/ioremap.c
5 * (C) Copyright 1995 1996 Linus Torvalds
6 * Hacked for ARM by Phil Blundell <philb@gnu.org>
7 * Hacked to allow all architectures to build, and various cleanups
9 * Copyright (C) 2012 ARM Ltd.
12 #include <linux/export.h>
14 #include <linux/vmalloc.h>
17 #include <asm/fixmap.h>
18 #include <asm/tlbflush.h>
20 static void __iomem
*__ioremap_caller(phys_addr_t phys_addr
, size_t size
,
21 pgprot_t prot
, void *caller
)
23 unsigned long last_addr
;
24 unsigned long offset
= phys_addr
& ~PAGE_MASK
;
27 struct vm_struct
*area
;
30 * Page align the mapping address and size, taking account of any
33 phys_addr
&= PAGE_MASK
;
34 size
= PAGE_ALIGN(size
+ offset
);
37 * Don't allow wraparound, zero size or outside PHYS_MASK.
39 last_addr
= phys_addr
+ size
- 1;
40 if (!size
|| last_addr
< phys_addr
|| (last_addr
& ~PHYS_MASK
))
44 * Don't allow RAM to be mapped.
46 if (WARN_ON(pfn_valid(__phys_to_pfn(phys_addr
))))
49 area
= get_vm_area_caller(size
, VM_IOREMAP
, caller
);
52 addr
= (unsigned long)area
->addr
;
53 area
->phys_addr
= phys_addr
;
55 err
= ioremap_page_range(addr
, addr
+ size
, phys_addr
, prot
);
61 return (void __iomem
*)(offset
+ addr
);
64 void __iomem
*__ioremap(phys_addr_t phys_addr
, size_t size
, pgprot_t prot
)
66 return __ioremap_caller(phys_addr
, size
, prot
,
67 __builtin_return_address(0));
69 EXPORT_SYMBOL(__ioremap
);
71 void iounmap(volatile void __iomem
*io_addr
)
73 unsigned long addr
= (unsigned long)io_addr
& PAGE_MASK
;
76 * We could get an address outside vmalloc range in case
77 * of ioremap_cache() reusing a RAM mapping.
79 if (is_vmalloc_addr((void *)addr
))
82 EXPORT_SYMBOL(iounmap
);
84 void __iomem
*ioremap_cache(phys_addr_t phys_addr
, size_t size
)
86 /* For normal memory we already have a cacheable mapping. */
87 if (pfn_valid(__phys_to_pfn(phys_addr
)))
88 return (void __iomem
*)__phys_to_virt(phys_addr
);
90 return __ioremap_caller(phys_addr
, size
, __pgprot(PROT_NORMAL
),
91 __builtin_return_address(0));
93 EXPORT_SYMBOL(ioremap_cache
);
96 * Must be called after early_fixmap_init
98 void __init
early_ioremap_init(void)
100 early_ioremap_setup();