summaryrefslogtreecommitdiff
path: root/drivers/mtd/nand/spi/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/nand/spi/core.c')
-rw-r--r--drivers/mtd/nand/spi/core.c35
1 files changed, 32 insertions, 3 deletions
diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 69dbdd60a6a..68a03ddee8b 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -1114,6 +1114,37 @@ static int spinand_mtd_block_isreserved(struct mtd_info *mtd, loff_t offs)
return ret;
}
+static struct spi_mem_dirmap_desc *spinand_create_rdesc(
+ struct spinand_device *spinand,
+ struct spi_mem_dirmap_info *info)
+{
+ struct nand_device *nand = spinand_to_nand(spinand);
+ struct spi_mem_dirmap_desc *desc = NULL;
+
+ if (spinand->cont_read_possible) {
+ /*
+ * spi controller may return an error if info->length is
+ * too large
+ */
+ info->length = nanddev_eraseblock_size(nand);
+ desc = spi_mem_dirmap_create(spinand->slave, info);
+ }
+
+ if (IS_ERR_OR_NULL(desc)) {
+ /*
+ * continuous reading is not supported by flash or
+ * its spi controller, use regular reading
+ */
+ spinand->cont_read_possible = false;
+
+ info->length = nanddev_page_size(nand) +
+ nanddev_per_page_oobsize(nand);
+ desc = spi_mem_dirmap_create(spinand->slave, info);
+ }
+
+ return desc;
+}
+
static int spinand_create_dirmap(struct spinand_device *spinand,
unsigned int plane)
{
@@ -1132,10 +1163,8 @@ static int spinand_create_dirmap(struct spinand_device *spinand,
spinand->dirmaps[plane].wdesc = desc;
- if (spinand->cont_read_possible)
- info.length = nanddev_eraseblock_size(nand);
info.op_tmpl = *spinand->op_templates.read_cache;
- desc = spi_mem_dirmap_create(spinand->slave, &info);
+ desc = spinand_create_rdesc(spinand, &info);
if (IS_ERR(desc)) {
spi_mem_dirmap_destroy(spinand->dirmaps[plane].wdesc);
return PTR_ERR(desc);