diff options
Diffstat (limited to 'drivers/mtd/maps/integrator-flash.c')
-rw-r--r-- | drivers/mtd/maps/integrator-flash.c | 309 |
1 files changed, 0 insertions, 309 deletions
diff --git a/drivers/mtd/maps/integrator-flash.c b/drivers/mtd/maps/integrator-flash.c deleted file mode 100644 index e22ff5adbbf..00000000000 --- a/drivers/mtd/maps/integrator-flash.c +++ /dev/null @@ -1,309 +0,0 @@ -/*====================================================================== - - drivers/mtd/maps/integrator-flash.c: ARM Integrator flash map driver - - Copyright (C) 2000 ARM Limited - Copyright (C) 2003 Deep Blue Solutions Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - This is access code for flashes using ARM's flash partitioning - standards. - -======================================================================*/ - -#include <linux/module.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/ioport.h> -#include <linux/platform_device.h> -#include <linux/init.h> -#include <linux/io.h> - -#include <linux/mtd/mtd.h> -#include <linux/mtd/map.h> -#include <linux/mtd/partitions.h> -#include <linux/mtd/concat.h> - -#include <asm/mach/flash.h> -#include <mach/hardware.h> -#include <asm/system.h> - -struct armflash_subdev_info { - char *name; - struct mtd_info *mtd; - struct map_info map; - struct flash_platform_data *plat; -}; - -struct armflash_info { - struct resource *res; - struct mtd_partition *parts; - struct mtd_info *mtd; - int nr_subdev; - struct armflash_subdev_info subdev[0]; -}; - -static void armflash_set_vpp(struct map_info *map, int on) -{ - struct armflash_subdev_info *info = - container_of(map, struct armflash_subdev_info, map); - - if (info->plat && info->plat->set_vpp) - info->plat->set_vpp(on); -} - -static const char *probes[] = { "cmdlinepart", "RedBoot", "afs", NULL }; - -static int armflash_subdev_probe(struct armflash_subdev_info *subdev, - struct resource *res) -{ - struct flash_platform_data *plat = subdev->plat; - resource_size_t size = res->end - res->start + 1; - void __iomem *base; - int err = 0; - - if (!request_mem_region(res->start, size, subdev->name)) { - err = -EBUSY; - goto out; - } - - base = ioremap(res->start, size); - if (!base) { - err = -ENOMEM; - goto no_mem; - } - - /* - * look for CFI based flash parts fitted to this board - */ - subdev->map.size = size; - subdev->map.bankwidth = plat->width; - subdev->map.phys = res->start; - subdev->map.virt = base; - subdev->map.name = subdev->name; - subdev->map.set_vpp = armflash_set_vpp; - - simple_map_init(&subdev->map); - - /* - * Also, the CFI layer automatically works out what size - * of chips we have, and does the necessary identification - * for us automatically. - */ - subdev->mtd = do_map_probe(plat->map_name, &subdev->map); - if (!subdev->mtd) { - err = -ENXIO; - goto no_device; - } - - subdev->mtd->owner = THIS_MODULE; - - /* Successful? */ - if (err == 0) - return err; - - if (subdev->mtd) - map_destroy(subdev->mtd); - no_device: - iounmap(base); - no_mem: - release_mem_region(res->start, size); - out: - return err; -} - -static void armflash_subdev_remove(struct armflash_subdev_info *subdev) -{ - if (subdev->mtd) - map_destroy(subdev->mtd); - if (subdev->map.virt) - iounmap(subdev->map.virt); - kfree(subdev->name); - subdev->name = NULL; - release_mem_region(subdev->map.phys, subdev->map.size); -} - -static int armflash_probe(struct platform_device *dev) -{ - struct flash_platform_data *plat = dev->dev.platform_data; - unsigned int size; - struct armflash_info *info; - int i, nr, err; - - /* Count the number of devices */ - for (nr = 0; ; nr++) - if (!platform_get_resource(dev, IORESOURCE_MEM, nr)) - break; - if (nr == 0) { - err = -ENODEV; - goto out; - } - - size = sizeof(struct armflash_info) + - sizeof(struct armflash_subdev_info) * nr; - info = kzalloc(size, GFP_KERNEL); - if (!info) { - err = -ENOMEM; - goto out; - } - - if (plat && plat->init) { - err = plat->init(); - if (err) - goto no_resource; - } - - for (i = 0; i < nr; i++) { - struct armflash_subdev_info *subdev = &info->subdev[i]; - struct resource *res; - - res = platform_get_resource(dev, IORESOURCE_MEM, i); - if (!res) - break; - - if (nr == 1) - /* No MTD concatenation, just use the default name */ - subdev->name = kstrdup(dev_name(&dev->dev), GFP_KERNEL); - else - subdev->name = kasprintf(GFP_KERNEL, "%s-%d", - dev_name(&dev->dev), i); - if (!subdev->name) { - err = -ENOMEM; - break; - } - subdev->plat = plat; - - err = armflash_subdev_probe(subdev, res); - if (err) { - kfree(subdev->name); - subdev->name = NULL; - break; - } - } - info->nr_subdev = i; - - if (err) - goto subdev_err; - - if (info->nr_subdev == 1) - info->mtd = info->subdev[0].mtd; - else if (info->nr_subdev > 1) { - struct mtd_info *cdev[info->nr_subdev]; - - /* - * We detected multiple devices. Concatenate them together. - */ - for (i = 0; i < info->nr_subdev; i++) - cdev[i] = info->subdev[i].mtd; - - info->mtd = mtd_concat_create(cdev, info->nr_subdev, - dev_name(&dev->dev)); - if (info->mtd == NULL) - err = -ENXIO; - } - - if (err < 0) - goto cleanup; - - err = parse_mtd_partitions(info->mtd, probes, &info->parts, 0); - if (err > 0) { - err = add_mtd_partitions(info->mtd, info->parts, err); - if (err) - printk(KERN_ERR - "mtd partition registration failed: %d\n", err); - } - - if (err == 0) { - platform_set_drvdata(dev, info); - return err; - } - - /* - * We got an error, free all resources. - */ - cleanup: - if (info->mtd) { - del_mtd_partitions(info->mtd); - if (info->mtd != info->subdev[0].mtd) - mtd_concat_destroy(info->mtd); - } - kfree(info->parts); - subdev_err: - for (i = info->nr_subdev - 1; i >= 0; i--) - armflash_subdev_remove(&info->subdev[i]); - no_resource: - if (plat && plat->exit) - plat->exit(); - kfree(info); - out: - return err; -} - -static int armflash_remove(struct platform_device *dev) -{ - struct armflash_info *info = platform_get_drvdata(dev); - struct flash_platform_data *plat = dev->dev.platform_data; - int i; - - platform_set_drvdata(dev, NULL); - - if (info) { - if (info->mtd) { - del_mtd_partitions(info->mtd); - if (info->mtd != info->subdev[0].mtd) - mtd_concat_destroy(info->mtd); - } - kfree(info->parts); - - for (i = info->nr_subdev - 1; i >= 0; i--) - armflash_subdev_remove(&info->subdev[i]); - - if (plat && plat->exit) - plat->exit(); - - kfree(info); - } - - return 0; -} - -static struct platform_driver armflash_driver = { - .probe = armflash_probe, - .remove = armflash_remove, - .driver = { - .name = "armflash", - .owner = THIS_MODULE, - }, -}; - -static int __init armflash_init(void) -{ - return platform_driver_register(&armflash_driver); -} - -static void __exit armflash_exit(void) -{ - platform_driver_unregister(&armflash_driver); -} - -module_init(armflash_init); -module_exit(armflash_exit); - -MODULE_AUTHOR("ARM Ltd"); -MODULE_DESCRIPTION("ARM Integrator CFI map driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:armflash"); |