diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-26 16:23:17 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-26 16:23:17 -0400 |
commit | 7f268a2ba7c884a239713696238dd4207a57dd9a (patch) | |
tree | fdc02fecda32f5df8de3ddc2c01c29ba68e6a42b /arch/blackfin/mm | |
parent | 689796a141cea79d745a4689c65dd01c39e5e100 (diff) | |
parent | 2d2009806dd843f3adc0cbbb5d2204980f28111a (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/blackfin-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/blackfin-2.6: (30 commits)
Blackfin arch: If we double fault, rather than hang forever, reset
Blackfin arch: When icache is off, make sure people know it
Blackfin arch: Fix bug - skip single step in high priority interrupt handler instead of disabling all interrupts in single step debugging.
Blackfin arch: cache the values of vco/sclk/cclk as the overhead of doing so (~24 bytes) is worth avoiding the software mult/div routines
Blackfin arch: fix bug - IMDMA is not type struct dma_register
Blackfin arch: check the EXTBANKS field of the DDRCTL1 register to see if we are using both memory banks
Blackfin arch: Apply Bluetechnix CM-BF527 board support patch
Blackfin arch: Add unwinding for stack info, and a little more detail on trace buffer
Blackfin arch: Add ISP1760 board resources to BF548-EZKIT
Blackfin arch: fix bug - detect 0.1 silicon revision BF527-EZKIT as 0.0 version
Blackfin arch: add missing IORESOURCE_MEM flags to UART3
Blackfin arch: Add return value check in bfin_sir_probe(), remove SSYNC().
Blackfin arch: Extend sram malloc to handle L2 SRAM.
Blackfin arch: Remove useless config option.
Blackfin arch: change L1 malloc to base on slab cache and lists.
Blackfin arch: use local labels and ENDPROC() markings
Blackfin arch: Do not need this dualcore test module in kernel.
Blackfin arch: Allow ptrace to peek and poke application data in L1 data SRAM.
Blackfin arch: Add ANOMALY_05000368 workaround
Blackfin arch: Functional power management support
...
Diffstat (limited to 'arch/blackfin/mm')
-rw-r--r-- | arch/blackfin/mm/blackfin_sram.c | 543 | ||||
-rw-r--r-- | arch/blackfin/mm/blackfin_sram.h | 4 | ||||
-rw-r--r-- | arch/blackfin/mm/init.c | 12 |
3 files changed, 381 insertions, 178 deletions
diff --git a/arch/blackfin/mm/blackfin_sram.c b/arch/blackfin/mm/blackfin_sram.c index 3246f91c7baa..5af3c31c9365 100644 --- a/arch/blackfin/mm/blackfin_sram.c +++ b/arch/blackfin/mm/blackfin_sram.c | |||
@@ -41,215 +41,309 @@ | |||
41 | #include <asm/blackfin.h> | 41 | #include <asm/blackfin.h> |
42 | #include "blackfin_sram.h" | 42 | #include "blackfin_sram.h" |
43 | 43 | ||
44 | spinlock_t l1sram_lock, l1_data_sram_lock, l1_inst_sram_lock; | 44 | static spinlock_t l1sram_lock, l1_data_sram_lock, l1_inst_sram_lock; |
45 | 45 | static spinlock_t l2_sram_lock; | |
46 | #if CONFIG_L1_MAX_PIECE < 16 | ||
47 | #undef CONFIG_L1_MAX_PIECE | ||
48 | #define CONFIG_L1_MAX_PIECE 16 | ||
49 | #endif | ||
50 | |||
51 | #if CONFIG_L1_MAX_PIECE > 1024 | ||
52 | #undef CONFIG_L1_MAX_PIECE | ||
53 | #define CONFIG_L1_MAX_PIECE 1024 | ||
54 | #endif | ||
55 | |||
56 | #define SRAM_SLT_NULL 0 | ||
57 | #define SRAM_SLT_FREE 1 | ||
58 | #define SRAM_SLT_ALLOCATED 2 | ||
59 | 46 | ||
60 | /* the data structure for L1 scratchpad and DATA SRAM */ | 47 | /* the data structure for L1 scratchpad and DATA SRAM */ |
61 | struct l1_sram_piece { | 48 | struct sram_piece { |
62 | void *paddr; | 49 | void *paddr; |
63 | int size; | 50 | int size; |
64 | int flag; | ||
65 | pid_t pid; | 51 | pid_t pid; |
52 | struct sram_piece *next; | ||
66 | }; | 53 | }; |
67 | 54 | ||
68 | static struct l1_sram_piece l1_ssram[CONFIG_L1_MAX_PIECE]; | 55 | static struct sram_piece free_l1_ssram_head, used_l1_ssram_head; |
69 | 56 | ||
70 | #if L1_DATA_A_LENGTH != 0 | 57 | #if L1_DATA_A_LENGTH != 0 |
71 | static struct l1_sram_piece l1_data_A_sram[CONFIG_L1_MAX_PIECE]; | 58 | static struct sram_piece free_l1_data_A_sram_head, used_l1_data_A_sram_head; |
72 | #endif | 59 | #endif |
73 | 60 | ||
74 | #if L1_DATA_B_LENGTH != 0 | 61 | #if L1_DATA_B_LENGTH != 0 |
75 | static struct l1_sram_piece l1_data_B_sram[CONFIG_L1_MAX_PIECE]; | 62 | static struct sram_piece free_l1_data_B_sram_head, used_l1_data_B_sram_head; |
76 | #endif | 63 | #endif |
77 | 64 | ||
78 | #if L1_CODE_LENGTH != 0 | 65 | #if L1_CODE_LENGTH != 0 |
79 | static struct l1_sram_piece l1_inst_sram[CONFIG_L1_MAX_PIECE]; | 66 | static struct sram_piece free_l1_inst_sram_head, used_l1_inst_sram_head; |
67 | #endif | ||
68 | |||
69 | #ifdef L2_LENGTH | ||
70 | static struct sram_piece free_l2_sram_head, used_l2_sram_head; | ||
80 | #endif | 71 | #endif |
81 | 72 | ||
73 | static struct kmem_cache *sram_piece_cache; | ||
74 | |||
82 | /* L1 Scratchpad SRAM initialization function */ | 75 | /* L1 Scratchpad SRAM initialization function */ |
83 | void __init l1sram_init(void) | 76 | static void __init l1sram_init(void) |
84 | { | 77 | { |
85 | printk(KERN_INFO "Blackfin Scratchpad data SRAM: %d KB\n", | 78 | free_l1_ssram_head.next = |
86 | L1_SCRATCH_LENGTH >> 10); | 79 | kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); |
80 | if (!free_l1_ssram_head.next) { | ||
81 | printk(KERN_INFO"Fail to initialize Scratchpad data SRAM.\n"); | ||
82 | return; | ||
83 | } | ||
84 | |||
85 | free_l1_ssram_head.next->paddr = (void *)L1_SCRATCH_START; | ||
86 | free_l1_ssram_head.next->size = L1_SCRATCH_LENGTH; | ||
87 | free_l1_ssram_head.next->pid = 0; | ||
88 | free_l1_ssram_head.next->next = NULL; | ||
87 | 89 | ||
88 | memset(&l1_ssram, 0x00, sizeof(l1_ssram)); | 90 | used_l1_ssram_head.next = NULL; |
89 | l1_ssram[0].paddr = (void *)L1_SCRATCH_START; | ||
90 | l1_ssram[0].size = L1_SCRATCH_LENGTH; | ||
91 | l1_ssram[0].flag = SRAM_SLT_FREE; | ||
92 | 91 | ||
93 | /* mutex initialize */ | 92 | /* mutex initialize */ |
94 | spin_lock_init(&l1sram_lock); | 93 | spin_lock_init(&l1sram_lock); |
94 | |||
95 | printk(KERN_INFO "Blackfin Scratchpad data SRAM: %d KB\n", | ||
96 | L1_SCRATCH_LENGTH >> 10); | ||
95 | } | 97 | } |
96 | 98 | ||
97 | void __init l1_data_sram_init(void) | 99 | static void __init l1_data_sram_init(void) |
98 | { | 100 | { |
99 | #if L1_DATA_A_LENGTH != 0 | 101 | #if L1_DATA_A_LENGTH != 0 |
100 | memset(&l1_data_A_sram, 0x00, sizeof(l1_data_A_sram)); | 102 | free_l1_data_A_sram_head.next = |
101 | l1_data_A_sram[0].paddr = (void *)L1_DATA_A_START + | 103 | kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); |
102 | (_ebss_l1 - _sdata_l1); | 104 | if (!free_l1_data_A_sram_head.next) { |
103 | l1_data_A_sram[0].size = L1_DATA_A_LENGTH - (_ebss_l1 - _sdata_l1); | 105 | printk(KERN_INFO"Fail to initialize L1 Data A SRAM.\n"); |
104 | l1_data_A_sram[0].flag = SRAM_SLT_FREE; | 106 | return; |
105 | 107 | } | |
106 | printk(KERN_INFO "Blackfin Data A SRAM: %d KB (%d KB free)\n", | 108 | |
107 | L1_DATA_A_LENGTH >> 10, l1_data_A_sram[0].size >> 10); | 109 | free_l1_data_A_sram_head.next->paddr = |
110 | (void *)L1_DATA_A_START + (_ebss_l1 - _sdata_l1); | ||
111 | free_l1_data_A_sram_head.next->size = | ||
112 | L1_DATA_A_LENGTH - (_ebss_l1 - _sdata_l1); | ||
113 | free_l1_data_A_sram_head.next->pid = 0; | ||
114 | free_l1_data_A_sram_head.next->next = NULL; | ||
115 | |||
116 | used_l1_data_A_sram_head.next = NULL; | ||
117 | |||
118 | printk(KERN_INFO "Blackfin L1 Data A SRAM: %d KB (%d KB free)\n", | ||
119 | L1_DATA_A_LENGTH >> 10, | ||
120 | free_l1_data_A_sram_head.next->size >> 10); | ||
108 | #endif | 121 | #endif |
109 | #if L1_DATA_B_LENGTH != 0 | 122 | #if L1_DATA_B_LENGTH != 0 |
110 | memset(&l1_data_B_sram, 0x00, sizeof(l1_data_B_sram)); | 123 | free_l1_data_B_sram_head.next = |
111 | l1_data_B_sram[0].paddr = (void *)L1_DATA_B_START + | 124 | kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); |
112 | (_ebss_b_l1 - _sdata_b_l1); | 125 | if (!free_l1_data_B_sram_head.next) { |
113 | l1_data_B_sram[0].size = L1_DATA_B_LENGTH - (_ebss_b_l1 - _sdata_b_l1); | 126 | printk(KERN_INFO"Fail to initialize L1 Data B SRAM.\n"); |
114 | l1_data_B_sram[0].flag = SRAM_SLT_FREE; | 127 | return; |
115 | 128 | } | |
116 | printk(KERN_INFO "Blackfin Data B SRAM: %d KB (%d KB free)\n", | 129 | |
117 | L1_DATA_B_LENGTH >> 10, l1_data_B_sram[0].size >> 10); | 130 | free_l1_data_B_sram_head.next->paddr = |
131 | (void *)L1_DATA_B_START + (_ebss_b_l1 - _sdata_b_l1); | ||
132 | free_l1_data_B_sram_head.next->size = | ||
133 | L1_DATA_B_LENGTH - (_ebss_b_l1 - _sdata_b_l1); | ||
134 | free_l1_data_B_sram_head.next->pid = 0; | ||
135 | free_l1_data_B_sram_head.next->next = NULL; | ||
136 | |||
137 | used_l1_data_B_sram_head.next = NULL; | ||
138 | |||
139 | printk(KERN_INFO "Blackfin L1 Data B SRAM: %d KB (%d KB free)\n", | ||
140 | L1_DATA_B_LENGTH >> 10, | ||
141 | free_l1_data_B_sram_head.next->size >> 10); | ||
118 | #endif | 142 | #endif |
119 | 143 | ||
120 | /* mutex initialize */ | 144 | /* mutex initialize */ |
121 | spin_lock_init(&l1_data_sram_lock); | 145 | spin_lock_init(&l1_data_sram_lock); |
122 | } | 146 | } |
123 | 147 | ||
124 | void __init l1_inst_sram_init(void) | 148 | static void __init l1_inst_sram_init(void) |
125 | { | 149 | { |
126 | #if L1_CODE_LENGTH != 0 | 150 | #if L1_CODE_LENGTH != 0 |
127 | memset(&l1_inst_sram, 0x00, sizeof(l1_inst_sram)); | 151 | free_l1_inst_sram_head.next = |
128 | l1_inst_sram[0].paddr = (void *)L1_CODE_START + (_etext_l1 - _stext_l1); | 152 | kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); |
129 | l1_inst_sram[0].size = L1_CODE_LENGTH - (_etext_l1 - _stext_l1); | 153 | if (!free_l1_inst_sram_head.next) { |
130 | l1_inst_sram[0].flag = SRAM_SLT_FREE; | 154 | printk(KERN_INFO"Fail to initialize L1 Instruction SRAM.\n"); |
155 | return; | ||
156 | } | ||
131 | 157 | ||
132 | printk(KERN_INFO "Blackfin Instruction SRAM: %d KB (%d KB free)\n", | 158 | free_l1_inst_sram_head.next->paddr = |
133 | L1_CODE_LENGTH >> 10, l1_inst_sram[0].size >> 10); | 159 | (void *)L1_CODE_START + (_etext_l1 - _stext_l1); |
160 | free_l1_inst_sram_head.next->size = | ||
161 | L1_CODE_LENGTH - (_etext_l1 - _stext_l1); | ||
162 | free_l1_inst_sram_head.next->pid = 0; | ||
163 | free_l1_inst_sram_head.next->next = NULL; | ||
164 | |||
165 | used_l1_inst_sram_head.next = NULL; | ||
166 | |||
167 | printk(KERN_INFO "Blackfin L1 Instruction SRAM: %d KB (%d KB free)\n", | ||
168 | L1_CODE_LENGTH >> 10, | ||
169 | free_l1_inst_sram_head.next->size >> 10); | ||
134 | #endif | 170 | #endif |
135 | 171 | ||
136 | /* mutex initialize */ | 172 | /* mutex initialize */ |
137 | spin_lock_init(&l1_inst_sram_lock); | 173 | spin_lock_init(&l1_inst_sram_lock); |
138 | } | 174 | } |
139 | 175 | ||
140 | /* L1 memory allocate function */ | 176 | static void __init l2_sram_init(void) |
141 | static void *_l1_sram_alloc(size_t size, struct l1_sram_piece *pfree, int count) | ||
142 | { | 177 | { |
143 | int i, index = 0; | 178 | #ifdef L2_LENGTH |
144 | void *addr = NULL; | 179 | free_l2_sram_head.next = |
180 | kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); | ||
181 | if (!free_l2_sram_head.next) { | ||
182 | printk(KERN_INFO"Fail to initialize L2 SRAM.\n"); | ||
183 | return; | ||
184 | } | ||
145 | 185 | ||
146 | if (size <= 0) | 186 | free_l2_sram_head.next->paddr = (void *)L2_START + |
187 | (_etext_l2 - _stext_l2) + (_edata_l2 - _sdata_l2); | ||
188 | free_l2_sram_head.next->size = L2_LENGTH - | ||
189 | (_etext_l2 - _stext_l2) + (_edata_l2 - _sdata_l2); | ||
190 | free_l2_sram_head.next->pid = 0; | ||
191 | free_l2_sram_head.next->next = NULL; | ||
192 | |||
193 | used_l2_sram_head.next = NULL; | ||
194 | |||
195 | printk(KERN_INFO "Blackfin L2 SRAM: %d KB (%d KB free)\n", | ||
196 | L2_LENGTH >> 10, | ||
197 | free_l2_sram_head.next->size >> 10); | ||
198 | #endif | ||
199 | |||
200 | /* mutex initialize */ | ||
201 | spin_lock_init(&l2_sram_lock); | ||
202 | } | ||
203 | void __init bfin_sram_init(void) | ||
204 | { | ||
205 | sram_piece_cache = kmem_cache_create("sram_piece_cache", | ||
206 | sizeof(struct sram_piece), | ||
207 | 0, SLAB_PANIC, NULL); | ||
208 | |||
209 | l1sram_init(); | ||
210 | l1_data_sram_init(); | ||
211 | l1_inst_sram_init(); | ||
212 | l2_sram_init(); | ||
213 | } | ||
214 | |||
215 | /* SRAM allocate function */ | ||
216 | static void *_sram_alloc(size_t size, struct sram_piece *pfree_head, | ||
217 | struct sram_piece *pused_head) | ||
218 | { | ||
219 | struct sram_piece *pslot, *plast, *pavail; | ||
220 | |||
221 | if (size <= 0 || !pfree_head || !pused_head) | ||
147 | return NULL; | 222 | return NULL; |
148 | 223 | ||
149 | /* Align the size */ | 224 | /* Align the size */ |
150 | size = (size + 3) & ~3; | 225 | size = (size + 3) & ~3; |
151 | 226 | ||
152 | /* not use the good method to match the best slot !!! */ | 227 | pslot = pfree_head->next; |
153 | /* search an available memory slot */ | 228 | plast = pfree_head; |
154 | for (i = 0; i < count; i++) { | 229 | |
155 | if ((pfree[i].flag == SRAM_SLT_FREE) | 230 | /* search an available piece slot */ |
156 | && (pfree[i].size >= size)) { | 231 | while (pslot != NULL && size > pslot->size) { |
157 | addr = pfree[i].paddr; | 232 | plast = pslot; |
158 | pfree[i].flag = SRAM_SLT_ALLOCATED; | 233 | pslot = pslot->next; |
159 | pfree[i].pid = current->pid; | ||
160 | index = i; | ||
161 | break; | ||
162 | } | ||
163 | } | 234 | } |
164 | if (i >= count) | 235 | |
236 | if (!pslot) | ||
165 | return NULL; | 237 | return NULL; |
166 | 238 | ||
167 | /* updated the NULL memory slot !!! */ | 239 | if (pslot->size == size) { |
168 | if (pfree[i].size > size) { | 240 | plast->next = pslot->next; |
169 | for (i = 0; i < count; i++) { | 241 | pavail = pslot; |
170 | if (pfree[i].flag == SRAM_SLT_NULL) { | 242 | } else { |
171 | pfree[i].pid = 0; | 243 | pavail = kmem_cache_alloc(sram_piece_cache, GFP_KERNEL); |
172 | pfree[i].flag = SRAM_SLT_FREE; | 244 | |
173 | pfree[i].paddr = addr + size; | 245 | if (!pavail) |
174 | pfree[i].size = pfree[index].size - size; | 246 | return NULL; |
175 | pfree[index].size = size; | 247 | |
176 | break; | 248 | pavail->paddr = pslot->paddr; |
177 | } | 249 | pavail->size = size; |
178 | } | 250 | pslot->paddr += size; |
251 | pslot->size -= size; | ||
179 | } | 252 | } |
180 | 253 | ||
181 | return addr; | 254 | pavail->pid = current->pid; |
255 | |||
256 | pslot = pused_head->next; | ||
257 | plast = pused_head; | ||
258 | |||
259 | /* insert new piece into used piece list !!! */ | ||
260 | while (pslot != NULL && pavail->paddr < pslot->paddr) { | ||
261 | plast = pslot; | ||
262 | pslot = pslot->next; | ||
263 | } | ||
264 | |||
265 | pavail->next = pslot; | ||
266 | plast->next = pavail; | ||
267 | |||
268 | return pavail->paddr; | ||
182 | } | 269 | } |
183 | 270 | ||
184 | /* Allocate the largest available block. */ | 271 | /* Allocate the largest available block. */ |
185 | static void *_l1_sram_alloc_max(struct l1_sram_piece *pfree, int count, | 272 | static void *_sram_alloc_max(struct sram_piece *pfree_head, |
273 | struct sram_piece *pused_head, | ||
186 | unsigned long *psize) | 274 | unsigned long *psize) |
187 | { | 275 | { |
188 | unsigned long best = 0; | 276 | struct sram_piece *pslot, *pmax; |
189 | int i, index = -1; | ||
190 | void *addr = NULL; | ||
191 | 277 | ||
192 | /* search an available memory slot */ | 278 | if (!pfree_head || !pused_head) |
193 | for (i = 0; i < count; i++) { | 279 | return NULL; |
194 | if (pfree[i].flag == SRAM_SLT_FREE && pfree[i].size > best) { | 280 | |
195 | addr = pfree[i].paddr; | 281 | pmax = pslot = pfree_head->next; |
196 | index = i; | 282 | |
197 | best = pfree[i].size; | 283 | /* search an available piece slot */ |
198 | } | 284 | while (pslot != NULL) { |
285 | if (pslot->size > pmax->size) | ||
286 | pmax = pslot; | ||
287 | pslot = pslot->next; | ||
199 | } | 288 | } |
200 | if (index < 0) | 289 | |
290 | if (!pmax) | ||
201 | return NULL; | 291 | return NULL; |
202 | *psize = best; | ||
203 | 292 | ||
204 | pfree[index].pid = current->pid; | 293 | *psize = pmax->size; |
205 | pfree[index].flag = SRAM_SLT_ALLOCATED; | 294 | |
206 | return addr; | 295 | return _sram_alloc(*psize, pfree_head, pused_head); |
207 | } | 296 | } |
208 | 297 | ||
209 | /* L1 memory free function */ | 298 | /* SRAM free function */ |
210 | static int _l1_sram_free(const void *addr, | 299 | static int _sram_free(const void *addr, |
211 | struct l1_sram_piece *pfree, | 300 | struct sram_piece *pfree_head, |
212 | int count) | 301 | struct sram_piece *pused_head) |
213 | { | 302 | { |
214 | int i, index = 0; | 303 | struct sram_piece *pslot, *plast, *pavail; |
304 | |||
305 | if (!pfree_head || !pused_head) | ||
306 | return -1; | ||
215 | 307 | ||
216 | /* search the relevant memory slot */ | 308 | /* search the relevant memory slot */ |
217 | for (i = 0; i < count; i++) { | 309 | pslot = pused_head->next; |
218 | if (pfree[i].paddr == addr) { | 310 | plast = pused_head; |
219 | if (pfree[i].flag != SRAM_SLT_ALLOCATED) { | 311 | |
220 | /* error log */ | 312 | /* search an available piece slot */ |
221 | return -1; | 313 | while (pslot != NULL && pslot->paddr != addr) { |
222 | } | 314 | plast = pslot; |
223 | index = i; | 315 | pslot = pslot->next; |
224 | break; | ||
225 | } | ||
226 | } | 316 | } |
227 | if (i >= count) | 317 | |
318 | if (!pslot) | ||
228 | return -1; | 319 | return -1; |
229 | 320 | ||
230 | pfree[index].pid = 0; | 321 | plast->next = pslot->next; |
231 | pfree[index].flag = SRAM_SLT_FREE; | 322 | pavail = pslot; |
232 | 323 | pavail->pid = 0; | |
233 | /* link the next address slot */ | 324 | |
234 | for (i = 0; i < count; i++) { | 325 | /* insert free pieces back to the free list */ |
235 | if (((pfree[index].paddr + pfree[index].size) == pfree[i].paddr) | 326 | pslot = pfree_head->next; |
236 | && (pfree[i].flag == SRAM_SLT_FREE)) { | 327 | plast = pfree_head; |
237 | pfree[i].pid = 0; | 328 | |
238 | pfree[i].flag = SRAM_SLT_NULL; | 329 | while (pslot != NULL && addr > pslot->paddr) { |
239 | pfree[index].size += pfree[i].size; | 330 | plast = pslot; |
240 | pfree[index].flag = SRAM_SLT_FREE; | 331 | pslot = pslot->next; |
241 | break; | 332 | } |
242 | } | 333 | |
334 | if (plast != pfree_head && plast->paddr + plast->size == pavail->paddr) { | ||
335 | plast->size += pavail->size; | ||
336 | kmem_cache_free(sram_piece_cache, pavail); | ||
337 | } else { | ||
338 | pavail->next = plast; | ||
339 | plast->next = pavail; | ||
340 | plast = pavail; | ||
243 | } | 341 | } |
244 | 342 | ||
245 | /* link the last address slot */ | 343 | if (pslot && plast->paddr + plast->size == pslot->paddr) { |
246 | for (i = 0; i < count; i++) { | 344 | plast->size += pslot->size; |
247 | if (((pfree[i].paddr + pfree[i].size) == pfree[index].paddr) && | 345 | plast->next = pslot->next; |
248 | (pfree[i].flag == SRAM_SLT_FREE)) { | 346 | kmem_cache_free(sram_piece_cache, pslot); |
249 | pfree[index].flag = SRAM_SLT_NULL; | ||
250 | pfree[i].size += pfree[index].size; | ||
251 | break; | ||
252 | } | ||
253 | } | 347 | } |
254 | 348 | ||
255 | return 0; | 349 | return 0; |
@@ -273,6 +367,11 @@ int sram_free(const void *addr) | |||
273 | && addr < (void *)(L1_DATA_B_START + L1_DATA_B_LENGTH)) | 367 | && addr < (void *)(L1_DATA_B_START + L1_DATA_B_LENGTH)) |
274 | return l1_data_B_sram_free(addr); | 368 | return l1_data_B_sram_free(addr); |
275 | #endif | 369 | #endif |
370 | #ifdef L2_LENGTH | ||
371 | else if (addr >= (void *)L2_START | ||
372 | && addr < (void *)(L2_START + L2_LENGTH)) | ||
373 | return l2_sram_free(addr); | ||
374 | #endif | ||
276 | else | 375 | else |
277 | return -1; | 376 | return -1; |
278 | } | 377 | } |
@@ -287,7 +386,8 @@ void *l1_data_A_sram_alloc(size_t size) | |||
287 | spin_lock_irqsave(&l1_data_sram_lock, flags); | 386 | spin_lock_irqsave(&l1_data_sram_lock, flags); |
288 | 387 | ||
289 | #if L1_DATA_A_LENGTH != 0 | 388 | #if L1_DATA_A_LENGTH != 0 |
290 | addr = _l1_sram_alloc(size, l1_data_A_sram, ARRAY_SIZE(l1_data_A_sram)); | 389 | addr = _sram_alloc(size, &free_l1_data_A_sram_head, |
390 | &used_l1_data_A_sram_head); | ||
291 | #endif | 391 | #endif |
292 | 392 | ||
293 | /* add mutex operation */ | 393 | /* add mutex operation */ |
@@ -309,8 +409,8 @@ int l1_data_A_sram_free(const void *addr) | |||
309 | spin_lock_irqsave(&l1_data_sram_lock, flags); | 409 | spin_lock_irqsave(&l1_data_sram_lock, flags); |
310 | 410 | ||
311 | #if L1_DATA_A_LENGTH != 0 | 411 | #if L1_DATA_A_LENGTH != 0 |
312 | ret = _l1_sram_free(addr, | 412 | ret = _sram_free(addr, &free_l1_data_A_sram_head, |
313 | l1_data_A_sram, ARRAY_SIZE(l1_data_A_sram)); | 413 | &used_l1_data_A_sram_head); |
314 | #else | 414 | #else |
315 | ret = -1; | 415 | ret = -1; |
316 | #endif | 416 | #endif |
@@ -331,7 +431,8 @@ void *l1_data_B_sram_alloc(size_t size) | |||
331 | /* add mutex operation */ | 431 | /* add mutex operation */ |
332 | spin_lock_irqsave(&l1_data_sram_lock, flags); | 432 | spin_lock_irqsave(&l1_data_sram_lock, flags); |
333 | 433 | ||
334 | addr = _l1_sram_alloc(size, l1_data_B_sram, ARRAY_SIZE(l1_data_B_sram)); | 434 | addr = _sram_alloc(size, &free_l1_data_B_sram_head, |
435 | &used_l1_data_B_sram_head); | ||
335 | 436 | ||
336 | /* add mutex operation */ | 437 | /* add mutex operation */ |
337 | spin_unlock_irqrestore(&l1_data_sram_lock, flags); | 438 | spin_unlock_irqrestore(&l1_data_sram_lock, flags); |
@@ -355,7 +456,8 @@ int l1_data_B_sram_free(const void *addr) | |||
355 | /* add mutex operation */ | 456 | /* add mutex operation */ |
356 | spin_lock_irqsave(&l1_data_sram_lock, flags); | 457 | spin_lock_irqsave(&l1_data_sram_lock, flags); |
357 | 458 | ||
358 | ret = _l1_sram_free(addr, l1_data_B_sram, ARRAY_SIZE(l1_data_B_sram)); | 459 | ret = _sram_free(addr, &free_l1_data_B_sram_head, |
460 | &used_l1_data_B_sram_head); | ||
359 | 461 | ||
360 | /* add mutex operation */ | 462 | /* add mutex operation */ |
361 | spin_unlock_irqrestore(&l1_data_sram_lock, flags); | 463 | spin_unlock_irqrestore(&l1_data_sram_lock, flags); |
@@ -408,7 +510,8 @@ void *l1_inst_sram_alloc(size_t size) | |||
408 | /* add mutex operation */ | 510 | /* add mutex operation */ |
409 | spin_lock_irqsave(&l1_inst_sram_lock, flags); | 511 | spin_lock_irqsave(&l1_inst_sram_lock, flags); |
410 | 512 | ||
411 | addr = _l1_sram_alloc(size, l1_inst_sram, ARRAY_SIZE(l1_inst_sram)); | 513 | addr = _sram_alloc(size, &free_l1_inst_sram_head, |
514 | &used_l1_inst_sram_head); | ||
412 | 515 | ||
413 | /* add mutex operation */ | 516 | /* add mutex operation */ |
414 | spin_unlock_irqrestore(&l1_inst_sram_lock, flags); | 517 | spin_unlock_irqrestore(&l1_inst_sram_lock, flags); |
@@ -432,7 +535,8 @@ int l1_inst_sram_free(const void *addr) | |||
432 | /* add mutex operation */ | 535 | /* add mutex operation */ |
433 | spin_lock_irqsave(&l1_inst_sram_lock, flags); | 536 | spin_lock_irqsave(&l1_inst_sram_lock, flags); |
434 | 537 | ||
435 | ret = _l1_sram_free(addr, l1_inst_sram, ARRAY_SIZE(l1_inst_sram)); | 538 | ret = _sram_free(addr, &free_l1_inst_sram_head, |
539 | &used_l1_inst_sram_head); | ||
436 | 540 | ||
437 | /* add mutex operation */ | 541 | /* add mutex operation */ |
438 | spin_unlock_irqrestore(&l1_inst_sram_lock, flags); | 542 | spin_unlock_irqrestore(&l1_inst_sram_lock, flags); |
@@ -453,7 +557,8 @@ void *l1sram_alloc(size_t size) | |||
453 | /* add mutex operation */ | 557 | /* add mutex operation */ |
454 | spin_lock_irqsave(&l1sram_lock, flags); | 558 | spin_lock_irqsave(&l1sram_lock, flags); |
455 | 559 | ||
456 | addr = _l1_sram_alloc(size, l1_ssram, ARRAY_SIZE(l1_ssram)); | 560 | addr = _sram_alloc(size, &free_l1_ssram_head, |
561 | &used_l1_ssram_head); | ||
457 | 562 | ||
458 | /* add mutex operation */ | 563 | /* add mutex operation */ |
459 | spin_unlock_irqrestore(&l1sram_lock, flags); | 564 | spin_unlock_irqrestore(&l1sram_lock, flags); |
@@ -470,7 +575,8 @@ void *l1sram_alloc_max(size_t *psize) | |||
470 | /* add mutex operation */ | 575 | /* add mutex operation */ |
471 | spin_lock_irqsave(&l1sram_lock, flags); | 576 | spin_lock_irqsave(&l1sram_lock, flags); |
472 | 577 | ||
473 | addr = _l1_sram_alloc_max(l1_ssram, ARRAY_SIZE(l1_ssram), psize); | 578 | addr = _sram_alloc_max(&free_l1_ssram_head, |
579 | &used_l1_ssram_head, psize); | ||
474 | 580 | ||
475 | /* add mutex operation */ | 581 | /* add mutex operation */ |
476 | spin_unlock_irqrestore(&l1sram_lock, flags); | 582 | spin_unlock_irqrestore(&l1sram_lock, flags); |
@@ -487,7 +593,8 @@ int l1sram_free(const void *addr) | |||
487 | /* add mutex operation */ | 593 | /* add mutex operation */ |
488 | spin_lock_irqsave(&l1sram_lock, flags); | 594 | spin_lock_irqsave(&l1sram_lock, flags); |
489 | 595 | ||
490 | ret = _l1_sram_free(addr, l1_ssram, ARRAY_SIZE(l1_ssram)); | 596 | ret = _sram_free(addr, &free_l1_ssram_head, |
597 | &used_l1_ssram_head); | ||
491 | 598 | ||
492 | /* add mutex operation */ | 599 | /* add mutex operation */ |
493 | spin_unlock_irqrestore(&l1sram_lock, flags); | 600 | spin_unlock_irqrestore(&l1sram_lock, flags); |
@@ -495,6 +602,64 @@ int l1sram_free(const void *addr) | |||
495 | return ret; | 602 | return ret; |
496 | } | 603 | } |
497 | 604 | ||
605 | void *l2_sram_alloc(size_t size) | ||
606 | { | ||
607 | #ifdef L2_LENGTH | ||
608 | unsigned flags; | ||
609 | void *addr; | ||
610 | |||
611 | /* add mutex operation */ | ||
612 | spin_lock_irqsave(&l2_sram_lock, flags); | ||
613 | |||
614 | addr = _sram_alloc(size, &free_l2_sram_head, | ||
615 | &used_l2_sram_head); | ||
616 | |||
617 | /* add mutex operation */ | ||
618 | spin_unlock_irqrestore(&l2_sram_lock, flags); | ||
619 | |||
620 | pr_debug("Allocated address in l2_sram_alloc is 0x%lx+0x%lx\n", | ||
621 | (long unsigned int)addr, size); | ||
622 | |||
623 | return addr; | ||
624 | #else | ||
625 | return NULL; | ||
626 | #endif | ||
627 | } | ||
628 | EXPORT_SYMBOL(l2_sram_alloc); | ||
629 | |||
630 | void *l2_sram_zalloc(size_t size) | ||
631 | { | ||
632 | void *addr = l2_sram_alloc(size); | ||
633 | |||
634 | if (addr) | ||
635 | memset(addr, 0x00, size); | ||
636 | |||
637 | return addr; | ||
638 | } | ||
639 | EXPORT_SYMBOL(l2_sram_zalloc); | ||
640 | |||
641 | int l2_sram_free(const void *addr) | ||
642 | { | ||
643 | #ifdef L2_LENGTH | ||
644 | unsigned flags; | ||
645 | int ret; | ||
646 | |||
647 | /* add mutex operation */ | ||
648 | spin_lock_irqsave(&l2_sram_lock, flags); | ||
649 | |||
650 | ret = _sram_free(addr, &free_l2_sram_head, | ||
651 | &used_l2_sram_head); | ||
652 | |||
653 | /* add mutex operation */ | ||
654 | spin_unlock_irqrestore(&l2_sram_lock, flags); | ||
655 | |||
656 | return ret; | ||
657 | #else | ||
658 | return -1; | ||
659 | #endif | ||
660 | } | ||
661 | EXPORT_SYMBOL(l2_sram_free); | ||
662 | |||
498 | int sram_free_with_lsl(const void *addr) | 663 | int sram_free_with_lsl(const void *addr) |
499 | { | 664 | { |
500 | struct sram_list_struct *lsl, **tmp; | 665 | struct sram_list_struct *lsl, **tmp; |
@@ -533,6 +698,9 @@ void *sram_alloc_with_lsl(size_t size, unsigned long flags) | |||
533 | if (addr == NULL && (flags & L1_DATA_B_SRAM)) | 698 | if (addr == NULL && (flags & L1_DATA_B_SRAM)) |
534 | addr = l1_data_B_sram_alloc(size); | 699 | addr = l1_data_B_sram_alloc(size); |
535 | 700 | ||
701 | if (addr == NULL && (flags & L2_SRAM)) | ||
702 | addr = l2_sram_alloc(size); | ||
703 | |||
536 | if (addr == NULL) { | 704 | if (addr == NULL) { |
537 | kfree(lsl); | 705 | kfree(lsl); |
538 | return NULL; | 706 | return NULL; |
@@ -549,49 +717,80 @@ EXPORT_SYMBOL(sram_alloc_with_lsl); | |||
549 | /* Once we get a real allocator, we'll throw all of this away. | 717 | /* Once we get a real allocator, we'll throw all of this away. |
550 | * Until then, we need some sort of visibility into the L1 alloc. | 718 | * Until then, we need some sort of visibility into the L1 alloc. |
551 | */ | 719 | */ |
552 | static void _l1sram_proc_read(char *buf, int *len, const char *desc, | 720 | /* Need to keep line of output the same. Currently, that is 44 bytes |
553 | struct l1_sram_piece *pfree, const int array_size) | 721 | * (including newline). |
722 | */ | ||
723 | static int _sram_proc_read(char *buf, int *len, int count, const char *desc, | ||
724 | struct sram_piece *pfree_head, | ||
725 | struct sram_piece *pused_head) | ||
554 | { | 726 | { |
555 | int i; | 727 | struct sram_piece *pslot; |
556 | 728 | ||
557 | *len += sprintf(&buf[*len], "--- L1 %-14s Size PID State\n", desc); | 729 | if (!pfree_head || !pused_head) |
558 | for (i = 0; i < array_size; ++i) { | 730 | return -1; |
559 | const char *alloc_type; | 731 | |
560 | switch (pfree[i].flag) { | 732 | *len += sprintf(&buf[*len], "--- SRAM %-14s Size PID State \n", desc); |
561 | case SRAM_SLT_NULL: alloc_type = "NULL"; break; | 733 | |
562 | case SRAM_SLT_FREE: alloc_type = "FREE"; break; | 734 | /* search the relevant memory slot */ |
563 | case SRAM_SLT_ALLOCATED: alloc_type = "ALLOCATED"; break; | 735 | pslot = pused_head->next; |
564 | default: alloc_type = "????"; break; | 736 | |
565 | } | 737 | while (pslot != NULL) { |
566 | *len += sprintf(&buf[*len], "%p-%p %8i %4i %s\n", | 738 | *len += sprintf(&buf[*len], "%p-%p %10i %5i %-10s\n", |
567 | pfree[i].paddr, pfree[i].paddr + pfree[i].size, | 739 | pslot->paddr, pslot->paddr + pslot->size, |
568 | pfree[i].size, pfree[i].pid, alloc_type); | 740 | pslot->size, pslot->pid, "ALLOCATED"); |
741 | |||
742 | pslot = pslot->next; | ||
569 | } | 743 | } |
744 | |||
745 | pslot = pfree_head->next; | ||
746 | |||
747 | while (pslot != NULL) { | ||
748 | *len += sprintf(&buf[*len], "%p-%p %10i %5i %-10s\n", | ||
749 | pslot->paddr, pslot->paddr + pslot->size, | ||
750 | pslot->size, pslot->pid, "FREE"); | ||
751 | |||
752 | pslot = pslot->next; | ||
753 | } | ||
754 | |||
755 | return 0; | ||
570 | } | 756 | } |
571 | static int l1sram_proc_read(char *buf, char **start, off_t offset, int count, | 757 | static int sram_proc_read(char *buf, char **start, off_t offset, int count, |
572 | int *eof, void *data) | 758 | int *eof, void *data) |
573 | { | 759 | { |
574 | int len = 0; | 760 | int len = 0; |
575 | 761 | ||
576 | _l1sram_proc_read(buf, &len, "Scratchpad", | 762 | if (_sram_proc_read(buf, &len, count, "Scratchpad", |
577 | l1_ssram, ARRAY_SIZE(l1_ssram)); | 763 | &free_l1_ssram_head, &used_l1_ssram_head)) |
764 | goto not_done; | ||
578 | #if L1_DATA_A_LENGTH != 0 | 765 | #if L1_DATA_A_LENGTH != 0 |
579 | _l1sram_proc_read(buf, &len, "Data A", | 766 | if (_sram_proc_read(buf, &len, count, "L1 Data A", |
580 | l1_data_A_sram, ARRAY_SIZE(l1_data_A_sram)); | 767 | &free_l1_data_A_sram_head, |
768 | &used_l1_data_A_sram_head)) | ||
769 | goto not_done; | ||
581 | #endif | 770 | #endif |
582 | #if L1_DATA_B_LENGTH != 0 | 771 | #if L1_DATA_B_LENGTH != 0 |
583 | _l1sram_proc_read(buf, &len, "Data B", | 772 | if (_sram_proc_read(buf, &len, count, "L1 Data B", |
584 | l1_data_B_sram, ARRAY_SIZE(l1_data_B_sram)); | 773 | &free_l1_data_B_sram_head, |
774 | &used_l1_data_B_sram_head)) | ||
775 | goto not_done; | ||
585 | #endif | 776 | #endif |
586 | #if L1_CODE_LENGTH != 0 | 777 | #if L1_CODE_LENGTH != 0 |
587 | _l1sram_proc_read(buf, &len, "Instruction", | 778 | if (_sram_proc_read(buf, &len, count, "L1 Instruction", |
588 | l1_inst_sram, ARRAY_SIZE(l1_inst_sram)); | 779 | &free_l1_inst_sram_head, &used_l1_inst_sram_head)) |
780 | goto not_done; | ||
781 | #endif | ||
782 | #ifdef L2_LENGTH | ||
783 | if (_sram_proc_read(buf, &len, count, "L2", | ||
784 | &free_l2_sram_head, &used_l2_sram_head)) | ||
785 | goto not_done; | ||
589 | #endif | 786 | #endif |
590 | 787 | ||
788 | *eof = 1; | ||
789 | not_done: | ||
591 | return len; | 790 | return len; |
592 | } | 791 | } |
593 | 792 | ||
594 | static int __init l1sram_proc_init(void) | 793 | static int __init sram_proc_init(void) |
595 | { | 794 | { |
596 | struct proc_dir_entry *ptr; | 795 | struct proc_dir_entry *ptr; |
597 | ptr = create_proc_entry("sram", S_IFREG | S_IRUGO, NULL); | 796 | ptr = create_proc_entry("sram", S_IFREG | S_IRUGO, NULL); |
@@ -600,8 +799,8 @@ static int __init l1sram_proc_init(void) | |||
600 | return -1; | 799 | return -1; |
601 | } | 800 | } |
602 | ptr->owner = THIS_MODULE; | 801 | ptr->owner = THIS_MODULE; |
603 | ptr->read_proc = l1sram_proc_read; | 802 | ptr->read_proc = sram_proc_read; |
604 | return 0; | 803 | return 0; |
605 | } | 804 | } |
606 | late_initcall(l1sram_proc_init); | 805 | late_initcall(sram_proc_init); |
607 | #endif | 806 | #endif |
diff --git a/arch/blackfin/mm/blackfin_sram.h b/arch/blackfin/mm/blackfin_sram.h index 0fb73b78dd60..8cb0945563f9 100644 --- a/arch/blackfin/mm/blackfin_sram.h +++ b/arch/blackfin/mm/blackfin_sram.h | |||
@@ -30,9 +30,7 @@ | |||
30 | #ifndef __BLACKFIN_SRAM_H__ | 30 | #ifndef __BLACKFIN_SRAM_H__ |
31 | #define __BLACKFIN_SRAM_H__ | 31 | #define __BLACKFIN_SRAM_H__ |
32 | 32 | ||
33 | extern void l1sram_init(void); | 33 | extern void bfin_sram_init(void); |
34 | extern void l1_inst_sram_init(void); | ||
35 | extern void l1_data_sram_init(void); | ||
36 | extern void *l1sram_alloc(size_t); | 34 | extern void *l1sram_alloc(size_t); |
37 | 35 | ||
38 | #endif | 36 | #endif |
diff --git a/arch/blackfin/mm/init.c b/arch/blackfin/mm/init.c index 4d5326ee9a85..bc240abb8745 100644 --- a/arch/blackfin/mm/init.c +++ b/arch/blackfin/mm/init.c | |||
@@ -137,11 +137,14 @@ void __init mem_init(void) | |||
137 | "(%uk init code, %uk kernel code, %uk data, %uk dma, %uk reserved)\n", | 137 | "(%uk init code, %uk kernel code, %uk data, %uk dma, %uk reserved)\n", |
138 | (unsigned long) freepages << (PAGE_SHIFT-10), _ramend >> 10, | 138 | (unsigned long) freepages << (PAGE_SHIFT-10), _ramend >> 10, |
139 | initk, codek, datak, DMA_UNCACHED_REGION >> 10, (reservedpages << (PAGE_SHIFT-10))); | 139 | initk, codek, datak, DMA_UNCACHED_REGION >> 10, (reservedpages << (PAGE_SHIFT-10))); |
140 | } | ||
141 | |||
142 | static int __init sram_init(void) | ||
143 | { | ||
144 | unsigned long tmp; | ||
140 | 145 | ||
141 | /* Initialize the blackfin L1 Memory. */ | 146 | /* Initialize the blackfin L1 Memory. */ |
142 | l1sram_init(); | 147 | bfin_sram_init(); |
143 | l1_data_sram_init(); | ||
144 | l1_inst_sram_init(); | ||
145 | 148 | ||
146 | /* Allocate this once; never free it. We assume this gives us a | 149 | /* Allocate this once; never free it. We assume this gives us a |
147 | pointer to the start of L1 scratchpad memory; panic if it | 150 | pointer to the start of L1 scratchpad memory; panic if it |
@@ -152,7 +155,10 @@ void __init mem_init(void) | |||
152 | tmp, (unsigned long)L1_SCRATCH_TASK_INFO); | 155 | tmp, (unsigned long)L1_SCRATCH_TASK_INFO); |
153 | panic("No L1, time to give up\n"); | 156 | panic("No L1, time to give up\n"); |
154 | } | 157 | } |
158 | |||
159 | return 0; | ||
155 | } | 160 | } |
161 | pure_initcall(sram_init); | ||
156 | 162 | ||
157 | static void __init free_init_pages(const char *what, unsigned long begin, unsigned long end) | 163 | static void __init free_init_pages(const char *what, unsigned long begin, unsigned long end) |
158 | { | 164 | { |