summaryrefslogtreecommitdiff
path: root/drivers/mtd/maps
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-07 21:20:31 +0300
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-07 21:20:31 +0300
commita8e98d6d51a3eb7bb061b1625193a129c8bd094f (patch)
tree0fa58b6e11e37023b024e55b8f0e7e01438706d4 /drivers/mtd/maps
parentf0f1b3364ae7f48084bdf2837fb979ff59622523 (diff)
parentf9f7dd222364a6428d2ad99a515935dd1dd89d18 (diff)
downloadlinux-a8e98d6d51a3eb7bb061b1625193a129c8bd094f.tar.xz
Merge git://git.infradead.org/mtd-2.6
* git://git.infradead.org/mtd-2.6: (120 commits) [MTD] Fix mtdoops.c compilation [MTD] [NOR] fix startup lock when using multiple nor flash chips [MTD] [DOC200x] eccbuf is statically defined and always evaluate to true [MTD] Fix maps/physmap.c compilation with CONFIG_PM [MTD] onenand: Add panic_write function to the onenand driver [MTD] mtdoops: Use the panic_write function when present [MTD] Add mtd panic_write function pointer [MTD] [NAND] Freescale enhanced Local Bus Controller FCM NAND support. [MTD] physmap.c: Add support for multiple resources [MTD] [NAND] Fix misparenthesization introduced by commit 78b65179... [MTD] [NAND] Fix Blackfin NFC ECC calculating bug with page size 512 bytes [MTD] [NAND] Remove wrong operation in PM function of the BF54x NFC driver [MTD] [NAND] Remove unused variable in plat_nand_remove [MTD] Unlocking all Intel flash that is locked on power up. [MTD] [NAND] at91_nand: Make mtdparts option can override board info [MTD] mtdoops: Various minor cleanups [MTD] mtdoops: Ensure sequential write to the buffer [MTD] mtdoops: Perform write operations in a workqueue [MTD] mtdoops: Add further error return code checking [MTD] [NOR] Test devtype, not definition in flash_probe(), drivers/mtd/devices/lart.c ...
Diffstat (limited to 'drivers/mtd/maps')
-rw-r--r--drivers/mtd/maps/Kconfig9
-rw-r--r--drivers/mtd/maps/Makefile1
-rw-r--r--drivers/mtd/maps/physmap.c168
-rw-r--r--drivers/mtd/maps/physmap_of.c88
-rw-r--r--drivers/mtd/maps/pnc2000.c93
-rw-r--r--drivers/mtd/maps/scb2_flash.c2
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;