// SPDX-License-Identifier: GPL-2.0-only
/*
 *  linux/arch/arm/mach-mmp/sram.c
 *
 *  based on mach-davinci/sram.c - DaVinci simple SRAM allocator
 *
 *  Copyright (c) 2011 Marvell Semiconductors Inc.
 *  All Rights Reserved
 *
 *  Add for mmp sram support - Leo Yan <leoy@marvell.com>
 */

#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/genalloc.h>

#include <linux/platform_data/dma-mmp_tdma.h>

struct sram_bank_info {
	char *pool_name;
	struct gen_pool *gpool;
	int granularity;

	phys_addr_t sram_phys;
	void __iomem *sram_virt;
	u32 sram_size;

	struct list_head node;
};

static DEFINE_MUTEX(sram_lock);
static LIST_HEAD(sram_bank_list);

struct gen_pool *sram_get_gpool(char *pool_name)
{
	struct sram_bank_info *info = NULL;

	if (!pool_name)
		return NULL;

	mutex_lock(&sram_lock);

	list_for_each_entry(info, &sram_bank_list, node)
		if (!strcmp(pool_name, info->pool_name))
			break;

	mutex_unlock(&sram_lock);

	if (&info->node == &sram_bank_list)
		return NULL;

	return info->gpool;
}
EXPORT_SYMBOL(sram_get_gpool);

static int sram_probe(struct platform_device *pdev)
{
	struct sram_platdata *pdata = pdev->dev.platform_data;
	struct sram_bank_info *info;
	struct resource *res;
	int ret = 0;

	if (!pdata || !pdata->pool_name)
		return -ENODEV;

	info = kzalloc(sizeof(*info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	platform_set_drvdata(pdev, info);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL) {
		dev_err(&pdev->dev, "no memory resource defined\n");
		ret = -ENODEV;
		goto out;
	}

	if (!resource_size(res))
		return 0;

	info->sram_phys   = (phys_addr_t)res->start;
	info->sram_size   = resource_size(res);
	info->sram_virt   = ioremap(info->sram_phys, info->sram_size);
	info->pool_name	  = kstrdup(pdata->pool_name, GFP_KERNEL);
	info->granularity = pdata->granularity;

	info->gpool = gen_pool_create(ilog2(info->granularity), -1);
	if (!info->gpool) {
		dev_err(&pdev->dev, "create pool failed\n");
		ret = -ENOMEM;
		goto create_pool_err;
	}

	ret = gen_pool_add_virt(info->gpool, (unsigned long)info->sram_virt,
				info->sram_phys, info->sram_size, -1);
	if (ret < 0) {
		dev_err(&pdev->dev, "add new chunk failed\n");
		ret = -ENOMEM;
		goto add_chunk_err;
	}

	mutex_lock(&sram_lock);
	list_add(&info->node, &sram_bank_list);
	mutex_unlock(&sram_lock);

	dev_info(&pdev->dev, "initialized\n");
	return 0;

add_chunk_err:
	gen_pool_destroy(info->gpool);
create_pool_err:
	iounmap(info->sram_virt);
	kfree(info->pool_name);
out:
	kfree(info);
	return ret;
}

static int sram_remove(struct platform_device *pdev)
{
	struct sram_bank_info *info;

	info = platform_get_drvdata(pdev);

	if (info->sram_size) {
		mutex_lock(&sram_lock);
		list_del(&info->node);
		mutex_unlock(&sram_lock);

		gen_pool_destroy(info->gpool);
		iounmap(info->sram_virt);
		kfree(info->pool_name);
	}

	kfree(info);

	return 0;
}

static const struct platform_device_id sram_id_table[] = {
	{ "asram", MMP_ASRAM },
	{ "isram", MMP_ISRAM },
	{ }
};

static struct platform_driver sram_driver = {
	.probe		= sram_probe,
	.remove		= sram_remove,
	.driver		= {
		.name	= "mmp-sram",
	},
	.id_table	= sram_id_table,
};

static int __init sram_init(void)
{
	return platform_driver_register(&sram_driver);
}
core_initcall(sram_init);

MODULE_LICENSE("GPL");
