aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/mm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-07-26 16:23:17 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-26 16:23:17 -0400
commit7f268a2ba7c884a239713696238dd4207a57dd9a (patch)
treefdc02fecda32f5df8de3ddc2c01c29ba68e6a42b /arch/blackfin/mm
parent689796a141cea79d745a4689c65dd01c39e5e100 (diff)
parent2d2009806dd843f3adc0cbbb5d2204980f28111a (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.c543
-rw-r--r--arch/blackfin/mm/blackfin_sram.h4
-rw-r--r--arch/blackfin/mm/init.c12
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
44spinlock_t l1sram_lock, l1_data_sram_lock, l1_inst_sram_lock; 44static spinlock_t l1sram_lock, l1_data_sram_lock, l1_inst_sram_lock;
45 45static 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 */
61struct l1_sram_piece { 48struct 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
68static struct l1_sram_piece l1_ssram[CONFIG_L1_MAX_PIECE]; 55static 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
71static struct l1_sram_piece l1_data_A_sram[CONFIG_L1_MAX_PIECE]; 58static 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
75static struct l1_sram_piece l1_data_B_sram[CONFIG_L1_MAX_PIECE]; 62static 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
79static struct l1_sram_piece l1_inst_sram[CONFIG_L1_MAX_PIECE]; 66static struct sram_piece free_l1_inst_sram_head, used_l1_inst_sram_head;
67#endif
68
69#ifdef L2_LENGTH
70static struct sram_piece free_l2_sram_head, used_l2_sram_head;
80#endif 71#endif
81 72
73static struct kmem_cache *sram_piece_cache;
74
82/* L1 Scratchpad SRAM initialization function */ 75/* L1 Scratchpad SRAM initialization function */
83void __init l1sram_init(void) 76static 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
97void __init l1_data_sram_init(void) 99static 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
124void __init l1_inst_sram_init(void) 148static 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 */ 176static void __init l2_sram_init(void)
141static 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}
203void __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 */
216static 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. */
185static void *_l1_sram_alloc_max(struct l1_sram_piece *pfree, int count, 272static 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 */
210static int _l1_sram_free(const void *addr, 299static 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
605void *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}
628EXPORT_SYMBOL(l2_sram_alloc);
629
630void *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}
639EXPORT_SYMBOL(l2_sram_zalloc);
640
641int 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}
661EXPORT_SYMBOL(l2_sram_free);
662
498int sram_free_with_lsl(const void *addr) 663int 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 */
552static 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 */
723static 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}
571static int l1sram_proc_read(char *buf, char **start, off_t offset, int count, 757static 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
594static int __init l1sram_proc_init(void) 793static 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}
606late_initcall(l1sram_proc_init); 805late_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
33extern void l1sram_init(void); 33extern void bfin_sram_init(void);
34extern void l1_inst_sram_init(void);
35extern void l1_data_sram_init(void);
36extern void *l1sram_alloc(size_t); 34extern 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
142static 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}
161pure_initcall(sram_init);
156 162
157static void __init free_init_pages(const char *what, unsigned long begin, unsigned long end) 163static void __init free_init_pages(const char *what, unsigned long begin, unsigned long end)
158{ 164{