diff options
| -rw-r--r-- | drivers/mtd/nand/spi/core.c | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index 27af973bc12f..58ec85c98ab8 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -1093,6 +1093,39 @@ 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 = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev, + spinand->spimem, 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 = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev, + spinand->spimem, info); + } + + return desc; +} + static int spinand_create_dirmap(struct spinand_device *spinand, unsigned int plane) { @@ -1112,11 +1145,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 = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev, - spinand->spimem, &info); + desc = spinand_create_rdesc(spinand, &info); if (IS_ERR(desc)) return PTR_ERR(desc); @@ -1139,12 +1169,9 @@ static int spinand_create_dirmap(struct spinand_device *spinand, spinand->dirmaps[plane].wdesc_ecc = desc; - if (spinand->cont_read_possible) - info.length = nanddev_eraseblock_size(nand); info.op_tmpl = *spinand->op_templates.read_cache; info.op_tmpl.data.ecc = true; - desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev, - spinand->spimem, &info); + desc = spinand_create_rdesc(spinand, &info); if (IS_ERR(desc)) return PTR_ERR(desc); |
