From: Christophe Kerello <christophe.kerello@xxxxxxxxxxx> Make use of spi-mem poll status APIs to let advanced controllers optimize wait operations Signed-off-by: Christophe Kerello <christophe.kerello@xxxxxxxxxxx> Signed-off-by: Patrice Chotard <patrice.chotard@xxxxxxxxxxx> --- drivers/mtd/nand/spi/core.c | 22 ++++++++++++++++++---- include/linux/mtd/spinand.h | 1 + 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index 17f63f95f4a2..916f435257bd 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -475,18 +475,32 @@ static int spinand_erase_op(struct spinand_device *spinand, static int spinand_wait(struct spinand_device *spinand, u8 *s) { - unsigned long timeo = jiffies + msecs_to_jiffies(400); + struct spi_mem_op op = SPINAND_GET_FEATURE_OP(REG_STATUS, + spinand->scratchbuf); + unsigned long timeo = jiffies + msecs_to_jiffies(SPINAND_STATUS_TIMEOUT_MS); u8 status; int ret; - do { - ret = spinand_read_status(spinand, &status); + ret = spi_mem_poll_status(spinand->spimem, &op, STATUS_BUSY, 0, + SPINAND_STATUS_TIMEOUT_MS); + if (ret != -EOPNOTSUPP) { if (ret) return ret; + status = *spinand->scratchbuf; + if (!(status & STATUS_BUSY)) goto out; - } while (time_before(jiffies, timeo)); + } else { + do { + ret = spinand_read_status(spinand, &status); + if (ret) + return ret; + + if (!(status & STATUS_BUSY)) + goto out; + } while (time_before(jiffies, timeo)); + } /* * Extra read, just in case the STATUS_READY bit has changed diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h index 6bb92f26833e..28ee481d96eb 100644 --- a/include/linux/mtd/spinand.h +++ b/include/linux/mtd/spinand.h @@ -170,6 +170,7 @@ struct spinand_op; struct spinand_device; #define SPINAND_MAX_ID_LEN 4 +#define SPINAND_STATUS_TIMEOUT_MS 400 /** * struct spinand_id - SPI NAND id structure -- 2.17.1