diff options
author | Han Xu <han.xu@nxp.com> | 2017-12-07 15:59:47 -0600 |
---|---|---|
committer | Jason Liu <jason.hui.liu@nxp.com> | 2019-02-12 10:33:12 +0800 |
commit | a5d7f4424ccb5b3155fd4cdfc708537c41ceb474 (patch) | |
tree | f097e3eeb41fa2bea25b05e2fd6134707b8aaaca /drivers/mtd | |
parent | 074c0daeca0ad21ea32e75e29e05f7d4d7a64bb0 (diff) |
MLK-17121: mtd: fsl-flexspi: re-init the flexspi after suspend/resume
re-init the flexspi controller after suspend/resume.
runtime resume will re-init the controller, Once the it was initialized
and need to be re-init(determined by read specific register bit).
Signed-off-by: Han Xu <han.xu@nxp.com>
(cherry picked from commit fbc92b8524fde7cc048d4ccf603266e1b5e8734c)
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/spi-nor/fsl-flexspi.c | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/drivers/mtd/spi-nor/fsl-flexspi.c b/drivers/mtd/spi-nor/fsl-flexspi.c index a63650649350..9b114cb54c3e 100644 --- a/drivers/mtd/spi-nor/fsl-flexspi.c +++ b/drivers/mtd/spi-nor/fsl-flexspi.c @@ -469,6 +469,9 @@ struct fsl_flexspi { u32 ddr_smp; struct mutex lock; struct pm_qos_request pm_qos_req; + +#define FLEXSPI_INITILIZED (1 << 0) + int flags; }; static inline int fsl_flexspi_quad_only(struct fsl_flexspi *flex) @@ -1355,6 +1358,9 @@ static int fsl_flexspi_probe(struct platform_device *pdev) if (ret) goto last_init_failed; + /* indicate the controller has been initialized */ + flex->flags |= FLEXSPI_INITILIZED; + return 0; last_init_failed: @@ -1396,17 +1402,19 @@ static int fsl_flexspi_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int fsl_flexspi_pm_suspend(struct device *dev) +static int fsl_flexspi_initialized(struct fsl_flexspi *flex) { - return pm_runtime_force_suspend(dev); + return flex->flags & FLEXSPI_INITILIZED; } -static int fsl_flexspi_pm_resume(struct device *dev) +static int fsl_flexspi_need_reinit(struct fsl_flexspi *flex) { - return pm_runtime_force_resume(dev); + /* we always use the controller in combination mode, so we check this */ + /* register bit to determine if the controller once lost power, such as */ + /* suspend/resume, and need to be re-init */ + + return !(readl(flex->iobase + FLEXSPI_MCR0) & FLEXSPI_MCR0_OCTCOMB_EN_MASK); } -#endif int fsl_flexspi_runtime_suspend(struct device *dev) { @@ -1421,12 +1429,21 @@ int fsl_flexspi_runtime_resume(struct device *dev) { struct fsl_flexspi *flex = dev_get_drvdata(dev); - return fsl_flexspi_clk_prep_enable(flex); + fsl_flexspi_clk_prep_enable(flex); + + if (fsl_flexspi_initialized(flex) && + fsl_flexspi_need_reinit(flex)) { + fsl_flexspi_nor_setup(flex); + fsl_flexspi_set_map_addr(flex); + fsl_flexspi_nor_setup_last(flex); + } + + return 0; } static const struct dev_pm_ops fsl_flexspi_pm_ops = { SET_RUNTIME_PM_OPS(fsl_flexspi_runtime_suspend, fsl_flexspi_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(fsl_flexspi_pm_suspend, fsl_flexspi_pm_resume) + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; static struct platform_driver fsl_flexspi_driver = { |