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

Tudor.Ambarus at microchip.com Tudor.Ambarus at microchip.com
Thu Oct 1 04:23:48 EDT 2020


On 9/30/20 9:57 PM, Pratyush Yadav wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> 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>

Reviewed-by: Tudor Ambarus <tudor.ambarus at microchip.com>

> ---
>  drivers/mtd/spi-nor/core.c  | 45 +++++++++++++++++++++++++++++++++++++
>  include/linux/mtd/spi-nor.h |  2 ++
>  2 files changed, 47 insertions(+)
> 
> diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
> index b42d59ab2724..9de811b33125 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.
> @@ -3175,6 +3178,45 @@ 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, 0),
> +                       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, 0),
> +                       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)
>  {
> @@ -3194,6 +3236,9 @@ void spi_nor_restore(struct spi_nor *nor)
>         if (nor->addr_width == 4 && !(nor->flags & SNOR_F_4B_OPCODES) &&
>             nor->flags & SNOR_F_BROKEN_RESET)
>                 nor->params->set_4byte_addr_mode(nor, false);
> +
> +       if (nor->flags & SNOR_F_SOFT_RESET)
> +               spi_nor_soft_reset(nor);
>  }
>  EXPORT_SYMBOL_GPL(spi_nor_restore);
> 
> diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
> index cd549042c53d..299685d15dc2 100644
> --- a/include/linux/mtd/spi-nor.h
> +++ b/include/linux/mtd/spi-nor.h
> @@ -51,6 +51,8 @@
>  #define SPINOR_OP_CLFSR                0x50    /* Clear flag status register */
>  #define SPINOR_OP_RDEAR                0xc8    /* Read Extended Address Register */
>  #define SPINOR_OP_WREAR                0xc5    /* Write Extended Address Register */
> +#define SPINOR_OP_SRSTEN       0x66    /* Software Reset Enable */
> +#define SPINOR_OP_SRST         0x99    /* Software Reset */
> 
>  /* 4-byte address opcodes - used on Spansion and some Macronix flashes. */
>  #define SPINOR_OP_READ_4B      0x13    /* Read data bytes (low frequency) */
> --
> 2.28.0
> 



More information about the linux-mtd mailing list