root/drivers/net/ethernet/freescale/fman/fman_muram.c

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

DEFINITIONS

This source file includes following definitions.
  1. fman_muram_vbase_to_offset
  2. fman_muram_init
  3. fman_muram_offset_to_vbase
  4. fman_muram_alloc
  5. fman_muram_free_mem

   1 /*
   2  * Copyright 2008-2015 Freescale Semiconductor Inc.
   3  *
   4  * Redistribution and use in source and binary forms, with or without
   5  * modification, are permitted provided that the following conditions are met:
   6  *     * Redistributions of source code must retain the above copyright
   7  *       notice, this list of conditions and the following disclaimer.
   8  *     * Redistributions in binary form must reproduce the above copyright
   9  *       notice, this list of conditions and the following disclaimer in the
  10  *       documentation and/or other materials provided with the distribution.
  11  *     * Neither the name of Freescale Semiconductor nor the
  12  *       names of its contributors may be used to endorse or promote products
  13  *       derived from this software without specific prior written permission.
  14  *
  15  *
  16  * ALTERNATIVELY, this software may be distributed under the terms of the
  17  * GNU General Public License ("GPL") as published by the Free Software
  18  * Foundation, either version 2 of that License or (at your option) any
  19  * later version.
  20  *
  21  * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
  22  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  23  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  24  * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
  25  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  28  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31  */
  32 
  33 #include "fman_muram.h"
  34 
  35 #include <linux/io.h>
  36 #include <linux/slab.h>
  37 #include <linux/genalloc.h>
  38 
  39 struct muram_info {
  40         struct gen_pool *pool;
  41         void __iomem *vbase;
  42         size_t size;
  43         phys_addr_t pbase;
  44 };
  45 
  46 static unsigned long fman_muram_vbase_to_offset(struct muram_info *muram,
  47                                                 unsigned long vaddr)
  48 {
  49         return vaddr - (unsigned long)muram->vbase;
  50 }
  51 
  52 /**
  53  * fman_muram_init
  54  * @base:       Pointer to base of memory mapped FM-MURAM.
  55  * @size:       Size of the FM-MURAM partition.
  56  *
  57  * Creates partition in the MURAM.
  58  * The routine returns a pointer to the MURAM partition.
  59  * This pointer must be passed as to all other FM-MURAM function calls.
  60  * No actual initialization or configuration of FM_MURAM hardware is done by
  61  * this routine.
  62  *
  63  * Return: pointer to FM-MURAM object, or NULL for Failure.
  64  */
  65 struct muram_info *fman_muram_init(phys_addr_t base, size_t size)
  66 {
  67         struct muram_info *muram;
  68         void __iomem *vaddr;
  69         int ret;
  70 
  71         muram = kzalloc(sizeof(*muram), GFP_KERNEL);
  72         if (!muram)
  73                 return NULL;
  74 
  75         muram->pool = gen_pool_create(ilog2(64), -1);
  76         if (!muram->pool) {
  77                 pr_err("%s(): MURAM pool create failed\n", __func__);
  78                 goto  muram_free;
  79         }
  80 
  81         vaddr = ioremap(base, size);
  82         if (!vaddr) {
  83                 pr_err("%s(): MURAM ioremap failed\n", __func__);
  84                 goto pool_destroy;
  85         }
  86 
  87         ret = gen_pool_add_virt(muram->pool, (unsigned long)vaddr,
  88                                 base, size, -1);
  89         if (ret < 0) {
  90                 pr_err("%s(): MURAM pool add failed\n", __func__);
  91                 iounmap(vaddr);
  92                 goto pool_destroy;
  93         }
  94 
  95         memset_io(vaddr, 0, (int)size);
  96 
  97         muram->vbase = vaddr;
  98         muram->pbase = base;
  99         return muram;
 100 
 101 pool_destroy:
 102         gen_pool_destroy(muram->pool);
 103 muram_free:
 104         kfree(muram);
 105         return NULL;
 106 }
 107 
 108 /**
 109  * fman_muram_offset_to_vbase
 110  * @muram:      FM-MURAM module pointer.
 111  * @offset:     the offset of the memory block
 112  *
 113  * Gives the address of the memory region from specific offset
 114  *
 115  * Return: The address of the memory block
 116  */
 117 unsigned long fman_muram_offset_to_vbase(struct muram_info *muram,
 118                                          unsigned long offset)
 119 {
 120         return offset + (unsigned long)muram->vbase;
 121 }
 122 
 123 /**
 124  * fman_muram_alloc
 125  * @muram:      FM-MURAM module pointer.
 126  * @size:       Size of the memory to be allocated.
 127  *
 128  * Allocate some memory from FM-MURAM partition.
 129  *
 130  * Return: address of the allocated memory; NULL otherwise.
 131  */
 132 unsigned long fman_muram_alloc(struct muram_info *muram, size_t size)
 133 {
 134         unsigned long vaddr;
 135 
 136         vaddr = gen_pool_alloc(muram->pool, size);
 137         if (!vaddr)
 138                 return -ENOMEM;
 139 
 140         memset_io((void __iomem *)vaddr, 0, size);
 141 
 142         return fman_muram_vbase_to_offset(muram, vaddr);
 143 }
 144 
 145 /**
 146  * fman_muram_free_mem
 147  * muram:       FM-MURAM module pointer.
 148  * offset:      offset of the memory region to be freed.
 149  * size:        size of the memory to be freed.
 150  *
 151  * Free an allocated memory from FM-MURAM partition.
 152  */
 153 void fman_muram_free_mem(struct muram_info *muram, unsigned long offset,
 154                          size_t size)
 155 {
 156         unsigned long addr = fman_muram_offset_to_vbase(muram, offset);
 157 
 158         gen_pool_free(muram->pool, addr, size);
 159 }

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