summaryrefslogtreecommitdiff
path: root/drivers/mtd/altera_qspi.c
diff options
context:
space:
mode:
authorThomas Chou <thomas@wytron.com.tw>2015-12-23 10:33:52 +0800
committerThomas Chou <thomas@wytron.com.tw>2015-12-28 09:32:43 +0800
commitf81a673ec4505553ce8d0362f9b8371a8e51c015 (patch)
tree4376eca3a3e084f9dec6bb224b958393dab8be05 /drivers/mtd/altera_qspi.c
parenta1b1d7eceb033c256ae661d65732323809fb9101 (diff)
downloadu-boot-f81a673ec4505553ce8d0362f9b8371a8e51c015.tar.gz
altera_qspi: skip erase if the sector is blank
Skip erase if the sector is blank. The sector erase is slow, and may take 0.7 sec typically or up to 3 sec worst-case. Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
Diffstat (limited to 'drivers/mtd/altera_qspi.c')
-rw-r--r--drivers/mtd/altera_qspi.c39
1 files changed, 25 insertions, 14 deletions
diff --git a/drivers/mtd/altera_qspi.c b/drivers/mtd/altera_qspi.c
index b0d4f2c810..8a630a66d6 100644
--- a/drivers/mtd/altera_qspi.c
+++ b/drivers/mtd/altera_qspi.c
@@ -131,24 +131,35 @@ static int altera_qspi_erase(struct mtd_info *mtd, struct erase_info *instr)
size_t end = addr + len;
u32 sect;
u32 stat;
+ u32 *flash, *last;
instr->state = MTD_ERASING;
addr &= ~(mtd->erasesize - 1); /* get lower aligned address */
while (addr < end) {
- sect = addr / mtd->erasesize;
- sect <<= 8;
- sect |= QUADSPI_MEM_OP_SECTOR_ERASE;
- debug("erase %08x\n", sect);
- writel(sect, &regs->mem_op);
- stat = readl(&regs->isr);
- if (stat & QUADSPI_ISR_ILLEGAL_ERASE) {
- /* erase failed, sector might be protected */
- debug("erase %08x fail %x\n", sect, stat);
- writel(stat, &regs->isr); /* clear isr */
- instr->fail_addr = addr;
- instr->state = MTD_ERASE_FAILED;
- mtd_erase_callback(instr);
- return -EIO;
+ flash = pdata->base + addr;
+ last = pdata->base + addr + mtd->erasesize;
+ /* skip erase if sector is blank */
+ while (flash < last) {
+ if (readl(flash) != 0xffffffff)
+ break;
+ flash++;
+ }
+ if (flash < last) {
+ sect = addr / mtd->erasesize;
+ sect <<= 8;
+ sect |= QUADSPI_MEM_OP_SECTOR_ERASE;
+ debug("erase %08x\n", sect);
+ writel(sect, &regs->mem_op);
+ stat = readl(&regs->isr);
+ if (stat & QUADSPI_ISR_ILLEGAL_ERASE) {
+ /* erase failed, sector might be protected */
+ debug("erase %08x fail %x\n", sect, stat);
+ writel(stat, &regs->isr); /* clear isr */
+ instr->fail_addr = addr;
+ instr->state = MTD_ERASE_FAILED;
+ mtd_erase_callback(instr);
+ return -EIO;
+ }
}
addr += mtd->erasesize;
}