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