summaryrefslogtreecommitdiff
path: root/drivers/mtd
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2021-10-23 10:49:28 -0400
committerTom Rini <[email protected]>2021-10-23 10:49:28 -0400
commit355d1e24f6143c4839be3c015c191421c4e9449c (patch)
treeff68e868d404d117f3f9599740f83fd73c99c306 /drivers/mtd
parentf055f2e5a2038002519e5b9affbf259345f4ade9 (diff)
parentb9cfd8b0911209e2ebec887e497510ee42f9e788 (diff)
Merge https://source.denx.de/u-boot/custodians/u-boot-spi
- Fix mtd erase with mtdpart (Marek BehĂșn) - NXP fspi driver fixes (Kuldeep Singh)
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/altera_qspi.c3
-rw-r--r--drivers/mtd/cfi_mtd.c1
-rw-r--r--drivers/mtd/mtdconcat.c11
-rw-r--r--drivers/mtd/mtdcore.c8
-rw-r--r--drivers/mtd/mtdpart.c23
-rw-r--r--drivers/mtd/nand/raw/nand_base.c4
-rw-r--r--drivers/mtd/nand/spi/macronix.c10
-rw-r--r--drivers/mtd/onenand/onenand_base.c3
-rw-r--r--drivers/mtd/spi/sf_mtd.c1
-rw-r--r--drivers/mtd/spi/spi-nor-core.c65
-rw-r--r--drivers/mtd/spi/spi-nor-ids.c13
-rw-r--r--drivers/mtd/ubi/io.c13
12 files changed, 79 insertions, 76 deletions
diff --git a/drivers/mtd/altera_qspi.c b/drivers/mtd/altera_qspi.c
index 7bac599a54a..d31391f36a4 100644
--- a/drivers/mtd/altera_qspi.c
+++ b/drivers/mtd/altera_qspi.c
@@ -153,7 +153,6 @@ static int altera_qspi_erase(struct mtd_info *mtd, struct erase_info *instr)
putc('\n');
instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
instr->state = MTD_ERASE_FAILED;
- mtd_erase_callback(instr);
return -EIO;
}
flash = pdata->base + addr;
@@ -177,7 +176,6 @@ static int altera_qspi_erase(struct mtd_info *mtd, struct erase_info *instr)
writel(stat, &regs->isr); /* clear isr */
instr->fail_addr = addr;
instr->state = MTD_ERASE_FAILED;
- mtd_erase_callback(instr);
return -EIO;
}
if (flash_verbose)
@@ -189,7 +187,6 @@ static int altera_qspi_erase(struct mtd_info *mtd, struct erase_info *instr)
addr += mtd->erasesize;
}
instr->state = MTD_ERASE_DONE;
- mtd_erase_callback(instr);
return 0;
}
diff --git a/drivers/mtd/cfi_mtd.c b/drivers/mtd/cfi_mtd.c
index 78293caa2f7..2295bb7220b 100644
--- a/drivers/mtd/cfi_mtd.c
+++ b/drivers/mtd/cfi_mtd.c
@@ -58,7 +58,6 @@ static int cfi_mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
}
instr->state = MTD_ERASE_DONE;
- mtd_erase_callback(instr);
return 0;
}
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index 684bc949985..af3c4765c4d 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -338,14 +338,6 @@ concat_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops)
return -EINVAL;
}
-static void concat_erase_callback(struct erase_info *instr)
-{
- /* Nothing to do here in U-Boot */
-#ifndef __UBOOT__
- wake_up((wait_queue_head_t *) instr->priv);
-#endif
-}
-
static int concat_dev_erase(struct mtd_info *mtd, struct erase_info *erase)
{
int err;
@@ -358,7 +350,6 @@ static int concat_dev_erase(struct mtd_info *mtd, struct erase_info *erase)
init_waitqueue_head(&waitq);
erase->mtd = mtd;
- erase->callback = concat_erase_callback;
erase->priv = (unsigned long) &waitq;
/*
@@ -498,8 +489,6 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr)
if (err)
return err;
- if (instr->callback)
- instr->callback(instr);
return 0;
}
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 9496903e861..1d45fb55c72 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -906,13 +906,6 @@ void __put_mtd_device(struct mtd_info *mtd)
}
EXPORT_SYMBOL_GPL(__put_mtd_device);
-/*
- * Erase is an asynchronous operation. Device drivers are supposed
- * to call instr->callback() whenever the operation completes, even
- * if it completes with a failure.
- * Callers are supposed to pass a callback function and wait for it
- * to be called before writing to the block.
- */
int mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
{
if (instr->addr > mtd->size || instr->len > mtd->size - instr->addr)
@@ -922,7 +915,6 @@ int mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
if (!instr->len) {
instr->state = MTD_ERASE_DONE;
- mtd_erase_callback(instr);
return 0;
}
return mtd->_erase(mtd, instr);
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index aa58f722dad..a435ce6d079 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -446,26 +446,15 @@ static int part_erase(struct mtd_info *mtd, struct erase_info *instr)
int ret;
instr->addr += mtd->offset;
+
ret = mtd->parent->_erase(mtd->parent, instr);
- if (ret) {
- if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
- instr->fail_addr -= mtd->offset;
- instr->addr -= mtd->offset;
- }
- return ret;
-}
+ if (ret && instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
+ instr->fail_addr -= mtd->offset;
-void mtd_erase_callback(struct erase_info *instr)
-{
- if (instr->mtd->_erase == part_erase) {
- if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
- instr->fail_addr -= instr->mtd->offset;
- instr->addr -= instr->mtd->offset;
- }
- if (instr->callback)
- instr->callback(instr);
+ instr->addr -= mtd->offset;
+
+ return ret;
}
-EXPORT_SYMBOL_GPL(mtd_erase_callback);
static int part_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
{
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index b533683dfe6..f7616985d95 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -3602,10 +3602,6 @@ erase_exit:
chip->select_chip(mtd, -1);
nand_release_device(mtd);
- /* Do call back function */
- if (!ret)
- mtd_erase_callback(instr);
-
/* Return more or less happy */
return ret;
}
diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c
index f4a8e816398..6d643a8000d 100644
--- a/drivers/mtd/nand/spi/macronix.c
+++ b/drivers/mtd/nand/spi/macronix.c
@@ -14,6 +14,8 @@
#include <linux/mtd/spinand.h>
#define SPINAND_MFR_MACRONIX 0xC2
+#define MACRONIX_ECCSR_MASK 0x0F
+
static SPINAND_OP_VARIANTS(read_cache_variants,
SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
@@ -59,7 +61,13 @@ static int mx35lf1ge4ab_get_eccsr(struct spinand_device *spinand, u8 *eccsr)
SPI_MEM_OP_DUMMY(1, 1),
SPI_MEM_OP_DATA_IN(1, eccsr, 1));
- return spi_mem_exec_op(spinand->slave, &op);
+ int ret = spi_mem_exec_op(spinand->slave, &op);
+
+ if (ret)
+ return ret;
+
+ *eccsr &= MACRONIX_ECCSR_MASK;
+ return 0;
}
static int mx35lf1ge4ab_ecc_get_status(struct spinand_device *spinand,
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 46aeef258d9..56e1858de45 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -1836,9 +1836,6 @@ int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
erase_exit:
ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
- /* Do call back function */
- if (!ret)
- mtd_erase_callback(instr);
/* Deselect and wake up anyone waiting on the device */
onenand_release_device(mtd);
diff --git a/drivers/mtd/spi/sf_mtd.c b/drivers/mtd/spi/sf_mtd.c
index 04de8680809..0aed28a52b7 100644
--- a/drivers/mtd/spi/sf_mtd.c
+++ b/drivers/mtd/spi/sf_mtd.c
@@ -46,7 +46,6 @@ static int spi_flash_mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
}
instr->state = MTD_ERASE_DONE;
- mtd_erase_callback(instr);
return 0;
}
diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index f1b4e5ea8e3..4388a08a90d 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -908,30 +908,40 @@ static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr)
static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
{
struct spi_nor *nor = mtd_to_spi_nor(mtd);
+ bool addr_known = false;
u32 addr, len, rem;
- int ret;
+ int ret, err;
dev_dbg(nor->dev, "at 0x%llx, len %lld\n", (long long)instr->addr,
(long long)instr->len);
- if (!instr->len)
- return 0;
-
div_u64_rem(instr->len, mtd->erasesize, &rem);
- if (rem)
- return -EINVAL;
+ if (rem) {
+ ret = -EINVAL;
+ goto err;
+ }
addr = instr->addr;
len = instr->len;
+ instr->state = MTD_ERASING;
+ addr_known = true;
+
while (len) {
WATCHDOG_RESET();
+ if (ctrlc()) {
+ addr_known = false;
+ ret = -EINTR;
+ goto erase_err;
+ }
#ifdef CONFIG_SPI_FLASH_BAR
ret = write_bar(nor, addr);
if (ret < 0)
- return ret;
+ goto erase_err;
#endif
- write_enable(nor);
+ ret = write_enable(nor);
+ if (ret < 0)
+ goto erase_err;
ret = spi_nor_erase_sector(nor, addr);
if (ret < 0)
@@ -945,11 +955,24 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
goto erase_err;
}
+ addr_known = false;
erase_err:
#ifdef CONFIG_SPI_FLASH_BAR
- ret = clean_bar(nor);
+ err = clean_bar(nor);
+ if (!ret)
+ ret = err;
#endif
- write_disable(nor);
+ err = write_disable(nor);
+ if (!ret)
+ ret = err;
+
+err:
+ if (ret) {
+ instr->fail_addr = addr_known ? addr : MTD_FAIL_ADDR_UNKNOWN;
+ instr->state = MTD_ERASE_FAILED;
+ } else {
+ instr->state = MTD_ERASE_DONE;
+ }
return ret;
}
@@ -1665,9 +1688,6 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
dev_dbg(nor->dev, "to 0x%08x, len %zd\n", (u32)to, len);
- if (!len)
- return 0;
-
for (i = 0; i < len; ) {
ssize_t written;
loff_t addr = to + i;
@@ -3224,6 +3244,21 @@ static struct spi_nor_fixups s25hx_t_fixups = {
.post_bfpt = s25hx_t_post_bfpt_fixup,
.post_sfdp = s25hx_t_post_sfdp_fixup,
};
+
+static int s25fl256l_setup(struct spi_nor *nor, const struct flash_info *info,
+ const struct spi_nor_flash_parameter *params)
+{
+ return -ENOTSUPP; /* Bank Address Register is not supported */
+}
+
+static void s25fl256l_default_init(struct spi_nor *nor)
+{
+ nor->setup = s25fl256l_setup;
+}
+
+static struct spi_nor_fixups s25fl256l_fixups = {
+ .default_init = s25fl256l_default_init,
+};
#endif
#ifdef CONFIG_SPI_FLASH_S28HS512T
@@ -3646,6 +3681,10 @@ void spi_nor_set_fixups(struct spi_nor *nor)
break;
}
}
+
+ if (CONFIG_IS_ENABLED(SPI_FLASH_BAR) &&
+ !strcmp(nor->info->name, "s25fl256l"))
+ nor->fixups = &s25fl256l_fixups;
#endif
#ifdef CONFIG_SPI_FLASH_S28HS512T
diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c
index 0bff52d5f2a..3ae7bb1ed7e 100644
--- a/drivers/mtd/spi/spi-nor-ids.c
+++ b/drivers/mtd/spi/spi-nor-ids.c
@@ -122,6 +122,11 @@ const struct flash_info spi_nor_ids[] = {
SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
},
+ {
+ INFO("gd25lq256d", 0xc86019, 0, 64 * 1024, 512,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
+ },
#endif
#ifdef CONFIG_SPI_FLASH_ISSI /* ISSI */
/* ISSI */
@@ -133,6 +138,8 @@ const struct flash_info spi_nor_ids[] = {
SECT_4K | SPI_NOR_DUAL_READ) },
{ INFO("is25lp256", 0x9d6019, 0, 64 * 1024, 512,
SECT_4K | SPI_NOR_DUAL_READ) },
+ { INFO("is25lp512", 0x9d601a, 0, 64 * 1024, 1024,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("is25wp032", 0x9d7016, 0, 64 * 1024, 64,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("is25wp064", 0x9d7017, 0, 64 * 1024, 128,
@@ -142,6 +149,8 @@ const struct flash_info spi_nor_ids[] = {
{ INFO("is25wp256", 0x9d7019, 0, 64 * 1024, 512,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
SPI_NOR_4B_OPCODES) },
+ { INFO("is25wp512", 0x9d701a, 0, 64 * 1024, 1024,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
#endif
#ifdef CONFIG_SPI_FLASH_MACRONIX /* MACRONIX */
/* Macronix */
@@ -186,7 +195,7 @@ const struct flash_info spi_nor_ids[] = {
{ INFO6("mt25qu256a", 0x20bb19, 0x104400, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES | USE_FSR) },
{ INFO("n25q256ax1", 0x20bb19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ | USE_FSR) },
{ INFO6("mt25qu512a", 0x20bb20, 0x104400, 64 * 1024, 1024,
- SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES |
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES |
USE_FSR) },
{ INFO("n25q512a", 0x20bb20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
{ INFO6("mt25ql512a", 0x20ba20, 0x104400, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
@@ -195,6 +204,7 @@ const struct flash_info spi_nor_ids[] = {
{ INFO("n25q00a", 0x20bb21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) },
{ INFO("mt25ql01g", 0x21ba20, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) },
{ INFO("mt25qu02g", 0x20bb22, 0, 64 * 1024, 4096, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) },
+ { INFO("mt25ql02g", 0x20ba22, 0, 64 * 1024, 4096, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE | SPI_NOR_4B_OPCODES) },
#ifdef CONFIG_SPI_FLASH_MT35XU
{ INFO("mt35xu512aba", 0x2c5b1a, 0, 128 * 1024, 512, USE_FSR | SPI_NOR_OCTAL_READ | SPI_NOR_4B_OPCODES | SPI_NOR_OCTAL_DTR_READ) },
#endif /* CONFIG_SPI_FLASH_MT35XU */
@@ -227,6 +237,7 @@ const struct flash_info spi_nor_ids[] = {
{ INFO("s25fl208k", 0x014014, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ) },
{ INFO("s25fl064l", 0x016017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
{ INFO("s25fl128l", 0x016018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+ { INFO("s25fl256l", 0x016019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
{ INFO6("s25hl512t", 0x342a1a, 0x0f0390, 256 * 1024, 256,
SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES |
USE_CLSR) },
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
index b8b878b9182..14be95b74bc 100644
--- a/drivers/mtd/ubi/io.c
+++ b/drivers/mtd/ubi/io.c
@@ -305,18 +305,6 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset,
}
/**
- * erase_callback - MTD erasure call-back.
- * @ei: MTD erase information object.
- *
- * Note, even though MTD erase interface is asynchronous, all the current
- * implementations are synchronous anyway.
- */
-static void erase_callback(struct erase_info *ei)
-{
- wake_up_interruptible((wait_queue_head_t *)ei->priv);
-}
-
-/**
* do_sync_erase - synchronously erase a physical eraseblock.
* @ubi: UBI device description object
* @pnum: the physical eraseblock number to erase
@@ -346,7 +334,6 @@ retry:
ei.mtd = ubi->mtd;
ei.addr = (loff_t)pnum * ubi->peb_size;
ei.len = ubi->peb_size;
- ei.callback = erase_callback;
ei.priv = (unsigned long)&wq;
err = mtd_erase(ubi->mtd, &ei);