MLK-17121: mtd: fsl-flexspi: re-init the flexspi after suspend/resume
authorHan Xu <han.xu@nxp.com>
Thu, 7 Dec 2017 21:59:47 +0000 (15:59 -0600)
committerNitin Garg <nitin.garg@nxp.com>
Tue, 20 Mar 2018 19:51:06 +0000 (14:51 -0500)
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>
drivers/mtd/spi-nor/fsl-flexspi.c

index 1e8f2e4..3ee9f44 100644 (file)
@@ -459,6 +459,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 void fsl_flexspi_unlock_lut(struct fsl_flexspi *flex)
@@ -1335,6 +1338,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:
@@ -1376,17 +1382,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)
 {
@@ -1401,12 +1409,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 = {