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>
19 #include <asm/pgalloc.h>
21 static void __iomem
*__ioremap_caller(phys_addr_t phys_addr
, size_t size
,
22 pgprot_t prot
, void *caller
)
24 unsigned long last_addr
;
25 unsigned long offset
= phys_addr
& ~PAGE_MASK
;
28 struct vm_struct
*area
;
31 * Page align the mapping address and size, taking account of any
34 phys_addr
&= PAGE_MASK
;
35 size
= PAGE_ALIGN(size
+ offset
);
38 * Don't allow wraparound, zero size or outside PHYS_MASK.
40 last_addr
= phys_addr
+ size
- 1;
41 if (!size
|| last_addr
< phys_addr
|| (last_addr
& ~PHYS_MASK
))
45 * Don't allow RAM to be mapped.
47 if (WARN_ON(pfn_valid(__phys_to_pfn(phys_addr
))))
50 area
= get_vm_area_caller(size
, VM_IOREMAP
, caller
);
53 addr
= (unsigned long)area
->addr
;
54 area
->phys_addr
= phys_addr
;
56 err
= ioremap_page_range(addr
, addr
+ size
, phys_addr
, prot
);
62 return (void __iomem
*)(offset
+ addr
);
65 void __iomem
*__ioremap(phys_addr_t phys_addr
, size_t size
, pgprot_t prot
)
67 return __ioremap_caller(phys_addr
, size
, prot
,
68 __builtin_return_address(0));
70 EXPORT_SYMBOL(__ioremap
);
72 void iounmap(volatile void __iomem
*io_addr
)
74 unsigned long addr
= (unsigned long)io_addr
& PAGE_MASK
;
77 * We could get an address outside vmalloc range in case
78 * of ioremap_cache() reusing a RAM mapping.
80 if (is_vmalloc_addr((void *)addr
))
83 EXPORT_SYMBOL(iounmap
);
85 void __iomem
*ioremap_cache(phys_addr_t phys_addr
, size_t size
)
87 /* For normal memory we already have a cacheable mapping. */
88 if (pfn_valid(__phys_to_pfn(phys_addr
)))
89 return (void __iomem
*)__phys_to_virt(phys_addr
);
91 return __ioremap_caller(phys_addr
, size
, __pgprot(PROT_NORMAL
),
92 __builtin_return_address(0));
94 EXPORT_SYMBOL(ioremap_cache
);
97 * Must be called after early_fixmap_init
99 void __init
early_ioremap_init(void)
101 early_ioremap_setup();