Commit 99f2a8aea18c9779c141050c6f95a8f1da63bbe4

Authored by Ben Dooks
Committed by Thomas Gleixner
1 parent a4ab4c5d32

[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>

Showing 4 changed files with 334 additions and 2 deletions Side-by-side Diff

drivers/mtd/maps/Kconfig
1 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  
4 4 menu "Mapping drivers for chip access"
5 5 depends on MTD!=n
... ... @@ -658,6 +658,16 @@
658 658 depends on MTD && ARCH_PXA
659 659 help
660 660 This enables access to the flash chip on the Sharp SL Series of PDAs.
  661 +
  662 +config 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.
661 671  
662 672 endmenu
drivers/mtd/maps/Makefile
1 1 #
2 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  
6 6 ifeq ($(CONFIG_MTD_COMPLEX_MAPPINGS),y)
7 7 obj-$(CONFIG_MTD) += map_funcs.o
... ... @@ -71,4 +71,5 @@
71 71 obj-$(CONFIG_MTD_WRSBC8260) += wr_sbc82xx_flash.o
72 72 obj-$(CONFIG_MTD_DMV182) += dmv182.o
73 73 obj-$(CONFIG_MTD_SHARP_SL) += sharpsl-flash.o
  74 +obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o
drivers/mtd/maps/plat-ram.c
  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 +
  45 +struct 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 +
  59 +static 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 +
  72 +static 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 +
  86 +static 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 +
  133 +static 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 +
  261 +static 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 +
  270 +static 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 +
  276 +static void __exit platram_exit(void)
  277 +{
  278 + driver_unregister(&platram_driver);
  279 +}
  280 +
  281 +module_init(platram_init);
  282 +module_exit(platram_exit);
  283 +
  284 +MODULE_LICENSE("GPL");
  285 +MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
  286 +MODULE_DESCRIPTION("MTD platform RAM map driver");
include/linux/mtd/plat-ram.h
  1 +/* linux/include/mtd/plat-ram.h
  2 + *
  3 + * (c) 2004 Simtec Electronics
  4 + * http://www.simtec.co.uk/products/SWLINUX/
  5 + * Ben Dooks <ben@simtec.co.uk>
  6 + *
  7 + * Generic platform device based RAM map
  8 + *
  9 + * $Id: plat-ram.h,v 1.2 2005/01/24 00:37:40 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 version 2 as
  13 + * published by the Free Software Foundation.
  14 + *
  15 + */
  16 +
  17 +#ifndef __LINUX_MTD_PLATRAM_H
  18 +#define __LINUX_MTD_PLATRAM_H __FILE__
  19 +
  20 +#define PLATRAM_RO (0)
  21 +#define PLATRAM_RW (1)
  22 +
  23 +struct platdata_mtd_ram {
  24 + char *mapname;
  25 + char **probes;
  26 + struct mtd_partition *partitions;
  27 + int nr_partitions;
  28 + int bankwidth;
  29 +
  30 + /* control callbacks */
  31 +
  32 + void (*set_rw)(struct device *dev, int to);
  33 +};
  34 +
  35 +#endif /* __LINUX_MTD_PLATRAM_H */