aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@dwmw2.baythorne.internal>2004-08-11 00:03:26 +0100
committerDavid Woodhouse <dwmw2@dwmw2.baythorne.internal>2004-08-11 00:03:26 +0100
commit1ad840010f200c411d680f089ca50ce426cb1e4f (patch)
treed9147211738d02aa32f5efe5bb640c250a6e59ba /drivers
parent384278b0d36291bc207d628251eb3b64d387c596 (diff)
parent60abe48a1812d4672578fa3f0f59e03fa1280ddc (diff)
downloadhistory-1ad840010f200c411d680f089ca50ce426cb1e4f.tar.gz
Merge bk://linux-mtd.bkbits.net/mtd-2.6
into dwmw2.baythorne.internal:/inst/bk/mtd-2.6
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/Kconfig4
-rw-r--r--drivers/mtd/Makefile7
-rw-r--r--drivers/mtd/chips/amd_flash.c6
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c5
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0002.c8
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0020.c5
-rw-r--r--drivers/mtd/chips/jedec.c5
-rw-r--r--drivers/mtd/chips/map_ram.c5
-rw-r--r--drivers/mtd/chips/sharp.c5
-rw-r--r--drivers/mtd/devices/Kconfig22
-rw-r--r--drivers/mtd/devices/blkmtd.c8
-rw-r--r--drivers/mtd/devices/doc2000.c5
-rw-r--r--drivers/mtd/devices/doc2001.c5
-rw-r--r--drivers/mtd/devices/doc2001plus.c5
-rw-r--r--drivers/mtd/devices/lart.c4
-rw-r--r--drivers/mtd/devices/ms02-nv.c4
-rw-r--r--drivers/mtd/devices/mtdram.c5
-rw-r--r--drivers/mtd/devices/phram.c7
-rw-r--r--drivers/mtd/devices/pmc551.c6
-rw-r--r--drivers/mtd/devices/slram.c9
-rw-r--r--drivers/mtd/ftl.c4
-rw-r--r--drivers/mtd/inftlcore.c4
-rw-r--r--drivers/mtd/inftlmount.c4
-rw-r--r--drivers/mtd/maps/Kconfig15
-rw-r--r--drivers/mtd/maps/ichxrom.c2
-rw-r--r--drivers/mtd/maps/physmap.c9
-rw-r--r--drivers/mtd/mtdchar.c7
-rw-r--r--drivers/mtd/mtdpart.c18
-rw-r--r--drivers/mtd/nand/Kconfig46
-rw-r--r--drivers/mtd/nand/diskonchip.c569
-rw-r--r--drivers/mtd/nand/nand_base.c20
-rw-r--r--drivers/mtd/redboot.c7
32 files changed, 645 insertions, 190 deletions
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 2839166ac76e5b..f0aaaa225fb58e 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -1,4 +1,4 @@
-# $Id: Kconfig,v 1.5 2004/06/04 15:59:32 gleixner Exp $
+# $Id: Kconfig,v 1.6 2004/08/09 13:19:42 dwmw2 Exp $
menu "Memory Technology Devices (MTD)"
@@ -28,7 +28,7 @@ config MTD_DEBUG_VERBOSE
Determines the verbosity level of the MTD debugging messages.
config MTD_PARTITIONS
- tristate "MTD partitioning support"
+ bool "MTD partitioning support"
depends on MTD
help
If you have a device which needs to divide its flash chip(s) up
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index 85239c969b9ed6..9316119a0e9e9c 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -1,10 +1,13 @@
#
# Makefile for the memory technology device drivers.
#
-# $Id: Makefile.common,v 1.3 2004/07/12 16:07:30 dwmw2 Exp $
+# $Id: Makefile.common,v 1.4 2004/08/09 13:19:42 dwmw2 Exp $
# Core functionality.
-obj-$(CONFIG_MTD) += mtdcore.o
+mtd-y := mtdcore.o
+mtd-$(CONFIG_MTD_PARTITIONS) += mtdpart.o
+obj-$(CONFIG_MTD) += $(mtd-y)
+
obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o
obj-$(CONFIG_MTD_PARTITIONS) += mtdpart.o
obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o
diff --git a/drivers/mtd/chips/amd_flash.c b/drivers/mtd/chips/amd_flash.c
index ca710c78c6f3f9..1c1640ebecf27c 100644
--- a/drivers/mtd/chips/amd_flash.c
+++ b/drivers/mtd/chips/amd_flash.c
@@ -3,7 +3,7 @@
*
* Author: Jonas Holmberg <jonas.holmberg@axis.com>
*
- * $Id: amd_flash.c,v 1.24 2004/07/12 13:34:30 dwmw2 Exp $
+ * $Id: amd_flash.c,v 1.25 2004/08/09 13:19:43 dwmw2 Exp $
*
* Copyright (c) 2001 Axis Communications AB
*
@@ -1307,9 +1307,7 @@ static int amd_flash_erase(struct mtd_info *mtd, struct erase_info *instr)
}
instr->state = MTD_ERASE_DONE;
- if (instr->callback) {
- instr->callback(instr);
- }
+ mtd_erase_callback(instr);
return 0;
}
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index a36168e8404bf0..e71624edb2aa75 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -4,7 +4,7 @@
*
* (C) 2000 Red Hat. GPL'd
*
- * $Id: cfi_cmdset_0001.c,v 1.153 2004/07/12 21:52:20 dwmw2 Exp $
+ * $Id: cfi_cmdset_0001.c,v 1.154 2004/08/09 13:19:43 dwmw2 Exp $
*
*
* 10/10/2000 Nicolas Pitre <nico@cam.org>
@@ -1554,8 +1554,7 @@ int cfi_intelext_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
return ret;
instr->state = MTD_ERASE_DONE;
- if (instr->callback)
- instr->callback(instr);
+ mtd_erase_callback(instr);
return 0;
}
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index 6f2b2aaf88a68b..5bd15f548f22e4 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -13,7 +13,7 @@
*
* This code is GPL
*
- * $Id: cfi_cmdset_0002.c,v 1.103 2004/07/14 16:24:03 dwmw2 Exp $
+ * $Id: cfi_cmdset_0002.c,v 1.106 2004/08/09 14:02:32 dwmw2 Exp $
*
*/
@@ -1420,8 +1420,7 @@ int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
return ret;
instr->state = MTD_ERASE_DONE;
- if (instr->callback)
- instr->callback(instr);
+ mtd_erase_callback(instr);
return 0;
}
@@ -1444,8 +1443,7 @@ static int cfi_amdstd_erase_chip(struct mtd_info *mtd, struct erase_info *instr)
return ret;
instr->state = MTD_ERASE_DONE;
- if (instr->callback)
- instr->callback(instr);
+ mtd_erase_callback(instr);
return 0;
}
diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c
index 7a552263f2da3a..326eaf7a2bbb99 100644
--- a/drivers/mtd/chips/cfi_cmdset_0020.c
+++ b/drivers/mtd/chips/cfi_cmdset_0020.c
@@ -4,7 +4,7 @@
*
* (C) 2000 Red Hat. GPL'd
*
- * $Id: cfi_cmdset_0020.c,v 1.14 2004/07/20 02:44:25 dwmw2 Exp $
+ * $Id: cfi_cmdset_0020.c,v 1.15 2004/08/09 13:19:43 dwmw2 Exp $
*
* 10/10/2000 Nicolas Pitre <nico@cam.org>
* - completely revamped method functions so they are aware and
@@ -966,8 +966,7 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
}
instr->state = MTD_ERASE_DONE;
- if (instr->callback)
- instr->callback(instr);
+ mtd_erase_callback(instr);
return 0;
}
diff --git a/drivers/mtd/chips/jedec.c b/drivers/mtd/chips/jedec.c
index 0b6e96f7ccfa3c..2dfd53ed39d2b0 100644
--- a/drivers/mtd/chips/jedec.c
+++ b/drivers/mtd/chips/jedec.c
@@ -11,7 +11,7 @@
* not going to guess how to send commands to them, plus I expect they will
* all speak CFI..
*
- * $Id: jedec.c,v 1.20 2004/07/12 14:03:01 dwmw2 Exp $
+ * $Id: jedec.c,v 1.21 2004/08/09 13:19:43 dwmw2 Exp $
*/
#include <linux/init.h>
@@ -780,8 +780,7 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
//printk("done\n");
instr->state = MTD_ERASE_DONE;
- if (instr->callback)
- instr->callback(instr);
+ mtd_erase_callback(instr);
return 0;
#undef flread
diff --git a/drivers/mtd/chips/map_ram.c b/drivers/mtd/chips/map_ram.c
index db6f6c40f428d5..283be02dc311af 100644
--- a/drivers/mtd/chips/map_ram.c
+++ b/drivers/mtd/chips/map_ram.c
@@ -1,7 +1,7 @@
/*
* Common code to handle map devices which are simple RAM
* (C) 2000 Red Hat. GPL'd.
- * $Id: map_ram.c,v 1.19 2004/07/12 21:58:44 dwmw2 Exp $
+ * $Id: map_ram.c,v 1.20 2004/08/09 13:19:43 dwmw2 Exp $
*/
#include <linux/module.h>
@@ -114,8 +114,7 @@ static int mapram_erase (struct mtd_info *mtd, struct erase_info *instr)
instr->state = MTD_ERASE_DONE;
- if (instr->callback)
- instr->callback(instr);
+ mtd_erase_callback(instr);
return 0;
}
diff --git a/drivers/mtd/chips/sharp.c b/drivers/mtd/chips/sharp.c
index 1313c70298a5e8..c3cf0f63bc9363 100644
--- a/drivers/mtd/chips/sharp.c
+++ b/drivers/mtd/chips/sharp.c
@@ -4,7 +4,7 @@
* Copyright 2000,2001 David A. Schleef <ds@schleef.org>
* 2000,2001 Lineo, Inc.
*
- * $Id: sharp.c,v 1.13 2004/07/12 14:06:34 dwmw2 Exp $
+ * $Id: sharp.c,v 1.14 2004/08/09 13:19:43 dwmw2 Exp $
*
* Devices supported:
* LH28F016SCT Symmetrical block flash memory, 2Mx8
@@ -425,8 +425,7 @@ static int sharp_erase(struct mtd_info *mtd, struct erase_info *instr)
}
instr->state = MTD_ERASE_DONE;
- if(instr->callback)
- instr->callback(instr);
+ mtd_erase_callback(instr);
return 0;
}
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index 6ecd5ec9e20fcd..ec8cd5bcb246c4 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -1,5 +1,5 @@
# drivers/mtd/maps/Kconfig
-# $Id: Kconfig,v 1.10 2004/07/15 00:34:49 dwmw2 Exp $
+# $Id: Kconfig,v 1.12 2004/08/10 13:12:18 dwmw2 Exp $
menu "Self-contained MTD device drivers"
depends on MTD!=n
@@ -128,7 +128,7 @@ config MTD_BLKMTD
comment "Disk-On-Chip Device Drivers"
config MTD_DOC2000
- tristate "M-Systems Disk-On-Chip 2000 and Millennium"
+ tristate "M-Systems Disk-On-Chip 2000 and Millennium (DEPRECATED)"
depends on MTD
---help---
This provides an MTD device driver for the M-Systems DiskOnChip
@@ -144,8 +144,12 @@ config MTD_DOC2000
emulate a block device by using a kind of file system on the flash
chips.
+ NOTE: This driver is deprecated and will probably be removed soon.
+ Please try the new DiskOnChip driver under "NAND Flash Device
+ Drivers".
+
config MTD_DOC2001
- tristate "M-Systems Disk-On-Chip Millennium-only alternative driver (see help)"
+ tristate "M-Systems Disk-On-Chip Millennium-only alternative driver (DEPRECATED)"
depends on MTD
---help---
This provides an alternative MTD device driver for the M-Systems
@@ -160,6 +164,10 @@ config MTD_DOC2001
emulate a block device by using a kind of file system on the flash
chips.
+ NOTE: This driver is deprecated and will probably be removed soon.
+ Please try the new DiskOnChip driver under "NAND Flash Device
+ Drivers".
+
config MTD_DOC2001PLUS
tristate "M-Systems Disk-On-Chip Millennium Plus"
depends on MTD
@@ -172,19 +180,23 @@ config MTD_DOC2001PLUS
to emulate a block device by using a kind of file system on the
flash chips.
+ NOTE: This driver will soon be replaced by the new DiskOnChip driver
+ under "NAND Flash Device Drivers" (currently that driver does not
+ support all Millennium Plus devices).
+
config MTD_DOCPROBE
tristate
default m if MTD_DOC2001!=y && MTD_DOC2000!=y && MTD_DOC2001PLUS!=y && (MTD_DOC2001=m || MTD_DOC2000=m || MTD_DOC2001PLUS=m)
default y if MTD_DOC2001=y || MTD_DOC2000=y || MTD_DOC2001PLUS=y
help
- This isn't a real config option, it's derived.
+ This isn't a real config option; it's derived.
config MTD_DOCECC
tristate
default m if MTD_DOCPROBE!=y && MTD_NAND_DISKONCHIP!=y && (MTD_DOCPROBE=m || MTD_NAND_DISKONCHIP=m)
default y if MTD_DOCPROBE=y || MTD_NAND_DISKONCHIP=y
help
- This isn't a real config option, it's derived.
+ This isn't a real config option; it's derived.
config MTD_DOCPROBE_ADVANCED
bool "Advanced detection options for DiskOnChip"
diff --git a/drivers/mtd/devices/blkmtd.c b/drivers/mtd/devices/blkmtd.c
index b25e20a5a5cab7..a3eb97a9490fd8 100644
--- a/drivers/mtd/devices/blkmtd.c
+++ b/drivers/mtd/devices/blkmtd.c
@@ -1,5 +1,5 @@
/*
- * $Id: blkmtd-25.c,v 1.6 2004/07/15 15:09:15 dwmw2 Exp $
+ * $Id: blkmtd.c,v 1.23 2004/08/09 14:03:19 dwmw2 Exp $
*
* blkmtd.c - use a block device as a fake MTD
*
@@ -39,7 +39,7 @@
/* Default erase size in K, always make it a multiple of PAGE_SIZE */
#define CONFIG_MTD_BLKDEV_ERASESIZE (128 << 10) /* 128KiB */
-#define VERSION "$Revision: 1.6 $"
+#define VERSION "$Revision: 1.23 $"
/* Info for the block device */
struct blkmtd_dev {
@@ -435,9 +435,7 @@ static int blkmtd_erase(struct mtd_info *mtd, struct erase_info *instr)
}
DEBUG(3, "blkmtd: erase: checking callback\n");
- if (instr->callback) {
- (*(instr->callback))(instr);
- }
+ mtd_erase_callback(instr);
DEBUG(2, "blkmtd: erase: finished (err = %d)\n", err);
return err;
}
diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c
index 0cdec06574ea3d..fefbf5eaf80514 100644
--- a/drivers/mtd/devices/doc2000.c
+++ b/drivers/mtd/devices/doc2000.c
@@ -4,7 +4,7 @@
* (c) 1999 Machine Vision Holdings, Inc.
* (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
*
- * $Id: doc2000.c,v 1.60 2004/04/07 08:30:04 gleixner Exp $
+ * $Id: doc2000.c,v 1.62 2004/08/09 14:04:02 dwmw2 Exp $
*/
#include <linux/kernel.h>
@@ -1277,8 +1277,7 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
instr->state = MTD_ERASE_DONE;
callback:
- if (instr->callback)
- instr->callback(instr);
+ mtd_erase_callback(instr);
up(&this->lock);
return 0;
diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c
index 1128009f1ca510..df588ac6503d2f 100644
--- a/drivers/mtd/devices/doc2001.c
+++ b/drivers/mtd/devices/doc2001.c
@@ -4,7 +4,7 @@
* (c) 1999 Machine Vision Holdings, Inc.
* (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
*
- * $Id: doc2001.c,v 1.42 2004/04/04 12:36:45 gleixner Exp $
+ * $Id: doc2001.c,v 1.44 2004/08/09 14:04:24 dwmw2 Exp $
*/
#include <linux/kernel.h>
@@ -845,8 +845,7 @@ int doc_erase (struct mtd_info *mtd, struct erase_info *instr)
instr->state = MTD_ERASE_DONE;
dummy = ReadDOC(docptr, LastDataRead);
- if (instr->callback)
- instr->callback(instr);
+ mtd_erase_callback(instr);
return 0;
}
diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c
index da4275cb73eb18..d30ba118f9201f 100644
--- a/drivers/mtd/devices/doc2001plus.c
+++ b/drivers/mtd/devices/doc2001plus.c
@@ -6,7 +6,7 @@
* (c) 1999 Machine Vision Holdings, Inc.
* (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
*
- * $Id: doc2001plus.c,v 1.8 2004/04/04 12:36:45 gleixner Exp $
+ * $Id: doc2001plus.c,v 1.9 2004/08/09 13:19:44 dwmw2 Exp $
*
* Released under GPL
*/
@@ -1111,8 +1111,7 @@ int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
/* Disable flash internally */
WriteDOC(0, docptr, Mplus_FlashSelect);
- if (instr->callback)
- instr->callback(instr);
+ mtd_erase_callback(instr);
return 0;
}
diff --git a/drivers/mtd/devices/lart.c b/drivers/mtd/devices/lart.c
index d67ca4cb206f60..dfd335e4a2a80c 100644
--- a/drivers/mtd/devices/lart.c
+++ b/drivers/mtd/devices/lart.c
@@ -2,7 +2,7 @@
/*
* MTD driver for the 28F160F3 Flash Memory (non-CFI) on LART.
*
- * $Id: lart.c,v 1.6 2004/07/14 17:21:38 dwmw2 Exp $
+ * $Id: lart.c,v 1.7 2004/08/09 13:19:44 dwmw2 Exp $
*
* Author: Abraham vd Merwe <abraham@2d3d.co.za>
*
@@ -433,7 +433,7 @@ static int flash_erase (struct mtd_info *mtd,struct erase_info *instr)
}
instr->state = MTD_ERASE_DONE;
- if (instr->callback) instr->callback (instr);
+ mtd_erase_callback(instr);
return (0);
}
diff --git a/drivers/mtd/devices/ms02-nv.c b/drivers/mtd/devices/ms02-nv.c
index 3a331aa0b97479..42417b05493cef 100644
--- a/drivers/mtd/devices/ms02-nv.c
+++ b/drivers/mtd/devices/ms02-nv.c
@@ -6,7 +6,7 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
- * $Id: ms02-nv.c,v 1.6 2003/08/19 09:25:36 dwmw2 Exp $
+ * $Id: ms02-nv.c,v 1.7 2004/07/29 14:16:45 macro Exp $
*/
#include <linux/init.h>
@@ -31,7 +31,7 @@
static char version[] __initdata =
"ms02-nv.c: v.1.0.0 13 Aug 2001 Maciej W. Rozycki.\n";
-MODULE_AUTHOR("Maciej W. Rozycki <macro@ds2.pg.gda.pl>");
+MODULE_AUTHOR("Maciej W. Rozycki <macro@linux-mips.org>");
MODULE_DESCRIPTION("DEC MS02-NV NVRAM module driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/devices/mtdram.c b/drivers/mtd/devices/mtdram.c
index 64397ddf82c8f0..5fe0a08655e25b 100644
--- a/drivers/mtd/devices/mtdram.c
+++ b/drivers/mtd/devices/mtdram.c
@@ -1,6 +1,6 @@
/*
* mtdram - a test mtd device
- * $Id: mtdram.c,v 1.32 2003/05/21 15:15:07 dwmw2 Exp $
+ * $Id: mtdram.c,v 1.33 2004/08/09 13:19:44 dwmw2 Exp $
* Author: Alexander Larsson <alex@cendio.se>
*
* Copyright (c) 1999 Alexander Larsson <alex@cendio.se>
@@ -57,9 +57,8 @@ ram_erase(struct mtd_info *mtd, struct erase_info *instr)
memset((char *)mtd->priv + instr->addr, 0xff, instr->len);
instr->state = MTD_ERASE_DONE;
+ mtd_erase_callback(instr);
- if (instr->callback)
- (*(instr->callback))(instr);
return 0;
}
diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c
index 5f66e9bfb10cb7..03a955cdf17a02 100644
--- a/drivers/mtd/devices/phram.c
+++ b/drivers/mtd/devices/phram.c
@@ -1,6 +1,6 @@
/**
*
- * $Id: phram.c,v 1.1 2003/08/21 17:52:30 joern Exp $
+ * $Id: phram.c,v 1.2 2004/08/09 13:19:44 dwmw2 Exp $
*
* Copyright (c) Jochen Schaeuble <psionic@psionic.de>
* 07/2003 rewritten by Joern Engel <joern@wh.fh-wedel.de>
@@ -55,10 +55,7 @@ int phram_erase(struct mtd_info *mtd, struct erase_info *instr)
instr->state = MTD_ERASE_DONE;
- if (instr->callback)
- (*(instr->callback))(instr);
- else
- kfree(instr);
+ mtd_erase_callback(instr);
return 0;
}
diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c
index cebb2821bc4e8b..c2c2a3c369b046 100644
--- a/drivers/mtd/devices/pmc551.c
+++ b/drivers/mtd/devices/pmc551.c
@@ -1,5 +1,5 @@
/*
- * $Id: pmc551.c,v 1.27 2004/07/20 02:44:26 dwmw2 Exp $
+ * $Id: pmc551.c,v 1.28 2004/08/09 13:19:44 dwmw2 Exp $
*
* PMC551 PCI Mezzanine Ram Device
*
@@ -169,9 +169,7 @@ out:
printk(KERN_DEBUG "pmc551_erase() done\n");
#endif
- if (instr->callback) {
- (*(instr->callback))(instr);
- }
+ mtd_erase_callback(instr);
return 0;
}
diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c
index 4dbcfcfd68fc45..fd579ae45dab84 100644
--- a/drivers/mtd/devices/slram.c
+++ b/drivers/mtd/devices/slram.c
@@ -1,6 +1,6 @@
/*======================================================================
- $Id: slram.c,v 1.30 2003/05/20 21:03:08 dwmw2 Exp $
+ $Id: slram.c,v 1.31 2004/08/09 13:19:44 dwmw2 Exp $
This driver provides a method to access memory not used by the kernel
itself (i.e. if the kernel commandline mem=xxx is used). To actually
@@ -98,12 +98,7 @@ int slram_erase(struct mtd_info *mtd, struct erase_info *instr)
instr->state = MTD_ERASE_DONE;
- if (instr->callback) {
- (*(instr->callback))(instr);
- }
- else {
- kfree(instr);
- }
+ mtd_erase_callback(instr);
return(0);
}
diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c
index f7554e94818e2d..f298aee1893d67 100644
--- a/drivers/mtd/ftl.c
+++ b/drivers/mtd/ftl.c
@@ -1,5 +1,5 @@
/* This version ported to the Linux-MTD system by dwmw2@infradead.org
- * $Id: ftl.c,v 1.52 2003/08/11 09:00:44 dwmw2 Exp $
+ * $Id: ftl.c,v 1.53 2004/08/09 13:55:43 dwmw2 Exp $
*
* Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
* - fixes some leaks on failure in build_maps and ftl_notify_add, cleanups
@@ -1094,7 +1094,7 @@ struct mtd_blktrans_ops ftl_tr = {
int init_ftl(void)
{
- DEBUG(0, "$Id: ftl.c,v 1.52 2003/08/11 09:00:44 dwmw2 Exp $\n");
+ DEBUG(0, "$Id: ftl.c,v 1.53 2004/08/09 13:55:43 dwmw2 Exp $\n");
return register_mtd_blktrans(&ftl_tr);
}
diff --git a/drivers/mtd/inftlcore.c b/drivers/mtd/inftlcore.c
index c01eed873854a3..ea32c03e670c4b 100644
--- a/drivers/mtd/inftlcore.c
+++ b/drivers/mtd/inftlcore.c
@@ -7,7 +7,7 @@
* (c) 1999 Machine Vision Holdings, Inc.
* Author: David Woodhouse <dwmw2@infradead.org>
*
- * $Id: inftlcore.c,v 1.16 2004/07/12 12:34:58 dwmw2 Exp $
+ * $Id: inftlcore.c,v 1.17 2004/08/09 13:56:48 dwmw2 Exp $
*
* 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
@@ -893,7 +893,7 @@ extern char inftlmountrev[];
int __init init_inftl(void)
{
- printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.16 $, "
+ printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.17 $, "
"inftlmount.c %s\n", inftlmountrev);
return register_mtd_blktrans(&inftl_tr);
diff --git a/drivers/mtd/inftlmount.c b/drivers/mtd/inftlmount.c
index 63d38ffad1b299..64cc97ca7bd310 100644
--- a/drivers/mtd/inftlmount.c
+++ b/drivers/mtd/inftlmount.c
@@ -8,7 +8,7 @@
* Author: Fabrice Bellard (fabrice.bellard@netgem.com)
* Copyright (C) 2000 Netgem S.A.
*
- * $Id: inftlmount.c,v 1.13 2004/06/28 16:06:36 dbrown Exp $
+ * $Id: inftlmount.c,v 1.14 2004/08/09 13:57:42 dwmw2 Exp $
*
* 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
@@ -41,7 +41,7 @@
#include <linux/mtd/inftl.h>
#include <linux/mtd/compatmac.h>
-char inftlmountrev[]="$Revision: 1.13 $";
+char inftlmountrev[]="$Revision: 1.14 $";
/*
* find_boot_record: Find the INFTL Media Header and its Spare copy which
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index b1ad6567b73547..cdc5bbd166a314 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -1,5 +1,5 @@
# drivers/mtd/maps/Kconfig
-# $Id: Kconfig,v 1.29 2004/07/15 15:29:17 dwmw2 Exp $
+# $Id: Kconfig,v 1.30 2004/07/21 00:16:14 jwboyer Exp $
menu "Mapping drivers for chip access"
depends on MTD!=n
@@ -19,7 +19,8 @@ config MTD_PHYSMAP
command set driver code to communicate with flash chips which
are mapped physically into the CPU's memory. You will need to
configure the physical address and size of the flash chips on
- your particular board as well as the bus width.
+ your particular board as well as the bus width, either statically
+ with config options or at run-time.
config MTD_PHYSMAP_START
hex "Physical start address of flash mapping"
@@ -30,6 +31,8 @@ config MTD_PHYSMAP_START
are mapped on your particular target board. Refer to the
memory map which should hopefully be in the documentation for
your board.
+ Ignore this option if you use run-time physmap configuration
+ (i.e., run-time calling physmap_configure()).
config MTD_PHYSMAP_LEN
hex "Physical length of flash mapping"
@@ -42,9 +45,11 @@ config MTD_PHYSMAP_LEN
than the total amount of flash present. Refer to the memory
map which should hopefully be in the documentation for your
board.
+ Ignore this option if you use run-time physmap configuration
+ (i.e., run-time calling physmap_configure()).
-config MTD_PHYSMAP_BUSWIDTH
- int "Bus width in octets"
+config MTD_PHYSMAP_BANKWIDTH
+ int "Bank width in octets"
depends on MTD_PHYSMAP
default "2"
help
@@ -52,6 +57,8 @@ config MTD_PHYSMAP_BUSWIDTH
in octets. For example, if you have a data bus width of 32
bits, you would set the bus width octect value to 4. This is
used internally by the CFI drivers.
+ Ignore this option if you use run-time physmap configuration
+ (i.e., run-time calling physmap_configure()).
config MTD_SUN_UFLASH
tristate "Sun Microsystems userflash support"
diff --git a/drivers/mtd/maps/ichxrom.c b/drivers/mtd/maps/ichxrom.c
index 281fbcf336a2c5..a26cc3af5e1f94 100644
--- a/drivers/mtd/maps/ichxrom.c
+++ b/drivers/mtd/maps/ichxrom.c
@@ -2,7 +2,7 @@
* ichxrom.c
*
* Normal mappings of chips in physical memory
- * $Id: ichxrom.c,v 1.7 2004/07/14 18:14:09 eric Exp $
+ * $Id: ichxrom.c,v 1.8 2004/07/16 17:43:11 dwmw2 Exp $
*/
#include <linux/module.h>
diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c
index 8dfd0b233616fb..5822ba99c19584 100644
--- a/drivers/mtd/maps/physmap.c
+++ b/drivers/mtd/maps/physmap.c
@@ -1,5 +1,5 @@
/*
- * $Id: physmap.c,v 1.33 2004/07/12 14:37:24 dwmw2 Exp $
+ * $Id: physmap.c,v 1.34 2004/07/21 00:16:14 jwboyer Exp $
*
* Normal mappings of chips in physical memory
*
@@ -22,7 +22,12 @@
static struct mtd_info *mymtd;
-struct map_info physmap_map = {.name = "phys_mapped_flash"};
+struct map_info physmap_map = {
+ .name = "phys_mapped_flash",
+ .phys = CONFIG_MTD_PHYSMAP_START,
+ .size = CONFIG_MTD_PHYSMAP_LEN,
+ .bankwidth = CONFIG_MTD_PHYSMAP_BANKWIDTH,
+};
#ifdef CONFIG_MTD_PARTITIONS
static struct mtd_partition *mtd_parts;
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 66eb3bf8974db5..3db73d8c26b867 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -1,5 +1,5 @@
/*
- * $Id: mtdchar.c,v 1.62 2004/07/14 13:20:42 dwmw2 Exp $
+ * $Id: mtdchar.c,v 1.64 2004/08/09 13:59:46 dwmw2 Exp $
*
* Character-device access to raw MTD devices.
*
@@ -262,7 +262,7 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
IOCTL calls for getting device parameters.
======================================================================*/
-static void mtd_erase_callback (struct erase_info *instr)
+static void mtdchar_erase_callback (struct erase_info *instr)
{
wake_up((wait_queue_head_t *)instr->priv);
}
@@ -336,7 +336,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
return -EFAULT;
}
erase->mtd = mtd;
- erase->callback = mtd_erase_callback;
+ erase->callback = mtdchar_erase_callback;
erase->priv = (unsigned long)&waitq;
/*
@@ -511,7 +511,6 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
}
default:
- DEBUG(MTD_DEBUG_LEVEL0, "Invalid ioctl %x (MEMGETINFO = %lx)\n", cmd, (unsigned long)MEMGETINFO);
ret = -ENOTTY;
}
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index f007d0740f7379..c3369e0aa5c34c 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -5,7 +5,7 @@
*
* This code is GPL
*
- * $Id: mtdpart.c,v 1.46 2004/07/12 13:28:07 dwmw2 Exp $
+ * $Id: mtdpart.c,v 1.50 2004/08/10 16:18:34 dwmw2 Exp $
*
* 02-21-2002 Thomas Gleixner <gleixner@autronix.de>
* added support for read_oob, write_oob
@@ -246,11 +246,23 @@ static int part_erase (struct mtd_info *mtd, struct erase_info *instr)
return -EINVAL;
instr->addr += part->offset;
ret = part->master->erase(part->master, instr);
- if (instr->fail_addr != 0xffffffff)
- instr->fail_addr -= part->offset;
return ret;
}
+void mtd_erase_callback(struct erase_info *instr)
+{
+ if (instr->mtd->erase == part_erase) {
+ struct mtd_part *part = PART(instr->mtd);
+
+ if (instr->fail_addr != 0xffffffff)
+ instr->fail_addr -= part->offset;
+ instr->addr -= part->offset;
+ }
+ if (instr->callback)
+ instr->callback(instr);
+}
+EXPORT_SYMBOL_GPL(mtd_erase_callback);
+
static int part_lock (struct mtd_info *mtd, loff_t ofs, size_t len)
{
struct mtd_part *part = PART(mtd);
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index ddd29306df519e..ed085292c57d03 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -1,5 +1,5 @@
# drivers/mtd/nand/Kconfig
-# $Id: Kconfig,v 1.14 2004/07/13 00:14:35 dbrown Exp $
+# $Id: Kconfig,v 1.17 2004/08/10 14:24:07 dwmw2 Exp $
menu "NAND Flash Device Drivers"
depends on MTD!=n
@@ -81,15 +81,51 @@ config MTD_NAND_PPCHAMELEONEVB
This enables the NAND flash driver on the PPChameleon EVB Board.
config MTD_NAND_DISKONCHIP
- tristate "DiskOnChip 2000 and Millennium (NAND reimplementation) (EXPERIMENTAL)"
+ tristate "DiskOnChip 2000, Millennium and Millennium Plus (NAND reimplementation) (EXPERIMENTAL)"
depends on MTD_NAND && EXPERIMENTAL
help
- This is a reimplementation of M-Systems DiskOnChip 2000 and
- Millennium as a standard NAND device driver, as opposed to the
- earlier self-contained MTD device drivers.
+ This is a reimplementation of M-Systems DiskOnChip 2000,
+ Millennium and Millennium Plus as a standard NAND device driver,
+ as opposed to the earlier self-contained MTD device drivers.
This should enable, among other things, proper JFFS2 operation on
these devices.
+config MTD_NAND_DISKONCHIP_PROBE_ADVANCED
+ bool "Advanced detection options for DiskOnChip"
+ depends on MTD_NAND_DISKONCHIP
+ help
+ This option allows you to specify nonstandard address at which to
+ probe for a DiskOnChip, or to change the detection options. You
+ are unlikely to need any of this unless you are using LinuxBIOS.
+ Say 'N'.
+
+config MTD_NAND_DISKONCHIP_PROBE_ADDRESS
+ hex "Physical address of DiskOnChip" if MTD_NAND_DISKONCHIP_PROBE_ADVANCED
+ depends on MTD_NAND_DISKONCHIP
+ default "0"
+ ---help---
+ By default, the probe for DiskOnChip devices will look for a
+ DiskOnChip at every multiple of 0x2000 between 0xC8000 and 0xEE000.
+ This option allows you to specify a single address at which to probe
+ for the device, which is useful if you have other devices in that
+ range which get upset when they are probed.
+
+ (Note that on PowerPC, the normal probe will only check at
+ 0xE4000000.)
+
+ Normally, you should leave this set to zero, to allow the probe at
+ the normal addresses.
+
+config MTD_NAND_DISKONCHIP_PROBE_HIGH
+ bool "Probe high addresses"
+ depends on MTD_NAND_DISKONCHIP_PROBE_ADVANCED
+ help
+ By default, the probe for DiskOnChip devices will look for a
+ DiskOnChip at every multiple of 0x2000 between 0xC8000 and 0xEE000.
+ This option changes to make it probe between 0xFFFC8000 and
+ 0xFFFEE000. Unless you are using LinuxBIOS, this is unlikely to be
+ useful to you. Say 'N'.
+
config MTD_NAND_DISKONCHIP_BBTWRITE
bool "Allow BBT writes on DiskOnChip Millennium and 2000TSOP"
depends on MTD_NAND_DISKONCHIP
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index 4edb86b7a118cf..0f7dedd6b88ecd 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -2,12 +2,16 @@
* drivers/mtd/nand/diskonchip.c
*
* (C) 2003 Red Hat, Inc.
+ * (C) 2004 Dan Brown <dan_brown@ieee.org>
+ * (C) 2004 Kalev Lember <kalev@smartlink.ee>
*
* Author: David Woodhouse <dwmw2@infradead.org>
+ * Additional Diskonchip 2000 and Millennium support by Dan Brown <dan_brown@ieee.org>
+ * Diskonchip Millennium Plus support by Kalev Lember <kalev@smartlink.ee>
*
* Interface to generic NAND code for M-Systems DiskOnChip devices
*
- * $Id: diskonchip.c,v 1.25 2004/07/16 13:54:27 dbrown Exp $
+ * $Id: diskonchip.c,v 1.34 2004/08/09 19:41:12 dbrown Exp $
*/
#include <linux/kernel.h>
@@ -24,13 +28,13 @@
#include <linux/mtd/inftl.h>
/* Where to look for the devices? */
-#ifndef CONFIG_MTD_DOCPROBE_ADDRESS
-#define CONFIG_MTD_DOCPROBE_ADDRESS 0
+#ifndef CONFIG_MTD_DISKONCHIP_PROBE_ADDRESS
+#define CONFIG_MTD_DISKONCHIP_PROBE_ADDRESS 0
#endif
static unsigned long __initdata doc_locations[] = {
#if defined (__alpha__) || defined(__i386__) || defined(__x86_64__)
-#ifdef CONFIG_MTD_DOCPROBE_HIGH
+#ifdef CONFIG_MTD_DISKONCHIP_PROBE_HIGH
0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000,
0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000,
0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000,
@@ -84,6 +88,7 @@ static u_char empty_write_ecc[6] = { 0x4b, 0x00, 0xe2, 0x0e, 0x93, 0xf7 };
#define INFTL_BBT_RESERVED_BLOCKS 4
+#define DoC_is_MillenniumPlus(doc) ((doc)->ChipID == DOC_ChipID_DocMilPlus16 || (doc)->ChipID == DOC_ChipID_DocMilPlus32)
#define DoC_is_Millennium(doc) ((doc)->ChipID == DOC_ChipID_DocMil)
#define DoC_is_2000(doc) ((doc)->ChipID == DOC_ChipID_Doc2k)
@@ -109,7 +114,7 @@ static int inftl_bbt_write=0;
#endif
MODULE_PARM(inftl_bbt_write, "i");
-static unsigned long doc_config_location = CONFIG_MTD_DOCPROBE_ADDRESS;
+static unsigned long doc_config_location = CONFIG_MTD_DISKONCHIP_PROBE_ADDRESS;
MODULE_PARM(doc_config_location, "l");
MODULE_PARM_DESC(doc_config_location, "Physical memory address at which to probe for DiskOnChip");
@@ -121,11 +126,16 @@ static void DoC_Delay(struct doc_priv *doc, unsigned short cycles)
for (i = 0; i < cycles; i++) {
if (DoC_is_Millennium(doc))
dummy = ReadDOC(doc->virtadr, NOP);
+ else if (DoC_is_MillenniumPlus(doc))
+ dummy = ReadDOC(doc->virtadr, Mplus_NOP);
else
dummy = ReadDOC(doc->virtadr, DOCStatus);
}
}
+
+#define CDSN_CTRL_FR_B_MASK (CDSN_CTRL_FR_B0 | CDSN_CTRL_FR_B1)
+
/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
static int _DoC_WaitReady(struct doc_priv *doc)
{
@@ -134,13 +144,24 @@ static int _DoC_WaitReady(struct doc_priv *doc)
if(debug) printk("_DoC_WaitReady...\n");
/* Out-of-line routine to wait for chip response */
- while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
- if (time_after(jiffies, timeo)) {
- printk("_DoC_WaitReady timed out.\n");
- return -EIO;
+ if (DoC_is_MillenniumPlus(doc)) {
+ while ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) {
+ if (time_after(jiffies, timeo)) {
+ printk("_DoC_WaitReady timed out.\n");
+ return -EIO;
+ }
+ udelay(1);
+ cond_resched();
+ }
+ } else {
+ while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
+ if (time_after(jiffies, timeo)) {
+ printk("_DoC_WaitReady timed out.\n");
+ return -EIO;
+ }
+ udelay(1);
+ cond_resched();
}
- udelay(1);
- cond_resched();
}
return 0;
@@ -151,13 +172,21 @@ static inline int DoC_WaitReady(struct doc_priv *doc)
unsigned long docptr = doc->virtadr;
int ret = 0;
- DoC_Delay(doc, 4);
+ if (DoC_is_MillenniumPlus(doc)) {
+ DoC_Delay(doc, 4);
- if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B))
- /* Call the out-of-line routine to wait */
- ret = _DoC_WaitReady(doc);
+ if ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK)
+ /* Call the out-of-line routine to wait */
+ ret = _DoC_WaitReady(doc);
+ } else {
+ DoC_Delay(doc, 4);
+
+ if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B))
+ /* Call the out-of-line routine to wait */
+ ret = _DoC_WaitReady(doc);
+ DoC_Delay(doc, 2);
+ }
- DoC_Delay(doc, 2);
if(debug) printk("DoC_WaitReady OK\n");
return ret;
}
@@ -409,15 +438,126 @@ static int doc2001_verifybuf(struct mtd_info *mtd,
return 0;
}
-static void doc200x_select_chip(struct mtd_info *mtd, int chip)
+static u_char doc2001plus_read_byte(struct mtd_info *mtd)
+{
+ struct nand_chip *this = mtd->priv;
+ struct doc_priv *doc = (void *)this->priv;
+ unsigned long docptr = doc->virtadr;
+ u_char ret;
+
+ ReadDOC(docptr, Mplus_ReadPipeInit);
+ ReadDOC(docptr, Mplus_ReadPipeInit);
+ ret = ReadDOC(docptr, Mplus_LastDataRead);
+ if (debug) printk("read_byte returns %02x\n", ret);
+ return ret;
+}
+
+static void doc2001plus_writebuf(struct mtd_info *mtd,
+ const u_char *buf, int len)
+{
+ struct nand_chip *this = mtd->priv;
+ struct doc_priv *doc = (void *)this->priv;
+ unsigned long docptr = doc->virtadr;
+ int i;
+
+ if (debug)printk("writebuf of %d bytes: ", len);
+ for (i=0; i < len; i++) {
+ WriteDOC_(buf[i], docptr, DoC_Mil_CDSN_IO + i);
+ if (debug && i < 16)
+ printk("%02x ", buf[i]);
+ }
+ if (debug) printk("\n");
+}
+
+static void doc2001plus_readbuf(struct mtd_info *mtd,
+ u_char *buf, int len)
+{
+ struct nand_chip *this = mtd->priv;
+ struct doc_priv *doc = (void *)this->priv;
+ unsigned long docptr = doc->virtadr;
+ int i;
+
+ if (debug)printk("readbuf of %d bytes: ", len);
+
+ /* Start read pipeline */
+ ReadDOC(docptr, Mplus_ReadPipeInit);
+ ReadDOC(docptr, Mplus_ReadPipeInit);
+
+ for (i=0; i < len-2; i++) {
+ buf[i] = ReadDOC(docptr, Mil_CDSN_IO);
+ if (debug && i < 16)
+ printk("%02x ", buf[i]);
+ }
+
+ /* Terminate read pipeline */
+ buf[len-2] = ReadDOC(docptr, Mplus_LastDataRead);
+ if (debug && i < 16)
+ printk("%02x ", buf[len-2]);
+ buf[len-1] = ReadDOC(docptr, Mplus_LastDataRead);
+ if (debug && i < 16)
+ printk("%02x ", buf[len-1]);
+ if (debug) printk("\n");
+}
+
+static int doc2001plus_verifybuf(struct mtd_info *mtd,
+ const u_char *buf, int len)
+{
+ struct nand_chip *this = mtd->priv;
+ struct doc_priv *doc = (void *)this->priv;
+ unsigned long docptr = doc->virtadr;
+ int i;
+
+ if (debug)printk("verifybuf of %d bytes: ", len);
+
+ /* Start read pipeline */
+ ReadDOC(docptr, Mplus_ReadPipeInit);
+ ReadDOC(docptr, Mplus_ReadPipeInit);
+
+ for (i=0; i < len-2; i++)
+ if (buf[i] != ReadDOC(docptr, Mil_CDSN_IO)) {
+ ReadDOC(docptr, Mplus_LastDataRead);
+ ReadDOC(docptr, Mplus_LastDataRead);
+ return i;
+ }
+ if (buf[len-2] != ReadDOC(docptr, Mplus_LastDataRead))
+ return len-2;
+ if (buf[len-1] != ReadDOC(docptr, Mplus_LastDataRead))
+ return len-1;
+ return 0;
+}
+
+static void doc2001plus_select_chip(struct mtd_info *mtd, int chip)
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = (void *)this->priv;
unsigned long docptr = doc->virtadr;
int floor = 0;
- /* 11.4.4 -- deassert CE before changing chip */
- doc200x_hwcontrol(mtd, NAND_CTL_CLRNCE);
+ if(debug)printk("select chip (%d)\n", chip);
+
+ if (chip == -1) {
+ /* Disable flash internally */
+ WriteDOC(0, docptr, Mplus_FlashSelect);
+ return;
+ }
+
+ floor = chip / doc->chips_per_floor;
+ chip -= (floor * doc->chips_per_floor);
+
+ /* Assert ChipEnable and deassert WriteProtect */
+ WriteDOC((DOC_FLASH_CE), docptr, Mplus_FlashSelect);
+ this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
+
+ doc->curchip = chip;
+ doc->curfloor = floor;
+}
+
+static void doc200x_select_chip(struct mtd_info *mtd, int chip)
+{
+ struct nand_chip *this = mtd->priv;
+ struct doc_priv *doc = (void *)this->priv;
+ unsigned long docptr = doc->virtadr;
+ int floor = 0;
if(debug)printk("select chip (%d)\n", chip);
@@ -427,6 +567,9 @@ static void doc200x_select_chip(struct mtd_info *mtd, int chip)
floor = chip / doc->chips_per_floor;
chip -= (floor * doc->chips_per_floor);
+ /* 11.4.4 -- deassert CE before changing chip */
+ doc200x_hwcontrol(mtd, NAND_CTL_CLRNCE);
+
WriteDOC(floor, docptr, FloorSelect);
WriteDOC(chip, docptr, CDSNDeviceSelect);
@@ -474,24 +617,140 @@ static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd)
DoC_Delay(doc, 4);
}
+static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
+{
+ struct nand_chip *this = mtd->priv;
+ struct doc_priv *doc = (void *)this->priv;
+ unsigned long docptr = doc->virtadr;
+
+ /*
+ * Must terminate write pipeline before sending any commands
+ * to the device.
+ */
+ if (command == NAND_CMD_PAGEPROG) {
+ WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
+ WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
+ }
+
+ /*
+ * Write out the command to the device.
+ */
+ if (command == NAND_CMD_SEQIN) {
+ int readcmd;
+
+ if (column >= mtd->oobblock) {
+ /* OOB area */
+ column -= mtd->oobblock;
+ readcmd = NAND_CMD_READOOB;
+ } else if (column < 256) {
+ /* First 256 bytes --> READ0 */
+ readcmd = NAND_CMD_READ0;
+ } else {
+ column -= 256;
+ readcmd = NAND_CMD_READ1;
+ }
+ WriteDOC(readcmd, docptr, Mplus_FlashCmd);
+ }
+ WriteDOC(command, docptr, Mplus_FlashCmd);
+ WriteDOC(0, docptr, Mplus_WritePipeTerm);
+ WriteDOC(0, docptr, Mplus_WritePipeTerm);
+
+ if (column != -1 || page_addr != -1) {
+ /* Serially input address */
+ if (column != -1) {
+ /* Adjust columns for 16 bit buswidth */
+ if (this->options & NAND_BUSWIDTH_16)
+ column >>= 1;
+ WriteDOC(column, docptr, Mplus_FlashAddress);
+ }
+ if (page_addr != -1) {
+ WriteDOC((unsigned char) (page_addr & 0xff), docptr, Mplus_FlashAddress);
+ WriteDOC((unsigned char) ((page_addr >> 8) & 0xff), docptr, Mplus_FlashAddress);
+ /* One more address cycle for higher density devices */
+ if (this->chipsize & 0x0c000000) {
+ WriteDOC((unsigned char) ((page_addr >> 16) & 0x0f), docptr, Mplus_FlashAddress);
+ printk("high density\n");
+ }
+ }
+ WriteDOC(0, docptr, Mplus_WritePipeTerm);
+ WriteDOC(0, docptr, Mplus_WritePipeTerm);
+ /* deassert ALE */
+ if (command == NAND_CMD_READ0 || command == NAND_CMD_READ1 || command == NAND_CMD_READOOB || command == NAND_CMD_READID)
+ WriteDOC(0, docptr, Mplus_FlashControl);
+ }
+
+ /*
+ * program and erase have their own busy handlers
+ * status and sequential in needs no delay
+ */
+ switch (command) {
+
+ case NAND_CMD_PAGEPROG:
+ case NAND_CMD_ERASE1:
+ case NAND_CMD_ERASE2:
+ case NAND_CMD_SEQIN:
+ case NAND_CMD_STATUS:
+ return;
+
+ case NAND_CMD_RESET:
+ if (this->dev_ready)
+ break;
+ udelay(this->chip_delay);
+ WriteDOC(NAND_CMD_STATUS, docptr, Mplus_FlashCmd);
+ WriteDOC(0, docptr, Mplus_WritePipeTerm);
+ WriteDOC(0, docptr, Mplus_WritePipeTerm);
+ while ( !(this->read_byte(mtd) & 0x40));
+ return;
+
+ /* This applies to read commands */
+ default:
+ /*
+ * If we don't have access to the busy pin, we apply the given
+ * command delay
+ */
+ if (!this->dev_ready) {
+ udelay (this->chip_delay);
+ return;
+ }
+ }
+
+ /* Apply this short delay always to ensure that we do wait tWB in
+ * any case on any machine. */
+ ndelay (100);
+ /* wait until command is processed */
+ while (!this->dev_ready(mtd));
+}
+
static int doc200x_dev_ready(struct mtd_info *mtd)
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = (void *)this->priv;
unsigned long docptr = doc->virtadr;
- /* 11.4.2 -- must NOP four times before checking FR/B# */
- DoC_Delay(doc, 4);
- if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
- if(debug)
- printk("not ready\n");
- return 0;
+ if (DoC_is_MillenniumPlus(doc)) {
+ /* 11.4.2 -- must NOP four times before checking FR/B# */
+ DoC_Delay(doc, 4);
+ if ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) {
+ if(debug)
+ printk("not ready\n");
+ return 0;
+ }
+ if (debug)printk("was ready\n");
+ return 1;
+ } else {
+ /* 11.4.2 -- must NOP four times before checking FR/B# */
+ DoC_Delay(doc, 4);
+ if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
+ if(debug)
+ printk("not ready\n");
+ return 0;
+ }
+ /* 11.4.2 -- Must NOP twice if it's ready */
+ DoC_Delay(doc, 2);
+ if (debug)printk("was ready\n");
+ return 1;
}
- /* 11.4.2 -- Must NOP twice if it's ready */
- DoC_Delay(doc, 2);
- if (debug)printk("was ready\n");
- return 1;
-}
+}
static int doc200x_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
{
@@ -516,7 +775,26 @@ static void doc200x_enable_hwecc(struct mtd_info *mtd, int mode)
WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf);
break;
- }
+ }
+}
+
+static void doc2001plus_enable_hwecc(struct mtd_info *mtd, int mode)
+{
+ struct nand_chip *this = mtd->priv;
+ struct doc_priv *doc = (void *)this->priv;
+ unsigned long docptr = doc->virtadr;
+
+ /* Prime the ECC engine */
+ switch(mode) {
+ case NAND_ECC_READ:
+ WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
+ WriteDOC(DOC_ECC_EN, docptr, Mplus_ECCConf);
+ break;
+ case NAND_ECC_WRITE:
+ WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
+ WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, Mplus_ECCConf);
+ break;
+ }
}
/* This code is only called on write */
@@ -536,6 +814,10 @@ static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
WriteDOC(0, docptr, 2k_CDSN_IO);
WriteDOC(0, docptr, 2k_CDSN_IO);
WriteDOC(doc->CDSNControl, docptr, CDSNControl);
+ } else if (DoC_is_MillenniumPlus(doc)) {
+ WriteDOC(0, docptr, Mplus_NOP);
+ WriteDOC(0, docptr, Mplus_NOP);
+ WriteDOC(0, docptr, Mplus_NOP);
} else {
WriteDOC(0, docptr, NOP);
WriteDOC(0, docptr, NOP);
@@ -543,11 +825,17 @@ static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
}
for (i = 0; i < 6; i++) {
- ecc_code[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i);
+ if (DoC_is_MillenniumPlus(doc))
+ ecc_code[i] = ReadDOC_(docptr, DoC_Mplus_ECCSyndrome0 + i);
+ else
+ ecc_code[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i);
if (ecc_code[i] != empty_write_ecc[i])
emptymatch = 0;
}
- WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
+ if (DoC_is_MillenniumPlus(doc))
+ WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf);
+ else
+ WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
#if 0
/* If emptymatch=1, we might have an all-0xff data buffer. Check. */
if (emptymatch) {
@@ -582,6 +870,10 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
dummy = ReadDOC(docptr, 2k_ECCStatus);
dummy = ReadDOC(docptr, 2k_ECCStatus);
dummy = ReadDOC(docptr, 2k_ECCStatus);
+ } else if (DoC_is_MillenniumPlus(doc)) {
+ dummy = ReadDOC(docptr, Mplus_ECCConf);
+ dummy = ReadDOC(docptr, Mplus_ECCConf);
+ dummy = ReadDOC(docptr, Mplus_ECCConf);
} else {
dummy = ReadDOC(docptr, ECCConf);
dummy = ReadDOC(docptr, ECCConf);
@@ -591,7 +883,10 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
/* Error occured ? */
if (dummy & 0x80) {
for (i = 0; i < 6; i++) {
- calc_ecc[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i);
+ if (DoC_is_MillenniumPlus(doc))
+ calc_ecc[i] = ReadDOC_(docptr, DoC_Mplus_ECCSyndrome0 + i);
+ else
+ calc_ecc[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i);
if (calc_ecc[i] != empty_read_syndrome[i])
emptymatch = 0;
}
@@ -623,7 +918,10 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
if (ret > 0)
printk(KERN_ERR "doc200x_correct_data corrected %d errors\n", ret);
}
- WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
+ if (DoC_is_MillenniumPlus(doc))
+ WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf);
+ else
+ WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
if (no_ecc_failures && (ret == -1)) {
printk(KERN_ERR "suppressing ECC failure\n");
ret = 0;
@@ -694,13 +992,20 @@ static inline int __init nftl_partscan(struct mtd_info *mtd,
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = (void *)this->priv;
- u_char *buf = this->data_buf;
- struct NFTLMediaHeader *mh = (struct NFTLMediaHeader *) buf;
+ int ret = 0;
+ u_char *buf;
+ struct NFTLMediaHeader *mh;
const unsigned psize = 1 << this->page_shift;
unsigned blocks, maxblocks;
int offs, numheaders;
- if (!(numheaders=find_media_headers(mtd, buf, "ANAND", 1))) return 0;
+ buf = kmalloc(mtd->oobblock, GFP_KERNEL);
+ if (!buf) {
+ printk(KERN_ERR "DiskOnChip mediaheader kmalloc failed!\n");
+ return 0;
+ }
+ if (!(numheaders=find_media_headers(mtd, buf, "ANAND", 1))) goto out;
+ mh = (struct NFTLMediaHeader *) buf;
//#ifdef CONFIG_MTD_DEBUG_VERBOSE
// if (CONFIG_MTD_DEBUG_VERBOSE >= 2)
@@ -747,7 +1052,7 @@ static inline int __init nftl_partscan(struct mtd_info *mtd,
if (blocks > maxblocks) {
printk(KERN_ERR "UnitSizeFactor of 0x%02x is inconsistent with device size. Aborting.\n", mh->UnitSizeFactor);
- return 0;
+ goto out;
}
/* Skip past the media headers. */
@@ -768,9 +1073,13 @@ static inline int __init nftl_partscan(struct mtd_info *mtd,
parts[1].name = " DiskOnChip Remainder partition";
parts[1].offset = offs;
parts[1].size = mtd->size - offs;
- return 2;
+ ret = 2;
+ goto out;
}
- return 1;
+ ret = 1;
+out:
+ kfree(buf);
+ return ret;
}
/* This is a stripped-down copy of the code in inftlmount.c */
@@ -779,8 +1088,9 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = (void *)this->priv;
- u_char *buf = this->data_buf;
- struct INFTLMediaHeader *mh = (struct INFTLMediaHeader *) buf;
+ int ret = 0;
+ u_char *buf;
+ struct INFTLMediaHeader *mh;
struct INFTLPartition *ip;
int numparts = 0;
int blocks;
@@ -791,8 +1101,15 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,
if (inftl_bbt_write)
end -= (INFTL_BBT_RESERVED_BLOCKS << this->phys_erase_shift);
- if (!find_media_headers(mtd, buf, "BNAND", 0)) return 0;
+ buf = kmalloc(mtd->oobblock, GFP_KERNEL);
+ if (!buf) {
+ printk(KERN_ERR "DiskOnChip mediaheader kmalloc failed!\n");
+ return 0;
+ }
+
+ if (!find_media_headers(mtd, buf, "BNAND", 0)) goto out;
doc->mh1_page = doc->mh0_page + (4096 >> this->page_shift);
+ mh = (struct INFTLMediaHeader *) buf;
mh->NoOfBootImageBlocks = le32_to_cpu(mh->NoOfBootImageBlocks);
mh->NoOfBinaryPartitions = le32_to_cpu(mh->NoOfBinaryPartitions);
@@ -809,13 +1126,17 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,
" NoOfBDTLPartitions = %d\n"
" BlockMultiplerBits = %d\n"
" FormatFlgs = %d\n"
- " OsakVersion = 0x%x\n"
+ " OsakVersion = %d.%d.%d.%d\n"
" PercentUsed = %d\n",
mh->bootRecordID, mh->NoOfBootImageBlocks,
mh->NoOfBinaryPartitions,
mh->NoOfBDTLPartitions,
mh->BlockMultiplierBits, mh->FormatFlags,
- mh->OsakVersion, mh->PercentUsed);
+ ((unsigned char *) &mh->OsakVersion)[0] & 0xf,
+ ((unsigned char *) &mh->OsakVersion)[1] & 0xf,
+ ((unsigned char *) &mh->OsakVersion)[2] & 0xf,
+ ((unsigned char *) &mh->OsakVersion)[3] & 0xf,
+ mh->PercentUsed);
//#endif
vshift = this->phys_erase_shift + mh->BlockMultiplierBits;
@@ -823,13 +1144,13 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,
blocks = mtd->size >> vshift;
if (blocks > 32768) {
printk(KERN_ERR "BlockMultiplierBits=%d is inconsistent with device size. Aborting.\n", mh->BlockMultiplierBits);
- return 0;
+ goto out;
}
blocks = doc->chips_per_floor << (this->chip_shift - this->phys_erase_shift);
if (inftl_bbt_write && (blocks > mtd->erasesize)) {
printk(KERN_ERR "Writeable BBTs spanning more than one erase block are not yet supported. FIX ME!\n");
- return 0;
+ goto out;
}
/* Scan the partitions */
@@ -881,7 +1202,10 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,
parts[numparts].size = end - parts[numparts].offset;
numparts++;
}
- return numparts;
+ ret = numparts;
+out:
+ kfree(buf);
+ return ret;
}
static int __init nftl_scan_bbt(struct mtd_info *mtd)
@@ -916,8 +1240,9 @@ static int __init nftl_scan_bbt(struct mtd_info *mtd)
if ((ret = nand_scan_bbt(mtd, NULL)))
return ret;
add_mtd_device(mtd);
-#if defined(CONFIG_MTD_PARTITIONS) || defined(CONFIG_MTD_PARTITIONS_MODULE)
- if (!no_autopart) add_mtd_partitions(mtd, parts, numparts);
+#ifdef CONFIG_MTD_PARTITIONS
+ if (!no_autopart)
+ add_mtd_partitions(mtd, parts, numparts);
#endif
return 0;
}
@@ -934,27 +1259,35 @@ static int __init inftl_scan_bbt(struct mtd_info *mtd)
return -EIO;
}
- this->bbt_td->options = NAND_BBT_LASTBLOCK | NAND_BBT_8BIT |
- NAND_BBT_VERSION;
- if (inftl_bbt_write)
- this->bbt_td->options |= NAND_BBT_WRITE;
- this->bbt_td->offs = 8;
- this->bbt_td->len = 8;
- this->bbt_td->veroffs = 7;
- this->bbt_td->maxblocks = INFTL_BBT_RESERVED_BLOCKS;
- this->bbt_td->reserved_block_code = 0x01;
- this->bbt_td->pattern = "MSYS_BBT";
-
- this->bbt_md->options = NAND_BBT_LASTBLOCK | NAND_BBT_8BIT |
- NAND_BBT_VERSION;
- if (inftl_bbt_write)
- this->bbt_md->options |= NAND_BBT_WRITE;
- this->bbt_md->offs = 8;
- this->bbt_md->len = 8;
- this->bbt_md->veroffs = 7;
- this->bbt_md->maxblocks = INFTL_BBT_RESERVED_BLOCKS;
- this->bbt_md->reserved_block_code = 0x01;
- this->bbt_md->pattern = "TBB_SYSM";
+ if (DoC_is_MillenniumPlus(doc)) {
+ this->bbt_td->options = NAND_BBT_2BIT | NAND_BBT_ABSPAGE;
+ if (inftl_bbt_write)
+ this->bbt_td->options |= NAND_BBT_WRITE;
+ this->bbt_td->pages[0] = 2;
+ this->bbt_md = NULL;
+ } else {
+ this->bbt_td->options = NAND_BBT_LASTBLOCK | NAND_BBT_8BIT |
+ NAND_BBT_VERSION;
+ if (inftl_bbt_write)
+ this->bbt_td->options |= NAND_BBT_WRITE;
+ this->bbt_td->offs = 8;
+ this->bbt_td->len = 8;
+ this->bbt_td->veroffs = 7;
+ this->bbt_td->maxblocks = INFTL_BBT_RESERVED_BLOCKS;
+ this->bbt_td->reserved_block_code = 0x01;
+ this->bbt_td->pattern = "MSYS_BBT";
+
+ this->bbt_md->options = NAND_BBT_LASTBLOCK | NAND_BBT_8BIT |
+ NAND_BBT_VERSION;
+ if (inftl_bbt_write)
+ this->bbt_md->options |= NAND_BBT_WRITE;
+ this->bbt_md->offs = 8;
+ this->bbt_md->len = 8;
+ this->bbt_md->veroffs = 7;
+ this->bbt_md->maxblocks = INFTL_BBT_RESERVED_BLOCKS;
+ this->bbt_md->reserved_block_code = 0x01;
+ this->bbt_md->pattern = "TBB_SYSM";
+ }
/* It's safe to set bd=NULL below because NAND_BBT_CREATE is not set.
At least as nand_bbt.c is currently written. */
@@ -967,8 +1300,9 @@ static int __init inftl_scan_bbt(struct mtd_info *mtd)
autopartitioning, but I want to give it more thought. */
if (!numparts) return -EIO;
add_mtd_device(mtd);
-#if defined(CONFIG_MTD_PARTITIONS) || defined(CONFIG_MTD_PARTITIONS_MODULE)
- if (!no_autopart) add_mtd_partitions(mtd, parts, numparts);
+#ifdef CONFIG_MTD_PARTITIONS
+ if (!no_autopart)
+ add_mtd_partitions(mtd, parts, numparts);
#endif
return 0;
}
@@ -1023,6 +1357,28 @@ static inline int __init doc2001_init(struct mtd_info *mtd)
}
}
+static inline int __init doc2001plus_init(struct mtd_info *mtd)
+{
+ struct nand_chip *this = mtd->priv;
+ struct doc_priv *doc = (void *)this->priv;
+
+ this->write_byte = NULL;
+ this->read_byte = doc2001plus_read_byte;
+ this->write_buf = doc2001plus_writebuf;
+ this->read_buf = doc2001plus_readbuf;
+ this->verify_buf = doc2001plus_verifybuf;
+ this->scan_bbt = inftl_scan_bbt;
+ this->hwcontrol = NULL;
+ this->select_chip = doc2001plus_select_chip;
+ this->cmdfunc = doc2001plus_command;
+ this->enable_hwecc = doc2001plus_enable_hwecc;
+
+ doc->chips_per_floor = 1;
+ mtd->name = "DiskOnChip Millennium Plus";
+
+ return 1;
+}
+
static inline int __init doc_probe(unsigned long physadr)
{
unsigned char ChipID;
@@ -1072,6 +1428,42 @@ static inline int __init doc_probe(unsigned long physadr)
case DOC_ChipID_DocMil:
reg = DoC_ECCConf;
break;
+ case DOC_ChipID_DocMilPlus16:
+ case DOC_ChipID_DocMilPlus32:
+ case 0:
+ /* Possible Millennium Plus, need to do more checks */
+ /* Possibly release from power down mode */
+ for (tmp = 0; (tmp < 4); tmp++)
+ ReadDOC(virtadr, Mplus_Power);
+
+ /* Reset the Millennium Plus ASIC */
+ tmp = DOC_MODE_RESET | DOC_MODE_MDWREN | DOC_MODE_RST_LAT |
+ DOC_MODE_BDECT;
+ WriteDOC(tmp, virtadr, Mplus_DOCControl);
+ WriteDOC(~tmp, virtadr, Mplus_CtrlConfirm);
+
+ mdelay(1);
+ /* Enable the Millennium Plus ASIC */
+ tmp = DOC_MODE_NORMAL | DOC_MODE_MDWREN | DOC_MODE_RST_LAT |
+ DOC_MODE_BDECT;
+ WriteDOC(tmp, virtadr, Mplus_DOCControl);
+ WriteDOC(~tmp, virtadr, Mplus_CtrlConfirm);
+ mdelay(1);
+
+ ChipID = ReadDOC(virtadr, ChipID);
+
+ switch (ChipID) {
+ case DOC_ChipID_DocMilPlus16:
+ reg = DoC_Mplus_Toggle;
+ break;
+ case DOC_ChipID_DocMilPlus32:
+ printk(KERN_ERR "DiskOnChip Millennium Plus 32MB is not supported, ignoring.\n");
+ default:
+ ret = -ENODEV;
+ goto notfound;
+ }
+ break;
+
default:
ret = -ENODEV;
goto notfound;
@@ -1095,16 +1487,27 @@ static inline int __init doc_probe(unsigned long physadr)
in fact the same DOC aliased to a new address. If writes
to one chip's alias resolution register change the value on
the other chip, they're the same chip. */
- oldval = ReadDOC(doc->virtadr, AliasResolution);
- newval = ReadDOC(virtadr, AliasResolution);
+ if (ChipID == DOC_ChipID_DocMilPlus16) {
+ oldval = ReadDOC(doc->virtadr, Mplus_AliasResolution);
+ newval = ReadDOC(virtadr, Mplus_AliasResolution);
+ } else {
+ oldval = ReadDOC(doc->virtadr, AliasResolution);
+ newval = ReadDOC(virtadr, AliasResolution);
+ }
if (oldval != newval)
continue;
- WriteDOC(~newval, virtadr, AliasResolution);
- oldval = ReadDOC(doc->virtadr, AliasResolution);
- WriteDOC(newval, virtadr, AliasResolution); // restore it
+ if (ChipID == DOC_ChipID_DocMilPlus16) {
+ WriteDOC(~newval, virtadr, Mplus_AliasResolution);
+ oldval = ReadDOC(doc->virtadr, Mplus_AliasResolution);
+ WriteDOC(newval, virtadr, Mplus_AliasResolution); // restore it
+ } else {
+ WriteDOC(~newval, virtadr, AliasResolution);
+ oldval = ReadDOC(doc->virtadr, AliasResolution);
+ WriteDOC(newval, virtadr, AliasResolution); // restore it
+ }
newval = ~newval;
if (oldval == newval) {
- //printk(KERN_DEBUG "Found alias of DOC at 0x%lx to 0x%lx\n", doc->physadr, physadr);
+ printk(KERN_DEBUG "Found alias of DOC at 0x%lx to 0x%lx\n", doc->physadr, physadr);
goto notfound;
}
}
@@ -1156,6 +1559,8 @@ static inline int __init doc_probe(unsigned long physadr)
if (ChipID == DOC_ChipID_Doc2k)
numchips = doc2000_init(mtd);
+ else if (ChipID == DOC_ChipID_DocMilPlus16)
+ numchips = doc2001plus_init(mtd);
else
numchips = doc2001_init(mtd);
@@ -1221,10 +1626,10 @@ void __exit cleanup_nanddoc(void)
kfree(mtd);
}
}
-
+
module_init(init_nanddoc);
module_exit(cleanup_nanddoc);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
-MODULE_DESCRIPTION("M-Systems DiskOnChip 2000 and Millennium device driver\n");
+MODULE_DESCRIPTION("M-Systems DiskOnChip 2000, Millennium and Millennium Plus device driver\n");
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 596bc8f70188bd..ff6adf43f73a40 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -37,7 +37,7 @@
* The AG-AND chips have nice features for speed improvement,
* which are not supported yet. Read / program 4 pages in one go.
*
- * $Id: nand_base.c,v 1.113 2004/07/14 16:31:31 gleixner Exp $
+ * $Id: nand_base.c,v 1.115 2004/08/09 13:19:45 dwmw2 Exp $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -58,7 +58,7 @@
#include <linux/bitops.h>
#include <asm/io.h>
-#if defined(CONFIG_MTD_PARTITIONS) || defined(CONFIG_MTD_PARTITIONS_MODULE)
+#ifdef CONFIG_MTD_PARTITIONS
#include <linux/mtd/partitions.h>
#endif
@@ -1284,12 +1284,12 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
nand_release_chip(mtd);
/*
- * Return success, if no ECC failures, else -EIO
+ * Return success, if no ECC failures, else -EBADMSG
* fs driver will take care of that, because
- * retlen == desired len and result == -EIO
+ * retlen == desired len and result == -EBADMSG
*/
*retlen = read;
- return ecc_failed ? -EIO : 0;
+ return ecc_failed ? -EBADMSG : 0;
}
/**
@@ -2108,8 +2108,8 @@ erase_exit:
ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
/* Do call back function */
- if (!ret && instr->callback)
- instr->callback (instr);
+ if (!ret)
+ mtd_erase_callback(instr);
/* Deselect and wake up anyone waiting on the device */
nand_release_chip(mtd);
@@ -2555,11 +2555,11 @@ void nand_release (struct mtd_info *mtd)
{
struct nand_chip *this = mtd->priv;
-#if defined(CONFIG_MTD_PARTITIONS) || defined(CONFIG_MTD_PARTITIONS_MODULE)
- /* Unregister partitions */
+#ifdef CONFIG_MTD_PARTITIONS
+ /* Deregister partitions */
del_mtd_partitions (mtd);
#endif
- /* Unregister the device */
+ /* Deregister the device */
del_mtd_device (mtd);
/* Free bad block table memory, if allocated */
diff --git a/drivers/mtd/redboot.c b/drivers/mtd/redboot.c
index 626ad368ecc2d5..0212a7df84c4d2 100644
--- a/drivers/mtd/redboot.c
+++ b/drivers/mtd/redboot.c
@@ -1,5 +1,5 @@
/*
- * $Id: redboot.c,v 1.13 2004/04/01 10:17:40 gthomas Exp $
+ * $Id: redboot.c,v 1.15 2004/08/10 07:55:16 dwmw2 Exp $
*
* Parse RedBoot-style Flash Image System (FIS) tables and
* produce a Linux partition array to match.
@@ -8,6 +8,7 @@
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/init.h>
+#include <linux/vmalloc.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
@@ -53,7 +54,7 @@ static int parse_redboot_partitions(struct mtd_info *master,
static char nullstring[] = "unallocated";
#endif
- buf = kmalloc(master->erasesize, GFP_KERNEL);
+ buf = vmalloc(master->erasesize);
if (!buf)
return -ENOMEM;
@@ -190,7 +191,7 @@ static int parse_redboot_partitions(struct mtd_info *master,
fl = fl->next;
kfree(old);
}
- kfree(buf);
+ vfree(buf);
return ret;
}