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
powerpc
sysdev
bestcomm
sram.c
Go to the documentation of this file.
1
/*
2
* Simple memory allocator for on-board SRAM
3
*
4
*
5
* Maintainer : Sylvain Munaut <
[email protected]
>
6
*
7
* Copyright (C) 2005 Sylvain Munaut <
[email protected]
>
8
*
9
* This file is licensed under the terms of the GNU General Public License
10
* version 2. This program is licensed "as is" without any warranty of any
11
* kind, whether express or implied.
12
*/
13
14
#include <
linux/err.h
>
15
#include <linux/kernel.h>
16
#include <linux/export.h>
17
#include <linux/slab.h>
18
#include <
linux/spinlock.h
>
19
#include <linux/string.h>
20
#include <
linux/ioport.h
>
21
#include <
linux/of.h
>
22
23
#include <asm/io.h>
24
#include <asm/mmu.h>
25
26
#include "
sram.h
"
27
28
29
/* Struct keeping our 'state' */
30
struct
bcom_sram
*
bcom_sram
=
NULL
;
31
EXPORT_SYMBOL_GPL
(bcom_sram);
/* needed for inline functions */
32
33
34
/* ======================================================================== */
35
/* Public API */
36
/* ======================================================================== */
37
/* DO NOT USE in interrupts, if needed in irq handler, we should use the
38
_irqsave version of the spin_locks */
39
40
int
bcom_sram_init
(
struct
device_node
*sram_node,
char
*
owner
)
41
{
42
int
rv;
43
const
u32
*regaddr_p;
44
u64
regaddr64, size64;
45
unsigned
int
psize;
46
47
/* Create our state struct */
48
if
(bcom_sram) {
49
printk
(
KERN_ERR
"%s: bcom_sram_init: "
50
"Already initialized !\n"
, owner);
51
return
-
EBUSY
;
52
}
53
54
bcom_sram =
kmalloc
(
sizeof
(
struct
bcom_sram),
GFP_KERNEL
);
55
if
(!bcom_sram) {
56
printk
(
KERN_ERR
"%s: bcom_sram_init: "
57
"Couldn't allocate internal state !\n"
, owner);
58
return
-
ENOMEM
;
59
}
60
61
/* Get address and size of the sram */
62
regaddr_p =
of_get_address
(sram_node, 0, &size64,
NULL
);
63
if
(!regaddr_p) {
64
printk
(
KERN_ERR
"%s: bcom_sram_init: "
65
"Invalid device node !\n"
, owner);
66
rv = -
EINVAL
;
67
goto
error_free;
68
}
69
70
regaddr64 =
of_translate_address
(sram_node, regaddr_p);
71
72
bcom_sram->
base_phys
= (
phys_addr_t
) regaddr64;
73
bcom_sram->
size
= (
unsigned
int
) size64;
74
75
/* Request region */
76
if
(!
request_mem_region
(bcom_sram->
base_phys
, bcom_sram->
size
, owner)) {
77
printk
(
KERN_ERR
"%s: bcom_sram_init: "
78
"Couldn't request region !\n"
, owner);
79
rv = -
EBUSY
;
80
goto
error_free;
81
}
82
83
/* Map SRAM */
84
/* sram is not really __iomem */
85
bcom_sram->
base_virt
= (
void
*)
ioremap
(bcom_sram->
base_phys
, bcom_sram->
size
);
86
87
if
(!bcom_sram->
base_virt
) {
88
printk
(
KERN_ERR
"%s: bcom_sram_init: "
89
"Map error SRAM zone 0x%08lx (0x%0x)!\n"
,
90
owner, (
long
)bcom_sram->
base_phys
, bcom_sram->
size
);
91
rv = -
ENOMEM
;
92
goto
error_release;
93
}
94
95
/* Create an rheap (defaults to 32 bits word alignment) */
96
bcom_sram->
rh
=
rh_create
(4);
97
98
/* Attach the free zones */
99
#if 0
100
/* Currently disabled ... for future use only */
101
reg_addr_p =
of_get_property
(sram_node,
"available"
, &psize);
102
#else
103
regaddr_p =
NULL
;
104
psize = 0;
105
#endif
106
107
if
(!regaddr_p || !psize) {
108
/* Attach the whole zone */
109
rh_attach_region
(bcom_sram->
rh
, 0, bcom_sram->
size
);
110
}
else
{
111
/* Attach each zone independently */
112
while
(psize >= 2 *
sizeof
(
u32
)) {
113
phys_addr_t
zbase =
of_translate_address
(sram_node, regaddr_p);
114
rh_attach_region
(bcom_sram->
rh
, zbase - bcom_sram->
base_phys
, regaddr_p[1]);
115
regaddr_p += 2;
116
psize -= 2 *
sizeof
(
u32
);
117
}
118
}
119
120
/* Init our spinlock */
121
spin_lock_init
(&bcom_sram->
lock
);
122
123
return
0;
124
125
error_release:
126
release_mem_region
(bcom_sram->
base_phys
, bcom_sram->
size
);
127
error_free:
128
kfree
(bcom_sram);
129
bcom_sram =
NULL
;
130
131
return
rv;
132
}
133
EXPORT_SYMBOL_GPL
(
bcom_sram_init
);
134
135
void
bcom_sram_cleanup
(
void
)
136
{
137
/* Free resources */
138
if
(bcom_sram) {
139
rh_destroy
(bcom_sram->
rh
);
140
iounmap
((
void
__iomem
*)bcom_sram->
base_virt
);
141
release_mem_region
(bcom_sram->
base_phys
, bcom_sram->
size
);
142
kfree
(bcom_sram);
143
bcom_sram =
NULL
;
144
}
145
}
146
EXPORT_SYMBOL_GPL
(
bcom_sram_cleanup
);
147
148
void
*
bcom_sram_alloc
(
int
size
,
int
align
,
phys_addr_t
*
phys
)
149
{
150
unsigned
long
offset
;
151
152
spin_lock(&bcom_sram->
lock
);
153
offset =
rh_alloc_align
(bcom_sram->
rh
, size, align,
NULL
);
154
spin_unlock(&bcom_sram->
lock
);
155
156
if
(
IS_ERR_VALUE
(offset))
157
return
NULL
;
158
159
*phys = bcom_sram->
base_phys
+
offset
;
160
return
bcom_sram->
base_virt
+
offset
;
161
}
162
EXPORT_SYMBOL_GPL
(
bcom_sram_alloc
);
163
164
void
bcom_sram_free
(
void
*
ptr
)
165
{
166
unsigned
long
offset
;
167
168
if
(!ptr)
169
return
;
170
171
offset = ptr - bcom_sram->
base_virt
;
172
173
spin_lock(&bcom_sram->
lock
);
174
rh_free
(bcom_sram->
rh
, offset);
175
spin_unlock(&bcom_sram->
lock
);
176
}
177
EXPORT_SYMBOL_GPL
(
bcom_sram_free
);
178
Generated on Thu Jan 10 2013 12:58:38 for Linux Kernel by
1.8.2