From ee9745fcf214272b7cdd9d320d044cf433ee958e Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Sat, 30 Jun 2007 13:57:49 +0900 Subject: [MTD] [OneNAND] 2X program support The 2X Program is an extension of Program Operation. Since the device is equipped with two DataRAMs, and two-plane NAND Flash memory array, these two component enables simultaneous program of 4KiB. Plane1 has only even blocks such as block0, block2, block4 while Plane2 has only odd blocks such as block1, block3, block5. So MTD regards it as 4KiB page size and 256KiB block size Now the following chips support it. (KFXXX16Q2M) Demux: KFG2G16Q2M, KFH4G16Q2M, KFW8G16Q2M, Mux: KFM2G16Q2M, KFN4G16Q2M, And more recent chips Signed-off-by: Kyungmin Park Signed-off-by: David Woodhouse --- include/linux/mtd/onenand.h | 12 ++++++++++++ include/linux/mtd/onenand_regs.h | 4 ++++ 2 files changed, 16 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h index a56d24ada505..fd0a260e070b 100644 --- a/include/linux/mtd/onenand.h +++ b/include/linux/mtd/onenand.h @@ -60,6 +60,7 @@ struct onenand_bufferram { * @erase_shift: [INTERN] number of address bits in a block * @page_shift: [INTERN] number of address bits in a page * @page_mask: [INTERN] a page per block mask + * @writesize: [INTERN] a real page size * @bufferram_index: [INTERN] BufferRAM index * @bufferram: [INTERN] BufferRAM info * @readw: [REPLACEABLE] hardware specific function for read short @@ -100,6 +101,7 @@ struct onenand_chip { unsigned int erase_shift; unsigned int page_shift; unsigned int page_mask; + unsigned int writesize; unsigned int bufferram_index; struct onenand_bufferram bufferram[MAX_BUFFERRAM]; @@ -140,6 +142,8 @@ struct onenand_chip { #define ONENAND_NEXT_BUFFERRAM(this) (this->bufferram_index ^ 1) #define ONENAND_SET_NEXT_BUFFERRAM(this) (this->bufferram_index ^= 1) #define ONENAND_SET_PREV_BUFFERRAM(this) (this->bufferram_index ^= 1) +#define ONENAND_SET_BUFFERRAM0(this) (this->bufferram_index = 0) +#define ONENAND_SET_BUFFERRAM1(this) (this->bufferram_index = 1) #define ONENAND_GET_SYS_CFG1(this) \ (this->read_word(this->base + ONENAND_REG_SYS_CFG1)) @@ -149,6 +153,13 @@ struct onenand_chip { #define ONENAND_IS_DDP(this) \ (this->device_id & ONENAND_DEVICE_IS_DDP) +#ifdef CONFIG_MTD_ONENAND_2X_PROGRAM +#define ONENAND_IS_2PLANE(this) \ + (this->options & ONENAND_HAS_2PLANE) +#else +#define ONENAND_IS_2PLANE(this) (0) +#endif + /* Check byte access in OneNAND */ #define ONENAND_CHECK_BYTE_ACCESS(addr) (addr & 0x1) @@ -157,6 +168,7 @@ struct onenand_chip { */ #define ONENAND_HAS_CONT_LOCK (0x0001) #define ONENAND_HAS_UNLOCK_ALL (0x0002) +#define ONENAND_HAS_2PLANE (0x0004) #define ONENAND_PAGEBUF_ALLOC (0x1000) #define ONENAND_OOBBUF_ALLOC (0x2000) diff --git a/include/linux/mtd/onenand_regs.h b/include/linux/mtd/onenand_regs.h index af94719890e7..c46161f4eee3 100644 --- a/include/linux/mtd/onenand_regs.h +++ b/include/linux/mtd/onenand_regs.h @@ -74,6 +74,8 @@ #define ONENAND_DEVICE_DENSITY_512Mb (0x002) #define ONENAND_DEVICE_DENSITY_1Gb (0x003) +#define ONENAND_DEVICE_DENSITY_2Gb (0x004) +#define ONENAND_DEVICE_DENSITY_4Gb (0x005) /* * Version ID Register F002h (R) @@ -111,6 +113,8 @@ #define ONENAND_CMD_READOOB (0x13) #define ONENAND_CMD_PROG (0x80) #define ONENAND_CMD_PROGOOB (0x1A) +#define ONENAND_CMD_2X_PROG (0x7D) +#define ONENAND_CMD_2X_CACHE_PROG (0x7F) #define ONENAND_CMD_UNLOCK (0x23) #define ONENAND_CMD_LOCK (0x2A) #define ONENAND_CMD_LOCK_TIGHT (0x2C) -- cgit v1.2.3 From c799aca31bfe61ba3a91133acf5a13a0773087d4 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Tue, 10 Jul 2007 10:28:36 +0100 Subject: [JFFS2] Add LZO compression support. Add LZO1X compression/decompression support to jffs2. LZO's interface doesn't entirely match that required by jffs2 so a buffer and memcpy is unavoidable. Signed-off-by: Richard Purdie Signed-off-by: David Woodhouse --- fs/Kconfig | 11 +++++ fs/jffs2/Makefile | 1 + fs/jffs2/compr.c | 6 +++ fs/jffs2/compr.h | 3 +- fs/jffs2/compr_lzo.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/jffs2.h | 1 + 6 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 fs/jffs2/compr_lzo.c (limited to 'include/linux') diff --git a/fs/Kconfig b/fs/Kconfig index e19423a2aa7d..a2ec0b375dff 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -1314,6 +1314,17 @@ config JFFS2_ZLIB Say 'Y' if unsure. +config JFFS2_LZO + bool "JFFS2 LZO compression support" if JFFS2_COMPRESSION_OPTIONS + select LZO_COMPRESS + select LZO_DECOMPRESS + depends on JFFS2_FS + default y + help + minilzo-based compression. Generally works better than Zlib. + + Say 'Y' if unsure. + config JFFS2_RTIME bool "JFFS2 RTIME compression support" if JFFS2_COMPRESSION_OPTIONS depends on JFFS2_FS diff --git a/fs/jffs2/Makefile b/fs/jffs2/Makefile index c32b241e3d91..60e5d49ca03e 100644 --- a/fs/jffs2/Makefile +++ b/fs/jffs2/Makefile @@ -17,4 +17,5 @@ jffs2-$(CONFIG_JFFS2_FS_POSIX_ACL) += acl.o jffs2-$(CONFIG_JFFS2_RUBIN) += compr_rubin.o jffs2-$(CONFIG_JFFS2_RTIME) += compr_rtime.o jffs2-$(CONFIG_JFFS2_ZLIB) += compr_zlib.o +jffs2-$(CONFIG_JFFS2_LZO) += compr_lzo.o jffs2-$(CONFIG_JFFS2_SUMMARY) += summary.o diff --git a/fs/jffs2/compr.c b/fs/jffs2/compr.c index d90ca05e4992..bcc28d266a12 100644 --- a/fs/jffs2/compr.c +++ b/fs/jffs2/compr.c @@ -286,6 +286,9 @@ int __init jffs2_compressors_init(void) jffs2_rubinmips_init(); jffs2_dynrubin_init(); #endif +#ifdef CONFIG_JFFS2_LZO + jffs2_lzo_init(); +#endif /* Setting default compression mode */ #ifdef CONFIG_JFFS2_CMODE_NONE jffs2_compression_mode = JFFS2_COMPR_MODE_NONE; @@ -304,6 +307,9 @@ int __init jffs2_compressors_init(void) int jffs2_compressors_exit(void) { /* Unregistering compressors */ +#ifdef CONFIG_JFFS2_LZO + jffs2_lzo_exit(); +#endif #ifdef CONFIG_JFFS2_RUBIN jffs2_dynrubin_exit(); jffs2_rubinmips_exit(); diff --git a/fs/jffs2/compr.h b/fs/jffs2/compr.h index 1070275da58f..a54828a4e9c6 100644 --- a/fs/jffs2/compr.h +++ b/fs/jffs2/compr.h @@ -27,9 +27,10 @@ #define JFFS2_RUBINMIPS_PRIORITY 10 #define JFFS2_DYNRUBIN_PRIORITY 20 #define JFFS2_LZARI_PRIORITY 30 -#define JFFS2_LZO_PRIORITY 40 #define JFFS2_RTIME_PRIORITY 50 #define JFFS2_ZLIB_PRIORITY 60 +#define JFFS2_LZO_PRIORITY 80 + #define JFFS2_RUBINMIPS_DISABLED /* RUBINs will be used only */ #define JFFS2_DYNRUBIN_DISABLED /* for decompression */ diff --git a/fs/jffs2/compr_lzo.c b/fs/jffs2/compr_lzo.c new file mode 100644 index 000000000000..47b045797e42 --- /dev/null +++ b/fs/jffs2/compr_lzo.c @@ -0,0 +1,108 @@ +/* + * JFFS2 -- Journalling Flash File System, Version 2. + * + * Copyright © 2007 Nokia Corporation. All rights reserved. + * + * Created by Richard Purdie + * + * For licensing information, see the file 'LICENCE' in this directory. + * + */ + +#include +#include +#include +#include +#include +#include +#include "compr.h" + +static void *lzo_mem; +static void *lzo_compress_buf; +static DEFINE_MUTEX(deflate_mutex); + +static void free_workspace(void) +{ + vfree(lzo_mem); + vfree(lzo_compress_buf); +} + +static int __init alloc_workspace(void) +{ + lzo_mem = vmalloc(LZO1X_MEM_COMPRESS); + lzo_compress_buf = vmalloc(lzo1x_worst_compress(PAGE_SIZE)); + + if (!lzo_mem || !lzo_compress_buf) { + printk(KERN_WARNING "Failed to allocate lzo deflate workspace\n"); + free_workspace(); + return -ENOMEM; + } + + return 0; +} + +static int jffs2_lzo_compress(unsigned char *data_in, unsigned char *cpage_out, + uint32_t *sourcelen, uint32_t *dstlen, void *model) +{ + size_t compress_size; + int ret; + + mutex_lock(&deflate_mutex); + ret = lzo1x_1_compress(data_in, *sourcelen, lzo_compress_buf, &compress_size, lzo_mem); + mutex_unlock(&deflate_mutex); + + if (ret != LZO_E_OK) + return -1; + + if (compress_size > *dstlen) + return -1; + + memcpy(cpage_out, lzo_compress_buf, compress_size); + *dstlen = compress_size; + + return 0; +} + +static int jffs2_lzo_decompress(unsigned char *data_in, unsigned char *cpage_out, + uint32_t srclen, uint32_t destlen, void *model) +{ + size_t dl = destlen; + int ret; + + ret = lzo1x_decompress_safe(data_in, srclen, cpage_out, &dl); + + if (ret != LZO_E_OK || dl != destlen) + return -1; + + return 0; +} + +static struct jffs2_compressor jffs2_lzo_comp = { + .priority = JFFS2_LZO_PRIORITY, + .name = "lzo", + .compr = JFFS2_COMPR_LZO, + .compress = &jffs2_lzo_compress, + .decompress = &jffs2_lzo_decompress, + .disabled = 0, +}; + +int __init jffs2_lzo_init(void) +{ + int ret; + + ret = alloc_workspace(); + if (ret < 0) + return ret; + + ret = jffs2_register_compressor(&jffs2_lzo_comp); + if (ret) + free_workspace(); + + return ret; +} + +void jffs2_lzo_exit(void) +{ + jffs2_unregister_compressor(&jffs2_lzo_comp); + free_workspace(); +} diff --git a/include/linux/jffs2.h b/include/linux/jffs2.h index 840631fa5ff1..6b563cae23df 100644 --- a/include/linux/jffs2.h +++ b/include/linux/jffs2.h @@ -46,6 +46,7 @@ #define JFFS2_COMPR_COPY 0x04 #define JFFS2_COMPR_DYNRUBIN 0x05 #define JFFS2_COMPR_ZLIB 0x06 +#define JFFS2_COMPR_LZO 0x07 /* Compatibility flags. */ #define JFFS2_COMPAT_MASK 0xc000 /* What do to if an unknown nodetype is found */ #define JFFS2_NODE_ACCURATE 0x2000 -- cgit v1.2.3 From 30eb0db07d67b9211da7f506220184df827e425d Mon Sep 17 00:00:00 2001 From: "Steven J. Hill" Date: Wed, 18 Jul 2007 23:29:46 -0500 Subject: [MTD] [NAND] Add NAND manufacturer AMD. This patch adds the manufacturer ID for AMD flash. Signed-off-by: Steven J. Hill Signed-off-by: David Woodhouse --- drivers/mtd/nand/nand_ids.c | 1 + include/linux/mtd/nand.h | 1 + 2 files changed, 2 insertions(+) (limited to 'include/linux') 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[] = { {NAND_MFR_STMICRO, "ST Micro"}, {NAND_MFR_HYNIX, "Hynix"}, {NAND_MFR_MICRON, "Micron"}, + {NAND_MFR_AMD, "AMD"}, {0x0, "Unknown"} }; diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index d2365c8dcacc..c42bc7f533a5 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -432,6 +432,7 @@ struct nand_chip { #define NAND_MFR_STMICRO 0x20 #define NAND_MFR_HYNIX 0xad #define NAND_MFR_MICRON 0x2c +#define NAND_MFR_AMD 0x01 /** * struct nand_flash_dev - NAND Flash Device ID Structure -- cgit v1.2.3 From 241651d04d672fb685b2874707016cbbf95931e5 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 6 Sep 2007 09:40:21 +0100 Subject: [MTD] Fix CFI build error when no map width or interleave supported When building NOR flash support, you have compile-time options for the bus width and the number of individual chips which are interleaved together onto that bus. The code to deal with arbitrary geometry is a bit convoluted, and people want to just configure it for the specific hardware they have, to avoid the runtime overhead. Selecting _none_ of the available options doesn't make any sense. You should have at least one. This makes it build though, since people persist in trying. Signed-off-by: David Woodhouse --- include/linux/mtd/cfi.h | 9 +++++++++ include/linux/mtd/map.h | 10 +++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h index 123948b14547..e17c5343cf51 100644 --- a/include/linux/mtd/cfi.h +++ b/include/linux/mtd/cfi.h @@ -57,6 +57,15 @@ #define cfi_interleave_is_8(cfi) (0) #endif +#ifndef cfi_interleave +#warning No CONFIG_MTD_CFI_Ix selected. No NOR chip support can work. +static inline int cfi_interleave(void *cfi) +{ + BUG(); + return 0; +} +#endif + static inline int cfi_interleave_supported(int i) { switch (i) { diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h index 81f3a314dd76..a9fae032ba81 100644 --- a/include/linux/mtd/map.h +++ b/include/linux/mtd/map.h @@ -125,7 +125,15 @@ #endif #ifndef map_bankwidth -#error "No bus width supported. What's the point?" +#warning "No CONFIG_MTD_MAP_BANK_WIDTH_xx selected. No NOR chip support can work" +static inline int map_bankwidth(void *map) +{ + BUG(); + return 0; +} +#define map_bankwidth_is_large(map) (0) +#define map_words(map) (0) +#define MAX_MAP_BANKWIDTH 1 #endif static inline int map_bankwidth_supported(int w) -- cgit v1.2.3 From b38178ee712e8608f20c8e741adf97f75f1aea39 Mon Sep 17 00:00:00 2001 From: Jörn Engel Date: Fri, 21 Sep 2007 15:41:44 +0200 Subject: [MTD] Document erase interface. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document mtd erase interface. Signed-off-by: Jörn Engel Signed-off-by: David Woodhouse --- include/linux/mtd/mtd.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index fd64ccfbce02..783fc983417c 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -133,6 +133,13 @@ struct mtd_info { int numeraseregions; struct mtd_erase_region_info *eraseregions; + /* + * Erase is an asynchronous operation. Device drivers are supposed + * to call instr->callback() whenever the operation completes, even + * if it completes with a failure. + * Callers are supposed to pass a callback function and wait for it + * to be called before writing to the block. + */ int (*erase) (struct mtd_info *mtd, struct erase_info *instr); /* This stuff for eXecute-In-Place */ -- cgit v1.2.3 From c4a9f88daf6c382fedde4cdddef0b30f1d0a20db Mon Sep 17 00:00:00 2001 From: Kevin Hao Date: Tue, 2 Oct 2007 13:56:04 -0700 Subject: [MTD] [NOR] fix ctrl-alt-del can't reboot for intel flash bug When we press ctrl-alt-del,kernel_restart_prepare will invoke cfi_intelext_reboot which will set flash to read array mode, but later when device_shutdown is invoked which may put current work queue to sleep and other process may be scheduled to running and programming flash in not FL_READY mode again. So we can't boot up if this flash is used for bootloader. Signed-off-by: Andrew Morton Signed-off-by: David Woodhouse --- drivers/mtd/chips/cfi_cmdset_0001.c | 9 ++++++--- include/linux/mtd/flashchip.h | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index c655e971c158..3aa3dca56ae6 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -653,7 +653,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr resettime: timeo = jiffies + HZ; retry: - if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING || mode == FL_OTP_WRITE)) { + if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING || mode == FL_OTP_WRITE || mode == FL_SHUTDOWN)) { /* * OK. We have possibility for contension on the write/erase * operations which are global to the real chip and not per @@ -798,6 +798,9 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr if (mode == FL_READY && chip->oldstate == FL_READY) return 0; + case FL_SHUTDOWN: + /* The machine is rebooting now,so no one can get chip anymore */ + return -EIO; default: sleep: set_current_state(TASK_UNINTERRUPTIBLE); @@ -2409,10 +2412,10 @@ static int cfi_intelext_reset(struct mtd_info *mtd) and switch to array mode so any bootloader in flash is accessible for soft reboot. */ spin_lock(chip->mutex); - ret = get_chip(map, chip, chip->start, FL_SYNCING); + ret = get_chip(map, chip, chip->start, FL_SHUTDOWN); if (!ret) { map_write(map, CMD(0xff), chip->start); - chip->state = FL_READY; + chip->state = FL_SHUTDOWN; } spin_unlock(chip->mutex); } diff --git a/include/linux/mtd/flashchip.h b/include/linux/mtd/flashchip.h index a293a3b78e05..39e7d2a1be9a 100644 --- a/include/linux/mtd/flashchip.h +++ b/include/linux/mtd/flashchip.h @@ -40,6 +40,7 @@ typedef enum { FL_POINT, FL_XIP_WHILE_ERASING, FL_XIP_WHILE_WRITING, + FL_SHUTDOWN, FL_UNKNOWN } flstate_t; -- cgit v1.2.3