Re: [PATCH v13 11/15] mtd: spi-nor: core: perform a Soft Reset on shutdown

From: Pratyush Yadav
Date: Tue Sep 29 2020 - 09:08:56 EST


On 16/09/20 06:14PM, Pratyush Yadav wrote:
> Perform a Soft Reset on shutdown on flashes that support it so that the
> flash can be reset to its initial state and any configurations made by
> spi-nor (given that they're only done in volatile registers) will be
> reset. This will hand back the flash in pristine state for any further
> operations on it.
>
> Signed-off-by: Pratyush Yadav <p.yadav@xxxxxx>
> ---
> drivers/mtd/spi-nor/core.c | 41 +++++++++++++++++++++++++++++++++++++
> include/linux/mtd/spi-nor.h | 2 ++
> 2 files changed, 43 insertions(+)
>
> diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
> index 6ee93544d72f..853dfa02f0de 100644
> --- a/drivers/mtd/spi-nor/core.c
> +++ b/drivers/mtd/spi-nor/core.c
> @@ -40,6 +40,9 @@
>
> #define SPI_NOR_MAX_ADDR_WIDTH 4
>
> +#define SPI_NOR_SRST_SLEEP_MIN 200
> +#define SPI_NOR_SRST_SLEEP_MAX 400
> +
> /**
> * spi_nor_get_cmd_ext() - Get the command opcode extension based on the
> * extension type.
> @@ -3174,6 +3177,41 @@ static int spi_nor_init(struct spi_nor *nor)
> return 0;
> }
>
> +static void spi_nor_soft_reset(struct spi_nor *nor)
> +{
> + struct spi_mem_op op;
> + int ret;
> +
> + op = (struct spi_mem_op)SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_SRSTEN, 8),

The buswidth used here should be 1 instead of 8. It makes no difference
in practice because the call to spi_nor_spimem_setup_op() immediately
after will over-write it to the correct value anyway, but let's follow
the style followed throughout the rest of the codebase. Will fix in the
next version.

> + SPI_MEM_OP_NO_DUMMY,
> + SPI_MEM_OP_NO_ADDR,
> + SPI_MEM_OP_NO_DATA);
> + spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
> + ret = spi_mem_exec_op(nor->spimem, &op);
> + if (ret) {
> + dev_warn(nor->dev, "Software reset failed: %d\n", ret);
> + return;
> + }
> +
> + op = (struct spi_mem_op)SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_SRST, 8),

Same here.

> + SPI_MEM_OP_NO_DUMMY,
> + SPI_MEM_OP_NO_ADDR,
> + SPI_MEM_OP_NO_DATA);
> + spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
> + ret = spi_mem_exec_op(nor->spimem, &op);
> + if (ret) {
> + dev_warn(nor->dev, "Software reset failed: %d\n", ret);
> + return;
> + }
> +
> + /*
> + * Software Reset is not instant, and the delay varies from flash to
> + * flash. Looking at a few flashes, most range somewhere below 100
> + * microseconds. So, sleep for a range of 200-400 us.
> + */
> + usleep_range(SPI_NOR_SRST_SLEEP_MIN, SPI_NOR_SRST_SLEEP_MAX);
> +}
> +
> /* mtd resume handler */
> static void spi_nor_resume(struct mtd_info *mtd)
> {

--
Regards,
Pratyush Yadav
Texas Instruments India