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