aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorBen Dooks <ben@simtec.co.uk>2005-01-23 19:37:04 -0500
committerThomas Gleixner <tglx@mtd.linutronix.de>2005-05-23 05:33:47 -0400
commit99f2a8aea18c9779c141050c6f95a8f1da63bbe4 (patch)
tree5afcd7442131196b69cb6ed406729fa96bb7e0ab /drivers/mtd
parenta4ab4c5d32b66a440fb2e00f975f919f559f001d (diff)
[MTD] Platform RAM Driver
Driver for generic RAM blocks which are exported by an platform_device from the device driver system. Signed-off-by: Ben Dooks <ben@simtec.co.uk> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/maps/Kconfig12
-rw-r--r--drivers/mtd/maps/Makefile3
-rw-r--r--drivers/mtd/maps/plat-ram.c286
3 files changed, 299 insertions, 2 deletions
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 8480057eadb4..7d21d432f380 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -1,5 +1,5 @@
1# drivers/mtd/maps/Kconfig 1# drivers/mtd/maps/Kconfig
2# $Id: Kconfig,v 1.42 2005/01/05 16:59:50 dwmw2 Exp $ 2# $Id: Kconfig,v 1.43 2005/01/24 00:35:21 bjd Exp $
3 3
4menu "Mapping drivers for chip access" 4menu "Mapping drivers for chip access"
5 depends on MTD!=n 5 depends on MTD!=n
@@ -659,5 +659,15 @@ config MTD_SHARP_SL
659 help 659 help
660 This enables access to the flash chip on the Sharp SL Series of PDAs. 660 This enables access to the flash chip on the Sharp SL Series of PDAs.
661 661
662config MTD_PLATRAM
663 tristate "Map driver for platfrom device RAM (mtd-ram)"
664 depends on MTD
665 select MTD_RAM
666 help
667 Map driver for RAM areas described via the platform device
668 system.
669
670 This selection automatically selects the map_ram driver.
671
662endmenu 672endmenu
663 673
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index 7ffe02b85301..d2e6dcc87059 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -1,7 +1,7 @@
1# 1#
2# linux/drivers/maps/Makefile 2# linux/drivers/maps/Makefile
3# 3#
4# $Id: Makefile.common,v 1.23 2005/01/05 17:06:36 dwmw2 Exp $ 4# $Id: Makefile.common,v 1.24 2005/01/24 00:35:21 bjd Exp $
5 5
6ifeq ($(CONFIG_MTD_COMPLEX_MAPPINGS),y) 6ifeq ($(CONFIG_MTD_COMPLEX_MAPPINGS),y)
7obj-$(CONFIG_MTD) += map_funcs.o 7obj-$(CONFIG_MTD) += map_funcs.o
@@ -71,3 +71,4 @@ obj-$(CONFIG_MTD_IXP2000) += ixp2000.o
71obj-$(CONFIG_MTD_WRSBC8260) += wr_sbc82xx_flash.o 71obj-$(CONFIG_MTD_WRSBC8260) += wr_sbc82xx_flash.o
72obj-$(CONFIG_MTD_DMV182) += dmv182.o 72obj-$(CONFIG_MTD_DMV182) += dmv182.o
73obj-$(CONFIG_MTD_SHARP_SL) += sharpsl-flash.o 73obj-$(CONFIG_MTD_SHARP_SL) += sharpsl-flash.o
74obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o
diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c
new file mode 100644
index 000000000000..808f94346add
--- /dev/null
+++ b/drivers/mtd/maps/plat-ram.c
@@ -0,0 +1,286 @@
1/* drivers/mtd/maps/plat-ram.c
2 *
3 * (c) 2004-2005 Simtec Electronics
4 * http://www.simtec.co.uk/products/SWLINUX/
5 * Ben Dooks <ben@simtec.co.uk>
6 *
7 * Generic platfrom device based RAM map
8 *
9 * $Id: plat-ram.c,v 1.1 2005/01/24 00:37:02 bjd Exp $
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24*/
25
26#define DEBUG
27
28#include <linux/module.h>
29#include <linux/types.h>
30#include <linux/init.h>
31#include <linux/kernel.h>
32#include <linux/string.h>
33#include <linux/ioport.h>
34#include <linux/device.h>
35
36#include <linux/mtd/mtd.h>
37#include <linux/mtd/map.h>
38#include <linux/mtd/partitions.h>
39#include <linux/mtd/plat-ram.h>
40
41#include <asm/io.h>
42
43/* private structure for each mtd platform ram device created */
44
45struct platram_info {
46 struct device *dev;
47 struct mtd_info *mtd;
48 struct map_info map;
49 struct mtd_partition *partitions;
50 struct resource *area;
51 struct platdata_mtd_ram *pdata;
52};
53
54/* to_platram_info()
55 *
56 * device private data to struct platram_info conversion
57*/
58
59static inline struct platram_info *to_platram_info(struct device *dev)
60{
61 return (struct platram_info *)dev_get_drvdata(dev);
62}
63
64/* platram_setrw
65 *
66 * call the platform device's set rw/ro control
67 *
68 * to = 0 => read-only
69 * = 1 => read-write
70*/
71
72static inline void platram_setrw(struct platram_info *info, int to)
73{
74 if (info->pdata == NULL)
75 return;
76
77 if (info->pdata->set_rw != NULL)
78 (info->pdata->set_rw)(info->dev, to);
79}
80
81/* platram_remove
82 *
83 * called to remove the device from the driver's control
84*/
85
86static int platram_remove(struct device *dev)
87{
88 struct platram_info *info = to_platram_info(dev);
89
90 dev_set_drvdata(dev, NULL);
91
92 dev_dbg(dev, "removing device\n");
93
94 if (info == NULL)
95 return 0;
96
97 if (info->mtd) {
98#ifdef CONFIG_MTD_PARTITIONS
99 if (info->partitions) {
100 del_mtd_partitions(info->mtd);
101 kfree(info->partitions);
102 }
103#endif
104 del_mtd_device(info->mtd);
105 map_destroy(info->mtd);
106 }
107
108 /* ensure ram is left read-only */
109
110 platram_setrw(info, PLATRAM_RO);
111
112 /* release resources */
113
114 if (info->area) {
115 release_resource(info->area);
116 kfree(info->area);
117 }
118
119 if (info->map.virt != NULL)
120 iounmap(info->map.virt);
121
122 kfree(info);
123
124 return 0;
125}
126
127/* platram_probe
128 *
129 * called from device drive system when a device matching our
130 * driver is found.
131*/
132
133static int platram_probe(struct device *dev)
134{
135 struct platform_device *pd = to_platform_device(dev);
136 struct platdata_mtd_ram *pdata;
137 struct platram_info *info;
138 struct resource *res;
139 int err = 0;
140
141 dev_dbg(dev, "probe entered\n");
142
143 if (dev->platform_data == NULL) {
144 dev_err(dev, "no platform data supplied\n");
145 err = -ENOENT;
146 goto exit_error;
147 }
148
149 pdata = dev->platform_data;
150
151 info = kmalloc(sizeof(*info), GFP_KERNEL);
152 if (info == NULL) {
153 dev_err(dev, "no memory for flash info\n");
154 err = -ENOMEM;
155 goto exit_error;
156 }
157
158 memzero(info, sizeof(*info));
159 dev_set_drvdata(dev, info);
160
161 info->dev = dev;
162 info->pdata = pdata;
163
164 /* get the resource for the memory mapping */
165
166 res = platform_get_resource(pd, IORESOURCE_MEM, 0);
167
168 if (res == NULL) {
169 dev_err(dev, "no memory resource specified\n");
170 err = -ENOENT;
171 goto exit_free;
172 }
173
174 dev_dbg(dev, "got platform resource %p (0x%lx)\n", res, res->start);
175
176 /* setup map parameters */
177
178 info->map.phys = res->start;
179 info->map.size = (res->end - res->start) + 1;
180 info->map.name = pdata->mapname != NULL ? pdata->mapname : pd->name;
181 info->map.bankwidth = pdata->bankwidth;
182
183 /* register our usage of the memory area */
184
185 info->area = request_mem_region(res->start, info->map.size, pd->name);
186 if (info->area == NULL) {
187 dev_err(dev, "failed to request memory region\n");
188 err = -EIO;
189 goto exit_free;
190 }
191
192 /* remap the memory area */
193
194 info->map.virt = ioremap(res->start, info->map.size);
195 dev_dbg(dev, "virt %p, %d bytes\n", info->map.virt, info->map.size);
196
197 if (info->map.virt == NULL) {
198 dev_err(dev, "failed to ioremap() region\n");
199 err = -EIO;
200 goto exit_free;
201 }
202
203 {
204 unsigned int *p = (unsigned int *)info->map.virt;
205 printk("%08x %08x %08x %08x\n",
206 readl(p), readl(p+1), readl(p+2), readl(p+3));
207 }
208
209 simple_map_init(&info->map);
210
211 dev_dbg(dev, "initialised map, probing for mtd\n");
212
213 /* probe for the right mtd map driver */
214
215 info->mtd = do_map_probe("map_ram" , &info->map);
216 if (info->mtd == NULL) {
217 dev_err(dev, "failed to probe for map_ram\n");
218 err = -ENOMEM;
219 goto exit_free;
220 }
221
222 info->mtd->owner = THIS_MODULE;
223
224 platram_setrw(info, PLATRAM_RW);
225
226 /* check to see if there are any available partitions, or wether
227 * to add this device whole */
228
229#ifdef CONFIG_MTD_PARTITIONS
230 if (pdata->nr_partitions > 0) {
231 const char **probes = { NULL };
232
233 if (pdata->probes)
234 probes = (const char **)pdata->probes;
235
236 err = parse_mtd_partitions(info->mtd, probes,
237 &info->partitions, 0);
238 if (err > 0) {
239 err = add_mtd_partitions(info->mtd, info->partitions,
240 err);
241 }
242 }
243#endif /* CONFIG_MTD_PARTITIONS */
244
245 if (add_mtd_device(info->mtd)) {
246 dev_err(dev, "add_mtd_device() failed\n");
247 err = -ENOMEM;
248 }
249
250 dev_info(dev, "registered mtd device\n");
251 return err;
252
253 exit_free:
254 platram_remove(dev);
255 exit_error:
256 return err;
257}
258
259/* device driver info */
260
261static struct device_driver platram_driver = {
262 .name = "mtd-ram",
263 .bus = &platform_bus_type,
264 .probe = platram_probe,
265 .remove = platram_remove,
266};
267
268/* module init/exit */
269
270static int __init platram_init(void)
271{
272 printk("Generic platform RAM MTD, (c) 2004 Simtec Electronics\n");
273 return driver_register(&platram_driver);
274}
275
276static void __exit platram_exit(void)
277{
278 driver_unregister(&platram_driver);
279}
280
281module_init(platram_init);
282module_exit(platram_exit);
283
284MODULE_LICENSE("GPL");
285MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
286MODULE_DESCRIPTION("MTD platform RAM map driver");