Path: blob/master/arch/powerpc/sysdev/fsl_85xx_cache_sram.c
10817 views
/*1* Copyright 2009-2010 Freescale Semiconductor, Inc.2*3* Simple memory allocator abstraction for QorIQ (P1/P2) based Cache-SRAM4*5* Author: Vivek Mahajan <[email protected]>6*7* This file is derived from the original work done8* by Sylvain Munaut for the Bestcomm SRAM allocator.9*10* This program is free software; you can redistribute it and/or modify it11* under the terms of the GNU General Public License as published by the12* Free Software Foundation; either version 2 of the License, or (at your13* option) any later version.14*15* This program is distributed in the hope that it will be useful,16* but WITHOUT ANY WARRANTY; without even the implied warranty of17* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the18* GNU General Public License for more details.19*20* You should have received a copy of the GNU General Public License21* along with this program; if not, write to the Free Software22* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.23*/2425#include <linux/kernel.h>26#include <linux/slab.h>27#include <linux/err.h>28#include <linux/of_platform.h>29#include <asm/pgtable.h>30#include <asm/fsl_85xx_cache_sram.h>3132#include "fsl_85xx_cache_ctlr.h"3334struct mpc85xx_cache_sram *cache_sram;3536void *mpc85xx_cache_sram_alloc(unsigned int size,37phys_addr_t *phys, unsigned int align)38{39unsigned long offset;40unsigned long flags;4142if (unlikely(cache_sram == NULL))43return NULL;4445if (!size || (size > cache_sram->size) || (align > cache_sram->size)) {46pr_err("%s(): size(=%x) or align(=%x) zero or too big\n",47__func__, size, align);48return NULL;49}5051if ((align & (align - 1)) || align <= 1) {52pr_err("%s(): align(=%x) must be power of two and >1\n",53__func__, align);54return NULL;55}5657spin_lock_irqsave(&cache_sram->lock, flags);58offset = rh_alloc_align(cache_sram->rh, size, align, NULL);59spin_unlock_irqrestore(&cache_sram->lock, flags);6061if (IS_ERR_VALUE(offset))62return NULL;6364*phys = cache_sram->base_phys + offset;6566return (unsigned char *)cache_sram->base_virt + offset;67}68EXPORT_SYMBOL(mpc85xx_cache_sram_alloc);6970void mpc85xx_cache_sram_free(void *ptr)71{72unsigned long flags;73BUG_ON(!ptr);7475spin_lock_irqsave(&cache_sram->lock, flags);76rh_free(cache_sram->rh, ptr - cache_sram->base_virt);77spin_unlock_irqrestore(&cache_sram->lock, flags);78}79EXPORT_SYMBOL(mpc85xx_cache_sram_free);8081int __init instantiate_cache_sram(struct platform_device *dev,82struct sram_parameters sram_params)83{84int ret = 0;8586if (cache_sram) {87dev_err(&dev->dev, "Already initialized cache-sram\n");88return -EBUSY;89}9091cache_sram = kzalloc(sizeof(struct mpc85xx_cache_sram), GFP_KERNEL);92if (!cache_sram) {93dev_err(&dev->dev, "Out of memory for cache_sram structure\n");94return -ENOMEM;95}9697cache_sram->base_phys = sram_params.sram_offset;98cache_sram->size = sram_params.sram_size;99100if (!request_mem_region(cache_sram->base_phys, cache_sram->size,101"fsl_85xx_cache_sram")) {102dev_err(&dev->dev, "%s: request memory failed\n",103dev->dev.of_node->full_name);104ret = -ENXIO;105goto out_free;106}107108cache_sram->base_virt = ioremap_prot(cache_sram->base_phys,109cache_sram->size, _PAGE_COHERENT | PAGE_KERNEL);110if (!cache_sram->base_virt) {111dev_err(&dev->dev, "%s: ioremap_prot failed\n",112dev->dev.of_node->full_name);113ret = -ENOMEM;114goto out_release;115}116117cache_sram->rh = rh_create(sizeof(unsigned int));118if (IS_ERR(cache_sram->rh)) {119dev_err(&dev->dev, "%s: Unable to create remote heap\n",120dev->dev.of_node->full_name);121ret = PTR_ERR(cache_sram->rh);122goto out_unmap;123}124125rh_attach_region(cache_sram->rh, 0, cache_sram->size);126spin_lock_init(&cache_sram->lock);127128dev_info(&dev->dev, "[base:0x%llx, size:0x%x] configured and loaded\n",129(unsigned long long)cache_sram->base_phys, cache_sram->size);130131return 0;132133out_unmap:134iounmap(cache_sram->base_virt);135136out_release:137release_mem_region(cache_sram->base_phys, cache_sram->size);138139out_free:140kfree(cache_sram);141return ret;142}143144void remove_cache_sram(struct platform_device *dev)145{146BUG_ON(!cache_sram);147148rh_detach_region(cache_sram->rh, 0, cache_sram->size);149rh_destroy(cache_sram->rh);150151iounmap(cache_sram->base_virt);152release_mem_region(cache_sram->base_phys, cache_sram->size);153154kfree(cache_sram);155cache_sram = NULL;156157dev_info(&dev->dev, "MPC85xx Cache-SRAM driver unloaded\n");158}159160161