diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mtd/Kconfig | 3 | ||||
-rw-r--r-- | drivers/mtd/maps/Makefile | 1 | ||||
-rw-r--r-- | drivers/mtd/maps/integrator-flash.c | 309 | ||||
-rw-r--r-- | drivers/mtd/maps/physmap.c | 28 | ||||
-rw-r--r-- | drivers/mtd/maps/pismo.c | 40 |
5 files changed, 30 insertions, 351 deletions
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index b4567c35a32..bc50d5ea553 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -148,8 +148,7 @@ config MTD_AFS_PARTS You will still need the parsing functions to be called by the driver for your particular device. It won't happen automatically. The - 'armflash' map driver (CONFIG_MTD_ARM_INTEGRATOR) does this, for - example. + 'physmap' map driver (CONFIG_MTD_PHYSMAP) does this, for example. config MTD_OF_PARTS def_bool y diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile index 6adf4c9b905..cb48b11afff 100644 --- a/drivers/mtd/maps/Makefile +++ b/drivers/mtd/maps/Makefile @@ -8,7 +8,6 @@ endif # Chip mappings obj-$(CONFIG_MTD_CDB89712) += cdb89712.o -obj-$(CONFIG_MTD_ARM_INTEGRATOR)+= integrator-flash.o obj-$(CONFIG_MTD_CFI_FLAGADM) += cfi_flagadm.o obj-$(CONFIG_MTD_DC21285) += dc21285.o obj-$(CONFIG_MTD_DILNETPC) += dilnetpc.o 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"); diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c index 7522df4f71f..1a9b94f0ee5 100644 --- a/drivers/mtd/maps/physmap.c +++ b/drivers/mtd/maps/physmap.c @@ -67,9 +67,25 @@ static int physmap_flash_remove(struct platform_device *dev) if (info->mtd[i] != NULL) map_destroy(info->mtd[i]); } + + if (physmap_data->exit) + physmap_data->exit(dev); + return 0; } +static void physmap_set_vpp(struct map_info *map, int state) +{ + struct platform_device *pdev; + struct physmap_flash_data *physmap_data; + + pdev = (struct platform_device *)map->map_priv_1; + physmap_data = pdev->dev.platform_data; + + if (physmap_data->set_vpp) + physmap_data->set_vpp(pdev, state); +} + static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", @@ -77,7 +93,8 @@ static const char *rom_probe_types[] = { "map_rom", NULL }; #ifdef CONFIG_MTD_PARTITIONS -static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; +static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", "afs", + NULL }; #endif static int physmap_flash_probe(struct platform_device *dev) @@ -100,6 +117,12 @@ static int physmap_flash_probe(struct platform_device *dev) goto err_out; } + if (physmap_data->init) { + err = physmap_data->init(dev); + if (err) + goto err_out; + } + platform_set_drvdata(dev, info); for (i = 0; i < dev->num_resources; i++) { @@ -120,8 +143,9 @@ static int physmap_flash_probe(struct platform_device *dev) info->map[i].phys = dev->resource[i].start; info->map[i].size = resource_size(&dev->resource[i]); info->map[i].bankwidth = physmap_data->width; - info->map[i].set_vpp = physmap_data->set_vpp; + info->map[i].set_vpp = physmap_set_vpp; info->map[i].pfow_base = physmap_data->pfow_base; + info->map[i].map_priv_1 = (unsigned long)dev; info->map[i].virt = devm_ioremap(&dev->dev, info->map[i].phys, info->map[i].size); diff --git a/drivers/mtd/maps/pismo.c b/drivers/mtd/maps/pismo.c index f4ce273e93f..65bd1cd4d62 100644 --- a/drivers/mtd/maps/pismo.c +++ b/drivers/mtd/maps/pismo.c @@ -50,39 +50,13 @@ struct pismo_data { struct platform_device *dev[PISMO_NUM_CS]; }; -/* FIXME: set_vpp could do with a better calling convention */ -static struct pismo_data *vpp_pismo; -static DEFINE_MUTEX(pismo_mutex); - -static int pismo_setvpp_probe_fix(struct pismo_data *pismo) +static void pismo_set_vpp(struct platform_device *pdev, int on) { - mutex_lock(&pismo_mutex); - if (vpp_pismo) { - mutex_unlock(&pismo_mutex); - kfree(pismo); - return -EBUSY; - } - vpp_pismo = pismo; - mutex_unlock(&pismo_mutex); - return 0; -} - -static void pismo_setvpp_remove_fix(struct pismo_data *pismo) -{ - mutex_lock(&pismo_mutex); - if (vpp_pismo == pismo) - vpp_pismo = NULL; - mutex_unlock(&pismo_mutex); -} - -static void pismo_set_vpp(struct map_info *map, int on) -{ - struct pismo_data *pismo = vpp_pismo; + struct i2c_client *client = to_i2c_client(pdev->dev.parent); + struct pismo_data *pismo = i2c_get_clientdata(client); pismo->vpp(pismo->vpp_data, on); } -/* end of hack */ - static unsigned int __devinit pismo_width_to_bytes(unsigned int width) { @@ -231,9 +205,6 @@ static int __devexit pismo_remove(struct i2c_client *client) for (i = 0; i < ARRAY_SIZE(pismo->dev); i++) platform_device_unregister(pismo->dev[i]); - /* FIXME: set_vpp needs saner arguments */ - pismo_setvpp_remove_fix(pismo); - kfree(pismo); return 0; @@ -257,11 +228,6 @@ static int __devinit pismo_probe(struct i2c_client *client, if (!pismo) return -ENOMEM; - /* FIXME: set_vpp needs saner arguments */ - ret = pismo_setvpp_probe_fix(pismo); - if (ret) - return ret; - pismo->client = client; if (pdata) { pismo->vpp = pdata->set_vpp; |