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

Pratyush Yadav p.yadav at ti.com
Tue Sep 29 09:08:40 EDT 2020


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 at ti.com>
> ---
>  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



More information about the linux-mtd mailing list