lkml.org 
[lkml]   [2021]   [Oct]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [PATCH v2 11/14] mtd: spinand: Perform Power-on-Reset on the flash in mtd_suspend()
    On Tue, 12 Oct 2021 02:16:16 +0530
    Apurva Nandan <a-nandan@ti.com> wrote:

    > A soft reset using FFh command doesn't erase the flash's configuration
    > and doesn't reset the SPI IO mode also. This can result in the flash
    > being in a different SPI IO mode, e.g. Octal DTR, when resuming from
    > sleep. This could put the flash in an unrecognized SPI IO mode, making
    > it unusable.
    >
    > Perform a Power-on-Reset (PoR), if available in the flash, when
    > performing mtd_suspend(). This would set the flash to clean
    > state for reinitialization during resume and would also ensure that it
    > is in standard SPI IO mode (1S-1S-1S) before the resume begins.
    >
    > Signed-off-by: Apurva Nandan <a-nandan@ti.com>
    > ---
    > drivers/mtd/nand/spi/core.c | 21 +++++++++++++++++++++
    > 1 file changed, 21 insertions(+)
    >
    > diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
    > index 9b570570ee81..60408531979a 100644
    > --- a/drivers/mtd/nand/spi/core.c
    > +++ b/drivers/mtd/nand/spi/core.c
    > @@ -1316,6 +1316,11 @@ static void spinand_mtd_resume(struct mtd_info *mtd)
    > int ret;
    >
    > spinand->reg_proto = SPINAND_SINGLE_STR;
    > + /*
    > + * PoR Reset (if available by the manufacturer) is performed at the suspend
    > + * time. Hence, those flashes remain in power-on-state at this point, in a
    > + * standard SPI IO mode. So, now the core unanimously performs a soft reset.
    > + */
    > ret = spinand_reset_op(spinand);
    > if (ret)
    > return;
    > @@ -1327,6 +1332,21 @@ static void spinand_mtd_resume(struct mtd_info *mtd)
    > spinand_ecc_enable(spinand, false);
    > }
    >
    > +static int spinand_mtd_suspend(struct mtd_info *mtd)
    > +{
    > + struct spinand_device *spinand = mtd_to_spinand(mtd);
    > + int ret;
    > +
    > + if (!(spinand->flags & SPINAND_HAS_POR_CMD_BIT))
    > + return 0;
    > +
    > + ret = spinand_power_on_rst_op(spinand);
    > + if (ret)
    > + dev_err(&spinand->spimem->spi->dev, "suspend() failed\n");
    > +
    > + return ret;
    > +}

    I suspect you need to implement the spi_mem_driver.shutdown() method
    and do a PoR in that case too. If the device doesn't support the PoR
    command, we should at least switch back to the 1-1-1-STR mode manually.

    > +
    > static int spinand_init(struct spinand_device *spinand)
    > {
    > struct device *dev = &spinand->spimem->spi->dev;
    > @@ -1399,6 +1419,7 @@ static int spinand_init(struct spinand_device *spinand)
    > mtd->_erase = spinand_mtd_erase;
    > mtd->_max_bad_blocks = nanddev_mtd_max_bad_blocks;
    > mtd->_resume = spinand_mtd_resume;
    > + mtd->_suspend = spinand_mtd_suspend;
    >
    > if (nand->ecc.engine) {
    > ret = mtd_ooblayout_count_freebytes(mtd);

    \
     
     \ /
      Last update: 2021-10-12 09:26    [W:2.238 / U:0.112 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site