diff options
Diffstat (limited to 'drivers/mtd/maps')
-rw-r--r-- | drivers/mtd/maps/Kconfig | 9 | ||||
-rw-r--r-- | drivers/mtd/maps/Makefile | 1 | ||||
-rw-r--r-- | drivers/mtd/maps/physmap.c | 168 | ||||
-rw-r--r-- | drivers/mtd/maps/physmap_of.c | 88 | ||||
-rw-r--r-- | drivers/mtd/maps/pnc2000.c | 93 | ||||
-rw-r--r-- | drivers/mtd/maps/scb2_flash.c | 2 |
6 files changed, 137 insertions, 224 deletions
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index a592fc04cf78..12c253664eb2 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig @@ -110,13 +110,6 @@ config MTD_SUN_UFLASH Sun Microsystems boardsets. This driver will require CFI support in the kernel, so if you did not enable CFI previously, do that now. -config MTD_PNC2000 - tristate "CFI Flash device mapped on Photron PNC-2000" - depends on X86 && MTD_CFI && MTD_PARTITIONS - help - PNC-2000 is the name of Network Camera product from PHOTRON - Ltd. in Japan. It uses CFI-compliant flash. - config MTD_SC520CDP tristate "CFI Flash device mapped on AMD SC520 CDP" depends on X86 && MTD_CFI && MTD_CONCAT @@ -576,7 +569,7 @@ config MTD_BAST_MAXSIZE default "4" config MTD_SHARP_SL - bool "ROM mapped on Sharp SL Series" + tristate "ROM mapped on Sharp SL Series" depends on ARCH_PXA help This enables access to the flash chip on the Sharp SL Series of PDAs. diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile index 316382a1401b..a9cbe80f99a0 100644 --- a/drivers/mtd/maps/Makefile +++ b/drivers/mtd/maps/Makefile @@ -28,7 +28,6 @@ obj-$(CONFIG_MTD_PHYSMAP) += physmap.o obj-$(CONFIG_MTD_PHYSMAP_OF) += physmap_of.o obj-$(CONFIG_MTD_PMC_MSP_EVM) += pmcmsp-flash.o obj-$(CONFIG_MTD_PMC_MSP_RAMROOT)+= pmcmsp-ramroot.o -obj-$(CONFIG_MTD_PNC2000) += pnc2000.o obj-$(CONFIG_MTD_PCMCIA) += pcmciamtd.o obj-$(CONFIG_MTD_RPXLITE) += rpxlite.o obj-$(CONFIG_MTD_TQM8XXL) += tqm8xxl.o diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c index 28c5ffd75233..f00e04efbe28 100644 --- a/drivers/mtd/maps/physmap.c +++ b/drivers/mtd/maps/physmap.c @@ -20,11 +20,15 @@ #include <linux/mtd/map.h> #include <linux/mtd/partitions.h> #include <linux/mtd/physmap.h> +#include <linux/mtd/concat.h> #include <asm/io.h> +#define MAX_RESOURCES 4 + struct physmap_flash_info { - struct mtd_info *mtd; - struct map_info map; + struct mtd_info *mtd[MAX_RESOURCES]; + struct mtd_info *cmtd; + struct map_info map[MAX_RESOURCES]; struct resource *res; #ifdef CONFIG_MTD_PARTITIONS int nr_parts; @@ -32,11 +36,11 @@ struct physmap_flash_info { #endif }; - static int physmap_flash_remove(struct platform_device *dev) { struct physmap_flash_info *info; struct physmap_flash_data *physmap_data; + int i; info = platform_get_drvdata(dev); if (info == NULL) @@ -45,24 +49,33 @@ static int physmap_flash_remove(struct platform_device *dev) physmap_data = dev->dev.platform_data; - if (info->mtd != NULL) { +#ifdef CONFIG_MTD_CONCAT + if (info->cmtd != info->mtd[0]) { + del_mtd_device(info->cmtd); + mtd_concat_destroy(info->cmtd); + } +#endif + + for (i = 0; i < MAX_RESOURCES; i++) { + if (info->mtd[i] != NULL) { #ifdef CONFIG_MTD_PARTITIONS - if (info->nr_parts) { - del_mtd_partitions(info->mtd); - kfree(info->parts); - } else if (physmap_data->nr_parts) { - del_mtd_partitions(info->mtd); - } else { - del_mtd_device(info->mtd); - } + if (info->nr_parts) { + del_mtd_partitions(info->mtd[i]); + kfree(info->parts); + } else if (physmap_data->nr_parts) { + del_mtd_partitions(info->mtd[i]); + } else { + del_mtd_device(info->mtd[i]); + } #else - del_mtd_device(info->mtd); + del_mtd_device(info->mtd[i]); #endif - map_destroy(info->mtd); - } + map_destroy(info->mtd[i]); + } - if (info->map.virt != NULL) - iounmap(info->map.virt); + if (info->map[i].virt != NULL) + iounmap(info->map[i].virt); + } if (info->res != NULL) { release_resource(info->res); @@ -82,16 +95,14 @@ static int physmap_flash_probe(struct platform_device *dev) struct physmap_flash_data *physmap_data; struct physmap_flash_info *info; const char **probe_type; - int err; + int err = 0; + int i; + int devices_found = 0; physmap_data = dev->dev.platform_data; if (physmap_data == NULL) return -ENODEV; - printk(KERN_NOTICE "physmap platform flash device: %.8llx at %.8llx\n", - (unsigned long long)(dev->resource->end - dev->resource->start + 1), - (unsigned long long)dev->resource->start); - info = kzalloc(sizeof(struct physmap_flash_info), GFP_KERNEL); if (info == NULL) { err = -ENOMEM; @@ -100,56 +111,83 @@ static int physmap_flash_probe(struct platform_device *dev) platform_set_drvdata(dev, info); - info->res = request_mem_region(dev->resource->start, - dev->resource->end - dev->resource->start + 1, - dev->dev.bus_id); - if (info->res == NULL) { - dev_err(&dev->dev, "Could not reserve memory region\n"); - err = -ENOMEM; - goto err_out; - } + for (i = 0; i < dev->num_resources; i++) { + printk(KERN_NOTICE "physmap platform flash device: %.8llx at %.8llx\n", + (unsigned long long)(dev->resource[i].end - dev->resource[i].start + 1), + (unsigned long long)dev->resource[i].start); + + info->res = request_mem_region(dev->resource[i].start, + dev->resource[i].end - dev->resource[i].start + 1, + dev->dev.bus_id); + if (info->res == NULL) { + dev_err(&dev->dev, "Could not reserve memory region\n"); + err = -ENOMEM; + goto err_out; + } - info->map.name = dev->dev.bus_id; - info->map.phys = dev->resource->start; - info->map.size = dev->resource->end - dev->resource->start + 1; - info->map.bankwidth = physmap_data->width; - info->map.set_vpp = physmap_data->set_vpp; + info->map[i].name = dev->dev.bus_id; + info->map[i].phys = dev->resource[i].start; + info->map[i].size = dev->resource[i].end - dev->resource[i].start + 1; + info->map[i].bankwidth = physmap_data->width; + info->map[i].set_vpp = physmap_data->set_vpp; + + info->map[i].virt = ioremap(info->map[i].phys, info->map[i].size); + if (info->map[i].virt == NULL) { + dev_err(&dev->dev, "Failed to ioremap flash region\n"); + err = EIO; + goto err_out; + } - info->map.virt = ioremap(info->map.phys, info->map.size); - if (info->map.virt == NULL) { - dev_err(&dev->dev, "Failed to ioremap flash region\n"); - err = EIO; - goto err_out; - } + simple_map_init(&info->map[i]); - simple_map_init(&info->map); + probe_type = rom_probe_types; + for (; info->mtd[i] == NULL && *probe_type != NULL; probe_type++) + info->mtd[i] = do_map_probe(*probe_type, &info->map[i]); + if (info->mtd[i] == NULL) { + dev_err(&dev->dev, "map_probe failed\n"); + err = -ENXIO; + goto err_out; + } else { + devices_found++; + } + info->mtd[i]->owner = THIS_MODULE; + } - probe_type = rom_probe_types; - for (; info->mtd == NULL && *probe_type != NULL; probe_type++) - info->mtd = do_map_probe(*probe_type, &info->map); - if (info->mtd == NULL) { - dev_err(&dev->dev, "map_probe failed\n"); + if (devices_found == 1) { + info->cmtd = info->mtd[0]; + } else if (devices_found > 1) { + /* + * We detected multiple devices. Concatenate them together. + */ +#ifdef CONFIG_MTD_CONCAT + info->cmtd = mtd_concat_create(info->mtd, devices_found, dev->dev.bus_id); + if (info->cmtd == NULL) + err = -ENXIO; +#else + printk(KERN_ERR "physmap-flash: multiple devices " + "found but MTD concat support disabled.\n"); err = -ENXIO; - goto err_out; +#endif } - info->mtd->owner = THIS_MODULE; + if (err) + goto err_out; #ifdef CONFIG_MTD_PARTITIONS - err = parse_mtd_partitions(info->mtd, part_probe_types, &info->parts, 0); + err = parse_mtd_partitions(info->cmtd, part_probe_types, &info->parts, 0); if (err > 0) { - add_mtd_partitions(info->mtd, info->parts, err); + add_mtd_partitions(info->cmtd, info->parts, err); return 0; } if (physmap_data->nr_parts) { printk(KERN_NOTICE "Using physmap partition information\n"); - add_mtd_partitions(info->mtd, physmap_data->parts, - physmap_data->nr_parts); + add_mtd_partitions(info->cmtd, physmap_data->parts, + physmap_data->nr_parts); return 0; } #endif - add_mtd_device(info->mtd); + add_mtd_device(info->cmtd); return 0; err_out: @@ -162,9 +200,11 @@ static int physmap_flash_suspend(struct platform_device *dev, pm_message_t state { struct physmap_flash_info *info = platform_get_drvdata(dev); int ret = 0; + int i; if (info) - ret = info->mtd->suspend(info->mtd); + for (i = 0; i < MAX_RESOURCES; i++) + ret |= info->mtd[i]->suspend(info->mtd[i]); return ret; } @@ -172,27 +212,35 @@ static int physmap_flash_suspend(struct platform_device *dev, pm_message_t state static int physmap_flash_resume(struct platform_device *dev) { struct physmap_flash_info *info = platform_get_drvdata(dev); + int i; + if (info) - info->mtd->resume(info->mtd); + for (i = 0; i < MAX_RESOURCES; i++) + info->mtd[i]->resume(info->mtd[i]); return 0; } static void physmap_flash_shutdown(struct platform_device *dev) { struct physmap_flash_info *info = platform_get_drvdata(dev); - if (info && info->mtd->suspend(info->mtd) == 0) - info->mtd->resume(info->mtd); + int i; + + for (i = 0; i < MAX_RESOURCES; i++) + if (info && info->mtd[i]->suspend(info->mtd[i]) == 0) + info->mtd[i]->resume(info->mtd[i]); } +#else +#define physmap_flash_suspend NULL +#define physmap_flash_resume NULL +#define physmap_flash_shutdown NULL #endif static struct platform_driver physmap_flash_driver = { .probe = physmap_flash_probe, .remove = physmap_flash_remove, -#ifdef CONFIG_PM .suspend = physmap_flash_suspend, .resume = physmap_flash_resume, .shutdown = physmap_flash_shutdown, -#endif .driver = { .name = "physmap-flash", }, diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index aeed9ea79714..49acd4171893 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c @@ -80,64 +80,6 @@ static int parse_obsolete_partitions(struct of_device *dev, return nr_parts; } - -static int __devinit parse_partitions(struct of_flash *info, - struct of_device *dev) -{ - const char *partname; - static const char *part_probe_types[] - = { "cmdlinepart", "RedBoot", NULL }; - struct device_node *dp = dev->node, *pp; - int nr_parts, i; - - /* First look for RedBoot table or partitions on the command - * line, these take precedence over device tree information */ - nr_parts = parse_mtd_partitions(info->mtd, part_probe_types, - &info->parts, 0); - if (nr_parts > 0) { - add_mtd_partitions(info->mtd, info->parts, nr_parts); - return 0; - } - - /* First count the subnodes */ - nr_parts = 0; - for (pp = dp->child; pp; pp = pp->sibling) - nr_parts++; - - if (nr_parts == 0) - return parse_obsolete_partitions(dev, info, dp); - - info->parts = kzalloc(nr_parts * sizeof(*info->parts), - GFP_KERNEL); - if (!info->parts) - return -ENOMEM; - - for (pp = dp->child, i = 0; pp; pp = pp->sibling, i++) { - const u32 *reg; - int len; - - reg = of_get_property(pp, "reg", &len); - if (!reg || (len != 2*sizeof(u32))) { - dev_err(&dev->dev, "Invalid 'reg' on %s\n", - dp->full_name); - kfree(info->parts); - info->parts = NULL; - return -EINVAL; - } - info->parts[i].offset = reg[0]; - info->parts[i].size = reg[1]; - - partname = of_get_property(pp, "label", &len); - if (!partname) - partname = of_get_property(pp, "name", &len); - info->parts[i].name = (char *)partname; - - if (of_get_property(pp, "read-only", &len)) - info->parts[i].mask_flags = MTD_WRITEABLE; - } - - return nr_parts; -} #else /* MTD_PARTITIONS */ #define OF_FLASH_PARTS(info) (0) #define parse_partitions(info, dev) (0) @@ -212,6 +154,10 @@ static struct mtd_info * __devinit obsolete_probe(struct of_device *dev, static int __devinit of_flash_probe(struct of_device *dev, const struct of_device_id *match) { +#ifdef CONFIG_MTD_PARTITIONS + static const char *part_probe_types[] + = { "cmdlinepart", "RedBoot", NULL }; +#endif struct device_node *dp = dev->node; struct resource res; struct of_flash *info; @@ -274,13 +220,33 @@ static int __devinit of_flash_probe(struct of_device *dev, } info->mtd->owner = THIS_MODULE; - err = parse_partitions(info, dev); +#ifdef CONFIG_MTD_PARTITIONS + /* First look for RedBoot table or partitions on the command + * line, these take precedence over device tree information */ + err = parse_mtd_partitions(info->mtd, part_probe_types, + &info->parts, 0); if (err < 0) - goto err_out; + return err; + +#ifdef CONFIG_MTD_OF_PARTS + if (err == 0) { + err = of_mtd_parse_partitions(&dev->dev, info->mtd, + dp, &info->parts); + if (err < 0) + return err; + } +#endif + + if (err == 0) { + err = parse_obsolete_partitions(dev, info, dp); + if (err < 0) + return err; + } if (err > 0) - add_mtd_partitions(info->mtd, OF_FLASH_PARTS(info), err); + add_mtd_partitions(info->mtd, info->parts, err); else +#endif add_mtd_device(info->mtd); return 0; diff --git a/drivers/mtd/maps/pnc2000.c b/drivers/mtd/maps/pnc2000.c deleted file mode 100644 index d7e16c2d5c44..000000000000 --- a/drivers/mtd/maps/pnc2000.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * pnc2000.c - mapper for Photron PNC-2000 board. - * - * Copyright (C) 2000 Crossnet Co. <info@crossnet.co.jp> - * - * This code is GPL - * - * $Id: pnc2000.c,v 1.18 2005/11/07 11:14:28 gleixner Exp $ - */ - -#include <linux/module.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/init.h> - -#include <linux/mtd/mtd.h> -#include <linux/mtd/map.h> -#include <linux/mtd/partitions.h> - - -#define WINDOW_ADDR 0xbf000000 -#define WINDOW_SIZE 0x00400000 - -/* - * MAP DRIVER STUFF - */ - - -static struct map_info pnc_map = { - .name = "PNC-2000", - .size = WINDOW_SIZE, - .bankwidth = 4, - .phys = 0xFFFFFFFF, - .virt = (void __iomem *)WINDOW_ADDR, -}; - - -/* - * MTD 'PARTITIONING' STUFF - */ -static struct mtd_partition pnc_partitions[3] = { - { - .name = "PNC-2000 boot firmware", - .size = 0x20000, - .offset = 0 - }, - { - .name = "PNC-2000 kernel", - .size = 0x1a0000, - .offset = 0x20000 - }, - { - .name = "PNC-2000 filesystem", - .size = 0x240000, - .offset = 0x1c0000 - } -}; - -/* - * This is the master MTD device for which all the others are just - * auto-relocating aliases. - */ -static struct mtd_info *mymtd; - -static int __init init_pnc2000(void) -{ - printk(KERN_NOTICE "Photron PNC-2000 flash mapping: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR); - - simple_map_init(&pnc_map); - - mymtd = do_map_probe("cfi_probe", &pnc_map); - if (mymtd) { - mymtd->owner = THIS_MODULE; - return add_mtd_partitions(mymtd, pnc_partitions, 3); - } - - return -ENXIO; -} - -static void __exit cleanup_pnc2000(void) -{ - if (mymtd) { - del_mtd_partitions(mymtd); - map_destroy(mymtd); - } -} - -module_init(init_pnc2000); -module_exit(cleanup_pnc2000); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Crossnet Co. <info@crossnet.co.jp>"); -MODULE_DESCRIPTION("MTD map driver for Photron PNC-2000 board"); diff --git a/drivers/mtd/maps/scb2_flash.c b/drivers/mtd/maps/scb2_flash.c index dcfb85840d1e..0fc5584324e3 100644 --- a/drivers/mtd/maps/scb2_flash.c +++ b/drivers/mtd/maps/scb2_flash.c @@ -79,7 +79,7 @@ scb2_fixup_mtd(struct mtd_info *mtd) struct cfi_private *cfi = map->fldrv_priv; /* barf if this doesn't look right */ - if (cfi->cfiq->InterfaceDesc != 1) { + if (cfi->cfiq->InterfaceDesc != CFI_INTERFACE_X16_ASYNC) { printk(KERN_ERR MODNAME ": unsupported InterfaceDesc: %#x\n", cfi->cfiq->InterfaceDesc); return -1; |