root/drivers/dma/bestcomm/sram.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. bcom_sram_init
  2. bcom_sram_cleanup
  3. bcom_sram_alloc
  4. bcom_sram_free

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

/* [<][>][^][v][top][bottom][index][help] */