Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  linux/arch/arm/mach-mmp/sram.c
0004  *
0005  *  based on mach-davinci/sram.c - DaVinci simple SRAM allocator
0006  *
0007  *  Copyright (c) 2011 Marvell Semiconductors Inc.
0008  *  All Rights Reserved
0009  *
0010  *  Add for mmp sram support - Leo Yan <leoy@marvell.com>
0011  */
0012 
0013 #include <linux/module.h>
0014 #include <linux/mod_devicetable.h>
0015 #include <linux/init.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/io.h>
0018 #include <linux/err.h>
0019 #include <linux/slab.h>
0020 #include <linux/genalloc.h>
0021 
0022 #include <linux/platform_data/dma-mmp_tdma.h>
0023 
0024 struct sram_bank_info {
0025     char *pool_name;
0026     struct gen_pool *gpool;
0027     int granularity;
0028 
0029     phys_addr_t sram_phys;
0030     void __iomem *sram_virt;
0031     u32 sram_size;
0032 
0033     struct list_head node;
0034 };
0035 
0036 static DEFINE_MUTEX(sram_lock);
0037 static LIST_HEAD(sram_bank_list);
0038 
0039 struct gen_pool *sram_get_gpool(char *pool_name)
0040 {
0041     struct sram_bank_info *info = NULL;
0042 
0043     if (!pool_name)
0044         return NULL;
0045 
0046     mutex_lock(&sram_lock);
0047 
0048     list_for_each_entry(info, &sram_bank_list, node)
0049         if (!strcmp(pool_name, info->pool_name))
0050             break;
0051 
0052     mutex_unlock(&sram_lock);
0053 
0054     if (&info->node == &sram_bank_list)
0055         return NULL;
0056 
0057     return info->gpool;
0058 }
0059 EXPORT_SYMBOL(sram_get_gpool);
0060 
0061 static int sram_probe(struct platform_device *pdev)
0062 {
0063     struct sram_platdata *pdata = pdev->dev.platform_data;
0064     struct sram_bank_info *info;
0065     struct resource *res;
0066     int ret = 0;
0067 
0068     if (!pdata || !pdata->pool_name)
0069         return -ENODEV;
0070 
0071     info = kzalloc(sizeof(*info), GFP_KERNEL);
0072     if (!info)
0073         return -ENOMEM;
0074 
0075     platform_set_drvdata(pdev, info);
0076 
0077     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0078     if (res == NULL) {
0079         dev_err(&pdev->dev, "no memory resource defined\n");
0080         ret = -ENODEV;
0081         goto out;
0082     }
0083 
0084     if (!resource_size(res))
0085         return 0;
0086 
0087     info->sram_phys   = (phys_addr_t)res->start;
0088     info->sram_size   = resource_size(res);
0089     info->sram_virt   = ioremap(info->sram_phys, info->sram_size);
0090     info->pool_name   = kstrdup(pdata->pool_name, GFP_KERNEL);
0091     info->granularity = pdata->granularity;
0092 
0093     info->gpool = gen_pool_create(ilog2(info->granularity), -1);
0094     if (!info->gpool) {
0095         dev_err(&pdev->dev, "create pool failed\n");
0096         ret = -ENOMEM;
0097         goto create_pool_err;
0098     }
0099 
0100     ret = gen_pool_add_virt(info->gpool, (unsigned long)info->sram_virt,
0101                 info->sram_phys, info->sram_size, -1);
0102     if (ret < 0) {
0103         dev_err(&pdev->dev, "add new chunk failed\n");
0104         ret = -ENOMEM;
0105         goto add_chunk_err;
0106     }
0107 
0108     mutex_lock(&sram_lock);
0109     list_add(&info->node, &sram_bank_list);
0110     mutex_unlock(&sram_lock);
0111 
0112     dev_info(&pdev->dev, "initialized\n");
0113     return 0;
0114 
0115 add_chunk_err:
0116     gen_pool_destroy(info->gpool);
0117 create_pool_err:
0118     iounmap(info->sram_virt);
0119     kfree(info->pool_name);
0120 out:
0121     kfree(info);
0122     return ret;
0123 }
0124 
0125 static int sram_remove(struct platform_device *pdev)
0126 {
0127     struct sram_bank_info *info;
0128 
0129     info = platform_get_drvdata(pdev);
0130 
0131     if (info->sram_size) {
0132         mutex_lock(&sram_lock);
0133         list_del(&info->node);
0134         mutex_unlock(&sram_lock);
0135 
0136         gen_pool_destroy(info->gpool);
0137         iounmap(info->sram_virt);
0138         kfree(info->pool_name);
0139     }
0140 
0141     kfree(info);
0142 
0143     return 0;
0144 }
0145 
0146 static const struct platform_device_id sram_id_table[] = {
0147     { "asram", MMP_ASRAM },
0148     { "isram", MMP_ISRAM },
0149     { }
0150 };
0151 
0152 static struct platform_driver sram_driver = {
0153     .probe      = sram_probe,
0154     .remove     = sram_remove,
0155     .driver     = {
0156         .name   = "mmp-sram",
0157     },
0158     .id_table   = sram_id_table,
0159 };
0160 
0161 static int __init sram_init(void)
0162 {
0163     return platform_driver_register(&sram_driver);
0164 }
0165 core_initcall(sram_init);
0166 
0167 MODULE_LICENSE("GPL");