diff options
Diffstat (limited to 'drivers/mtd/onenand')
-rw-r--r-- | drivers/mtd/onenand/onenand_base.c | 32 |
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 | */ |
2055 | static void onenand_check_lock_status(struct onenand_chip *this) | 2055 | static 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 | */ |
2084 | static int onenand_unlock_all(struct mtd_info *mtd) | 2088 | static 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 |