Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.13.7.
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 *  linux/arch/arm/mach-mmp/sram.c
  4 *
  5 *  based on mach-davinci/sram.c - DaVinci simple SRAM allocator
  6 *
  7 *  Copyright (c) 2011 Marvell Semiconductors Inc.
  8 *  All Rights Reserved
  9 *
 10 *  Add for mmp sram support - Leo Yan <leoy@marvell.com>
 11 */
 12
 13#include <linux/module.h>
 14#include <linux/mod_devicetable.h>
 15#include <linux/init.h>
 16#include <linux/platform_device.h>
 17#include <linux/io.h>
 18#include <linux/err.h>
 19#include <linux/slab.h>
 20#include <linux/genalloc.h>
 21
 22#include <linux/platform_data/dma-mmp_tdma.h>
 23
 24struct sram_bank_info {
 25	char *pool_name;
 26	struct gen_pool *gpool;
 27	int granularity;
 28
 29	phys_addr_t sram_phys;
 30	void __iomem *sram_virt;
 31	u32 sram_size;
 32
 33	struct list_head node;
 34};
 35
 36static DEFINE_MUTEX(sram_lock);
 37static LIST_HEAD(sram_bank_list);
 38
 39struct gen_pool *sram_get_gpool(char *pool_name)
 40{
 41	struct sram_bank_info *info = NULL;
 42
 43	if (!pool_name)
 44		return NULL;
 45
 46	mutex_lock(&sram_lock);
 47
 48	list_for_each_entry(info, &sram_bank_list, node)
 49		if (!strcmp(pool_name, info->pool_name))
 50			break;
 51
 52	mutex_unlock(&sram_lock);
 53
 54	if (&info->node == &sram_bank_list)
 55		return NULL;
 56
 57	return info->gpool;
 58}
 59EXPORT_SYMBOL(sram_get_gpool);
 60
 61static int sram_probe(struct platform_device *pdev)
 62{
 63	struct sram_platdata *pdata = pdev->dev.platform_data;
 64	struct sram_bank_info *info;
 65	struct resource *res;
 66	int ret = 0;
 67
 68	if (!pdata || !pdata->pool_name)
 69		return -ENODEV;
 70
 71	info = kzalloc(sizeof(*info), GFP_KERNEL);
 72	if (!info)
 73		return -ENOMEM;
 74
 75	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 76	if (res == NULL) {
 77		dev_err(&pdev->dev, "no memory resource defined\n");
 78		ret = -ENODEV;
 79		goto out;
 80	}
 81
 82	if (!resource_size(res))
 83		return 0;
 84
 85	info->sram_phys   = (phys_addr_t)res->start;
 86	info->sram_size   = resource_size(res);
 87	info->sram_virt   = ioremap(info->sram_phys, info->sram_size);
 88	info->pool_name	  = kstrdup(pdata->pool_name, GFP_KERNEL);
 89	info->granularity = pdata->granularity;
 90
 91	info->gpool = gen_pool_create(ilog2(info->granularity), -1);
 92	if (!info->gpool) {
 93		dev_err(&pdev->dev, "create pool failed\n");
 94		ret = -ENOMEM;
 95		goto create_pool_err;
 96	}
 97
 98	ret = gen_pool_add_virt(info->gpool, (unsigned long)info->sram_virt,
 99				info->sram_phys, info->sram_size, -1);
100	if (ret < 0) {
101		dev_err(&pdev->dev, "add new chunk failed\n");
102		ret = -ENOMEM;
103		goto add_chunk_err;
104	}
105
106	mutex_lock(&sram_lock);
107	list_add(&info->node, &sram_bank_list);
108	mutex_unlock(&sram_lock);
109
110	platform_set_drvdata(pdev, info);
111
112	dev_info(&pdev->dev, "initialized\n");
113	return 0;
114
115add_chunk_err:
116	gen_pool_destroy(info->gpool);
117create_pool_err:
118	iounmap(info->sram_virt);
119	kfree(info->pool_name);
120out:
121	kfree(info);
122	return ret;
123}
124
125static int sram_remove(struct platform_device *pdev)
126{
127	struct sram_bank_info *info;
128
129	info = platform_get_drvdata(pdev);
130	if (info == NULL)
131		return -ENODEV;
132
133	mutex_lock(&sram_lock);
134	list_del(&info->node);
135	mutex_unlock(&sram_lock);
136
137	gen_pool_destroy(info->gpool);
138	iounmap(info->sram_virt);
139	kfree(info->pool_name);
140	kfree(info);
141	return 0;
142}
143
144static const struct platform_device_id sram_id_table[] = {
145	{ "asram", MMP_ASRAM },
146	{ "isram", MMP_ISRAM },
147	{ }
148};
149
150static struct platform_driver sram_driver = {
151	.probe		= sram_probe,
152	.remove		= sram_remove,
153	.driver		= {
154		.name	= "mmp-sram",
155	},
156	.id_table	= sram_id_table,
157};
158
159static int __init sram_init(void)
160{
161	return platform_driver_register(&sram_driver);
162}
163core_initcall(sram_init);
164
165MODULE_LICENSE("GPL");