2 * Re-map IO memory to kernel address space so that we can access it.
4 * These functions should only be used when it is necessary to map a
5 * physical address space into the kernel address space before ioremap()
6 * can be used, e.g. early in boot before paging_init().
8 * Copyright (C) 2009 Matt Fleming
11 #include <linux/vmalloc.h>
12 #include <linux/ioport.h>
13 #include <linux/module.h>
16 #include <linux/bootmem.h>
17 #include <linux/proc_fs.h>
18 #include <asm/fixmap.h>
20 #include <asm/pgalloc.h>
21 #include <asm/addrspace.h>
22 #include <asm/cacheflush.h>
23 #include <asm/tlbflush.h>
25 #include <asm/mmu_context.h>
30 unsigned long fixmap_addr
;
33 static struct ioremap_map ioremap_maps
[FIX_N_IOREMAPS
];
35 void __init
ioremap_fixed_init(void)
37 struct ioremap_map
*map
;
40 for (i
= 0; i
< FIX_N_IOREMAPS
; i
++) {
41 map
= &ioremap_maps
[i
];
42 map
->fixmap_addr
= __fix_to_virt(FIX_IOREMAP_BEGIN
+ i
);
47 ioremap_fixed(phys_addr_t phys_addr
, unsigned long size
, pgprot_t prot
)
49 enum fixed_addresses idx0
, idx
;
50 struct ioremap_map
*map
;
56 * Mappings have to be page-aligned
58 offset
= phys_addr
& ~PAGE_MASK
;
59 phys_addr
&= PAGE_MASK
;
60 size
= PAGE_ALIGN(phys_addr
+ size
) - phys_addr
;
63 for (i
= 0; i
< FIX_N_IOREMAPS
; i
++) {
64 map
= &ioremap_maps
[i
];
76 * Mappings have to fit in the FIX_IOREMAP area.
78 nrpages
= size
>> PAGE_SHIFT
;
79 if (nrpages
> FIX_N_IOREMAPS
)
85 idx0
= FIX_IOREMAP_BEGIN
+ slot
;
88 pgprot_val(prot
) |= _PAGE_WIRED
;
89 __set_fixmap(idx
, phys_addr
, prot
);
90 phys_addr
+= PAGE_SIZE
;
95 map
->addr
= (void __iomem
*)(offset
+ map
->fixmap_addr
);
99 int iounmap_fixed(void __iomem
*addr
)
101 enum fixed_addresses idx
;
102 struct ioremap_map
*map
;
103 unsigned int nrpages
;
107 for (i
= 0; i
< FIX_N_IOREMAPS
; i
++) {
108 map
= &ioremap_maps
[i
];
109 if (map
->addr
== addr
) {
116 * If we don't match, it's not for us.
121 nrpages
= map
->size
>> PAGE_SHIFT
;
123 idx
= FIX_IOREMAP_BEGIN
+ slot
+ nrpages
- 1;
124 while (nrpages
> 0) {
125 __clear_fixmap(idx
, __pgprot(_PAGE_WIRED
));