aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/Kconfig8
-rw-r--r--drivers/mtd/Makefile1
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c14
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0002.c2
-rw-r--r--drivers/mtd/chips/jedec_probe.c37
-rw-r--r--drivers/mtd/devices/Kconfig17
-rw-r--r--drivers/mtd/devices/docprobe.c4
-rw-r--r--drivers/mtd/devices/m25p80.c271
-rw-r--r--drivers/mtd/devices/mtd_dataflash.c17
-rw-r--r--drivers/mtd/devices/pmc551.c27
-rw-r--r--drivers/mtd/inftlmount.c3
-rw-r--r--drivers/mtd/maps/alchemy-flash.c14
-rw-r--r--drivers/mtd/maps/nettel.c65
-rw-r--r--drivers/mtd/maps/physmap_of.c5
-rw-r--r--drivers/mtd/maps/pmcmsp-flash.c22
-rw-r--r--drivers/mtd/maps/pmcmsp-ramroot.c1
-rw-r--r--drivers/mtd/mtd_blkdevs.c7
-rw-r--r--drivers/mtd/mtdchar.c3
-rw-r--r--drivers/mtd/mtdconcat.c2
-rw-r--r--drivers/mtd/mtdcore.c2
-rw-r--r--drivers/mtd/mtdcore.h11
-rw-r--r--drivers/mtd/mtdoops.c376
-rw-r--r--drivers/mtd/nand/Kconfig6
-rw-r--r--drivers/mtd/nand/at91_nand.c5
-rw-r--r--drivers/mtd/nand/diskonchip.c2
-rw-r--r--drivers/mtd/nand/edb7312.c10
-rw-r--r--drivers/mtd/nand/excite_nandflash.c1
-rw-r--r--drivers/mtd/nand/nand_base.c14
-rw-r--r--drivers/mtd/nand/nand_ids.c1
-rw-r--r--drivers/mtd/nand/ndfc.c8
-rw-r--r--drivers/mtd/onenand/Kconfig23
-rw-r--r--drivers/mtd/onenand/Makefile3
-rw-r--r--drivers/mtd/onenand/onenand_base.c139
-rw-r--r--drivers/mtd/onenand/onenand_sim.c495
-rw-r--r--drivers/mtd/rfd_ftl.c7
-rw-r--r--drivers/mtd/ubi/scan.c17
36 files changed, 1371 insertions, 269 deletions
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index fbec8cd55e38..8848e8ac705d 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -278,6 +278,14 @@ config SSFDC
278 This enables read only access to SmartMedia formatted NAND 278 This enables read only access to SmartMedia formatted NAND
279 flash. You can mount it with FAT file system. 279 flash. You can mount it with FAT file system.
280 280
281config MTD_OOPS
282 tristate "Log panic/oops to an MTD buffer"
283 depends on MTD
284 help
285 This enables panic and oops messages to be logged to a circular
286 buffer in a flash partition where it can be read back at some
287 later point.
288
281source "drivers/mtd/chips/Kconfig" 289source "drivers/mtd/chips/Kconfig"
282 290
283source "drivers/mtd/maps/Kconfig" 291source "drivers/mtd/maps/Kconfig"
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index 451adcc52b3c..024d0e5e3e5d 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_NFTL) += nftl.o
22obj-$(CONFIG_INFTL) += inftl.o 22obj-$(CONFIG_INFTL) += inftl.o
23obj-$(CONFIG_RFD_FTL) += rfd_ftl.o 23obj-$(CONFIG_RFD_FTL) += rfd_ftl.o
24obj-$(CONFIG_SSFDC) += ssfdc.o 24obj-$(CONFIG_SSFDC) += ssfdc.o
25obj-$(CONFIG_MTD_OOPS) += mtdoops.o
25 26
26nftl-objs := nftlcore.o nftlmount.o 27nftl-objs := nftlcore.o nftlmount.o
27inftl-objs := inftlcore.o inftlmount.o 28inftl-objs := inftlcore.o inftlmount.o
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index 2f19fa78d24a..39eff9ff575c 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -526,7 +526,7 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
526 struct cfi_pri_intelext *extp = cfi->cmdset_priv; 526 struct cfi_pri_intelext *extp = cfi->cmdset_priv;
527 527
528 /* 528 /*
529 * Probing of multi-partition flash ships. 529 * Probing of multi-partition flash chips.
530 * 530 *
531 * To support multiple partitions when available, we simply arrange 531 * To support multiple partitions when available, we simply arrange
532 * for each of them to have their own flchip structure even if they 532 * for each of them to have their own flchip structure even if they
@@ -1780,7 +1780,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
1780 return ret; 1780 return ret;
1781} 1781}
1782 1782
1783int cfi_intelext_erase_varsize(struct mtd_info *mtd, struct erase_info *instr) 1783static int cfi_intelext_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
1784{ 1784{
1785 unsigned long ofs, len; 1785 unsigned long ofs, len;
1786 int ret; 1786 int ret;
@@ -1930,7 +1930,7 @@ static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
1930 printk(KERN_DEBUG "%s: lock status before, ofs=0x%08llx, len=0x%08X\n", 1930 printk(KERN_DEBUG "%s: lock status before, ofs=0x%08llx, len=0x%08X\n",
1931 __FUNCTION__, ofs, len); 1931 __FUNCTION__, ofs, len);
1932 cfi_varsize_frob(mtd, do_printlockstatus_oneblock, 1932 cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
1933 ofs, len, 0); 1933 ofs, len, NULL);
1934#endif 1934#endif
1935 1935
1936 ret = cfi_varsize_frob(mtd, do_xxlock_oneblock, 1936 ret = cfi_varsize_frob(mtd, do_xxlock_oneblock,
@@ -1940,7 +1940,7 @@ static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
1940 printk(KERN_DEBUG "%s: lock status after, ret=%d\n", 1940 printk(KERN_DEBUG "%s: lock status after, ret=%d\n",
1941 __FUNCTION__, ret); 1941 __FUNCTION__, ret);
1942 cfi_varsize_frob(mtd, do_printlockstatus_oneblock, 1942 cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
1943 ofs, len, 0); 1943 ofs, len, NULL);
1944#endif 1944#endif
1945 1945
1946 return ret; 1946 return ret;
@@ -1954,7 +1954,7 @@ static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
1954 printk(KERN_DEBUG "%s: lock status before, ofs=0x%08llx, len=0x%08X\n", 1954 printk(KERN_DEBUG "%s: lock status before, ofs=0x%08llx, len=0x%08X\n",
1955 __FUNCTION__, ofs, len); 1955 __FUNCTION__, ofs, len);
1956 cfi_varsize_frob(mtd, do_printlockstatus_oneblock, 1956 cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
1957 ofs, len, 0); 1957 ofs, len, NULL);
1958#endif 1958#endif
1959 1959
1960 ret = cfi_varsize_frob(mtd, do_xxlock_oneblock, 1960 ret = cfi_varsize_frob(mtd, do_xxlock_oneblock,
@@ -1964,7 +1964,7 @@ static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
1964 printk(KERN_DEBUG "%s: lock status after, ret=%d\n", 1964 printk(KERN_DEBUG "%s: lock status after, ret=%d\n",
1965 __FUNCTION__, ret); 1965 __FUNCTION__, ret);
1966 cfi_varsize_frob(mtd, do_printlockstatus_oneblock, 1966 cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
1967 ofs, len, 0); 1967 ofs, len, NULL);
1968#endif 1968#endif
1969 1969
1970 return ret; 1970 return ret;
@@ -2255,7 +2255,7 @@ static void cfi_intelext_save_locks(struct mtd_info *mtd)
2255 adr = region->offset + block * len; 2255 adr = region->offset + block * len;
2256 2256
2257 status = cfi_varsize_frob(mtd, 2257 status = cfi_varsize_frob(mtd,
2258 do_getlockstatus_oneblock, adr, len, 0); 2258 do_getlockstatus_oneblock, adr, len, NULL);
2259 if (status) 2259 if (status)
2260 set_bit(block, region->lockmap); 2260 set_bit(block, region->lockmap);
2261 else 2261 else
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index 1f6445840461..389acc600f5e 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -1609,7 +1609,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
1609} 1609}
1610 1610
1611 1611
1612int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr) 1612static int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
1613{ 1613{
1614 unsigned long ofs, len; 1614 unsigned long ofs, len;
1615 int ret; 1615 int ret;
diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c
index 58e561e87699..a67b23b87fc0 100644
--- a/drivers/mtd/chips/jedec_probe.c
+++ b/drivers/mtd/chips/jedec_probe.c
@@ -17,7 +17,6 @@
17#include <linux/errno.h> 17#include <linux/errno.h>
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <linux/init.h>
21 20
22#include <linux/mtd/mtd.h> 21#include <linux/mtd/mtd.h>
23#include <linux/mtd/map.h> 22#include <linux/mtd/map.h>
@@ -70,6 +69,7 @@
70 69
71/* Fujitsu */ 70/* Fujitsu */
72#define MBM29F040C 0x00A4 71#define MBM29F040C 0x00A4
72#define MBM29F800BA 0x2258
73#define MBM29LV650UE 0x22D7 73#define MBM29LV650UE 0x22D7
74#define MBM29LV320TE 0x22F6 74#define MBM29LV320TE 0x22F6
75#define MBM29LV320BE 0x22F9 75#define MBM29LV320BE 0x22F9
@@ -129,6 +129,7 @@
129#define LH28F640BF 0x00b0 129#define LH28F640BF 0x00b0
130 130
131/* ST - www.st.com */ 131/* ST - www.st.com */
132#define M29F800AB 0x0058
132#define M29W800DT 0x00D7 133#define M29W800DT 0x00D7
133#define M29W800DB 0x005B 134#define M29W800DB 0x005B
134#define M29W160DT 0x22C4 135#define M29W160DT 0x22C4
@@ -646,6 +647,23 @@ static const struct amd_flash_info jedec_table[] = {
646 } 647 }
647 }, { 648 }, {
648 .mfr_id = MANUFACTURER_FUJITSU, 649 .mfr_id = MANUFACTURER_FUJITSU,
650 .dev_id = MBM29F800BA,
651 .name = "Fujitsu MBM29F800BA",
652 .uaddr = {
653 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
654 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
655 },
656 .DevSize = SIZE_1MiB,
657 .CmdSet = P_ID_AMD_STD,
658 .NumEraseRegions= 4,
659 .regions = {
660 ERASEINFO(0x04000,1),
661 ERASEINFO(0x02000,2),
662 ERASEINFO(0x08000,1),
663 ERASEINFO(0x10000,15),
664 }
665 }, {
666 .mfr_id = MANUFACTURER_FUJITSU,
649 .dev_id = MBM29LV650UE, 667 .dev_id = MBM29LV650UE,
650 .name = "Fujitsu MBM29LV650UE", 668 .name = "Fujitsu MBM29LV650UE",
651 .uaddr = { 669 .uaddr = {
@@ -1510,6 +1528,23 @@ static const struct amd_flash_info jedec_table[] = {
1510 ERASEINFO(0x1000,256) 1528 ERASEINFO(0x1000,256)
1511 } 1529 }
1512 1530
1531 }, {
1532 .mfr_id = MANUFACTURER_ST,
1533 .dev_id = M29F800AB,
1534 .name = "ST M29F800AB",
1535 .uaddr = {
1536 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1537 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
1538 },
1539 .DevSize = SIZE_1MiB,
1540 .CmdSet = P_ID_AMD_STD,
1541 .NumEraseRegions= 4,
1542 .regions = {
1543 ERASEINFO(0x04000,1),
1544 ERASEINFO(0x02000,2),
1545 ERASEINFO(0x08000,1),
1546 ERASEINFO(0x10000,15),
1547 }
1513 }, { 1548 }, {
1514 .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */ 1549 .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
1515 .dev_id = M29W800DT, 1550 .dev_id = M29W800DT,
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index ff642f8fbee7..b4ea64dc9360 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -69,12 +69,21 @@ config MTD_DATAFLASH26
69 If you have such a board and such a DataFlash, say 'Y'. 69 If you have such a board and such a DataFlash, say 'Y'.
70 70
71config MTD_M25P80 71config MTD_M25P80
72 tristate "Support for M25 SPI Flash" 72 tristate "Support most SPI Flash chips (AT26DF, M25P, W25X, ...)"
73 depends on SPI_MASTER && EXPERIMENTAL 73 depends on SPI_MASTER && EXPERIMENTAL
74 help 74 help
75 This enables access to ST M25P80 and similar SPI flash chips, 75 This enables access to most modern SPI flash chips, used for
76 used for program and data storage. Set up your spi devices 76 program and data storage. Series supported include Atmel AT26DF,
77 with the right board-specific platform data. 77 Spansion S25SL, SST 25VF, ST M25P, and Winbond W25X. Other chips
78 are supported as well. See the driver source for the current list,
79 or to add other chips.
80
81 Note that the original DataFlash chips (AT45 series, not AT26DF),
82 need an entirely different driver.
83
84 Set up your spi devices with the right board-specific platform data,
85 if you want to specify device partitioning or to use a device which
86 doesn't support the JEDEC ID instruction.
78 87
79config MTD_SLRAM 88config MTD_SLRAM
80 tristate "Uncached system RAM" 89 tristate "Uncached system RAM"
diff --git a/drivers/mtd/devices/docprobe.c b/drivers/mtd/devices/docprobe.c
index 54aa75907640..d8cc94ec4e50 100644
--- a/drivers/mtd/devices/docprobe.c
+++ b/drivers/mtd/devices/docprobe.c
@@ -81,9 +81,7 @@ static unsigned long __initdata doc_locations[] = {
81#endif /* CONFIG_MTD_DOCPROBE_HIGH */ 81#endif /* CONFIG_MTD_DOCPROBE_HIGH */
82#elif defined(__PPC__) 82#elif defined(__PPC__)
83 0xe4000000, 83 0xe4000000,
84#elif defined(CONFIG_MOMENCO_OCELOT_G) 84#else
85 0xff000000,
86##else
87#warning Unknown architecture for DiskOnChip. No default probe locations defined 85#warning Unknown architecture for DiskOnChip. No default probe locations defined
88#endif 86#endif
89 0xffffffff }; 87 0xffffffff };
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 78c2511ae9e0..98df5bcc02f3 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * MTD SPI driver for ST M25Pxx flash chips 2 * MTD SPI driver for ST M25Pxx (and similar) serial flash chips
3 * 3 *
4 * Author: Mike Lavender, mike@steroidmicros.com 4 * Author: Mike Lavender, mike@steroidmicros.com
5 * 5 *
@@ -19,33 +19,32 @@
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/device.h> 20#include <linux/device.h>
21#include <linux/interrupt.h> 21#include <linux/interrupt.h>
22#include <linux/interrupt.h> 22#include <linux/mutex.h>
23
23#include <linux/mtd/mtd.h> 24#include <linux/mtd/mtd.h>
24#include <linux/mtd/partitions.h> 25#include <linux/mtd/partitions.h>
26
25#include <linux/spi/spi.h> 27#include <linux/spi/spi.h>
26#include <linux/spi/flash.h> 28#include <linux/spi/flash.h>
27 29
28#include <asm/semaphore.h>
29
30
31/* NOTE: AT 25F and SST 25LF series are very similar,
32 * but commands for sector erase and chip id differ...
33 */
34 30
35#define FLASH_PAGESIZE 256 31#define FLASH_PAGESIZE 256
36 32
37/* Flash opcodes. */ 33/* Flash opcodes. */
38#define OPCODE_WREN 6 /* Write enable */ 34#define OPCODE_WREN 0x06 /* Write enable */
39#define OPCODE_RDSR 5 /* Read status register */ 35#define OPCODE_RDSR 0x05 /* Read status register */
40#define OPCODE_READ 3 /* Read data bytes */ 36#define OPCODE_READ 0x03 /* Read data bytes (low frequency) */
41#define OPCODE_PP 2 /* Page program */ 37#define OPCODE_FAST_READ 0x0b /* Read data bytes (high frequency) */
42#define OPCODE_SE 0xd8 /* Sector erase */ 38#define OPCODE_PP 0x02 /* Page program (up to 256 bytes) */
43#define OPCODE_RES 0xab /* Read Electronic Signature */ 39#define OPCODE_BE_4K 0x20 /* Erase 4KiB block */
40#define OPCODE_BE_32K 0x52 /* Erase 32KiB block */
41#define OPCODE_SE 0xd8 /* Sector erase (usually 64KiB) */
44#define OPCODE_RDID 0x9f /* Read JEDEC ID */ 42#define OPCODE_RDID 0x9f /* Read JEDEC ID */
45 43
46/* Status Register bits. */ 44/* Status Register bits. */
47#define SR_WIP 1 /* Write in progress */ 45#define SR_WIP 1 /* Write in progress */
48#define SR_WEL 2 /* Write enable latch */ 46#define SR_WEL 2 /* Write enable latch */
47/* meaning of other SR_* bits may differ between vendors */
49#define SR_BP0 4 /* Block protect 0 */ 48#define SR_BP0 4 /* Block protect 0 */
50#define SR_BP1 8 /* Block protect 1 */ 49#define SR_BP1 8 /* Block protect 1 */
51#define SR_BP2 0x10 /* Block protect 2 */ 50#define SR_BP2 0x10 /* Block protect 2 */
@@ -65,9 +64,10 @@
65 64
66struct m25p { 65struct m25p {
67 struct spi_device *spi; 66 struct spi_device *spi;
68 struct semaphore lock; 67 struct mutex lock;
69 struct mtd_info mtd; 68 struct mtd_info mtd;
70 unsigned partitioned; 69 unsigned partitioned:1;
70 u8 erase_opcode;
71 u8 command[4]; 71 u8 command[4];
72}; 72};
73 73
@@ -150,8 +150,9 @@ static int wait_till_ready(struct m25p *flash)
150 */ 150 */
151static int erase_sector(struct m25p *flash, u32 offset) 151static int erase_sector(struct m25p *flash, u32 offset)
152{ 152{
153 DEBUG(MTD_DEBUG_LEVEL3, "%s: %s at 0x%08x\n", flash->spi->dev.bus_id, 153 DEBUG(MTD_DEBUG_LEVEL3, "%s: %s %dKiB at 0x%08x\n",
154 __FUNCTION__, offset); 154 flash->spi->dev.bus_id, __FUNCTION__,
155 flash->mtd.erasesize / 1024, offset);
155 156
156 /* Wait until finished previous write command. */ 157 /* Wait until finished previous write command. */
157 if (wait_till_ready(flash)) 158 if (wait_till_ready(flash))
@@ -161,7 +162,7 @@ static int erase_sector(struct m25p *flash, u32 offset)
161 write_enable(flash); 162 write_enable(flash);
162 163
163 /* Set up command buffer. */ 164 /* Set up command buffer. */
164 flash->command[0] = OPCODE_SE; 165 flash->command[0] = flash->erase_opcode;
165 flash->command[1] = offset >> 16; 166 flash->command[1] = offset >> 16;
166 flash->command[2] = offset >> 8; 167 flash->command[2] = offset >> 8;
167 flash->command[3] = offset; 168 flash->command[3] = offset;
@@ -201,13 +202,17 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
201 addr = instr->addr; 202 addr = instr->addr;
202 len = instr->len; 203 len = instr->len;
203 204
204 down(&flash->lock); 205 mutex_lock(&flash->lock);
206
207 /* REVISIT in some cases we could speed up erasing large regions
208 * by using OPCODE_SE instead of OPCODE_BE_4K
209 */
205 210
206 /* now erase those sectors */ 211 /* now erase those sectors */
207 while (len) { 212 while (len) {
208 if (erase_sector(flash, addr)) { 213 if (erase_sector(flash, addr)) {
209 instr->state = MTD_ERASE_FAILED; 214 instr->state = MTD_ERASE_FAILED;
210 up(&flash->lock); 215 mutex_unlock(&flash->lock);
211 return -EIO; 216 return -EIO;
212 } 217 }
213 218
@@ -215,7 +220,7 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
215 len -= mtd->erasesize; 220 len -= mtd->erasesize;
216 } 221 }
217 222
218 up(&flash->lock); 223 mutex_unlock(&flash->lock);
219 224
220 instr->state = MTD_ERASE_DONE; 225 instr->state = MTD_ERASE_DONE;
221 mtd_erase_callback(instr); 226 mtd_erase_callback(instr);
@@ -260,16 +265,19 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
260 if (retlen) 265 if (retlen)
261 *retlen = 0; 266 *retlen = 0;
262 267
263 down(&flash->lock); 268 mutex_lock(&flash->lock);
264 269
265 /* Wait till previous write/erase is done. */ 270 /* Wait till previous write/erase is done. */
266 if (wait_till_ready(flash)) { 271 if (wait_till_ready(flash)) {
267 /* REVISIT status return?? */ 272 /* REVISIT status return?? */
268 up(&flash->lock); 273 mutex_unlock(&flash->lock);
269 return 1; 274 return 1;
270 } 275 }
271 276
272 /* NOTE: OPCODE_FAST_READ (if available) is faster... */ 277 /* FIXME switch to OPCODE_FAST_READ. It's required for higher
278 * clocks; and at this writing, every chip this driver handles
279 * supports that opcode.
280 */
273 281
274 /* Set up the write data buffer. */ 282 /* Set up the write data buffer. */
275 flash->command[0] = OPCODE_READ; 283 flash->command[0] = OPCODE_READ;
@@ -281,7 +289,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
281 289
282 *retlen = m.actual_length - sizeof(flash->command); 290 *retlen = m.actual_length - sizeof(flash->command);
283 291
284 up(&flash->lock); 292 mutex_unlock(&flash->lock);
285 293
286 return 0; 294 return 0;
287} 295}
@@ -323,7 +331,7 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
323 t[1].tx_buf = buf; 331 t[1].tx_buf = buf;
324 spi_message_add_tail(&t[1], &m); 332 spi_message_add_tail(&t[1], &m);
325 333
326 down(&flash->lock); 334 mutex_lock(&flash->lock);
327 335
328 /* Wait until finished previous write command. */ 336 /* Wait until finished previous write command. */
329 if (wait_till_ready(flash)) 337 if (wait_till_ready(flash))
@@ -381,10 +389,10 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
381 if (retlen) 389 if (retlen)
382 *retlen += m.actual_length 390 *retlen += m.actual_length
383 - sizeof(flash->command); 391 - sizeof(flash->command);
384 } 392 }
385 } 393 }
386 394
387 up(&flash->lock); 395 mutex_unlock(&flash->lock);
388 396
389 return 0; 397 return 0;
390} 398}
@@ -398,24 +406,118 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
398 406
399struct flash_info { 407struct flash_info {
400 char *name; 408 char *name;
401 u8 id; 409
402 u16 jedec_id; 410 /* JEDEC id zero means "no ID" (most older chips); otherwise it has
411 * a high byte of zero plus three data bytes: the manufacturer id,
412 * then a two byte device id.
413 */
414 u32 jedec_id;
415
416 /* The size listed here is what works with OPCODE_SE, which isn't
417 * necessarily called a "sector" by the vendor.
418 */
403 unsigned sector_size; 419 unsigned sector_size;
404 unsigned n_sectors; 420 u16 n_sectors;
421
422 u16 flags;
423#define SECT_4K 0x01 /* OPCODE_BE_4K works uniformly */
405}; 424};
406 425
426
427/* NOTE: double check command sets and memory organization when you add
428 * more flash chips. This current list focusses on newer chips, which
429 * have been converging on command sets which including JEDEC ID.
430 */
407static struct flash_info __devinitdata m25p_data [] = { 431static struct flash_info __devinitdata m25p_data [] = {
408 /* REVISIT: fill in JEDEC ids, for parts that have them */ 432
409 { "m25p05", 0x05, 0x2010, 32 * 1024, 2 }, 433 /* Atmel -- some are (confusingly) marketed as "DataFlash" */
410 { "m25p10", 0x10, 0x2011, 32 * 1024, 4 }, 434 { "at25fs010", 0x1f6601, 32 * 1024, 4, SECT_4K, },
411 { "m25p20", 0x11, 0x2012, 64 * 1024, 4 }, 435 { "at25fs040", 0x1f6604, 64 * 1024, 8, SECT_4K, },
412 { "m25p40", 0x12, 0x2013, 64 * 1024, 8 }, 436
413 { "m25p80", 0x13, 0x0000, 64 * 1024, 16 }, 437 { "at25df041a", 0x1f4401, 64 * 1024, 8, SECT_4K, },
414 { "m25p16", 0x14, 0x2015, 64 * 1024, 32 }, 438
415 { "m25p32", 0x15, 0x2016, 64 * 1024, 64 }, 439 { "at26f004", 0x1f0400, 64 * 1024, 8, SECT_4K, },
416 { "m25p64", 0x16, 0x2017, 64 * 1024, 128 }, 440 { "at26df081a", 0x1f4501, 64 * 1024, 16, SECT_4K, },
441 { "at26df161a", 0x1f4601, 64 * 1024, 32, SECT_4K, },
442 { "at26df321", 0x1f4701, 64 * 1024, 64, SECT_4K, },
443
444 /* Spansion -- single (large) sector size only, at least
445 * for the chips listed here (without boot sectors).
446 */
447 { "s25sl004a", 0x010212, 64 * 1024, 8, },
448 { "s25sl008a", 0x010213, 64 * 1024, 16, },
449 { "s25sl016a", 0x010214, 64 * 1024, 32, },
450 { "s25sl032a", 0x010215, 64 * 1024, 64, },
451 { "s25sl064a", 0x010216, 64 * 1024, 128, },
452
453 /* SST -- large erase sizes are "overlays", "sectors" are 4K */
454 { "sst25vf040b", 0xbf258d, 64 * 1024, 8, SECT_4K, },
455 { "sst25vf080b", 0xbf258e, 64 * 1024, 16, SECT_4K, },
456 { "sst25vf016b", 0xbf2541, 64 * 1024, 32, SECT_4K, },
457 { "sst25vf032b", 0xbf254a, 64 * 1024, 64, SECT_4K, },
458
459 /* ST Microelectronics -- newer production may have feature updates */
460 { "m25p05", 0x202010, 32 * 1024, 2, },
461 { "m25p10", 0x202011, 32 * 1024, 4, },
462 { "m25p20", 0x202012, 64 * 1024, 4, },
463 { "m25p40", 0x202013, 64 * 1024, 8, },
464 { "m25p80", 0, 64 * 1024, 16, },
465 { "m25p16", 0x202015, 64 * 1024, 32, },
466 { "m25p32", 0x202016, 64 * 1024, 64, },
467 { "m25p64", 0x202017, 64 * 1024, 128, },
468 { "m25p128", 0x202018, 256 * 1024, 64, },
469
470 { "m45pe80", 0x204014, 64 * 1024, 16, },
471 { "m45pe16", 0x204015, 64 * 1024, 32, },
472
473 { "m25pe80", 0x208014, 64 * 1024, 16, },
474 { "m25pe16", 0x208015, 64 * 1024, 32, SECT_4K, },
475
476 /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
477 { "w25x10", 0xef3011, 64 * 1024, 2, SECT_4K, },
478 { "w25x20", 0xef3012, 64 * 1024, 4, SECT_4K, },
479 { "w25x40", 0xef3013, 64 * 1024, 8, SECT_4K, },
480 { "w25x80", 0xef3014, 64 * 1024, 16, SECT_4K, },
481 { "w25x16", 0xef3015, 64 * 1024, 32, SECT_4K, },
482 { "w25x32", 0xef3016, 64 * 1024, 64, SECT_4K, },
483 { "w25x64", 0xef3017, 64 * 1024, 128, SECT_4K, },
417}; 484};
418 485
486static struct flash_info *__devinit jedec_probe(struct spi_device *spi)
487{
488 int tmp;
489 u8 code = OPCODE_RDID;
490 u8 id[3];
491 u32 jedec;
492 struct flash_info *info;
493
494 /* JEDEC also defines an optional "extended device information"
495 * string for after vendor-specific data, after the three bytes
496 * we use here. Supporting some chips might require using it.
497 */
498 tmp = spi_write_then_read(spi, &code, 1, id, 3);
499 if (tmp < 0) {
500 DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n",
501 spi->dev.bus_id, tmp);
502 return NULL;
503 }
504 jedec = id[0];
505 jedec = jedec << 8;
506 jedec |= id[1];
507 jedec = jedec << 8;
508 jedec |= id[2];
509
510 for (tmp = 0, info = m25p_data;
511 tmp < ARRAY_SIZE(m25p_data);
512 tmp++, info++) {
513 if (info->jedec_id == jedec)
514 return info;
515 }
516 dev_err(&spi->dev, "unrecognized JEDEC id %06x\n", jedec);
517 return NULL;
518}
519
520
419/* 521/*
420 * board specific setup should have ensured the SPI clock used here 522 * board specific setup should have ensured the SPI clock used here
421 * matches what the READ command supports, at least until this driver 523 * matches what the READ command supports, at least until this driver
@@ -429,37 +531,51 @@ static int __devinit m25p_probe(struct spi_device *spi)
429 unsigned i; 531 unsigned i;
430 532
431 /* Platform data helps sort out which chip type we have, as 533 /* Platform data helps sort out which chip type we have, as
432 * well as how this board partitions it. 534 * well as how this board partitions it. If we don't have
535 * a chip ID, try the JEDEC id commands; they'll work for most
536 * newer chips, even if we don't recognize the particular chip.
433 */ 537 */
434 data = spi->dev.platform_data; 538 data = spi->dev.platform_data;
435 if (!data || !data->type) { 539 if (data && data->type) {
436 /* FIXME some chips can identify themselves with RES 540 for (i = 0, info = m25p_data;
437 * or JEDEC get-id commands. Try them ... 541 i < ARRAY_SIZE(m25p_data);
438 */ 542 i++, info++) {
439 DEBUG(MTD_DEBUG_LEVEL1, "%s: no chip id\n", 543 if (strcmp(data->type, info->name) == 0)
440 spi->dev.bus_id); 544 break;
441 return -ENODEV; 545 }
442 }
443 546
444 for (i = 0, info = m25p_data; i < ARRAY_SIZE(m25p_data); i++, info++) { 547 /* unrecognized chip? */
445 if (strcmp(data->type, info->name) == 0) 548 if (i == ARRAY_SIZE(m25p_data)) {
446 break; 549 DEBUG(MTD_DEBUG_LEVEL0, "%s: unrecognized id %s\n",
447 } 550 spi->dev.bus_id, data->type);
448 if (i == ARRAY_SIZE(m25p_data)) { 551 info = NULL;
449 DEBUG(MTD_DEBUG_LEVEL1, "%s: unrecognized id %s\n", 552
450 spi->dev.bus_id, data->type); 553 /* recognized; is that chip really what's there? */
554 } else if (info->jedec_id) {
555 struct flash_info *chip = jedec_probe(spi);
556
557 if (!chip || chip != info) {
558 dev_warn(&spi->dev, "found %s, expected %s\n",
559 chip ? chip->name : "UNKNOWN",
560 info->name);
561 info = NULL;
562 }
563 }
564 } else
565 info = jedec_probe(spi);
566
567 if (!info)
451 return -ENODEV; 568 return -ENODEV;
452 }
453 569
454 flash = kzalloc(sizeof *flash, GFP_KERNEL); 570 flash = kzalloc(sizeof *flash, GFP_KERNEL);
455 if (!flash) 571 if (!flash)
456 return -ENOMEM; 572 return -ENOMEM;
457 573
458 flash->spi = spi; 574 flash->spi = spi;
459 init_MUTEX(&flash->lock); 575 mutex_init(&flash->lock);
460 dev_set_drvdata(&spi->dev, flash); 576 dev_set_drvdata(&spi->dev, flash);
461 577
462 if (data->name) 578 if (data && data->name)
463 flash->mtd.name = data->name; 579 flash->mtd.name = data->name;
464 else 580 else
465 flash->mtd.name = spi->dev.bus_id; 581 flash->mtd.name = spi->dev.bus_id;
@@ -468,17 +584,25 @@ static int __devinit m25p_probe(struct spi_device *spi)
468 flash->mtd.writesize = 1; 584 flash->mtd.writesize = 1;
469 flash->mtd.flags = MTD_CAP_NORFLASH; 585 flash->mtd.flags = MTD_CAP_NORFLASH;
470 flash->mtd.size = info->sector_size * info->n_sectors; 586 flash->mtd.size = info->sector_size * info->n_sectors;
471 flash->mtd.erasesize = info->sector_size;
472 flash->mtd.erase = m25p80_erase; 587 flash->mtd.erase = m25p80_erase;
473 flash->mtd.read = m25p80_read; 588 flash->mtd.read = m25p80_read;
474 flash->mtd.write = m25p80_write; 589 flash->mtd.write = m25p80_write;
475 590
591 /* prefer "small sector" erase if possible */
592 if (info->flags & SECT_4K) {
593 flash->erase_opcode = OPCODE_BE_4K;
594 flash->mtd.erasesize = 4096;
595 } else {
596 flash->erase_opcode = OPCODE_SE;
597 flash->mtd.erasesize = info->sector_size;
598 }
599
476 dev_info(&spi->dev, "%s (%d Kbytes)\n", info->name, 600 dev_info(&spi->dev, "%s (%d Kbytes)\n", info->name,
477 flash->mtd.size / 1024); 601 flash->mtd.size / 1024);
478 602
479 DEBUG(MTD_DEBUG_LEVEL2, 603 DEBUG(MTD_DEBUG_LEVEL2,
480 "mtd .name = %s, .size = 0x%.8x (%uM) " 604 "mtd .name = %s, .size = 0x%.8x (%uMiB) "
481 ".erasesize = 0x%.8x (%uK) .numeraseregions = %d\n", 605 ".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n",
482 flash->mtd.name, 606 flash->mtd.name,
483 flash->mtd.size, flash->mtd.size / (1024*1024), 607 flash->mtd.size, flash->mtd.size / (1024*1024),
484 flash->mtd.erasesize, flash->mtd.erasesize / 1024, 608 flash->mtd.erasesize, flash->mtd.erasesize / 1024,
@@ -488,7 +612,7 @@ static int __devinit m25p_probe(struct spi_device *spi)
488 for (i = 0; i < flash->mtd.numeraseregions; i++) 612 for (i = 0; i < flash->mtd.numeraseregions; i++)
489 DEBUG(MTD_DEBUG_LEVEL2, 613 DEBUG(MTD_DEBUG_LEVEL2,
490 "mtd.eraseregions[%d] = { .offset = 0x%.8x, " 614 "mtd.eraseregions[%d] = { .offset = 0x%.8x, "
491 ".erasesize = 0x%.8x (%uK), " 615 ".erasesize = 0x%.8x (%uKiB), "
492 ".numblocks = %d }\n", 616 ".numblocks = %d }\n",
493 i, flash->mtd.eraseregions[i].offset, 617 i, flash->mtd.eraseregions[i].offset,
494 flash->mtd.eraseregions[i].erasesize, 618 flash->mtd.eraseregions[i].erasesize,
@@ -516,14 +640,14 @@ static int __devinit m25p_probe(struct spi_device *spi)
516 } 640 }
517 641
518 if (nr_parts > 0) { 642 if (nr_parts > 0) {
519 for (i = 0; i < data->nr_parts; i++) { 643 for (i = 0; i < nr_parts; i++) {
520 DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = " 644 DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = "
521 "{.name = %s, .offset = 0x%.8x, " 645 "{.name = %s, .offset = 0x%.8x, "
522 ".size = 0x%.8x (%uK) }\n", 646 ".size = 0x%.8x (%uKiB) }\n",
523 i, data->parts[i].name, 647 i, parts[i].name,
524 data->parts[i].offset, 648 parts[i].offset,
525 data->parts[i].size, 649 parts[i].size,
526 data->parts[i].size / 1024); 650 parts[i].size / 1024);
527 } 651 }
528 flash->partitioned = 1; 652 flash->partitioned = 1;
529 return add_mtd_partitions(&flash->mtd, parts, nr_parts); 653 return add_mtd_partitions(&flash->mtd, parts, nr_parts);
@@ -560,6 +684,11 @@ static struct spi_driver m25p80_driver = {
560 }, 684 },
561 .probe = m25p_probe, 685 .probe = m25p_probe,
562 .remove = __devexit_p(m25p_remove), 686 .remove = __devexit_p(m25p_remove),
687
688 /* REVISIT: many of these chips have deep power-down modes, which
689 * should clearly be entered on suspend() to minimize power use.
690 * And also when they're otherwise idle...
691 */
563}; 692};
564 693
565 694
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c
index a987e917f4e0..a5ed6d232c35 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -14,6 +14,7 @@
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <linux/delay.h> 15#include <linux/delay.h>
16#include <linux/device.h> 16#include <linux/device.h>
17#include <linux/mutex.h>
17#include <linux/spi/spi.h> 18#include <linux/spi/spi.h>
18#include <linux/spi/flash.h> 19#include <linux/spi/flash.h>
19 20
@@ -89,7 +90,7 @@ struct dataflash {
89 unsigned short page_offset; /* offset in flash address */ 90 unsigned short page_offset; /* offset in flash address */
90 unsigned int page_size; /* of bytes per page */ 91 unsigned int page_size; /* of bytes per page */
91 92
92 struct semaphore lock; 93 struct mutex lock;
93 struct spi_device *spi; 94 struct spi_device *spi;
94 95
95 struct mtd_info mtd; 96 struct mtd_info mtd;
@@ -167,7 +168,7 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr)
167 x.len = 4; 168 x.len = 4;
168 spi_message_add_tail(&x, &msg); 169 spi_message_add_tail(&x, &msg);
169 170
170 down(&priv->lock); 171 mutex_lock(&priv->lock);
171 while (instr->len > 0) { 172 while (instr->len > 0) {
172 unsigned int pageaddr; 173 unsigned int pageaddr;
173 int status; 174 int status;
@@ -210,7 +211,7 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr)
210 instr->len -= priv->page_size; 211 instr->len -= priv->page_size;
211 } 212 }
212 } 213 }
213 up(&priv->lock); 214 mutex_unlock(&priv->lock);
214 215
215 /* Inform MTD subsystem that erase is complete */ 216 /* Inform MTD subsystem that erase is complete */
216 instr->state = MTD_ERASE_DONE; 217 instr->state = MTD_ERASE_DONE;
@@ -266,7 +267,7 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len,
266 x[1].len = len; 267 x[1].len = len;
267 spi_message_add_tail(&x[1], &msg); 268 spi_message_add_tail(&x[1], &msg);
268 269
269 down(&priv->lock); 270 mutex_lock(&priv->lock);
270 271
271 /* Continuous read, max clock = f(car) which may be less than 272 /* Continuous read, max clock = f(car) which may be less than
272 * the peak rate available. Some chips support commands with 273 * the peak rate available. Some chips support commands with
@@ -279,7 +280,7 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len,
279 /* plus 4 "don't care" bytes */ 280 /* plus 4 "don't care" bytes */
280 281
281 status = spi_sync(priv->spi, &msg); 282 status = spi_sync(priv->spi, &msg);
282 up(&priv->lock); 283 mutex_unlock(&priv->lock);
283 284
284 if (status >= 0) { 285 if (status >= 0) {
285 *retlen = msg.actual_length - 8; 286 *retlen = msg.actual_length - 8;
@@ -336,7 +337,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
336 else 337 else
337 writelen = len; 338 writelen = len;
338 339
339 down(&priv->lock); 340 mutex_lock(&priv->lock);
340 while (remaining > 0) { 341 while (remaining > 0) {
341 DEBUG(MTD_DEBUG_LEVEL3, "write @ %i:%i len=%i\n", 342 DEBUG(MTD_DEBUG_LEVEL3, "write @ %i:%i len=%i\n",
342 pageaddr, offset, writelen); 343 pageaddr, offset, writelen);
@@ -441,7 +442,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
441 else 442 else
442 writelen = remaining; 443 writelen = remaining;
443 } 444 }
444 up(&priv->lock); 445 mutex_unlock(&priv->lock);
445 446
446 return status; 447 return status;
447} 448}
@@ -463,7 +464,7 @@ add_dataflash(struct spi_device *spi, char *name,
463 if (!priv) 464 if (!priv)
464 return -ENOMEM; 465 return -ENOMEM;
465 466
466 init_MUTEX(&priv->lock); 467 mutex_init(&priv->lock);
467 priv->spi = spi; 468 priv->spi = spi;
468 priv->page_size = pagesize; 469 priv->page_size = pagesize;
469 priv->page_offset = pageoffset; 470 priv->page_offset = pageoffset;
diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c
index e8f686f7a357..7060a0895ce2 100644
--- a/drivers/mtd/devices/pmc551.c
+++ b/drivers/mtd/devices/pmc551.c
@@ -30,8 +30,8 @@
30 * 30 *
31 * Notes: 31 * Notes:
32 * Due to what I assume is more buggy SROM, the 64M PMC551 I 32 * Due to what I assume is more buggy SROM, the 64M PMC551 I
33 * have available claims that all 4 of it's DRAM banks have 64M 33 * have available claims that all 4 of its DRAM banks have 64MiB
34 * of ram configured (making a grand total of 256M onboard). 34 * of ram configured (making a grand total of 256MiB onboard).
35 * This is slightly annoying since the BAR0 size reflects the 35 * This is slightly annoying since the BAR0 size reflects the
36 * aperture size, not the dram size, and the V370PDC supplies no 36 * aperture size, not the dram size, and the V370PDC supplies no
37 * other method for memory size discovery. This problem is 37 * other method for memory size discovery. This problem is
@@ -70,7 +70,7 @@
70 * made the memory unusable, added a fix to code to touch up 70 * made the memory unusable, added a fix to code to touch up
71 * the DRAM some. 71 * the DRAM some.
72 * 72 *
73 * Bugs/FIXME's: 73 * Bugs/FIXMEs:
74 * * MUST fix the init function to not spin on a register 74 * * MUST fix the init function to not spin on a register
75 * waiting for it to set .. this does not safely handle busted 75 * waiting for it to set .. this does not safely handle busted
76 * devices that never reset the register correctly which will 76 * devices that never reset the register correctly which will
@@ -562,10 +562,10 @@ static u32 fixup_pmc551(struct pci_dev *dev)
562 /* 562 /*
563 * Some screen fun 563 * Some screen fun
564 */ 564 */
565 printk(KERN_DEBUG "pmc551: %d%c (0x%x) of %sprefetchable memory at " 565 printk(KERN_DEBUG "pmc551: %d%sB (0x%x) of %sprefetchable memory at "
566 "0x%llx\n", (size < 1024) ? size : (size < 1048576) ? 566 "0x%llx\n", (size < 1024) ? size : (size < 1048576) ?
567 size >> 10 : size >> 20, 567 size >> 10 : size >> 20,
568 (size < 1024) ? 'B' : (size < 1048576) ? 'K' : 'M', size, 568 (size < 1024) ? "" : (size < 1048576) ? "Ki" : "Mi", size,
569 ((dcmd & (0x1 << 3)) == 0) ? "non-" : "", 569 ((dcmd & (0x1 << 3)) == 0) ? "non-" : "",
570 (unsigned long long)pci_resource_start(dev, 0)); 570 (unsigned long long)pci_resource_start(dev, 0));
571 571
@@ -649,14 +649,10 @@ MODULE_DESCRIPTION(PMC551_VERSION);
649 * Stuff these outside the ifdef so as to not bust compiled in driver support 649 * Stuff these outside the ifdef so as to not bust compiled in driver support
650 */ 650 */
651static int msize = 0; 651static int msize = 0;
652#if defined(CONFIG_MTD_PMC551_APERTURE_SIZE)
653static int asize = CONFIG_MTD_PMC551_APERTURE_SIZE;
654#else
655static int asize = 0; 652static int asize = 0;
656#endif
657 653
658module_param(msize, int, 0); 654module_param(msize, int, 0);
659MODULE_PARM_DESC(msize, "memory size in Megabytes [1 - 1024]"); 655MODULE_PARM_DESC(msize, "memory size in MiB [1 - 1024]");
660module_param(asize, int, 0); 656module_param(asize, int, 0);
661MODULE_PARM_DESC(asize, "aperture size, must be <= memsize [1-1024]"); 657MODULE_PARM_DESC(asize, "aperture size, must be <= memsize [1-1024]");
662 658
@@ -799,8 +795,7 @@ static int __init init_pmc551(void)
799 mtd->owner = THIS_MODULE; 795 mtd->owner = THIS_MODULE;
800 796
801 if (add_mtd_device(mtd)) { 797 if (add_mtd_device(mtd)) {
802 printk(KERN_NOTICE "pmc551: Failed to register new " 798 printk(KERN_NOTICE "pmc551: Failed to register new device\n");
803 "device\n");
804 pci_iounmap(PCI_Device, priv->start); 799 pci_iounmap(PCI_Device, priv->start);
805 kfree(mtd->priv); 800 kfree(mtd->priv);
806 kfree(mtd); 801 kfree(mtd);
@@ -811,13 +806,13 @@ static int __init init_pmc551(void)
811 pci_dev_get(PCI_Device); 806 pci_dev_get(PCI_Device);
812 807
813 printk(KERN_NOTICE "Registered pmc551 memory device.\n"); 808 printk(KERN_NOTICE "Registered pmc551 memory device.\n");
814 printk(KERN_NOTICE "Mapped %dM of memory from 0x%p to 0x%p\n", 809 printk(KERN_NOTICE "Mapped %dMiB of memory from 0x%p to 0x%p\n",
815 priv->asize >> 20, 810 priv->asize >> 20,
816 priv->start, priv->start + priv->asize); 811 priv->start, priv->start + priv->asize);
817 printk(KERN_NOTICE "Total memory is %d%c\n", 812 printk(KERN_NOTICE "Total memory is %d%sB\n",
818 (length < 1024) ? length : 813 (length < 1024) ? length :
819 (length < 1048576) ? length >> 10 : length >> 20, 814 (length < 1048576) ? length >> 10 : length >> 20,
820 (length < 1024) ? 'B' : (length < 1048576) ? 'K' : 'M'); 815 (length < 1024) ? "" : (length < 1048576) ? "Ki" : "Mi");
821 priv->nextpmc551 = pmc551list; 816 priv->nextpmc551 = pmc551list;
822 pmc551list = mtd; 817 pmc551list = mtd;
823 found++; 818 found++;
@@ -850,7 +845,7 @@ static void __exit cleanup_pmc551(void)
850 pmc551list = priv->nextpmc551; 845 pmc551list = priv->nextpmc551;
851 846
852 if (priv->start) { 847 if (priv->start) {
853 printk(KERN_DEBUG "pmc551: unmapping %dM starting at " 848 printk(KERN_DEBUG "pmc551: unmapping %dMiB starting at "
854 "0x%p\n", priv->asize >> 20, priv->start); 849 "0x%p\n", priv->asize >> 20, priv->start);
855 pci_iounmap(priv->dev, priv->start); 850 pci_iounmap(priv->dev, priv->start);
856 } 851 }
diff --git a/drivers/mtd/inftlmount.c b/drivers/mtd/inftlmount.c
index ecac0e438f49..b8917beeb650 100644
--- a/drivers/mtd/inftlmount.c
+++ b/drivers/mtd/inftlmount.c
@@ -580,14 +580,13 @@ int INFTL_mount(struct INFTLrecord *s)
580 logical_block = block = BLOCK_NIL; 580 logical_block = block = BLOCK_NIL;
581 581
582 /* Temporary buffer to store ANAC numbers. */ 582 /* Temporary buffer to store ANAC numbers. */
583 ANACtable = kmalloc(s->nb_blocks * sizeof(u8), GFP_KERNEL); 583 ANACtable = kcalloc(s->nb_blocks, sizeof(u8), GFP_KERNEL);
584 if (!ANACtable) { 584 if (!ANACtable) {
585 printk(KERN_WARNING "INFTL: allocation of ANACtable " 585 printk(KERN_WARNING "INFTL: allocation of ANACtable "
586 "failed (%zd bytes)\n", 586 "failed (%zd bytes)\n",
587 s->nb_blocks * sizeof(u8)); 587 s->nb_blocks * sizeof(u8));
588 return -ENOMEM; 588 return -ENOMEM;
589 } 589 }
590 memset(ANACtable, 0, s->nb_blocks);
591 590
592 /* 591 /*
593 * First pass is to explore each physical unit, and construct the 592 * First pass is to explore each physical unit, and construct the
diff --git a/drivers/mtd/maps/alchemy-flash.c b/drivers/mtd/maps/alchemy-flash.c
index 84fbe0e8c47e..82811bcb0436 100644
--- a/drivers/mtd/maps/alchemy-flash.c
+++ b/drivers/mtd/maps/alchemy-flash.c
@@ -75,13 +75,6 @@
75#define BOARD_FLASH_WIDTH 2 /* 16-bits */ 75#define BOARD_FLASH_WIDTH 2 /* 16-bits */
76#endif 76#endif
77 77
78#ifdef CONFIG_MIPS_HYDROGEN3
79#define BOARD_MAP_NAME "Hydrogen3 Flash"
80#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
81#define BOARD_FLASH_WIDTH 4 /* 32-bits */
82#define USE_LOCAL_ACCESSORS /* why? */
83#endif
84
85#ifdef CONFIG_MIPS_BOSPORUS 78#ifdef CONFIG_MIPS_BOSPORUS
86#define BOARD_MAP_NAME "Bosporus Flash" 79#define BOARD_MAP_NAME "Bosporus Flash"
87#define BOARD_FLASH_SIZE 0x01000000 /* 16MB */ 80#define BOARD_FLASH_SIZE 0x01000000 /* 16MB */
@@ -130,13 +123,6 @@ int __init alchemy_mtd_init(void)
130 123
131 window_addr = 0x20000000 - BOARD_FLASH_SIZE; 124 window_addr = 0x20000000 - BOARD_FLASH_SIZE;
132 window_size = BOARD_FLASH_SIZE; 125 window_size = BOARD_FLASH_SIZE;
133#ifdef CONFIG_MIPS_MIRAGE_WHY
134 /* Boot ROM flash bank only; no user bank */
135 window_addr = 0x1C000000;
136 window_size = 0x04000000;
137 /* USERFS from 0x1C00 0000 to 0x1FC00000 */
138 alchemy_partitions[0].size = 0x03C00000;
139#endif
140 126
141 /* 127 /*
142 * Static partition definition selection 128 * Static partition definition selection
diff --git a/drivers/mtd/maps/nettel.c b/drivers/mtd/maps/nettel.c
index 7b96cd02f82b..0c9b305a72e0 100644
--- a/drivers/mtd/maps/nettel.c
+++ b/drivers/mtd/maps/nettel.c
@@ -158,68 +158,11 @@ static struct notifier_block nettel_notifier_block = {
158 nettel_reboot_notifier, NULL, 0 158 nettel_reboot_notifier, NULL, 0
159}; 159};
160 160
161/*
162 * Erase the configuration file system.
163 * Used to support the software reset button.
164 */
165static void nettel_erasecallback(struct erase_info *done)
166{
167 wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv;
168 wake_up(wait_q);
169}
170
171static struct erase_info nettel_erase;
172
173int nettel_eraseconfig(void)
174{
175 struct mtd_info *mtd;
176 DECLARE_WAITQUEUE(wait, current);
177 wait_queue_head_t wait_q;
178 int ret;
179
180 init_waitqueue_head(&wait_q);
181 mtd = get_mtd_device(NULL, 2);
182 if (!IS_ERR(mtd)) {
183 nettel_erase.mtd = mtd;
184 nettel_erase.callback = nettel_erasecallback;
185 nettel_erase.callback = NULL;
186 nettel_erase.addr = 0;
187 nettel_erase.len = mtd->size;
188 nettel_erase.priv = (u_long) &wait_q;
189 nettel_erase.priv = 0;
190
191 set_current_state(TASK_INTERRUPTIBLE);
192 add_wait_queue(&wait_q, &wait);
193
194 ret = mtd->erase(mtd, &nettel_erase);
195 if (ret) {
196 set_current_state(TASK_RUNNING);
197 remove_wait_queue(&wait_q, &wait);
198 put_mtd_device(mtd);
199 return(ret);
200 }
201
202 schedule(); /* Wait for erase to finish. */
203 remove_wait_queue(&wait_q, &wait);
204
205 put_mtd_device(mtd);
206 }
207
208 return(0);
209}
210
211#else
212
213int nettel_eraseconfig(void)
214{
215 return(0);
216}
217
218#endif 161#endif
219 162
220/****************************************************************************/ 163/****************************************************************************/
221 164
222int __init nettel_init(void) 165static int __init nettel_init(void)
223{ 166{
224 volatile unsigned long *amdpar; 167 volatile unsigned long *amdpar;
225 unsigned long amdaddr, maxsize; 168 unsigned long amdaddr, maxsize;
@@ -421,10 +364,6 @@ int __init nettel_init(void)
421 364
422 intel_mtd->owner = THIS_MODULE; 365 intel_mtd->owner = THIS_MODULE;
423 366
424#ifndef CONFIG_BLK_DEV_INITRD
425 ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, 1);
426#endif
427
428 num_intel_partitions = sizeof(nettel_intel_partitions) / 367 num_intel_partitions = sizeof(nettel_intel_partitions) /
429 sizeof(nettel_intel_partitions[0]); 368 sizeof(nettel_intel_partitions[0]);
430 369
@@ -477,7 +416,7 @@ out_unmap2:
477 416
478/****************************************************************************/ 417/****************************************************************************/
479 418
480void __exit nettel_cleanup(void) 419static void __exit nettel_cleanup(void)
481{ 420{
482#ifdef CONFIG_MTD_CFI_INTELEXT 421#ifdef CONFIG_MTD_CFI_INTELEXT
483 unregister_reboot_notifier(&nettel_notifier_block); 422 unregister_reboot_notifier(&nettel_notifier_block);
diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c
index bbb42c35b69b..fbd613968717 100644
--- a/drivers/mtd/maps/physmap_of.c
+++ b/drivers/mtd/maps/physmap_of.c
@@ -141,7 +141,6 @@ static int __devinit of_physmap_probe(struct of_device *dev, const struct of_dev
141 err = -ENOMEM; 141 err = -ENOMEM;
142 goto err_out; 142 goto err_out;
143 } 143 }
144 memset(info, 0, sizeof(*info));
145 144
146 dev_set_drvdata(&dev->dev, info); 145 dev_set_drvdata(&dev->dev, info);
147 146
@@ -213,10 +212,6 @@ static int __devinit of_physmap_probe(struct of_device *dev, const struct of_dev
213err_out: 212err_out:
214 of_physmap_remove(dev); 213 of_physmap_remove(dev);
215 return err; 214 return err;
216
217 return 0;
218
219
220} 215}
221 216
222static struct of_device_id of_physmap_match[] = { 217static struct of_device_id of_physmap_match[] = {
diff --git a/drivers/mtd/maps/pmcmsp-flash.c b/drivers/mtd/maps/pmcmsp-flash.c
index 7e0377ec1c40..02bde8c982ec 100644
--- a/drivers/mtd/maps/pmcmsp-flash.c
+++ b/drivers/mtd/maps/pmcmsp-flash.c
@@ -73,13 +73,16 @@ int __init init_msp_flash(void)
73 return -ENXIO; 73 return -ENXIO;
74 74
75 printk(KERN_NOTICE "Found %d PMC flash devices\n", fcnt); 75 printk(KERN_NOTICE "Found %d PMC flash devices\n", fcnt);
76 msp_flash = (struct mtd_info **)kmalloc( 76
77 fcnt * sizeof(struct map_info *), GFP_KERNEL); 77 msp_flash = kmalloc(fcnt * sizeof(struct map_info *), GFP_KERNEL);
78 msp_parts = (struct mtd_partition **)kmalloc( 78 msp_parts = kmalloc(fcnt * sizeof(struct mtd_partition *), GFP_KERNEL);
79 fcnt * sizeof(struct mtd_partition *), GFP_KERNEL); 79 msp_maps = kcalloc(fcnt, sizeof(struct mtd_info), GFP_KERNEL);
80 msp_maps = (struct map_info *)kmalloc( 80 if (!msp_flash || !msp_parts || !msp_maps) {
81 fcnt * sizeof(struct mtd_info), GFP_KERNEL); 81 kfree(msp_maps);
82 memset(msp_maps, 0, fcnt * sizeof(struct mtd_info)); 82 kfree(msp_parts);
83 kfree(msp_flash);
84 return -ENOMEM;
85 }
83 86
84 /* loop over the flash devices, initializing each */ 87 /* loop over the flash devices, initializing each */
85 for (i = 0; i < fcnt; i++) { 88 for (i = 0; i < fcnt; i++) {
@@ -95,9 +98,8 @@ int __init init_msp_flash(void)
95 continue; 98 continue;
96 } 99 }
97 100
98 msp_parts[i] = (struct mtd_partition *)kmalloc( 101 msp_parts[i] = kcalloc(pcnt, sizeof(struct mtd_partition),
99 pcnt * sizeof(struct mtd_partition), GFP_KERNEL); 102 GFP_KERNEL);
100 memset(msp_parts[i], 0, pcnt * sizeof(struct mtd_partition));
101 103
102 /* now initialize the devices proper */ 104 /* now initialize the devices proper */
103 flash_name[5] = '0' + i; 105 flash_name[5] = '0' + i;
diff --git a/drivers/mtd/maps/pmcmsp-ramroot.c b/drivers/mtd/maps/pmcmsp-ramroot.c
index 18049bceba8d..30de5c0c09a9 100644
--- a/drivers/mtd/maps/pmcmsp-ramroot.c
+++ b/drivers/mtd/maps/pmcmsp-ramroot.c
@@ -79,7 +79,6 @@ static int __init init_rrmap(void)
79 rr_mtd->owner = THIS_MODULE; 79 rr_mtd->owner = THIS_MODULE;
80 80
81 add_mtd_device(rr_mtd); 81 add_mtd_device(rr_mtd);
82 ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, rr_mtd->index);
83 82
84 return 0; 83 return 0;
85 } 84 }
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index ef89780eb9d6..74d9d30edabd 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -24,10 +24,9 @@
24#include <linux/kthread.h> 24#include <linux/kthread.h>
25#include <asm/uaccess.h> 25#include <asm/uaccess.h>
26 26
27static LIST_HEAD(blktrans_majors); 27#include "mtdcore.h"
28 28
29extern struct mutex mtd_table_mutex; 29static LIST_HEAD(blktrans_majors);
30extern struct mtd_info *mtd_table[];
31 30
32struct mtd_blkcore_priv { 31struct mtd_blkcore_priv {
33 struct task_struct *thread; 32 struct task_struct *thread;
@@ -202,7 +201,7 @@ static int blktrans_ioctl(struct inode *inode, struct file *file,
202 } 201 }
203} 202}
204 203
205struct block_device_operations mtd_blktrans_ops = { 204static struct block_device_operations mtd_blktrans_ops = {
206 .owner = THIS_MODULE, 205 .owner = THIS_MODULE,
207 .open = blktrans_open, 206 .open = blktrans_open,
208 .release = blktrans_release, 207 .release = blktrans_release,
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 8c86b802f212..942c88ec5b6a 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -135,7 +135,8 @@ static int mtd_close(struct inode *inode, struct file *file)
135 135
136 DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n"); 136 DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n");
137 137
138 if (mtd->sync) 138 /* Only sync if opened RW */
139 if ((file->f_mode & 2) && mtd->sync)
139 mtd->sync(mtd); 140 mtd->sync(mtd);
140 141
141 put_mtd_device(mtd); 142 put_mtd_device(mtd);
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index 41844ea02462..96be7ef62f35 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -178,7 +178,7 @@ concat_writev(struct mtd_info *mtd, const struct kvec *vecs,
178 178
179 /* Check alignment */ 179 /* Check alignment */
180 if (mtd->writesize > 1) { 180 if (mtd->writesize > 1) {
181 loff_t __to = to; 181 uint64_t __to = to;
182 if (do_div(__to, mtd->writesize) || (total_len % mtd->writesize)) 182 if (do_div(__to, mtd->writesize) || (total_len % mtd->writesize))
183 return -EINVAL; 183 return -EINVAL;
184 } 184 }
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index c153b64a8300..6c2645e28371 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -22,6 +22,8 @@
22 22
23#include <linux/mtd/mtd.h> 23#include <linux/mtd/mtd.h>
24 24
25#include "mtdcore.h"
26
25/* These are exported solely for the purpose of mtd_blkdevs.c. You 27/* These are exported solely for the purpose of mtd_blkdevs.c. You
26 should not use them for _anything_ else */ 28 should not use them for _anything_ else */
27DEFINE_MUTEX(mtd_table_mutex); 29DEFINE_MUTEX(mtd_table_mutex);
diff --git a/drivers/mtd/mtdcore.h b/drivers/mtd/mtdcore.h
new file mode 100644
index 000000000000..a33251f4b872
--- /dev/null
+++ b/drivers/mtd/mtdcore.h
@@ -0,0 +1,11 @@
1/* linux/drivers/mtd/mtdcore.h
2 *
3 * Header file for driver private mtdcore exports
4 *
5 */
6
7/* These are exported solely for the purpose of mtd_blkdevs.c. You
8 should not use them for _anything_ else */
9
10extern struct mutex mtd_table_mutex;
11extern struct mtd_info *mtd_table[MAX_MTD_DEVICES];
diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c
new file mode 100644
index 000000000000..62ee2043d046
--- /dev/null
+++ b/drivers/mtd/mtdoops.c
@@ -0,0 +1,376 @@
1/*
2 * MTD Oops/Panic logger
3 *
4 * Copyright (C) 2007 Nokia Corporation. All rights reserved.
5 *
6 * Author: Richard Purdie <rpurdie@openedhand.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/console.h>
27#include <linux/vmalloc.h>
28#include <linux/workqueue.h>
29#include <linux/sched.h>
30#include <linux/wait.h>
31#include <linux/mtd/mtd.h>
32
33#define OOPS_PAGE_SIZE 4096
34
35static struct mtdoops_context {
36 int mtd_index;
37 struct work_struct work;
38 struct mtd_info *mtd;
39 int oops_pages;
40 int nextpage;
41 int nextcount;
42
43 void *oops_buf;
44 int ready;
45 int writecount;
46} oops_cxt;
47
48static void mtdoops_erase_callback(struct erase_info *done)
49{
50 wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv;
51 wake_up(wait_q);
52}
53
54static int mtdoops_erase_block(struct mtd_info *mtd, int offset)
55{
56 struct erase_info erase;
57 DECLARE_WAITQUEUE(wait, current);
58 wait_queue_head_t wait_q;
59 int ret;
60
61 init_waitqueue_head(&wait_q);
62 erase.mtd = mtd;
63 erase.callback = mtdoops_erase_callback;
64 erase.addr = offset;
65 if (mtd->erasesize < OOPS_PAGE_SIZE)
66 erase.len = OOPS_PAGE_SIZE;
67 else
68 erase.len = mtd->erasesize;
69 erase.priv = (u_long)&wait_q;
70
71 set_current_state(TASK_INTERRUPTIBLE);
72 add_wait_queue(&wait_q, &wait);
73
74 ret = mtd->erase(mtd, &erase);
75 if (ret) {
76 set_current_state(TASK_RUNNING);
77 remove_wait_queue(&wait_q, &wait);
78 printk (KERN_WARNING "mtdoops: erase of region [0x%x, 0x%x] "
79 "on \"%s\" failed\n",
80 erase.addr, erase.len, mtd->name);
81 return ret;
82 }
83
84 schedule(); /* Wait for erase to finish. */
85 remove_wait_queue(&wait_q, &wait);
86
87 return 0;
88}
89
90static int mtdoops_inc_counter(struct mtdoops_context *cxt)
91{
92 struct mtd_info *mtd = cxt->mtd;
93 size_t retlen;
94 u32 count;
95 int ret;
96
97 cxt->nextpage++;
98 if (cxt->nextpage > cxt->oops_pages)
99 cxt->nextpage = 0;
100 cxt->nextcount++;
101 if (cxt->nextcount == 0xffffffff)
102 cxt->nextcount = 0;
103
104 ret = mtd->read(mtd, cxt->nextpage * OOPS_PAGE_SIZE, 4,
105 &retlen, (u_char *) &count);
106 if ((retlen != 4) || (ret < 0)) {
107 printk(KERN_ERR "mtdoops: Read failure at %d (%d of 4 read)"
108 ", err %d.\n", cxt->nextpage * OOPS_PAGE_SIZE,
109 retlen, ret);
110 return 1;
111 }
112
113 /* See if we need to erase the next block */
114 if (count != 0xffffffff)
115 return 1;
116
117 printk(KERN_DEBUG "mtdoops: Ready %d, %d (no erase)\n",
118 cxt->nextpage, cxt->nextcount);
119 cxt->ready = 1;
120 return 0;
121}
122
123static void mtdoops_prepare(struct mtdoops_context *cxt)
124{
125 struct mtd_info *mtd = cxt->mtd;
126 int i = 0, j, ret, mod;
127
128 /* We were unregistered */
129 if (!mtd)
130 return;
131
132 mod = (cxt->nextpage * OOPS_PAGE_SIZE) % mtd->erasesize;
133 if (mod != 0) {
134 cxt->nextpage = cxt->nextpage + ((mtd->erasesize - mod) / OOPS_PAGE_SIZE);
135 if (cxt->nextpage > cxt->oops_pages)
136 cxt->nextpage = 0;
137 }
138
139 while (mtd->block_isbad &&
140 mtd->block_isbad(mtd, cxt->nextpage * OOPS_PAGE_SIZE)) {
141badblock:
142 printk(KERN_WARNING "mtdoops: Bad block at %08x\n",
143 cxt->nextpage * OOPS_PAGE_SIZE);
144 i++;
145 cxt->nextpage = cxt->nextpage + (mtd->erasesize / OOPS_PAGE_SIZE);
146 if (cxt->nextpage > cxt->oops_pages)
147 cxt->nextpage = 0;
148 if (i == (cxt->oops_pages / (mtd->erasesize / OOPS_PAGE_SIZE))) {
149 printk(KERN_ERR "mtdoops: All blocks bad!\n");
150 return;
151 }
152 }
153
154 for (j = 0, ret = -1; (j < 3) && (ret < 0); j++)
155 ret = mtdoops_erase_block(mtd, cxt->nextpage * OOPS_PAGE_SIZE);
156
157 if (ret < 0) {
158 if (mtd->block_markbad)
159 mtd->block_markbad(mtd, cxt->nextpage * OOPS_PAGE_SIZE);
160 goto badblock;
161 }
162
163 printk(KERN_DEBUG "mtdoops: Ready %d, %d \n", cxt->nextpage, cxt->nextcount);
164
165 cxt->ready = 1;
166}
167
168static void mtdoops_workfunc(struct work_struct *work)
169{
170 struct mtdoops_context *cxt =
171 container_of(work, struct mtdoops_context, work);
172
173 mtdoops_prepare(cxt);
174}
175
176static int find_next_position(struct mtdoops_context *cxt)
177{
178 struct mtd_info *mtd = cxt->mtd;
179 int page, maxpos = 0;
180 u32 count, maxcount = 0xffffffff;
181 size_t retlen;
182
183 for (page = 0; page < cxt->oops_pages; page++) {
184 mtd->read(mtd, page * OOPS_PAGE_SIZE, 4, &retlen, (u_char *) &count);
185 if (count == 0xffffffff)
186 continue;
187 if (maxcount == 0xffffffff) {
188 maxcount = count;
189 maxpos = page;
190 } else if ((count < 0x40000000) && (maxcount > 0xc0000000)) {
191 maxcount = count;
192 maxpos = page;
193 } else if ((count > maxcount) && (count < 0xc0000000)) {
194 maxcount = count;
195 maxpos = page;
196 } else if ((count > maxcount) && (count > 0xc0000000)
197 && (maxcount > 0x80000000)) {
198 maxcount = count;
199 maxpos = page;
200 }
201 }
202 if (maxcount == 0xffffffff) {
203 cxt->nextpage = 0;
204 cxt->nextcount = 1;
205 cxt->ready = 1;
206 printk(KERN_DEBUG "mtdoops: Ready %d, %d (first init)\n",
207 cxt->nextpage, cxt->nextcount);
208 return 0;
209 }
210
211 cxt->nextpage = maxpos;
212 cxt->nextcount = maxcount;
213
214 return mtdoops_inc_counter(cxt);
215}
216
217
218static void mtdoops_notify_add(struct mtd_info *mtd)
219{
220 struct mtdoops_context *cxt = &oops_cxt;
221 int ret;
222
223 if ((mtd->index != cxt->mtd_index) || cxt->mtd_index < 0)
224 return;
225
226 if (mtd->size < (mtd->erasesize * 2)) {
227 printk(KERN_ERR "MTD partition %d not big enough for mtdoops\n",
228 mtd->index);
229 return;
230 }
231
232 cxt->mtd = mtd;
233 cxt->oops_pages = mtd->size / OOPS_PAGE_SIZE;
234
235 ret = find_next_position(cxt);
236 if (ret == 1)
237 mtdoops_prepare(cxt);
238
239 printk(KERN_DEBUG "mtdoops: Attached to MTD device %d\n", mtd->index);
240}
241
242static void mtdoops_notify_remove(struct mtd_info *mtd)
243{
244 struct mtdoops_context *cxt = &oops_cxt;
245
246 if ((mtd->index != cxt->mtd_index) || cxt->mtd_index < 0)
247 return;
248
249 cxt->mtd = NULL;
250 flush_scheduled_work();
251}
252
253static void mtdoops_console_sync(void)
254{
255 struct mtdoops_context *cxt = &oops_cxt;
256 struct mtd_info *mtd = cxt->mtd;
257 size_t retlen;
258 int ret;
259
260 if (!cxt->ready || !mtd)
261 return;
262
263 if (cxt->writecount == 0)
264 return;
265
266 if (cxt->writecount < OOPS_PAGE_SIZE)
267 memset(cxt->oops_buf + cxt->writecount, 0xff,
268 OOPS_PAGE_SIZE - cxt->writecount);
269
270 ret = mtd->write(mtd, cxt->nextpage * OOPS_PAGE_SIZE,
271 OOPS_PAGE_SIZE, &retlen, cxt->oops_buf);
272 cxt->ready = 0;
273 cxt->writecount = 0;
274
275 if ((retlen != OOPS_PAGE_SIZE) || (ret < 0))
276 printk(KERN_ERR "mtdoops: Write failure at %d (%d of %d written), err %d.\n",
277 cxt->nextpage * OOPS_PAGE_SIZE, retlen, OOPS_PAGE_SIZE, ret);
278
279 ret = mtdoops_inc_counter(cxt);
280 if (ret == 1)
281 schedule_work(&cxt->work);
282}
283
284static void
285mtdoops_console_write(struct console *co, const char *s, unsigned int count)
286{
287 struct mtdoops_context *cxt = co->data;
288 struct mtd_info *mtd = cxt->mtd;
289 int i;
290
291 if (!oops_in_progress) {
292 mtdoops_console_sync();
293 return;
294 }
295
296 if (!cxt->ready || !mtd)
297 return;
298
299 if (cxt->writecount == 0) {
300 u32 *stamp = cxt->oops_buf;
301 *stamp = cxt->nextcount;
302 cxt->writecount = 4;
303 }
304
305 if ((count + cxt->writecount) > OOPS_PAGE_SIZE)
306 count = OOPS_PAGE_SIZE - cxt->writecount;
307
308 for (i = 0; i < count; i++, s++)
309 *((char *)(cxt->oops_buf) + cxt->writecount + i) = *s;
310
311 cxt->writecount = cxt->writecount + count;
312}
313
314static int __init mtdoops_console_setup(struct console *co, char *options)
315{
316 struct mtdoops_context *cxt = co->data;
317
318 if (cxt->mtd_index != -1)
319 return -EBUSY;
320 if (co->index == -1)
321 return -EINVAL;
322
323 cxt->mtd_index = co->index;
324 return 0;
325}
326
327static struct mtd_notifier mtdoops_notifier = {
328 .add = mtdoops_notify_add,
329 .remove = mtdoops_notify_remove,
330};
331
332static struct console mtdoops_console = {
333 .name = "ttyMTD",
334 .write = mtdoops_console_write,
335 .setup = mtdoops_console_setup,
336 .unblank = mtdoops_console_sync,
337 .flags = CON_PRINTBUFFER,
338 .index = -1,
339 .data = &oops_cxt,
340};
341
342static int __init mtdoops_console_init(void)
343{
344 struct mtdoops_context *cxt = &oops_cxt;
345
346 cxt->mtd_index = -1;
347 cxt->oops_buf = vmalloc(OOPS_PAGE_SIZE);
348
349 if (!cxt->oops_buf) {
350 printk(KERN_ERR "Failed to allocate oops buffer workspace\n");
351 return -ENOMEM;
352 }
353
354 INIT_WORK(&cxt->work, mtdoops_workfunc);
355
356 register_console(&mtdoops_console);
357 register_mtd_user(&mtdoops_notifier);
358 return 0;
359}
360
361static void __exit mtdoops_console_exit(void)
362{
363 struct mtdoops_context *cxt = &oops_cxt;
364
365 unregister_mtd_user(&mtdoops_notifier);
366 unregister_console(&mtdoops_console);
367 vfree(cxt->oops_buf);
368}
369
370
371subsys_initcall(mtdoops_console_init);
372module_exit(mtdoops_console_exit);
373
374MODULE_LICENSE("GPL");
375MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>");
376MODULE_DESCRIPTION("MTD Oops/Panic console logger/driver");
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index f1d60b6f048e..df25cabb0481 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -134,10 +134,10 @@ config MTD_NAND_S3C2410_HWECC
134 134
135config MTD_NAND_NDFC 135config MTD_NAND_NDFC
136 tristate "NDFC NanD Flash Controller" 136 tristate "NDFC NanD Flash Controller"
137 depends on 44x 137 depends on 4xx
138 select MTD_NAND_ECC_SMC 138 select MTD_NAND_ECC_SMC
139 help 139 help
140 NDFC Nand Flash Controllers are integrated in EP44x SoCs 140 NDFC Nand Flash Controllers are integrated in IBM/AMCC's 4xx SoCs
141 141
142config MTD_NAND_S3C2410_CLKSTOP 142config MTD_NAND_S3C2410_CLKSTOP
143 bool "S3C2410 NAND IDLE clock stop" 143 bool "S3C2410 NAND IDLE clock stop"
@@ -237,7 +237,7 @@ config MTD_NAND_CAFE
237 select REED_SOLOMON 237 select REED_SOLOMON
238 select REED_SOLOMON_DEC16 238 select REED_SOLOMON_DEC16
239 help 239 help
240 Use NAND flash attached to the CAFÉ chip designed for the $100 240 Use NAND flash attached to the CAFÉ chip designed for the OLPC
241 laptop. 241 laptop.
242 242
243config MTD_NAND_CS553X 243config MTD_NAND_CS553X
diff --git a/drivers/mtd/nand/at91_nand.c b/drivers/mtd/nand/at91_nand.c
index 512e999177f7..b2a5672df6e0 100644
--- a/drivers/mtd/nand/at91_nand.c
+++ b/drivers/mtd/nand/at91_nand.c
@@ -128,7 +128,10 @@ static int __init at91_nand_probe(struct platform_device *pdev)
128 nand_chip->IO_ADDR_R = host->io_base; 128 nand_chip->IO_ADDR_R = host->io_base;
129 nand_chip->IO_ADDR_W = host->io_base; 129 nand_chip->IO_ADDR_W = host->io_base;
130 nand_chip->cmd_ctrl = at91_nand_cmd_ctrl; 130 nand_chip->cmd_ctrl = at91_nand_cmd_ctrl;
131 nand_chip->dev_ready = at91_nand_device_ready; 131
132 if (host->board->rdy_pin)
133 nand_chip->dev_ready = at91_nand_device_ready;
134
132 nand_chip->ecc.mode = NAND_ECC_SOFT; /* enable ECC */ 135 nand_chip->ecc.mode = NAND_ECC_SOFT; /* enable ECC */
133 nand_chip->chip_delay = 20; /* 20us command delay time */ 136 nand_chip->chip_delay = 20; /* 20us command delay time */
134 137
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index e96259f22cca..ab9f5c5db38d 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -56,8 +56,6 @@ static unsigned long __initdata doc_locations[] = {
56#endif /* CONFIG_MTD_DOCPROBE_HIGH */ 56#endif /* CONFIG_MTD_DOCPROBE_HIGH */
57#elif defined(__PPC__) 57#elif defined(__PPC__)
58 0xe4000000, 58 0xe4000000,
59#elif defined(CONFIG_MOMENCO_OCELOT_G)
60 0xff000000,
61#else 59#else
62#warning Unknown architecture for DiskOnChip. No default probe locations defined 60#warning Unknown architecture for DiskOnChip. No default probe locations defined
63#endif 61#endif
diff --git a/drivers/mtd/nand/edb7312.c b/drivers/mtd/nand/edb7312.c
index 1daf8231aaef..0146cdc48039 100644
--- a/drivers/mtd/nand/edb7312.c
+++ b/drivers/mtd/nand/edb7312.c
@@ -74,7 +74,7 @@ static struct mtd_partition partition_info[] = {
74/* 74/*
75 * hardware specific access to control-lines 75 * hardware specific access to control-lines
76 * 76 *
77 * NAND_NCE: bit 0 -> bit 7 77 * NAND_NCE: bit 0 -> bit 6 (bit 7 = 1)
78 * NAND_CLE: bit 1 -> bit 4 78 * NAND_CLE: bit 1 -> bit 4
79 * NAND_ALE: bit 2 -> bit 5 79 * NAND_ALE: bit 2 -> bit 5
80 */ 80 */
@@ -83,12 +83,12 @@ static void ep7312_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
83 struct nand_chip *chip = mtd->priv; 83 struct nand_chip *chip = mtd->priv;
84 84
85 if (ctrl & NAND_CTRL_CHANGE) { 85 if (ctrl & NAND_CTRL_CHANGE) {
86 unsigned char bits; 86 unsigned char bits = 0x80;
87 87
88 bits = (ctrl & (NAND_CLE | NAND_ALE)) << 3; 88 bits |= (ctrl & (NAND_CLE | NAND_ALE)) << 3;
89 bits = (ctrl & NAND_NCE) << 7; 89 bits |= (ctrl & NAND_NCE) ? 0x00 : 0x40;
90 90
91 clps_writeb((clps_readb(ep7312_pxdr) & 0xB0) | 0x10, 91 clps_writeb((clps_readb(ep7312_pxdr) & 0xF0) | bits,
92 ep7312_pxdr); 92 ep7312_pxdr);
93 } 93 }
94 if (cmd != NAND_CMD_NONE) 94 if (cmd != NAND_CMD_NONE)
diff --git a/drivers/mtd/nand/excite_nandflash.c b/drivers/mtd/nand/excite_nandflash.c
index 7e9afc4c7757..bed87290decc 100644
--- a/drivers/mtd/nand/excite_nandflash.c
+++ b/drivers/mtd/nand/excite_nandflash.c
@@ -27,7 +27,6 @@
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/err.h> 29#include <linux/err.h>
30#include <linux/kernel.h>
31 30
32#include <linux/mtd/mtd.h> 31#include <linux/mtd/mtd.h>
33#include <linux/mtd/nand.h> 32#include <linux/mtd/nand.h>
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 7e68203fe1ba..d5691212058d 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -7,7 +7,7 @@
7 * Basic support for AG-AND chips is provided. 7 * Basic support for AG-AND chips is provided.
8 * 8 *
9 * Additional technical information is available on 9 * Additional technical information is available on
10 * http://www.linux-mtd.infradead.org/tech/nand.html 10 * http://www.linux-mtd.infradead.org/doc/nand.html
11 * 11 *
12 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) 12 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
13 * 2002-2006 Thomas Gleixner (tglx@linutronix.de) 13 * 2002-2006 Thomas Gleixner (tglx@linutronix.de)
@@ -24,6 +24,7 @@
24 * if we have HW ecc support. 24 * if we have HW ecc support.
25 * The AG-AND chips have nice features for speed improvement, 25 * The AG-AND chips have nice features for speed improvement,
26 * which are not supported yet. Read / program 4 pages in one go. 26 * which are not supported yet. Read / program 4 pages in one go.
27 * BBT table is not serialized, has to be fixed
27 * 28 *
28 * This program is free software; you can redistribute it and/or modify 29 * This program is free software; you can redistribute it and/or modify
29 * it under the terms of the GNU General Public License version 2 as 30 * it under the terms of the GNU General Public License version 2 as
@@ -360,6 +361,7 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
360 /* We write two bytes, so we dont have to mess with 16 bit 361 /* We write two bytes, so we dont have to mess with 16 bit
361 * access 362 * access
362 */ 363 */
364 nand_get_device(chip, mtd, FL_WRITING);
363 ofs += mtd->oobsize; 365 ofs += mtd->oobsize;
364 chip->ops.len = chip->ops.ooblen = 2; 366 chip->ops.len = chip->ops.ooblen = 2;
365 chip->ops.datbuf = NULL; 367 chip->ops.datbuf = NULL;
@@ -367,9 +369,11 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
367 chip->ops.ooboffs = chip->badblockpos & ~0x01; 369 chip->ops.ooboffs = chip->badblockpos & ~0x01;
368 370
369 ret = nand_do_write_oob(mtd, ofs, &chip->ops); 371 ret = nand_do_write_oob(mtd, ofs, &chip->ops);
372 nand_release_device(mtd);
370 } 373 }
371 if (!ret) 374 if (!ret)
372 mtd->ecc_stats.badblocks++; 375 mtd->ecc_stats.badblocks++;
376
373 return ret; 377 return ret;
374} 378}
375 379
@@ -768,7 +772,7 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
768 uint8_t *p = buf; 772 uint8_t *p = buf;
769 uint8_t *ecc_calc = chip->buffers->ecccalc; 773 uint8_t *ecc_calc = chip->buffers->ecccalc;
770 uint8_t *ecc_code = chip->buffers->ecccode; 774 uint8_t *ecc_code = chip->buffers->ecccode;
771 int *eccpos = chip->ecc.layout->eccpos; 775 uint32_t *eccpos = chip->ecc.layout->eccpos;
772 776
773 chip->ecc.read_page_raw(mtd, chip, buf); 777 chip->ecc.read_page_raw(mtd, chip, buf);
774 778
@@ -810,7 +814,7 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
810 uint8_t *p = buf; 814 uint8_t *p = buf;
811 uint8_t *ecc_calc = chip->buffers->ecccalc; 815 uint8_t *ecc_calc = chip->buffers->ecccalc;
812 uint8_t *ecc_code = chip->buffers->ecccode; 816 uint8_t *ecc_code = chip->buffers->ecccode;
813 int *eccpos = chip->ecc.layout->eccpos; 817 uint32_t *eccpos = chip->ecc.layout->eccpos;
814 818
815 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { 819 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
816 chip->ecc.hwctl(mtd, NAND_ECC_READ); 820 chip->ecc.hwctl(mtd, NAND_ECC_READ);
@@ -1416,7 +1420,7 @@ static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
1416 int eccsteps = chip->ecc.steps; 1420 int eccsteps = chip->ecc.steps;
1417 uint8_t *ecc_calc = chip->buffers->ecccalc; 1421 uint8_t *ecc_calc = chip->buffers->ecccalc;
1418 const uint8_t *p = buf; 1422 const uint8_t *p = buf;
1419 int *eccpos = chip->ecc.layout->eccpos; 1423 uint32_t *eccpos = chip->ecc.layout->eccpos;
1420 1424
1421 /* Software ecc calculation */ 1425 /* Software ecc calculation */
1422 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) 1426 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
@@ -1442,7 +1446,7 @@ static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
1442 int eccsteps = chip->ecc.steps; 1446 int eccsteps = chip->ecc.steps;
1443 uint8_t *ecc_calc = chip->buffers->ecccalc; 1447 uint8_t *ecc_calc = chip->buffers->ecccalc;
1444 const uint8_t *p = buf; 1448 const uint8_t *p = buf;
1445 int *eccpos = chip->ecc.layout->eccpos; 1449 uint32_t *eccpos = chip->ecc.layout->eccpos;
1446 1450
1447 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { 1451 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
1448 chip->ecc.hwctl(mtd, NAND_ECC_WRITE); 1452 chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c
index 2fc674a190cf..a3e3ab0185d5 100644
--- a/drivers/mtd/nand/nand_ids.c
+++ b/drivers/mtd/nand/nand_ids.c
@@ -141,6 +141,7 @@ struct nand_manufacturers nand_manuf_ids[] = {
141 {NAND_MFR_STMICRO, "ST Micro"}, 141 {NAND_MFR_STMICRO, "ST Micro"},
142 {NAND_MFR_HYNIX, "Hynix"}, 142 {NAND_MFR_HYNIX, "Hynix"},
143 {NAND_MFR_MICRON, "Micron"}, 143 {NAND_MFR_MICRON, "Micron"},
144 {NAND_MFR_AMD, "AMD"},
144 {0x0, "Unknown"} 145 {0x0, "Unknown"}
145}; 146};
146 147
diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c
index fd7a8d5ba29a..1c0e89f00e8d 100644
--- a/drivers/mtd/nand/ndfc.c
+++ b/drivers/mtd/nand/ndfc.c
@@ -24,7 +24,11 @@
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25 25
26#include <asm/io.h> 26#include <asm/io.h>
27#ifdef CONFIG_40x
28#include <asm/ibm405.h>
29#else
27#include <asm/ibm44x.h> 30#include <asm/ibm44x.h>
31#endif
28 32
29struct ndfc_nand_mtd { 33struct ndfc_nand_mtd {
30 struct mtd_info mtd; 34 struct mtd_info mtd;
@@ -230,7 +234,11 @@ static int ndfc_nand_probe(struct platform_device *pdev)
230 struct ndfc_controller *ndfc = &ndfc_ctrl; 234 struct ndfc_controller *ndfc = &ndfc_ctrl;
231 unsigned long long phys = settings->ndfc_erpn | res->start; 235 unsigned long long phys = settings->ndfc_erpn | res->start;
232 236
237#ifndef CONFIG_PHYS_64BIT
238 ndfc->ndfcbase = ioremap((phys_addr_t)phys, res->end - res->start + 1);
239#else
233 ndfc->ndfcbase = ioremap64(phys, res->end - res->start + 1); 240 ndfc->ndfcbase = ioremap64(phys, res->end - res->start + 1);
241#endif
234 if (!ndfc->ndfcbase) { 242 if (!ndfc->ndfcbase) {
235 printk(KERN_ERR "NDFC: ioremap failed\n"); 243 printk(KERN_ERR "NDFC: ioremap failed\n");
236 return -EIO; 244 return -EIO;
diff --git a/drivers/mtd/onenand/Kconfig b/drivers/mtd/onenand/Kconfig
index c257d397d08a..cb41cbca64f7 100644
--- a/drivers/mtd/onenand/Kconfig
+++ b/drivers/mtd/onenand/Kconfig
@@ -40,4 +40,27 @@ config MTD_ONENAND_OTP
40 40
41 OTP block is fully-guaranteed to be a valid block. 41 OTP block is fully-guaranteed to be a valid block.
42 42
43config MTD_ONENAND_2X_PROGRAM
44 bool "OneNAND 2X program support"
45 help
46 The 2X Program is an extension of Program Operation.
47 Since the device is equipped with two DataRAMs, and two-plane NAND
48 Flash memory array, these two component enables simultaneous program
49 of 4KiB. Plane1 has only even blocks such as block0, block2, block4
50 while Plane2 has only odd blocks such as block1, block3, block5.
51 So MTD regards it as 4KiB page size and 256KiB block size
52
53 Now the following chips support it. (KFXXX16Q2M)
54 Demux: KFG2G16Q2M, KFH4G16Q2M, KFW8G16Q2M,
55 Mux: KFM2G16Q2M, KFN4G16Q2M,
56
57 And more recent chips
58
59config MTD_ONENAND_SIM
60 tristate "OneNAND simulator support"
61 depends on MTD_PARTITIONS
62 help
63 The simulator may simulate various OneNAND flash chips for the
64 OneNAND MTD layer.
65
43endif # MTD_ONENAND 66endif # MTD_ONENAND
diff --git a/drivers/mtd/onenand/Makefile b/drivers/mtd/onenand/Makefile
index 269cfe467345..4d2eacfd7e11 100644
--- a/drivers/mtd/onenand/Makefile
+++ b/drivers/mtd/onenand/Makefile
@@ -8,4 +8,7 @@ obj-$(CONFIG_MTD_ONENAND) += onenand.o
8# Board specific. 8# Board specific.
9obj-$(CONFIG_MTD_ONENAND_GENERIC) += generic.o 9obj-$(CONFIG_MTD_ONENAND_GENERIC) += generic.o
10 10
11# Simulator
12obj-$(CONFIG_MTD_ONENAND_SIM) += onenand_sim.o
13
11onenand-objs = onenand_base.o onenand_bbt.o 14onenand-objs = onenand_base.o onenand_bbt.o
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 0537fac8de74..7d194cfdb873 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -206,6 +206,15 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
206 default: 206 default:
207 block = (int) (addr >> this->erase_shift); 207 block = (int) (addr >> this->erase_shift);
208 page = (int) (addr >> this->page_shift); 208 page = (int) (addr >> this->page_shift);
209
210 if (ONENAND_IS_2PLANE(this)) {
211 /* Make the even block number */
212 block &= ~1;
213 /* Is it the odd plane? */
214 if (addr & this->writesize)
215 block++;
216 page >>= 1;
217 }
209 page &= this->page_mask; 218 page &= this->page_mask;
210 break; 219 break;
211 } 220 }
@@ -216,8 +225,12 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
216 value = onenand_bufferram_address(this, block); 225 value = onenand_bufferram_address(this, block);
217 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2); 226 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
218 227
219 /* Switch to the next data buffer */ 228 if (ONENAND_IS_2PLANE(this))
220 ONENAND_SET_NEXT_BUFFERRAM(this); 229 /* It is always BufferRAM0 */
230 ONENAND_SET_BUFFERRAM0(this);
231 else
232 /* Switch to the next data buffer */
233 ONENAND_SET_NEXT_BUFFERRAM(this);
221 234
222 return 0; 235 return 0;
223 } 236 }
@@ -247,6 +260,8 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le
247 break; 260 break;
248 261
249 default: 262 default:
263 if (ONENAND_IS_2PLANE(this) && cmd == ONENAND_CMD_PROG)
264 cmd = ONENAND_CMD_2X_PROG;
250 dataram = ONENAND_CURRENT_BUFFERRAM(this); 265 dataram = ONENAND_CURRENT_BUFFERRAM(this);
251 break; 266 break;
252 } 267 }
@@ -445,8 +460,9 @@ static inline int onenand_bufferram_offset(struct mtd_info *mtd, int area)
445 struct onenand_chip *this = mtd->priv; 460 struct onenand_chip *this = mtd->priv;
446 461
447 if (ONENAND_CURRENT_BUFFERRAM(this)) { 462 if (ONENAND_CURRENT_BUFFERRAM(this)) {
463 /* Note: the 'this->writesize' is a real page size */
448 if (area == ONENAND_DATARAM) 464 if (area == ONENAND_DATARAM)
449 return mtd->writesize; 465 return this->writesize;
450 if (area == ONENAND_SPARERAM) 466 if (area == ONENAND_SPARERAM)
451 return mtd->oobsize; 467 return mtd->oobsize;
452 } 468 }
@@ -572,6 +588,30 @@ static int onenand_write_bufferram(struct mtd_info *mtd, int area,
572} 588}
573 589
574/** 590/**
591 * onenand_get_2x_blockpage - [GENERIC] Get blockpage at 2x program mode
592 * @param mtd MTD data structure
593 * @param addr address to check
594 * @return blockpage address
595 *
596 * Get blockpage address at 2x program mode
597 */
598static int onenand_get_2x_blockpage(struct mtd_info *mtd, loff_t addr)
599{
600 struct onenand_chip *this = mtd->priv;
601 int blockpage, block, page;
602
603 /* Calculate the even block number */
604 block = (int) (addr >> this->erase_shift) & ~1;
605 /* Is it the odd plane? */
606 if (addr & this->writesize)
607 block++;
608 page = (int) (addr >> (this->page_shift + 1)) & this->page_mask;
609 blockpage = (block << 7) | page;
610
611 return blockpage;
612}
613
614/**
575 * onenand_check_bufferram - [GENERIC] Check BufferRAM information 615 * onenand_check_bufferram - [GENERIC] Check BufferRAM information
576 * @param mtd MTD data structure 616 * @param mtd MTD data structure
577 * @param addr address to check 617 * @param addr address to check
@@ -585,7 +625,10 @@ static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr)
585 int blockpage, found = 0; 625 int blockpage, found = 0;
586 unsigned int i; 626 unsigned int i;
587 627
588 blockpage = (int) (addr >> this->page_shift); 628 if (ONENAND_IS_2PLANE(this))
629 blockpage = onenand_get_2x_blockpage(mtd, addr);
630 else
631 blockpage = (int) (addr >> this->page_shift);
589 632
590 /* Is there valid data? */ 633 /* Is there valid data? */
591 i = ONENAND_CURRENT_BUFFERRAM(this); 634 i = ONENAND_CURRENT_BUFFERRAM(this);
@@ -625,7 +668,10 @@ static void onenand_update_bufferram(struct mtd_info *mtd, loff_t addr,
625 int blockpage; 668 int blockpage;
626 unsigned int i; 669 unsigned int i;
627 670
628 blockpage = (int) (addr >> this->page_shift); 671 if (ONENAND_IS_2PLANE(this))
672 blockpage = onenand_get_2x_blockpage(mtd, addr);
673 else
674 blockpage = (int) (addr >> this->page_shift);
629 675
630 /* Invalidate another BufferRAM */ 676 /* Invalidate another BufferRAM */
631 i = ONENAND_NEXT_BUFFERRAM(this); 677 i = ONENAND_NEXT_BUFFERRAM(this);
@@ -734,6 +780,7 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
734 int read = 0, column; 780 int read = 0, column;
735 int thislen; 781 int thislen;
736 int ret = 0, boundary = 0; 782 int ret = 0, boundary = 0;
783 int writesize = this->writesize;
737 784
738 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len); 785 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
739 786
@@ -754,22 +801,22 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
754 /* Do first load to bufferRAM */ 801 /* Do first load to bufferRAM */
755 if (read < len) { 802 if (read < len) {
756 if (!onenand_check_bufferram(mtd, from)) { 803 if (!onenand_check_bufferram(mtd, from)) {
757 this->command(mtd, ONENAND_CMD_READ, from, mtd->writesize); 804 this->command(mtd, ONENAND_CMD_READ, from, writesize);
758 ret = this->wait(mtd, FL_READING); 805 ret = this->wait(mtd, FL_READING);
759 onenand_update_bufferram(mtd, from, !ret); 806 onenand_update_bufferram(mtd, from, !ret);
760 } 807 }
761 } 808 }
762 809
763 thislen = min_t(int, mtd->writesize, len - read); 810 thislen = min_t(int, writesize, len - read);
764 column = from & (mtd->writesize - 1); 811 column = from & (writesize - 1);
765 if (column + thislen > mtd->writesize) 812 if (column + thislen > writesize)
766 thislen = mtd->writesize - column; 813 thislen = writesize - column;
767 814
768 while (!ret) { 815 while (!ret) {
769 /* If there is more to load then start next load */ 816 /* If there is more to load then start next load */
770 from += thislen; 817 from += thislen;
771 if (read + thislen < len) { 818 if (read + thislen < len) {
772 this->command(mtd, ONENAND_CMD_READ, from, mtd->writesize); 819 this->command(mtd, ONENAND_CMD_READ, from, writesize);
773 /* 820 /*
774 * Chip boundary handling in DDP 821 * Chip boundary handling in DDP
775 * Now we issued chip 1 read and pointed chip 1 822 * Now we issued chip 1 read and pointed chip 1
@@ -794,7 +841,7 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
794 this->write_word(ONENAND_DDP_CHIP1, this->base + ONENAND_REG_START_ADDRESS2); 841 this->write_word(ONENAND_DDP_CHIP1, this->base + ONENAND_REG_START_ADDRESS2);
795 ONENAND_SET_NEXT_BUFFERRAM(this); 842 ONENAND_SET_NEXT_BUFFERRAM(this);
796 buf += thislen; 843 buf += thislen;
797 thislen = min_t(int, mtd->writesize, len - read); 844 thislen = min_t(int, writesize, len - read);
798 column = 0; 845 column = 0;
799 cond_resched(); 846 cond_resched();
800 /* Now wait for load */ 847 /* Now wait for load */
@@ -1079,7 +1126,7 @@ int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
1079 /* Read more? */ 1126 /* Read more? */
1080 if (read < len) { 1127 if (read < len) {
1081 /* Update Page size */ 1128 /* Update Page size */
1082 from += mtd->writesize; 1129 from += this->writesize;
1083 column = 0; 1130 column = 0;
1084 } 1131 }
1085 } 1132 }
@@ -1135,12 +1182,12 @@ static int onenand_verify(struct mtd_info *mtd, const u_char *buf, loff_t addr,
1135 int thislen, column; 1182 int thislen, column;
1136 1183
1137 while (len != 0) { 1184 while (len != 0) {
1138 thislen = min_t(int, mtd->writesize, len); 1185 thislen = min_t(int, this->writesize, len);
1139 column = addr & (mtd->writesize - 1); 1186 column = addr & (this->writesize - 1);
1140 if (column + thislen > mtd->writesize) 1187 if (column + thislen > this->writesize)
1141 thislen = mtd->writesize - column; 1188 thislen = this->writesize - column;
1142 1189
1143 this->command(mtd, ONENAND_CMD_READ, addr, mtd->writesize); 1190 this->command(mtd, ONENAND_CMD_READ, addr, this->writesize);
1144 1191
1145 onenand_update_bufferram(mtd, addr, 0); 1192 onenand_update_bufferram(mtd, addr, 0);
1146 1193
@@ -1236,6 +1283,10 @@ static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
1236 1283
1237 /* In partial page write we don't update bufferram */ 1284 /* In partial page write we don't update bufferram */
1238 onenand_update_bufferram(mtd, to, !ret && !subpage); 1285 onenand_update_bufferram(mtd, to, !ret && !subpage);
1286 if (ONENAND_IS_2PLANE(this)) {
1287 ONENAND_SET_BUFFERRAM1(this);
1288 onenand_update_bufferram(mtd, to + this->writesize, !ret && !subpage);
1289 }
1239 1290
1240 if (ret) { 1291 if (ret) {
1241 printk(KERN_ERR "onenand_write: write filaed %d\n", ret); 1292 printk(KERN_ERR "onenand_write: write filaed %d\n", ret);
@@ -1384,6 +1435,10 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
1384 this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize); 1435 this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize);
1385 1436
1386 onenand_update_bufferram(mtd, to, 0); 1437 onenand_update_bufferram(mtd, to, 0);
1438 if (ONENAND_IS_2PLANE(this)) {
1439 ONENAND_SET_BUFFERRAM1(this);
1440 onenand_update_bufferram(mtd, to + this->writesize, 0);
1441 }
1387 1442
1388 ret = this->wait(mtd, FL_WRITING); 1443 ret = this->wait(mtd, FL_WRITING);
1389 if (ret) { 1444 if (ret) {
@@ -2107,6 +2162,7 @@ static int onenand_lock_user_prot_reg(struct mtd_info *mtd, loff_t from,
2107 * 2162 *
2108 * Check and set OneNAND features 2163 * Check and set OneNAND features
2109 * - lock scheme 2164 * - lock scheme
2165 * - two plane
2110 */ 2166 */
2111static void onenand_check_features(struct mtd_info *mtd) 2167static void onenand_check_features(struct mtd_info *mtd)
2112{ 2168{
@@ -2118,19 +2174,35 @@ static void onenand_check_features(struct mtd_info *mtd)
2118 process = this->version_id >> ONENAND_VERSION_PROCESS_SHIFT; 2174 process = this->version_id >> ONENAND_VERSION_PROCESS_SHIFT;
2119 2175
2120 /* Lock scheme */ 2176 /* Lock scheme */
2121 if (density >= ONENAND_DEVICE_DENSITY_1Gb) { 2177 switch (density) {
2178 case ONENAND_DEVICE_DENSITY_4Gb:
2179 this->options |= ONENAND_HAS_2PLANE;
2180
2181 case ONENAND_DEVICE_DENSITY_2Gb:
2182 /* 2Gb DDP don't have 2 plane */
2183 if (!ONENAND_IS_DDP(this))
2184 this->options |= ONENAND_HAS_2PLANE;
2185 this->options |= ONENAND_HAS_UNLOCK_ALL;
2186
2187 case ONENAND_DEVICE_DENSITY_1Gb:
2122 /* A-Die has all block unlock */ 2188 /* A-Die has all block unlock */
2123 if (process) { 2189 if (process)
2124 printk(KERN_DEBUG "Chip support all block unlock\n");
2125 this->options |= ONENAND_HAS_UNLOCK_ALL; 2190 this->options |= ONENAND_HAS_UNLOCK_ALL;
2126 } 2191 break;
2127 } else { 2192
2128 /* Some OneNAND has continues lock scheme */ 2193 default:
2129 if (!process) { 2194 /* Some OneNAND has continuous lock scheme */
2130 printk(KERN_DEBUG "Lock scheme is Continues Lock\n"); 2195 if (!process)
2131 this->options |= ONENAND_HAS_CONT_LOCK; 2196 this->options |= ONENAND_HAS_CONT_LOCK;
2132 } 2197 break;
2133 } 2198 }
2199
2200 if (this->options & ONENAND_HAS_CONT_LOCK)
2201 printk(KERN_DEBUG "Lock scheme is Continuous Lock\n");
2202 if (this->options & ONENAND_HAS_UNLOCK_ALL)
2203 printk(KERN_DEBUG "Chip support all block unlock\n");
2204 if (this->options & ONENAND_HAS_2PLANE)
2205 printk(KERN_DEBUG "Chip has 2 plane\n");
2134} 2206}
2135 2207
2136/** 2208/**
@@ -2257,6 +2329,8 @@ static int onenand_probe(struct mtd_info *mtd)
2257 this->erase_shift = ffs(mtd->erasesize) - 1; 2329 this->erase_shift = ffs(mtd->erasesize) - 1;
2258 this->page_shift = ffs(mtd->writesize) - 1; 2330 this->page_shift = ffs(mtd->writesize) - 1;
2259 this->page_mask = (1 << (this->erase_shift - this->page_shift)) - 1; 2331 this->page_mask = (1 << (this->erase_shift - this->page_shift)) - 1;
2332 /* It's real page size */
2333 this->writesize = mtd->writesize;
2260 2334
2261 /* REVIST: Multichip handling */ 2335 /* REVIST: Multichip handling */
2262 2336
@@ -2265,6 +2339,17 @@ static int onenand_probe(struct mtd_info *mtd)
2265 /* Check OneNAND features */ 2339 /* Check OneNAND features */
2266 onenand_check_features(mtd); 2340 onenand_check_features(mtd);
2267 2341
2342 /*
2343 * We emulate the 4KiB page and 256KiB erase block size
2344 * But oobsize is still 64 bytes.
2345 * It is only valid if you turn on 2X program support,
2346 * Otherwise it will be ignored by compiler.
2347 */
2348 if (ONENAND_IS_2PLANE(this)) {
2349 mtd->writesize <<= 1;
2350 mtd->erasesize <<= 1;
2351 }
2352
2268 return 0; 2353 return 0;
2269} 2354}
2270 2355
diff --git a/drivers/mtd/onenand/onenand_sim.c b/drivers/mtd/onenand/onenand_sim.c
new file mode 100644
index 000000000000..0d89ad5776fa
--- /dev/null
+++ b/drivers/mtd/onenand/onenand_sim.c
@@ -0,0 +1,495 @@
1/*
2 * linux/drivers/mtd/onenand/onenand_sim.c
3 *
4 * The OneNAND simulator
5 *
6 * Copyright © 2005-2007 Samsung Electronics
7 * Kyungmin Park <kyungmin.park@samsung.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/vmalloc.h>
18#include <linux/mtd/mtd.h>
19#include <linux/mtd/partitions.h>
20#include <linux/mtd/onenand.h>
21
22#include <linux/io.h>
23
24#ifndef CONFIG_ONENAND_SIM_MANUFACTURER
25#define CONFIG_ONENAND_SIM_MANUFACTURER 0xec
26#endif
27#ifndef CONFIG_ONENAND_SIM_DEVICE_ID
28#define CONFIG_ONENAND_SIM_DEVICE_ID 0x04
29#endif
30#ifndef CONFIG_ONENAND_SIM_VERSION_ID
31#define CONFIG_ONENAND_SIM_VERSION_ID 0x1e
32#endif
33
34static int manuf_id = CONFIG_ONENAND_SIM_MANUFACTURER;
35static int device_id = CONFIG_ONENAND_SIM_DEVICE_ID;
36static int version_id = CONFIG_ONENAND_SIM_VERSION_ID;
37
38struct onenand_flash {
39 void __iomem *base;
40 void __iomem *data;
41};
42
43#define ONENAND_CORE(flash) (flash->data)
44#define ONENAND_CORE_SPARE(flash, this, offset) \
45 ((flash->data) + (this->chipsize) + (offset >> 5))
46
47#define ONENAND_MAIN_AREA(this, offset) \
48 (this->base + ONENAND_DATARAM + offset)
49
50#define ONENAND_SPARE_AREA(this, offset) \
51 (this->base + ONENAND_SPARERAM + offset)
52
53#define ONENAND_GET_WP_STATUS(this) \
54 (readw(this->base + ONENAND_REG_WP_STATUS))
55
56#define ONENAND_SET_WP_STATUS(v, this) \
57 (writew(v, this->base + ONENAND_REG_WP_STATUS))
58
59/* It has all 0xff chars */
60#define MAX_ONENAND_PAGESIZE (2048 + 64)
61static unsigned char *ffchars;
62
63static struct mtd_partition os_partitions[] = {
64 {
65 .name = "OneNAND simulator partition",
66 .offset = 0,
67 .size = MTDPART_SIZ_FULL,
68 },
69};
70
71/*
72 * OneNAND simulator mtd
73 */
74struct onenand_info {
75 struct mtd_info mtd;
76 struct mtd_partition *parts;
77 struct onenand_chip onenand;
78 struct onenand_flash flash;
79};
80
81static struct onenand_info *info;
82
83#define DPRINTK(format, args...) \
84do { \
85 printk(KERN_DEBUG "%s[%d]: " format "\n", __func__, \
86 __LINE__, ##args); \
87} while (0)
88
89/**
90 * onenand_lock_handle - Handle Lock scheme
91 * @param this OneNAND device structure
92 * @param cmd The command to be sent
93 *
94 * Send lock command to OneNAND device.
95 * The lock scheme is depends on chip type.
96 */
97static void onenand_lock_handle(struct onenand_chip *this, int cmd)
98{
99 int block_lock_scheme;
100 int status;
101
102 status = ONENAND_GET_WP_STATUS(this);
103 block_lock_scheme = !(this->options & ONENAND_HAS_CONT_LOCK);
104
105 switch (cmd) {
106 case ONENAND_CMD_UNLOCK:
107 if (block_lock_scheme)
108 ONENAND_SET_WP_STATUS(ONENAND_WP_US, this);
109 else
110 ONENAND_SET_WP_STATUS(status | ONENAND_WP_US, this);
111 break;
112
113 case ONENAND_CMD_LOCK:
114 if (block_lock_scheme)
115 ONENAND_SET_WP_STATUS(ONENAND_WP_LS, this);
116 else
117 ONENAND_SET_WP_STATUS(status | ONENAND_WP_LS, this);
118 break;
119
120 case ONENAND_CMD_LOCK_TIGHT:
121 if (block_lock_scheme)
122 ONENAND_SET_WP_STATUS(ONENAND_WP_LTS, this);
123 else
124 ONENAND_SET_WP_STATUS(status | ONENAND_WP_LTS, this);
125 break;
126
127 default:
128 break;
129 }
130}
131
132/**
133 * onenand_bootram_handle - Handle BootRAM area
134 * @param this OneNAND device structure
135 * @param cmd The command to be sent
136 *
137 * Emulate BootRAM area. It is possible to do basic operation using BootRAM.
138 */
139static void onenand_bootram_handle(struct onenand_chip *this, int cmd)
140{
141 switch (cmd) {
142 case ONENAND_CMD_READID:
143 writew(manuf_id, this->base);
144 writew(device_id, this->base + 2);
145 writew(version_id, this->base + 4);
146 break;
147
148 default:
149 /* REVIST: Handle other commands */
150 break;
151 }
152}
153
154/**
155 * onenand_update_interrupt - Set interrupt register
156 * @param this OneNAND device structure
157 * @param cmd The command to be sent
158 *
159 * Update interrupt register. The status is depends on command.
160 */
161static void onenand_update_interrupt(struct onenand_chip *this, int cmd)
162{
163 int interrupt = ONENAND_INT_MASTER;
164
165 switch (cmd) {
166 case ONENAND_CMD_READ:
167 case ONENAND_CMD_READOOB:
168 interrupt |= ONENAND_INT_READ;
169 break;
170
171 case ONENAND_CMD_PROG:
172 case ONENAND_CMD_PROGOOB:
173 interrupt |= ONENAND_INT_WRITE;
174 break;
175
176 case ONENAND_CMD_ERASE:
177 interrupt |= ONENAND_INT_ERASE;
178 break;
179
180 case ONENAND_CMD_RESET:
181 interrupt |= ONENAND_INT_RESET;
182 break;
183
184 default:
185 break;
186 }
187
188 writew(interrupt, this->base + ONENAND_REG_INTERRUPT);
189}
190
191/**
192 * onenand_check_overwrite - Check over-write if happend
193 * @param dest The destination pointer
194 * @param src The source pointer
195 * @param count The length to be check
196 * @return 0 on same, otherwise 1
197 *
198 * Compare the source with destination
199 */
200static int onenand_check_overwrite(void *dest, void *src, size_t count)
201{
202 unsigned int *s = (unsigned int *) src;
203 unsigned int *d = (unsigned int *) dest;
204 int i;
205
206 count >>= 2;
207 for (i = 0; i < count; i++)
208 if ((*s++ ^ *d++) != 0)
209 return 1;
210
211 return 0;
212}
213
214/**
215 * onenand_data_handle - Handle OneNAND Core and DataRAM
216 * @param this OneNAND device structure
217 * @param cmd The command to be sent
218 * @param dataram Which dataram used
219 * @param offset The offset to OneNAND Core
220 *
221 * Copy data from OneNAND Core to DataRAM (read)
222 * Copy data from DataRAM to OneNAND Core (write)
223 * Erase the OneNAND Core (erase)
224 */
225static void onenand_data_handle(struct onenand_chip *this, int cmd,
226 int dataram, unsigned int offset)
227{
228 struct mtd_info *mtd = &info->mtd;
229 struct onenand_flash *flash = this->priv;
230 int main_offset, spare_offset;
231 void __iomem *src;
232 void __iomem *dest;
233 unsigned int i;
234
235 if (dataram) {
236 main_offset = mtd->writesize;
237 spare_offset = mtd->oobsize;
238 } else {
239 main_offset = 0;
240 spare_offset = 0;
241 }
242
243 switch (cmd) {
244 case ONENAND_CMD_READ:
245 src = ONENAND_CORE(flash) + offset;
246 dest = ONENAND_MAIN_AREA(this, main_offset);
247 memcpy(dest, src, mtd->writesize);
248 /* Fall through */
249
250 case ONENAND_CMD_READOOB:
251 src = ONENAND_CORE_SPARE(flash, this, offset);
252 dest = ONENAND_SPARE_AREA(this, spare_offset);
253 memcpy(dest, src, mtd->oobsize);
254 break;
255
256 case ONENAND_CMD_PROG:
257 src = ONENAND_MAIN_AREA(this, main_offset);
258 dest = ONENAND_CORE(flash) + offset;
259 /* To handle partial write */
260 for (i = 0; i < (1 << mtd->subpage_sft); i++) {
261 int off = i * this->subpagesize;
262 if (!memcmp(src + off, ffchars, this->subpagesize))
263 continue;
264 if (memcmp(dest + off, ffchars, this->subpagesize) &&
265 onenand_check_overwrite(dest + off, src + off, this->subpagesize))
266 printk(KERN_ERR "over-write happend at 0x%08x\n", offset);
267 memcpy(dest + off, src + off, this->subpagesize);
268 }
269 /* Fall through */
270
271 case ONENAND_CMD_PROGOOB:
272 src = ONENAND_SPARE_AREA(this, spare_offset);
273 /* Check all data is 0xff chars */
274 if (!memcmp(src, ffchars, mtd->oobsize))
275 break;
276
277 dest = ONENAND_CORE_SPARE(flash, this, offset);
278 if (memcmp(dest, ffchars, mtd->oobsize) &&
279 onenand_check_overwrite(dest, src, mtd->oobsize))
280 printk(KERN_ERR "OOB: over-write happend at 0x%08x\n",
281 offset);
282 memcpy(dest, src, mtd->oobsize);
283 break;
284
285 case ONENAND_CMD_ERASE:
286 memset(ONENAND_CORE(flash) + offset, 0xff, mtd->erasesize);
287 memset(ONENAND_CORE_SPARE(flash, this, offset), 0xff,
288 (mtd->erasesize >> 5));
289 break;
290
291 default:
292 break;
293 }
294}
295
296/**
297 * onenand_command_handle - Handle command
298 * @param this OneNAND device structure
299 * @param cmd The command to be sent
300 *
301 * Emulate OneNAND command.
302 */
303static void onenand_command_handle(struct onenand_chip *this, int cmd)
304{
305 unsigned long offset = 0;
306 int block = -1, page = -1, bufferram = -1;
307 int dataram = 0;
308
309 switch (cmd) {
310 case ONENAND_CMD_UNLOCK:
311 case ONENAND_CMD_LOCK:
312 case ONENAND_CMD_LOCK_TIGHT:
313 case ONENAND_CMD_UNLOCK_ALL:
314 onenand_lock_handle(this, cmd);
315 break;
316
317 case ONENAND_CMD_BUFFERRAM:
318 /* Do nothing */
319 return;
320
321 default:
322 block = (int) readw(this->base + ONENAND_REG_START_ADDRESS1);
323 if (block & (1 << ONENAND_DDP_SHIFT)) {
324 block &= ~(1 << ONENAND_DDP_SHIFT);
325 /* The half of chip block */
326 block += this->chipsize >> (this->erase_shift + 1);
327 }
328 if (cmd == ONENAND_CMD_ERASE)
329 break;
330
331 page = (int) readw(this->base + ONENAND_REG_START_ADDRESS8);
332 page = (page >> ONENAND_FPA_SHIFT);
333 bufferram = (int) readw(this->base + ONENAND_REG_START_BUFFER);
334 bufferram >>= ONENAND_BSA_SHIFT;
335 bufferram &= ONENAND_BSA_DATARAM1;
336 dataram = (bufferram == ONENAND_BSA_DATARAM1) ? 1 : 0;
337 break;
338 }
339
340 if (block != -1)
341 offset += block << this->erase_shift;
342
343 if (page != -1)
344 offset += page << this->page_shift;
345
346 onenand_data_handle(this, cmd, dataram, offset);
347
348 onenand_update_interrupt(this, cmd);
349}
350
351/**
352 * onenand_writew - [OneNAND Interface] Emulate write operation
353 * @param value value to write
354 * @param addr address to write
355 *
356 * Write OneNAND register with value
357 */
358static void onenand_writew(unsigned short value, void __iomem * addr)
359{
360 struct onenand_chip *this = info->mtd.priv;
361
362 /* BootRAM handling */
363 if (addr < this->base + ONENAND_DATARAM) {
364 onenand_bootram_handle(this, value);
365 return;
366 }
367 /* Command handling */
368 if (addr == this->base + ONENAND_REG_COMMAND)
369 onenand_command_handle(this, value);
370
371 writew(value, addr);
372}
373
374/**
375 * flash_init - Initialize OneNAND simulator
376 * @param flash OneNAND simulaotr data strucutres
377 *
378 * Initialize OneNAND simulator.
379 */
380static int __init flash_init(struct onenand_flash *flash)
381{
382 int density, size;
383 int buffer_size;
384
385 flash->base = kzalloc(131072, GFP_KERNEL);
386 if (!flash->base) {
387 printk(KERN_ERR "Unable to allocate base address.\n");
388 return -ENOMEM;
389 }
390
391 density = device_id >> ONENAND_DEVICE_DENSITY_SHIFT;
392 size = ((16 << 20) << density);
393
394 ONENAND_CORE(flash) = vmalloc(size + (size >> 5));
395 if (!ONENAND_CORE(flash)) {
396 printk(KERN_ERR "Unable to allocate nand core address.\n");
397 kfree(flash->base);
398 return -ENOMEM;
399 }
400
401 memset(ONENAND_CORE(flash), 0xff, size + (size >> 5));
402
403 /* Setup registers */
404 writew(manuf_id, flash->base + ONENAND_REG_MANUFACTURER_ID);
405 writew(device_id, flash->base + ONENAND_REG_DEVICE_ID);
406 writew(version_id, flash->base + ONENAND_REG_VERSION_ID);
407
408 if (density < 2)
409 buffer_size = 0x0400; /* 1KiB page */
410 else
411 buffer_size = 0x0800; /* 2KiB page */
412 writew(buffer_size, flash->base + ONENAND_REG_DATA_BUFFER_SIZE);
413
414 return 0;
415}
416
417/**
418 * flash_exit - Clean up OneNAND simulator
419 * @param flash OneNAND simulaotr data strucutres
420 *
421 * Clean up OneNAND simulator.
422 */
423static void flash_exit(struct onenand_flash *flash)
424{
425 vfree(ONENAND_CORE(flash));
426 kfree(flash->base);
427 kfree(flash);
428}
429
430static int __init onenand_sim_init(void)
431{
432 /* Allocate all 0xff chars pointer */
433 ffchars = kmalloc(MAX_ONENAND_PAGESIZE, GFP_KERNEL);
434 if (!ffchars) {
435 printk(KERN_ERR "Unable to allocate ff chars.\n");
436 return -ENOMEM;
437 }
438 memset(ffchars, 0xff, MAX_ONENAND_PAGESIZE);
439
440 /* Allocate OneNAND simulator mtd pointer */
441 info = kzalloc(sizeof(struct onenand_info), GFP_KERNEL);
442 if (!info) {
443 printk(KERN_ERR "Unable to allocate core structures.\n");
444 kfree(ffchars);
445 return -ENOMEM;
446 }
447
448 /* Override write_word function */
449 info->onenand.write_word = onenand_writew;
450
451 if (flash_init(&info->flash)) {
452 printk(KERN_ERR "Unable to allocat flash.\n");
453 kfree(ffchars);
454 kfree(info);
455 return -ENOMEM;
456 }
457
458 info->parts = os_partitions;
459
460 info->onenand.base = info->flash.base;
461 info->onenand.priv = &info->flash;
462
463 info->mtd.name = "OneNAND simulator";
464 info->mtd.priv = &info->onenand;
465 info->mtd.owner = THIS_MODULE;
466
467 if (onenand_scan(&info->mtd, 1)) {
468 flash_exit(&info->flash);
469 kfree(ffchars);
470 kfree(info);
471 return -ENXIO;
472 }
473
474 add_mtd_partitions(&info->mtd, info->parts, ARRAY_SIZE(os_partitions));
475
476 return 0;
477}
478
479static void __exit onenand_sim_exit(void)
480{
481 struct onenand_chip *this = info->mtd.priv;
482 struct onenand_flash *flash = this->priv;
483
484 onenand_release(&info->mtd);
485 flash_exit(flash);
486 kfree(ffchars);
487 kfree(info);
488}
489
490module_init(onenand_sim_init);
491module_exit(onenand_sim_exit);
492
493MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
494MODULE_DESCRIPTION("The OneNAND flash simulator");
495MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/rfd_ftl.c b/drivers/mtd/rfd_ftl.c
index d4b1ba8f23ef..823fba4e6d2f 100644
--- a/drivers/mtd/rfd_ftl.c
+++ b/drivers/mtd/rfd_ftl.c
@@ -779,9 +779,8 @@ static void rfd_ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
779 else { 779 else {
780 if (!mtd->erasesize) { 780 if (!mtd->erasesize) {
781 printk(KERN_WARNING PREFIX "please provide block_size"); 781 printk(KERN_WARNING PREFIX "please provide block_size");
782 return; 782 goto out;
783 } 783 } else
784 else
785 part->block_size = mtd->erasesize; 784 part->block_size = mtd->erasesize;
786 } 785 }
787 786
@@ -803,7 +802,7 @@ static void rfd_ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
803 if (!add_mtd_blktrans_dev((void*)part)) 802 if (!add_mtd_blktrans_dev((void*)part))
804 return; 803 return;
805 } 804 }
806 805out:
807 kfree(part); 806 kfree(part);
808} 807}
809 808
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c
index 94ee54934411..29c41eeb09fe 100644
--- a/drivers/mtd/ubi/scan.c
+++ b/drivers/mtd/ubi/scan.c
@@ -1314,11 +1314,10 @@ static int paranoid_check_si(const struct ubi_device *ubi,
1314 * Make sure that all the physical eraseblocks are in one of the lists 1314 * Make sure that all the physical eraseblocks are in one of the lists
1315 * or trees. 1315 * or trees.
1316 */ 1316 */
1317 buf = kmalloc(ubi->peb_count, GFP_KERNEL); 1317 buf = kzalloc(ubi->peb_count, GFP_KERNEL);
1318 if (!buf) 1318 if (!buf)
1319 return -ENOMEM; 1319 return -ENOMEM;
1320 1320
1321 memset(buf, 1, ubi->peb_count);
1322 for (pnum = 0; pnum < ubi->peb_count; pnum++) { 1321 for (pnum = 0; pnum < ubi->peb_count; pnum++) {
1323 err = ubi_io_is_bad(ubi, pnum); 1322 err = ubi_io_is_bad(ubi, pnum);
1324 if (err < 0) { 1323 if (err < 0) {
@@ -1326,28 +1325,28 @@ static int paranoid_check_si(const struct ubi_device *ubi,
1326 return err; 1325 return err;
1327 } 1326 }
1328 else if (err) 1327 else if (err)
1329 buf[pnum] = 0; 1328 buf[pnum] = 1;
1330 } 1329 }
1331 1330
1332 ubi_rb_for_each_entry(rb1, sv, &si->volumes, rb) 1331 ubi_rb_for_each_entry(rb1, sv, &si->volumes, rb)
1333 ubi_rb_for_each_entry(rb2, seb, &sv->root, u.rb) 1332 ubi_rb_for_each_entry(rb2, seb, &sv->root, u.rb)
1334 buf[seb->pnum] = 0; 1333 buf[seb->pnum] = 1;
1335 1334
1336 list_for_each_entry(seb, &si->free, u.list) 1335 list_for_each_entry(seb, &si->free, u.list)
1337 buf[seb->pnum] = 0; 1336 buf[seb->pnum] = 1;
1338 1337
1339 list_for_each_entry(seb, &si->corr, u.list) 1338 list_for_each_entry(seb, &si->corr, u.list)
1340 buf[seb->pnum] = 0; 1339 buf[seb->pnum] = 1;
1341 1340
1342 list_for_each_entry(seb, &si->erase, u.list) 1341 list_for_each_entry(seb, &si->erase, u.list)
1343 buf[seb->pnum] = 0; 1342 buf[seb->pnum] = 1;
1344 1343
1345 list_for_each_entry(seb, &si->alien, u.list) 1344 list_for_each_entry(seb, &si->alien, u.list)
1346 buf[seb->pnum] = 0; 1345 buf[seb->pnum] = 1;
1347 1346
1348 err = 0; 1347 err = 0;
1349 for (pnum = 0; pnum < ubi->peb_count; pnum++) 1348 for (pnum = 0; pnum < ubi->peb_count; pnum++)
1350 if (buf[pnum]) { 1349 if (!buf[pnum]) {
1351 ubi_err("PEB %d is not referred", pnum); 1350 ubi_err("PEB %d is not referred", pnum);
1352 err = 1; 1351 err = 1;
1353 } 1352 }