aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/onenand/onenand_base.c
diff options
context:
space:
mode:
authorKyungmin Park <kyungmin.park@samsung.com>2008-02-13 01:55:38 -0500
committerDavid Woodhouse <dwmw2@infradead.org>2008-02-16 10:15:55 -0500
commit66a10506d632051e1153e2555f4b2c820d427f64 (patch)
tree458bf34c8b93a958306ad283d00d43c74142a72d /drivers/mtd/onenand/onenand_base.c
parent1309d4e68497184d2fd87e892ddf14076c2bda98 (diff)
[MTD] [OneNAND] Fix unlock all in Double Density Package (DDP)
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'drivers/mtd/onenand/onenand_base.c')
-rw-r--r--drivers/mtd/onenand/onenand_base.c32
1 files changed, 17 insertions, 15 deletions
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 8d7d21be1541..15a62db656de 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -2052,7 +2052,7 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
2052 * 2052 *
2053 * Check lock status 2053 * Check lock status
2054 */ 2054 */
2055static void onenand_check_lock_status(struct onenand_chip *this) 2055static int onenand_check_lock_status(struct onenand_chip *this)
2056{ 2056{
2057 unsigned int value, block, status; 2057 unsigned int value, block, status;
2058 unsigned int end; 2058 unsigned int end;
@@ -2070,9 +2070,13 @@ static void onenand_check_lock_status(struct onenand_chip *this)
2070 2070
2071 /* Check lock status */ 2071 /* Check lock status */
2072 status = this->read_word(this->base + ONENAND_REG_WP_STATUS); 2072 status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
2073 if (!(status & ONENAND_WP_US)) 2073 if (!(status & ONENAND_WP_US)) {
2074 printk(KERN_ERR "block = %d, wp status = 0x%x\n", block, status); 2074 printk(KERN_ERR "block = %d, wp status = 0x%x\n", block, status);
2075 return 0;
2076 }
2075 } 2077 }
2078
2079 return 1;
2076} 2080}
2077 2081
2078/** 2082/**
@@ -2081,9 +2085,11 @@ static void onenand_check_lock_status(struct onenand_chip *this)
2081 * 2085 *
2082 * Unlock all blocks 2086 * Unlock all blocks
2083 */ 2087 */
2084static int onenand_unlock_all(struct mtd_info *mtd) 2088static void onenand_unlock_all(struct mtd_info *mtd)
2085{ 2089{
2086 struct onenand_chip *this = mtd->priv; 2090 struct onenand_chip *this = mtd->priv;
2091 loff_t ofs = 0;
2092 size_t len = this->chipsize;
2087 2093
2088 if (this->options & ONENAND_HAS_UNLOCK_ALL) { 2094 if (this->options & ONENAND_HAS_UNLOCK_ALL) {
2089 /* Set start block address */ 2095 /* Set start block address */
@@ -2099,23 +2105,19 @@ static int onenand_unlock_all(struct mtd_info *mtd)
2099 & ONENAND_CTRL_ONGO) 2105 & ONENAND_CTRL_ONGO)
2100 continue; 2106 continue;
2101 2107
2108 /* Check lock status */
2109 if (onenand_check_lock_status(this))
2110 return;
2111
2102 /* Workaround for all block unlock in DDP */ 2112 /* Workaround for all block unlock in DDP */
2103 if (ONENAND_IS_DDP(this)) { 2113 if (ONENAND_IS_DDP(this)) {
2104 /* 1st block on another chip */ 2114 /* All blocks on another chip */
2105 loff_t ofs = this->chipsize >> 1; 2115 ofs = this->chipsize >> 1;
2106 size_t len = mtd->erasesize; 2116 len = this->chipsize >> 1;
2107
2108 onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK);
2109 } 2117 }
2110
2111 onenand_check_lock_status(this);
2112
2113 return 0;
2114 } 2118 }
2115 2119
2116 onenand_do_lock_cmd(mtd, 0x0, this->chipsize, ONENAND_CMD_UNLOCK); 2120 onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK);
2117
2118 return 0;
2119} 2121}
2120 2122
2121#ifdef CONFIG_MTD_ONENAND_OTP 2123#ifdef CONFIG_MTD_ONENAND_OTP