linux/arch/blackfin/mm/blackfin_sram.c
<<
>>
Prefs
   1/*
   2 * File:         arch/blackfin/mm/blackfin_sram.c
   3 * Based on:
   4 * Author:
   5 *
   6 * Created:
   7 * Description:  SRAM driver for Blackfin ADSP-BF5xx
   8 *
   9 * Modified:
  10 *               Copyright 2004-2007 Analog Devices Inc.
  11 *
  12 * Bugs:         Enter bugs at http://blackfin.uclinux.org/
  13 *
  14 * This program is free software; you can redistribute it and/or modify
  15 * it under the terms of the GNU General Public License as published by
  16 * the Free Software Foundation; either version 2 of the License, or
  17 * (at your option) any later version.
  18 *
  19 * This program is distributed in the hope that it will be useful,
  20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22 * GNU General Public License for more details.
  23 *
  24 * You should have received a copy of the GNU General Public License
  25 * along with this program; if not, see the file COPYING, or write
  26 * to the Free Software Foundation, Inc.,
  27 * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  28 */
  29
  30#include <linux/module.h>
  31#include <linux/kernel.h>
  32#include <linux/types.h>
  33#include <linux/miscdevice.h>
  34#include <linux/ioport.h>
  35#include <linux/fcntl.h>
  36#include <linux/init.h>
  37#include <linux/poll.h>
  38#include <linux/proc_fs.h>
  39#include <linux/spinlock.h>
  40#include <linux/rtc.h>
  41#include <asm/blackfin.h>
  42#include "blackfin_sram.h"
  43
  44static spinlock_t l1sram_lock, l1_data_sram_lock, l1_inst_sram_lock;
  45static spinlock_t l2_sram_lock;
  46
  47/* the data structure for L1 scratchpad and DATA SRAM */
  48struct sram_piece {
  49        void *paddr;
  50        int size;
  51        pid_t pid;
  52        struct sram_piece *next;
  53};
  54
  55static struct sram_piece free_l1_ssram_head, used_l1_ssram_head;
  56
  57#if L1_DATA_A_LENGTH != 0
  58static struct sram_piece free_l1_data_A_sram_head, used_l1_data_A_sram_head;
  59#endif
  60
  61#if L1_DATA_B_LENGTH != 0
  62static struct sram_piece free_l1_data_B_sram_head, used_l1_data_B_sram_head;
  63#endif
  64
  65#if L1_CODE_LENGTH != 0
  66static struct sram_piece free_l1_inst_sram_head, used_l1_inst_sram_head;
  67#endif
  68
  69#if L2_LENGTH != 0
  70static struct sram_piece free_l2_sram_head, used_l2_sram_head;
  71#endif
  72
  73static struct kmem_cache *sram_piece_cache;
  74
  75/* L1 Scratchpad SRAM initialization function */
  76static void __init l1sram_init(void)
  77{
  78        free_l1_ssram_head.next =
  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;
  89
  90        used_l1_ssram_head.next = NULL;
  91
  92        /* mutex initialize */
  93        spin_lock_init(&l1sram_lock);
  94
  95        printk(KERN_INFO "Blackfin Scratchpad data SRAM: %d KB\n",
  96               L1_SCRATCH_LENGTH >> 10);
  97}
  98
  99static void __init l1_data_sram_init(void)
 100{
 101#if L1_DATA_A_LENGTH != 0
 102        free_l1_data_A_sram_head.next =
 103                kmem_cache_alloc(sram_piece_cache, GFP_KERNEL);
 104        if (!free_l1_data_A_sram_head.next) {
 105                printk(KERN_INFO"Fail to initialize L1 Data A SRAM.\n");
 106                return;
 107        }
 108
 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);
 121#endif
 122#if L1_DATA_B_LENGTH != 0
 123        free_l1_data_B_sram_head.next =
 124                kmem_cache_alloc(sram_piece_cache, GFP_KERNEL);
 125        if (!free_l1_data_B_sram_head.next) {
 126                printk(KERN_INFO"Fail to initialize L1 Data B SRAM.\n");
 127                return;
 128        }
 129
 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);
 142#endif
 143
 144        /* mutex initialize */
 145        spin_lock_init(&l1_data_sram_lock);
 146}
 147
 148static void __init l1_inst_sram_init(void)
 149{
 150#if L1_CODE_LENGTH != 0
 151        free_l1_inst_sram_head.next =
 152                kmem_cache_alloc(sram_piece_cache, GFP_KERNEL);
 153        if (!free_l1_inst_sram_head.next) {
 154                printk(KERN_INFO"Fail to initialize L1 Instruction SRAM.\n");
 155                return;
 156        }
 157
 158        free_l1_inst_sram_head.next->paddr =
 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);
 170#endif
 171
 172        /* mutex initialize */
 173        spin_lock_init(&l1_inst_sram_lock);
 174}
 175
 176static void __init l2_sram_init(void)
 177{
 178#if L2_LENGTH != 0
 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        }
 185
 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)
 222                return NULL;
 223
 224        /* Align the size */
 225        size = (size + 3) & ~3;
 226
 227        pslot = pfree_head->next;
 228        plast = pfree_head;
 229
 230        /* search an available piece slot */
 231        while (pslot != NULL && size > pslot->size) {
 232                plast = pslot;
 233                pslot = pslot->next;
 234        }
 235
 236        if (!pslot)
 237                return NULL;
 238
 239        if (pslot->size == size) {
 240                plast->next = pslot->next;
 241                pavail = pslot;
 242        } else {
 243                pavail = kmem_cache_alloc(sram_piece_cache, GFP_KERNEL);
 244
 245                if (!pavail)
 246                        return NULL;
 247
 248                pavail->paddr = pslot->paddr;
 249                pavail->size = size;
 250                pslot->paddr += size;
 251                pslot->size -= size;
 252        }
 253
 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;
 269}
 270
 271/* Allocate the largest available block.  */
 272static void *_sram_alloc_max(struct sram_piece *pfree_head,
 273                                struct sram_piece *pused_head,
 274                                unsigned long *psize)
 275{
 276        struct sram_piece *pslot, *pmax;
 277
 278        if (!pfree_head || !pused_head)
 279                return NULL;
 280
 281        pmax = pslot = pfree_head->next;
 282
 283        /* search an available piece slot */
 284        while (pslot != NULL) {
 285                if (pslot->size > pmax->size)
 286                        pmax = pslot;
 287                pslot = pslot->next;
 288        }
 289
 290        if (!pmax)
 291                return NULL;
 292
 293        *psize = pmax->size;
 294
 295        return _sram_alloc(*psize, pfree_head, pused_head);
 296}
 297
 298/* SRAM free function */
 299static int _sram_free(const void *addr,
 300                        struct sram_piece *pfree_head,
 301                        struct sram_piece *pused_head)
 302{
 303        struct sram_piece *pslot, *plast, *pavail;
 304
 305        if (!pfree_head || !pused_head)
 306                return -1;
 307
 308        /* search the relevant memory slot */
 309        pslot = pused_head->next;
 310        plast = pused_head;
 311
 312        /* search an available piece slot */
 313        while (pslot != NULL && pslot->paddr != addr) {
 314                plast = pslot;
 315                pslot = pslot->next;
 316        }
 317
 318        if (!pslot)
 319                return -1;
 320
 321        plast->next = pslot->next;
 322        pavail = pslot;
 323        pavail->pid = 0;
 324
 325        /* insert free pieces back to the free list */
 326        pslot = pfree_head->next;
 327        plast = pfree_head;
 328
 329        while (pslot != NULL && addr > pslot->paddr) {
 330                plast = pslot;
 331                pslot = pslot->next;
 332        }
 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->next;
 339                plast->next = pavail;
 340                plast = pavail;
 341        }
 342
 343        if (pslot && plast->paddr + plast->size == pslot->paddr) {
 344                plast->size += pslot->size;
 345                plast->next = pslot->next;
 346                kmem_cache_free(sram_piece_cache, pslot);
 347        }
 348
 349        return 0;
 350}
 351
 352int sram_free(const void *addr)
 353{
 354        if (0) {}
 355#if L1_CODE_LENGTH != 0
 356        else if (addr >= (void *)L1_CODE_START
 357                 && addr < (void *)(L1_CODE_START + L1_CODE_LENGTH))
 358                return l1_inst_sram_free(addr);
 359#endif
 360#if L1_DATA_A_LENGTH != 0
 361        else if (addr >= (void *)L1_DATA_A_START
 362                 && addr < (void *)(L1_DATA_A_START + L1_DATA_A_LENGTH))
 363                return l1_data_A_sram_free(addr);
 364#endif
 365#if L1_DATA_B_LENGTH != 0
 366        else if (addr >= (void *)L1_DATA_B_START
 367                 && addr < (void *)(L1_DATA_B_START + L1_DATA_B_LENGTH))
 368                return l1_data_B_sram_free(addr);
 369#endif
 370#if L2_LENGTH != 0
 371        else if (addr >= (void *)L2_START
 372                 && addr < (void *)(L2_START + L2_LENGTH))
 373                return l2_sram_free(addr);
 374#endif
 375        else
 376                return -1;
 377}
 378EXPORT_SYMBOL(sram_free);
 379
 380void *l1_data_A_sram_alloc(size_t size)
 381{
 382        unsigned long flags;
 383        void *addr = NULL;
 384
 385        /* add mutex operation */
 386        spin_lock_irqsave(&l1_data_sram_lock, flags);
 387
 388#if L1_DATA_A_LENGTH != 0
 389        addr = _sram_alloc(size, &free_l1_data_A_sram_head,
 390                        &used_l1_data_A_sram_head);
 391#endif
 392
 393        /* add mutex operation */
 394        spin_unlock_irqrestore(&l1_data_sram_lock, flags);
 395
 396        pr_debug("Allocated address in l1_data_A_sram_alloc is 0x%lx+0x%lx\n",
 397                 (long unsigned int)addr, size);
 398
 399        return addr;
 400}
 401EXPORT_SYMBOL(l1_data_A_sram_alloc);
 402
 403int l1_data_A_sram_free(const void *addr)
 404{
 405        unsigned long flags;
 406        int ret;
 407
 408        /* add mutex operation */
 409        spin_lock_irqsave(&l1_data_sram_lock, flags);
 410
 411#if L1_DATA_A_LENGTH != 0
 412        ret = _sram_free(addr, &free_l1_data_A_sram_head,
 413                        &used_l1_data_A_sram_head);
 414#else
 415        ret = -1;
 416#endif
 417
 418        /* add mutex operation */
 419        spin_unlock_irqrestore(&l1_data_sram_lock, flags);
 420
 421        return ret;
 422}
 423EXPORT_SYMBOL(l1_data_A_sram_free);
 424
 425void *l1_data_B_sram_alloc(size_t size)
 426{
 427#if L1_DATA_B_LENGTH != 0
 428        unsigned long flags;
 429        void *addr;
 430
 431        /* add mutex operation */
 432        spin_lock_irqsave(&l1_data_sram_lock, flags);
 433
 434        addr = _sram_alloc(size, &free_l1_data_B_sram_head,
 435                        &used_l1_data_B_sram_head);
 436
 437        /* add mutex operation */
 438        spin_unlock_irqrestore(&l1_data_sram_lock, flags);
 439
 440        pr_debug("Allocated address in l1_data_B_sram_alloc is 0x%lx+0x%lx\n",
 441                 (long unsigned int)addr, size);
 442
 443        return addr;
 444#else
 445        return NULL;
 446#endif
 447}
 448EXPORT_SYMBOL(l1_data_B_sram_alloc);
 449
 450int l1_data_B_sram_free(const void *addr)
 451{
 452#if L1_DATA_B_LENGTH != 0
 453        unsigned long flags;
 454        int ret;
 455
 456        /* add mutex operation */
 457        spin_lock_irqsave(&l1_data_sram_lock, flags);
 458
 459        ret = _sram_free(addr, &free_l1_data_B_sram_head,
 460                        &used_l1_data_B_sram_head);
 461
 462        /* add mutex operation */
 463        spin_unlock_irqrestore(&l1_data_sram_lock, flags);
 464
 465        return ret;
 466#else
 467        return -1;
 468#endif
 469}
 470EXPORT_SYMBOL(l1_data_B_sram_free);
 471
 472void *l1_data_sram_alloc(size_t size)
 473{
 474        void *addr = l1_data_A_sram_alloc(size);
 475
 476        if (!addr)
 477                addr = l1_data_B_sram_alloc(size);
 478
 479        return addr;
 480}
 481EXPORT_SYMBOL(l1_data_sram_alloc);
 482
 483void *l1_data_sram_zalloc(size_t size)
 484{
 485        void *addr = l1_data_sram_alloc(size);
 486
 487        if (addr)
 488                memset(addr, 0x00, size);
 489
 490        return addr;
 491}
 492EXPORT_SYMBOL(l1_data_sram_zalloc);
 493
 494int l1_data_sram_free(const void *addr)
 495{
 496        int ret;
 497        ret = l1_data_A_sram_free(addr);
 498        if (ret == -1)
 499                ret = l1_data_B_sram_free(addr);
 500        return ret;
 501}
 502EXPORT_SYMBOL(l1_data_sram_free);
 503
 504void *l1_inst_sram_alloc(size_t size)
 505{
 506#if L1_CODE_LENGTH != 0
 507        unsigned long flags;
 508        void *addr;
 509
 510        /* add mutex operation */
 511        spin_lock_irqsave(&l1_inst_sram_lock, flags);
 512
 513        addr = _sram_alloc(size, &free_l1_inst_sram_head,
 514                        &used_l1_inst_sram_head);
 515
 516        /* add mutex operation */
 517        spin_unlock_irqrestore(&l1_inst_sram_lock, flags);
 518
 519        pr_debug("Allocated address in l1_inst_sram_alloc is 0x%lx+0x%lx\n",
 520                 (long unsigned int)addr, size);
 521
 522        return addr;
 523#else
 524        return NULL;
 525#endif
 526}
 527EXPORT_SYMBOL(l1_inst_sram_alloc);
 528
 529int l1_inst_sram_free(const void *addr)
 530{
 531#if L1_CODE_LENGTH != 0
 532        unsigned long flags;
 533        int ret;
 534
 535        /* add mutex operation */
 536        spin_lock_irqsave(&l1_inst_sram_lock, flags);
 537
 538        ret = _sram_free(addr, &free_l1_inst_sram_head,
 539                        &used_l1_inst_sram_head);
 540
 541        /* add mutex operation */
 542        spin_unlock_irqrestore(&l1_inst_sram_lock, flags);
 543
 544        return ret;
 545#else
 546        return -1;
 547#endif
 548}
 549EXPORT_SYMBOL(l1_inst_sram_free);
 550
 551/* L1 Scratchpad memory allocate function */
 552void *l1sram_alloc(size_t size)
 553{
 554        unsigned long flags;
 555        void *addr;
 556
 557        /* add mutex operation */
 558        spin_lock_irqsave(&l1sram_lock, flags);
 559
 560        addr = _sram_alloc(size, &free_l1_ssram_head,
 561                        &used_l1_ssram_head);
 562
 563        /* add mutex operation */
 564        spin_unlock_irqrestore(&l1sram_lock, flags);
 565
 566        return addr;
 567}
 568
 569/* L1 Scratchpad memory allocate function */
 570void *l1sram_alloc_max(size_t *psize)
 571{
 572        unsigned long flags;
 573        void *addr;
 574
 575        /* add mutex operation */
 576        spin_lock_irqsave(&l1sram_lock, flags);
 577
 578        addr = _sram_alloc_max(&free_l1_ssram_head,
 579                        &used_l1_ssram_head, psize);
 580
 581        /* add mutex operation */
 582        spin_unlock_irqrestore(&l1sram_lock, flags);
 583
 584        return addr;
 585}
 586
 587/* L1 Scratchpad memory free function */
 588int l1sram_free(const void *addr)
 589{
 590        unsigned long flags;
 591        int ret;
 592
 593        /* add mutex operation */
 594        spin_lock_irqsave(&l1sram_lock, flags);
 595
 596        ret = _sram_free(addr, &free_l1_ssram_head,
 597                        &used_l1_ssram_head);
 598
 599        /* add mutex operation */
 600        spin_unlock_irqrestore(&l1sram_lock, flags);
 601
 602        return ret;
 603}
 604
 605void *l2_sram_alloc(size_t size)
 606{
 607#if L2_LENGTH != 0
 608        unsigned long 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#if L2_LENGTH != 0
 644        unsigned long 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
 663int sram_free_with_lsl(const void *addr)
 664{
 665        struct sram_list_struct *lsl, **tmp;
 666        struct mm_struct *mm = current->mm;
 667
 668        for (tmp = &mm->context.sram_list; *tmp; tmp = &(*tmp)->next)
 669                if ((*tmp)->addr == addr)
 670                        goto found;
 671        return -1;
 672found:
 673        lsl = *tmp;
 674        sram_free(addr);
 675        *tmp = lsl->next;
 676        kfree(lsl);
 677
 678        return 0;
 679}
 680EXPORT_SYMBOL(sram_free_with_lsl);
 681
 682void *sram_alloc_with_lsl(size_t size, unsigned long flags)
 683{
 684        void *addr = NULL;
 685        struct sram_list_struct *lsl = NULL;
 686        struct mm_struct *mm = current->mm;
 687
 688        lsl = kzalloc(sizeof(struct sram_list_struct), GFP_KERNEL);
 689        if (!lsl)
 690                return NULL;
 691
 692        if (flags & L1_INST_SRAM)
 693                addr = l1_inst_sram_alloc(size);
 694
 695        if (addr == NULL && (flags & L1_DATA_A_SRAM))
 696                addr = l1_data_A_sram_alloc(size);
 697
 698        if (addr == NULL && (flags & L1_DATA_B_SRAM))
 699                addr = l1_data_B_sram_alloc(size);
 700
 701        if (addr == NULL && (flags & L2_SRAM))
 702                addr = l2_sram_alloc(size);
 703
 704        if (addr == NULL) {
 705                kfree(lsl);
 706                return NULL;
 707        }
 708        lsl->addr = addr;
 709        lsl->length = size;
 710        lsl->next = mm->context.sram_list;
 711        mm->context.sram_list = lsl;
 712        return addr;
 713}
 714EXPORT_SYMBOL(sram_alloc_with_lsl);
 715
 716#ifdef CONFIG_PROC_FS
 717/* Once we get a real allocator, we'll throw all of this away.
 718 * Until then, we need some sort of visibility into the L1 alloc.
 719 */
 720/* Need to keep line of output the same.  Currently, that is 44 bytes
 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)
 726{
 727        struct sram_piece *pslot;
 728
 729        if (!pfree_head || !pused_head)
 730                return -1;
 731
 732        *len += sprintf(&buf[*len], "--- SRAM %-14s Size   PID State     \n", desc);
 733
 734        /* search the relevant memory slot */
 735        pslot = pused_head->next;
 736
 737        while (pslot != NULL) {
 738                *len += sprintf(&buf[*len], "%p-%p %10i %5i %-10s\n",
 739                        pslot->paddr, pslot->paddr + pslot->size,
 740                        pslot->size, pslot->pid, "ALLOCATED");
 741
 742                pslot = pslot->next;
 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;
 756}
 757static int sram_proc_read(char *buf, char **start, off_t offset, int count,
 758                int *eof, void *data)
 759{
 760        int len = 0;
 761
 762        if (_sram_proc_read(buf, &len, count, "Scratchpad",
 763                        &free_l1_ssram_head, &used_l1_ssram_head))
 764                goto not_done;
 765#if L1_DATA_A_LENGTH != 0
 766        if (_sram_proc_read(buf, &len, count, "L1 Data A",
 767                        &free_l1_data_A_sram_head,
 768                        &used_l1_data_A_sram_head))
 769                goto not_done;
 770#endif
 771#if L1_DATA_B_LENGTH != 0
 772        if (_sram_proc_read(buf, &len, count, "L1 Data B",
 773                        &free_l1_data_B_sram_head,
 774                        &used_l1_data_B_sram_head))
 775                goto not_done;
 776#endif
 777#if L1_CODE_LENGTH != 0
 778        if (_sram_proc_read(buf, &len, count, "L1 Instruction",
 779                        &free_l1_inst_sram_head, &used_l1_inst_sram_head))
 780                goto not_done;
 781#endif
 782#if L2_LENGTH != 0
 783        if (_sram_proc_read(buf, &len, count, "L2",
 784                        &free_l2_sram_head, &used_l2_sram_head))
 785                goto not_done;
 786#endif
 787
 788        *eof = 1;
 789 not_done:
 790        return len;
 791}
 792
 793static int __init sram_proc_init(void)
 794{
 795        struct proc_dir_entry *ptr;
 796        ptr = create_proc_entry("sram", S_IFREG | S_IRUGO, NULL);
 797        if (!ptr) {
 798                printk(KERN_WARNING "unable to create /proc/sram\n");
 799                return -1;
 800        }
 801        ptr->owner = THIS_MODULE;
 802        ptr->read_proc = sram_proc_read;
 803        return 0;
 804}
 805late_initcall(sram_proc_init);
 806#endif
 807