/*
 * Copyright 2009-2010 Freescale Semiconductor, Inc.
 *
 * Simple memory allocator abstraction for QorIQ (P1/P2) based Cache-SRAM
 *
 * Author: Vivek Mahajan <vivek.mahajan@freescale.com>
 *
 * This file is derived from the original work done
 * by Sylvain Munaut for the Bestcomm SRAM allocator.
 *
 * This program is free software; you can redistribute  it and/or modify it
 * under  the terms of  the GNU General  Public License as published by the
 * Free Software Foundation;  either version 2 of the  License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/of_platform.h>
#include <asm/pgtable.h>
#include <asm/fsl_85xx_cache_sram.h>

#include "fsl_85xx_cache_ctlr.h"

struct mpc85xx_cache_sram *cache_sram;

void *mpc85xx_cache_sram_alloc(unsigned int size,
				phys_addr_t *phys, unsigned int align)
{
	unsigned long offset;
	unsigned long flags;

	if (unlikely(cache_sram == NULL))
		return NULL;

	if (!size || (size > cache_sram->size) || (align > cache_sram->size)) {
		pr_err("%s(): size(=%x) or align(=%x) zero or too big\n",
			__func__, size, align);
		return NULL;
	}

	if ((align & (align - 1)) || align <= 1) {
		pr_err("%s(): align(=%x) must be power of two and >1\n",
			__func__, align);
		return NULL;
	}

	spin_lock_irqsave(&cache_sram->lock, flags);
	offset = rh_alloc_align(cache_sram->rh, size, align, NULL);
	spin_unlock_irqrestore(&cache_sram->lock, flags);

	if (IS_ERR_VALUE(offset))
		return NULL;

	*phys = cache_sram->base_phys + offset;

	return (unsigned char *)cache_sram->base_virt + offset;
}
EXPORT_SYMBOL(mpc85xx_cache_sram_alloc);

void mpc85xx_cache_sram_free(void *ptr)
{
	unsigned long flags;
	BUG_ON(!ptr);

	spin_lock_irqsave(&cache_sram->lock, flags);
	rh_free(cache_sram->rh, ptr - cache_sram->base_virt);
	spin_unlock_irqrestore(&cache_sram->lock, flags);
}
EXPORT_SYMBOL(mpc85xx_cache_sram_free);

int __init instantiate_cache_sram(struct platform_device *dev,
		struct sram_parameters sram_params)
{
	int ret = 0;

	if (cache_sram) {
		dev_err(&dev->dev, "Already initialized cache-sram\n");
		return -EBUSY;
	}

	cache_sram = kzalloc(sizeof(struct mpc85xx_cache_sram), GFP_KERNEL);
	if (!cache_sram) {
		dev_err(&dev->dev, "Out of memory for cache_sram structure\n");
		return -ENOMEM;
	}

	cache_sram->base_phys = sram_params.sram_offset;
	cache_sram->size = sram_params.sram_size;

	if (!request_mem_region(cache_sram->base_phys, cache_sram->size,
						"fsl_85xx_cache_sram")) {
		dev_err(&dev->dev, "%s: request memory failed\n",
				dev->dev.of_node->full_name);
		ret = -ENXIO;
		goto out_free;
	}

	cache_sram->base_virt = ioremap_flags(cache_sram->base_phys,
				cache_sram->size, _PAGE_COHERENT | PAGE_KERNEL);
	if (!cache_sram->base_virt) {
		dev_err(&dev->dev, "%s: ioremap_flags failed\n",
				dev->dev.of_node->full_name);
		ret = -ENOMEM;
		goto out_release;
	}

	cache_sram->rh = rh_create(sizeof(unsigned int));
	if (IS_ERR(cache_sram->rh)) {
		dev_err(&dev->dev, "%s: Unable to create remote heap\n",
				dev->dev.of_node->full_name);
		ret = PTR_ERR(cache_sram->rh);
		goto out_unmap;
	}

	rh_attach_region(cache_sram->rh, 0, cache_sram->size);
	spin_lock_init(&cache_sram->lock);

	dev_info(&dev->dev, "[base:0x%llx, size:0x%x] configured and loaded\n",
		(unsigned long long)cache_sram->base_phys, cache_sram->size);

	return 0;

out_unmap:
	iounmap(cache_sram->base_virt);

out_release:
	release_mem_region(cache_sram->base_phys, cache_sram->size);

out_free:
	kfree(cache_sram);
	return ret;
}

void remove_cache_sram(struct platform_device *dev)
{
	BUG_ON(!cache_sram);

	rh_detach_region(cache_sram->rh, 0, cache_sram->size);
	rh_destroy(cache_sram->rh);

	iounmap(cache_sram->base_virt);
	release_mem_region(cache_sram->base_phys, cache_sram->size);

	kfree(cache_sram);
	cache_sram = NULL;

	dev_info(&dev->dev, "MPC85xx Cache-SRAM driver unloaded\n");
}
