diff options
Diffstat (limited to 'drivers/mtd/nand/spi/core.c')
| -rw-r--r-- | drivers/mtd/nand/spi/core.c | 35 |
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); |
