2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
6 * (C) Copyright 1995 1996 Linus Torvalds
7 * (C) Copyright 2001, 2002 Ralf Baechle
9 #include <linux/export.h>
10 #include <asm/addrspace.h>
11 #include <asm/byteorder.h>
12 #include <linux/ioport.h>
13 #include <linux/sched.h>
14 #include <linux/slab.h>
15 #include <linux/vmalloc.h>
16 #include <linux/mm_types.h>
18 #include <asm/cacheflush.h>
19 #include <asm/tlbflush.h>
22 #define IS_LOW512(addr) (!((phys_addr_t)(addr) & (phys_addr_t) ~0x1fffffffULL))
23 #define IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1)
25 static int __ioremap_check_ram(unsigned long start_pfn
, unsigned long nr_pages
,
30 for (i
= 0; i
< nr_pages
; i
++) {
31 if (pfn_valid(start_pfn
+ i
) &&
32 !PageReserved(pfn_to_page(start_pfn
+ i
)))
40 * ioremap_prot - map bus memory into CPU space
41 * @phys_addr: bus address of the memory
42 * @size: size of the resource to map
44 * ioremap_prot gives the caller control over cache coherency attributes (CCA)
46 void __iomem
*ioremap_prot(phys_addr_t phys_addr
, unsigned long size
,
47 unsigned long prot_val
)
49 unsigned long flags
= prot_val
& _CACHE_MASK
;
50 unsigned long offset
, pfn
, last_pfn
;
51 struct vm_struct
*area
;
52 phys_addr_t last_addr
;
54 void __iomem
*cpu_addr
;
56 cpu_addr
= plat_ioremap(phys_addr
, size
, flags
);
60 phys_addr
= fixup_bigphys_addr(phys_addr
, size
);
62 /* Don't allow wraparound or zero size */
63 last_addr
= phys_addr
+ size
- 1;
64 if (!size
|| last_addr
< phys_addr
)
68 * Map uncached objects in the low 512mb of address space using KSEG1,
69 * otherwise map using page tables.
71 if (IS_LOW512(phys_addr
) && IS_LOW512(last_addr
) &&
72 flags
== _CACHE_UNCACHED
)
73 return (void __iomem
*) CKSEG1ADDR(phys_addr
);
76 * Don't allow anybody to remap RAM that may be allocated by the page
77 * allocator, since that could lead to races & data clobbering.
79 pfn
= PFN_DOWN(phys_addr
);
80 last_pfn
= PFN_DOWN(last_addr
);
81 if (walk_system_ram_range(pfn
, last_pfn
- pfn
+ 1, NULL
,
82 __ioremap_check_ram
) == 1) {
83 WARN_ONCE(1, "ioremap on RAM at %pa - %pa\n",
84 &phys_addr
, &last_addr
);
89 * Mappings have to be page-aligned
91 offset
= phys_addr
& ~PAGE_MASK
;
92 phys_addr
&= PAGE_MASK
;
93 size
= PAGE_ALIGN(last_addr
+ 1) - phys_addr
;
98 area
= get_vm_area(size
, VM_IOREMAP
);
101 vaddr
= (unsigned long)area
->addr
;
103 flags
|= _PAGE_GLOBAL
| _PAGE_PRESENT
| __READABLE
| __WRITEABLE
;
104 if (ioremap_page_range(vaddr
, vaddr
+ size
, phys_addr
,
110 return (void __iomem
*)(vaddr
+ offset
);
112 EXPORT_SYMBOL(ioremap_prot
);
114 void iounmap(const volatile void __iomem
*addr
)
116 if (!plat_iounmap(addr
) && !IS_KSEG1(addr
))
117 vunmap((void *)((unsigned long)addr
& PAGE_MASK
));
119 EXPORT_SYMBOL(iounmap
);