From d0b36d8cc8f345ec5faadd15daaecfb409b94523 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Thu, 24 Jan 2008 12:48:37 +0200 Subject: [MTD] [OneNAND] Do not release chip twice Signed-off-by: Adrian Hunter Signed-off-by: Kyungmin Park --- drivers/mtd/onenand/onenand_base.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index ed9f9c061ac..e5882b609cf 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -1447,9 +1447,6 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to, buf += thislen; } - /* Deselect and wake up anyone waiting on the device */ - onenand_release_device(mtd); - ops->retlen = written; return ret; -- cgit v1.2.3 From 9d2f0b7a3de28d06ba4011b835b9a7e772553f0d Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Mon, 21 Jan 2008 17:13:07 +0200 Subject: [MTD] [OneNAND] fix call to onenand_verify when writing subpages Signed-off-by: Adrian Hunter Signed-off-by: Kyungmin Park --- drivers/mtd/onenand/onenand_base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index e5882b609cf..799bb1bc3db 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -1431,7 +1431,7 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to, } /* Only check verify write turn on */ - ret = onenand_verify(mtd, (u_char *) wbuf, to, thislen); + ret = onenand_verify(mtd, buf, to, thislen); if (ret) { printk(KERN_ERR "onenand_write_ops_nolock: verify failed %d\n", ret); break; -- cgit v1.2.3 From b21b72cf33bb212414c1d967850e261b795befa4 Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Tue, 11 Dec 2007 11:13:18 +0900 Subject: [MTD] [OneNAND] Consolidate OneNAND operation order Consolidate OneNAND operation order as OneNAND Spec. It also doesn't break previous operation order. Signed-off-by: Kyungmin Park --- drivers/mtd/onenand/onenand_base.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 799bb1bc3db..c79bc2ef3f5 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -182,8 +182,7 @@ static int onenand_buffer_address(int dataram1, int sectors, int count) static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t len) { struct onenand_chip *this = mtd->priv; - int value, readcmd = 0, block_cmd = 0; - int block, page; + int value, block, page; /* Address translation */ switch (cmd) { @@ -198,7 +197,6 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le case ONENAND_CMD_ERASE: case ONENAND_CMD_BUFFERRAM: case ONENAND_CMD_OTP_ACCESS: - block_cmd = 1; block = (int) (addr >> this->erase_shift); page = -1; break; @@ -240,11 +238,9 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le value = onenand_block_address(this, block); this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1); - if (block_cmd) { - /* Select DataRAM for DDP */ - value = onenand_bufferram_address(this, block); - this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2); - } + /* Select DataRAM for DDP */ + value = onenand_bufferram_address(this, block); + this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2); } if (page != -1) { @@ -256,7 +252,6 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le case ONENAND_CMD_READ: case ONENAND_CMD_READOOB: dataram = ONENAND_SET_NEXT_BUFFERRAM(this); - readcmd = 1; break; default: @@ -273,12 +268,6 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le /* Write 'BSA, BSC' of DataRAM */ value = onenand_buffer_address(dataram, sectors, count); this->write_word(value, this->base + ONENAND_REG_START_BUFFER); - - if (readcmd) { - /* Select DataRAM for DDP */ - value = onenand_bufferram_address(this, block); - this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2); - } } /* Interrupt clear */ -- cgit v1.2.3 From e71f04fc9234b14636887ceb5862755f1690642c Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Tue, 11 Dec 2007 11:23:45 +0900 Subject: [MTD] [OneNAND] Get correct density from device ID Use the higher bits for other purpose. Signed-off-by: Kyungmin Park --- drivers/mtd/onenand/onenand_base.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index c79bc2ef3f5..cf800932999 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -169,6 +169,18 @@ static int onenand_buffer_address(int dataram1, int sectors, int count) return ((bsa << ONENAND_BSA_SHIFT) | bsc); } +/** + * onenand_get_density - [DEFAULT] Get OneNAND density + * @param dev_id OneNAND device ID + * + * Get OneNAND density from device ID + */ +static inline int onenand_get_density(int dev_id) +{ + int density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT; + return (density & ONENAND_DEVICE_DENSITY_MASK); +} + /** * onenand_command - [DEFAULT] Send command to OneNAND device * @param mtd MTD device structure @@ -2146,7 +2158,7 @@ static int onenand_otp_walk(struct mtd_info *mtd, loff_t from, size_t len, *retlen = 0; - density = this->device_id >> ONENAND_DEVICE_DENSITY_SHIFT; + density = onenand_get_density(this->device_id); if (density < ONENAND_DEVICE_DENSITY_512Mb) otp_pages = 20; else @@ -2337,7 +2349,7 @@ static void onenand_check_features(struct mtd_info *mtd) unsigned int density, process; /* Lock scheme depends on density and process */ - density = this->device_id >> ONENAND_DEVICE_DENSITY_SHIFT; + density = onenand_get_density(this->device_id); process = this->version_id >> ONENAND_VERSION_PROCESS_SHIFT; /* Lock scheme */ @@ -2386,7 +2398,7 @@ static void onenand_print_device_info(int device, int version) vcc = device & ONENAND_DEVICE_VCC_MASK; demuxed = device & ONENAND_DEVICE_IS_DEMUX; ddp = device & ONENAND_DEVICE_IS_DDP; - density = device >> ONENAND_DEVICE_DENSITY_SHIFT; + density = onenand_get_density(device); printk(KERN_INFO "%sOneNAND%s %dMB %sV 16-bit (0x%02x)\n", demuxed ? "" : "Muxed ", ddp ? "(DDP)" : "", @@ -2478,7 +2490,7 @@ static int onenand_probe(struct mtd_info *mtd) this->device_id = dev_id; this->version_id = ver_id; - density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT; + density = onenand_get_density(dev_id); this->chipsize = (16 << density) << 20; /* Set density mask. it is used for DDP */ if (ONENAND_IS_DDP(this)) -- cgit v1.2.3 From b2581be291aa8595eadf3d6933d04d0f1d01b46d Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Thu, 13 Dec 2007 09:39:29 +0900 Subject: [MTD] [OneNAND] Check the initial bad block using ONENAND_CTRL_ERROR Some chips don't set the ONENAND_CTRL_LOAD bit. Signed-off-by: Kyungmin Park --- drivers/mtd/onenand/onenand_base.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index cf800932999..44c327a335e 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -1119,12 +1119,10 @@ static int onenand_bbt_wait(struct mtd_info *mtd, int state) interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT); ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS); + /* Initial bad block case: 0x2400 or 0x0400 */ if (ctrl & ONENAND_CTRL_ERROR) { printk(KERN_DEBUG "onenand_bbt_wait: controller error = 0x%04x\n", ctrl); - /* Initial bad block case */ - if (ctrl & ONENAND_CTRL_LOAD) - return ONENAND_BBT_READ_ERROR; - return ONENAND_BBT_READ_FATAL_ERROR; + return ONENAND_BBT_READ_ERROR; } if (interrupt & ONENAND_INT_READ) { -- cgit v1.2.3 From 978cb38a296fceac82a8a757f6387d7ef2a21ac6 Mon Sep 17 00:00:00 2001 From: "Sheng Yongjie (Sam" Date: Thu, 13 Dec 2007 11:47:33 +0900 Subject: [MTD] [OneNAND] Use the u_char instead of char in oobbuf In function onenand_verify_oob, local variable oobbuf shall be unsigned char. In the case of a value is >= 0x80, it's unequal in comparing the value in an unsigned char and signed char. Signed-off-by: Sheng Yongjie (Sam) Signed-off-by: Kyungmin Park --- drivers/mtd/onenand/onenand_base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 44c327a335e..ad052c8233c 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -1217,7 +1217,7 @@ int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from, static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to) { struct onenand_chip *this = mtd->priv; - char oobbuf[64]; + u_char oobbuf[64]; int status, i; this->command(mtd, ONENAND_CMD_READOOB, to, mtd->oobsize); -- cgit v1.2.3 From 69d79186dc48ca22a0ce69511bef8ef6c2465ada Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Fri, 14 Dec 2007 14:47:21 +0900 Subject: [MTD] [OneNAND] Use pre-alloced oob buffer instead of local buffer Signed-off-by: Kyungmin Park --- drivers/mtd/onenand/onenand_base.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index ad052c8233c..b281b116aae 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -1217,7 +1217,7 @@ int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from, static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to) { struct onenand_chip *this = mtd->priv; - u_char oobbuf[64]; + u_char *oob_buf = this->oob_buf; int status, i; this->command(mtd, ONENAND_CMD_READOOB, to, mtd->oobsize); @@ -1226,9 +1226,9 @@ static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to if (status) return status; - this->read_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize); + this->read_bufferram(mtd, ONENAND_SPARERAM, oob_buf, 0, mtd->oobsize); for (i = 0; i < mtd->oobsize; i++) - if (buf[i] != 0xFF && buf[i] != oobbuf[i]) + if (buf[i] != 0xFF && buf[i] != oob_buf[i]) return -EBADMSG; return 0; @@ -2307,7 +2307,8 @@ static int onenand_write_user_prot_reg(struct mtd_info *mtd, loff_t from, static int onenand_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len) { - unsigned char oob_buf[64]; + struct onenand_chip *this = mtd->priv; + u_char *oob_buf = this->oob_buf; size_t retlen; int ret; -- cgit v1.2.3