Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
•
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
sh
mm
ioremap_fixed.c
Go to the documentation of this file.
1
/*
2
* Re-map IO memory to kernel address space so that we can access it.
3
*
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().
7
*
8
* Copyright (C) 2009 Matt Fleming
9
*/
10
11
#include <
linux/vmalloc.h
>
12
#include <
linux/ioport.h
>
13
#include <linux/module.h>
14
#include <
linux/mm.h
>
15
#include <
linux/io.h
>
16
#include <
linux/bootmem.h
>
17
#include <
linux/proc_fs.h
>
18
#include <asm/fixmap.h>
19
#include <asm/page.h>
20
#include <asm/pgalloc.h>
21
#include <asm/addrspace.h>
22
#include <asm/cacheflush.h>
23
#include <asm/tlbflush.h>
24
#include <asm/mmu.h>
25
#include <asm/mmu_context.h>
26
27
struct
ioremap_map
{
28
void
__iomem
*
addr
;
29
unsigned
long
size
;
30
unsigned
long
fixmap_addr
;
31
};
32
33
static
struct
ioremap_map
ioremap_maps[
FIX_N_IOREMAPS
];
34
35
void
__init
ioremap_fixed_init
(
void
)
36
{
37
struct
ioremap_map
*
map
;
38
int
i
;
39
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);
43
}
44
}
45
46
void
__init
__iomem
*
47
ioremap_fixed
(
phys_addr_t
phys_addr
,
unsigned
long
size
,
pgprot_t
prot)
48
{
49
enum
fixed_addresses
idx0,
idx
;
50
struct
ioremap_map
*
map
;
51
unsigned
int
nrpages
;
52
unsigned
long
offset
;
53
int
i
,
slot
;
54
55
/*
56
* Mappings have to be page-aligned
57
*/
58
offset = phys_addr & ~
PAGE_MASK
;
59
phys_addr &=
PAGE_MASK
;
60
size =
PAGE_ALIGN
(phys_addr + size) -
phys_addr
;
61
62
slot = -1;
63
for
(i = 0; i <
FIX_N_IOREMAPS
; i++) {
64
map = &ioremap_maps[
i
];
65
if
(!map->
addr
) {
66
map->
size
=
size
;
67
slot =
i
;
68
break
;
69
}
70
}
71
72
if
(slot < 0)
73
return
NULL
;
74
75
/*
76
* Mappings have to fit in the FIX_IOREMAP area.
77
*/
78
nrpages = size >>
PAGE_SHIFT
;
79
if
(nrpages > FIX_N_IOREMAPS)
80
return
NULL
;
81
82
/*
83
* Ok, go for it..
84
*/
85
idx0 =
FIX_IOREMAP_BEGIN
+
slot
;
86
idx = idx0;
87
while
(nrpages > 0) {
88
pgprot_val
(prot) |=
_PAGE_WIRED
;
89
__set_fixmap
(idx, phys_addr, prot);
90
phys_addr +=
PAGE_SIZE
;
91
idx++;
92
--
nrpages
;
93
}
94
95
map->
addr
= (
void
__iomem
*)(offset + map->
fixmap_addr
);
96
return
map->
addr
;
97
}
98
99
int
iounmap_fixed
(
void
__iomem
*
addr
)
100
{
101
enum
fixed_addresses
idx
;
102
struct
ioremap_map
*
map
;
103
unsigned
int
nrpages
;
104
int
i
,
slot
;
105
106
slot = -1;
107
for
(i = 0; i <
FIX_N_IOREMAPS
; i++) {
108
map = &ioremap_maps[
i
];
109
if
(map->
addr
== addr) {
110
slot =
i
;
111
break
;
112
}
113
}
114
115
/*
116
* If we don't match, it's not for us.
117
*/
118
if
(slot < 0)
119
return
-
EINVAL
;
120
121
nrpages = map->
size
>>
PAGE_SHIFT
;
122
123
idx =
FIX_IOREMAP_BEGIN
+ slot + nrpages - 1;
124
while
(nrpages > 0) {
125
__clear_fixmap
(idx,
__pgprot
(
_PAGE_WIRED
));
126
--
idx
;
127
--
nrpages
;
128
}
129
130
map->
size
= 0;
131
map->
addr
=
NULL
;
132
133
return
0;
134
}
Generated on Thu Jan 10 2013 13:18:01 for Linux Kernel by
1.8.2