|
39 | 39 | #define OPCODE_PP 0x02 /* Page program (up to 256 bytes) */
|
40 | 40 | #define OPCODE_BE_4K 0x20 /* Erase 4KiB block */
|
41 | 41 | #define OPCODE_BE_32K 0x52 /* Erase 32KiB block */
|
| 42 | +#define OPCODE_BE 0xc7 /* Erase whole flash block */ |
42 | 43 | #define OPCODE_SE 0xd8 /* Sector erase (usually 64KiB) */
|
43 | 44 | #define OPCODE_RDID 0x9f /* Read JEDEC ID */
|
44 | 45 |
|
@@ -161,6 +162,31 @@ static int wait_till_ready(struct m25p *flash)
|
161 | 162 | return 1;
|
162 | 163 | }
|
163 | 164 |
|
| 165 | +/* |
| 166 | + * Erase the whole flash memory |
| 167 | + * |
| 168 | + * Returns 0 if successful, non-zero otherwise. |
| 169 | + */ |
| 170 | +static int erase_block(struct m25p *flash) |
| 171 | +{ |
| 172 | + DEBUG(MTD_DEBUG_LEVEL3, "%s: %s %dKiB\n", |
| 173 | + flash->spi->dev.bus_id, __func__, |
| 174 | + flash->mtd.size / 1024); |
| 175 | + |
| 176 | + /* Wait until finished previous write command. */ |
| 177 | + if (wait_till_ready(flash)) |
| 178 | + return 1; |
| 179 | + |
| 180 | + /* Send write enable, then erase commands. */ |
| 181 | + write_enable(flash); |
| 182 | + |
| 183 | + /* Set up command buffer. */ |
| 184 | + flash->command[0] = OPCODE_BE; |
| 185 | + |
| 186 | + spi_write(flash->spi, flash->command, 1); |
| 187 | + |
| 188 | + return 0; |
| 189 | +} |
164 | 190 |
|
165 | 191 | /*
|
166 | 192 | * Erase one sector of flash memory at offset ``offset'' which is any
|
@@ -229,15 +255,21 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
|
229 | 255 | */
|
230 | 256 |
|
231 | 257 | /* now erase those sectors */
|
232 |
| - while (len) { |
233 |
| - if (erase_sector(flash, addr)) { |
234 |
| - instr->state = MTD_ERASE_FAILED; |
235 |
| - mutex_unlock(&flash->lock); |
236 |
| - return -EIO; |
237 |
| - } |
| 258 | + if (len == flash->mtd.size && erase_block(flash)) { |
| 259 | + instr->state = MTD_ERASE_FAILED; |
| 260 | + mutex_unlock(&flash->lock); |
| 261 | + return -EIO; |
| 262 | + } else { |
| 263 | + while (len) { |
| 264 | + if (erase_sector(flash, addr)) { |
| 265 | + instr->state = MTD_ERASE_FAILED; |
| 266 | + mutex_unlock(&flash->lock); |
| 267 | + return -EIO; |
| 268 | + } |
238 | 269 |
|
239 |
| - addr += mtd->erasesize; |
240 |
| - len -= mtd->erasesize; |
| 270 | + addr += mtd->erasesize; |
| 271 | + len -= mtd->erasesize; |
| 272 | + } |
241 | 273 | }
|
242 | 274 |
|
243 | 275 | mutex_unlock(&flash->lock);
|
|
0 commit comments