aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Zabel <p.zabel@pengutronix.de>2013-04-29 19:17:12 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-04-29 21:28:13 -0400
commit4984c6f5e56c3e68922fd979347ba7aff385783b (patch)
tree7931e0e6dbb71d837a24638cebc62a5dbb38798b
parent9375db07adeaeea5f5ea7ca0463a8b371d71ddbb (diff)
misc: generic on-chip SRAM allocation driver
This driver requests and remaps a memory region as configured in the device tree. It serves memory from this region via the genalloc API. It optionally enables the SRAM clock. Other drivers can retrieve the genalloc pool from a phandle pointing to this drivers' device node in the device tree. The allocation granularity is hard-coded to 32 bytes for now, to make the SRAM driver useful for the 6502 remoteproc driver. There is overhead for bigger SRAMs, where only a much coarser allocation granularity is needed: At 32 bytes minimum allocation size, a 256 KiB SRAM needs a 1 KiB bitmap to track allocations. [akpm@linux-foundation.org: fix Kconfig text, make sram_init static] Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de> Reviewed-by: Shawn Guo <shawn.guo@linaro.org> Acked-by: Grant Likely <grant.likely@secretlab.ca> Tested-by: Michal Simek <monstr@monstr.eu> Cc: Dong Aisheng <dong.aisheng@linaro.org> Cc: Fabio Estevam <fabio.estevam@freescale.com> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Huang Shijie <shijie8@gmail.com> Cc: Javier Martin <javier.martin@vista-silicon.com> Cc: Matt Porter <mporter@ti.com> Cc: Michal Simek <monstr@monstr.eu> Cc: Paul Gortmaker <paul.gortmaker@windriver.com> Cc: Rob Herring <rob.herring@calxeda.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--Documentation/devicetree/bindings/misc/sram.txt16
-rw-r--r--drivers/misc/Kconfig9
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/sram.c121
4 files changed, 147 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/misc/sram.txt b/Documentation/devicetree/bindings/misc/sram.txt
new file mode 100644
index 000000000000..4d0a00e453a8
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/sram.txt
@@ -0,0 +1,16 @@
1Generic on-chip SRAM
2
3Simple IO memory regions to be managed by the genalloc API.
4
5Required properties:
6
7- compatible : mmio-sram
8
9- reg : SRAM iomem address range
10
11Example:
12
13sram: sram@5c000000 {
14 compatible = "mmio-sram";
15 reg = <0x5c000000 0x40000>; /* 256 KiB SRAM at address 0x5c000000 */
16};
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index e29e7980a359..3659d00efdc5 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -518,6 +518,15 @@ config LATTICE_ECP3_CONFIG
518 518
519 If unsure, say N. 519 If unsure, say N.
520 520
521config SRAM
522 bool "Generic on-chip SRAM driver"
523 depends on HAS_IOMEM
524 select GENERIC_ALLOCATOR
525 help
526 This driver allows you to declare a memory region to be managed by
527 the genalloc API. It is supposed to be used for small on-chip SRAM
528 areas found on many SoCs.
529
521source "drivers/misc/c2port/Kconfig" 530source "drivers/misc/c2port/Kconfig"
522source "drivers/misc/eeprom/Kconfig" 531source "drivers/misc/eeprom/Kconfig"
523source "drivers/misc/cb710/Kconfig" 532source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 865cbc6a7ae1..c235d5b68311 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -52,3 +52,4 @@ obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/
52obj-$(CONFIG_INTEL_MEI) += mei/ 52obj-$(CONFIG_INTEL_MEI) += mei/
53obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/ 53obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/
54obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o 54obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o
55obj-$(CONFIG_SRAM) += sram.o
diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c
new file mode 100644
index 000000000000..437192e43006
--- /dev/null
+++ b/drivers/misc/sram.c
@@ -0,0 +1,121 @@
1/*
2 * Generic on-chip SRAM allocation driver
3 *
4 * Copyright (C) 2012 Philipp Zabel, Pengutronix
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 * MA 02110-1301, USA.
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/clk.h>
24#include <linux/err.h>
25#include <linux/io.h>
26#include <linux/of.h>
27#include <linux/platform_device.h>
28#include <linux/slab.h>
29#include <linux/spinlock.h>
30#include <linux/genalloc.h>
31
32#define SRAM_GRANULARITY 32
33
34struct sram_dev {
35 struct gen_pool *pool;
36 struct clk *clk;
37};
38
39static int sram_probe(struct platform_device *pdev)
40{
41 void __iomem *virt_base;
42 struct sram_dev *sram;
43 struct resource *res;
44 unsigned long size;
45 int ret;
46
47 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
48 if (!res)
49 return -EINVAL;
50
51 size = resource_size(res);
52
53 virt_base = devm_request_and_ioremap(&pdev->dev, res);
54 if (!virt_base)
55 return -EADDRNOTAVAIL;
56
57 sram = devm_kzalloc(&pdev->dev, sizeof(*sram), GFP_KERNEL);
58 if (!sram)
59 return -ENOMEM;
60
61 sram->clk = devm_clk_get(&pdev->dev, NULL);
62 if (IS_ERR(sram->clk))
63 sram->clk = NULL;
64 else
65 clk_prepare_enable(sram->clk);
66
67 sram->pool = devm_gen_pool_create(&pdev->dev, ilog2(SRAM_GRANULARITY), -1);
68 if (!sram->pool)
69 return -ENOMEM;
70
71 ret = gen_pool_add_virt(sram->pool, (unsigned long)virt_base,
72 res->start, size, -1);
73 if (ret < 0) {
74 gen_pool_destroy(sram->pool);
75 return ret;
76 }
77
78 platform_set_drvdata(pdev, sram);
79
80 dev_dbg(&pdev->dev, "SRAM pool: %ld KiB @ 0x%p\n", size / 1024, virt_base);
81
82 return 0;
83}
84
85static int sram_remove(struct platform_device *pdev)
86{
87 struct sram_dev *sram = platform_get_drvdata(pdev);
88
89 if (gen_pool_avail(sram->pool) < gen_pool_size(sram->pool))
90 dev_dbg(&pdev->dev, "removed while SRAM allocated\n");
91
92 gen_pool_destroy(sram->pool);
93
94 if (sram->clk)
95 clk_disable_unprepare(sram->clk);
96
97 return 0;
98}
99
100#ifdef CONFIG_OF
101static struct of_device_id sram_dt_ids[] = {
102 { .compatible = "mmio-sram" },
103 {}
104};
105#endif
106
107static struct platform_driver sram_driver = {
108 .driver = {
109 .name = "sram",
110 .of_match_table = of_match_ptr(sram_dt_ids),
111 },
112 .probe = sram_probe,
113 .remove = sram_remove,
114};
115
116static int __init sram_init(void)
117{
118 return platform_driver_register(&sram_driver);
119}
120
121postcore_initcall(sram_init);