spi: spi-mem: stm32-qspi: add suspend/resume support
authorLudovic Barre <ludovic.barre@st.com>
Fri, 8 Mar 2019 13:12:21 +0000 (14:12 +0100)
committerMark Brown <broonie@kernel.org>
Fri, 15 Mar 2019 17:14:32 +0000 (17:14 +0000)
This patch adds suspend and resume support for spi-stm32-qspi
drivers.

Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/spi/spi-stm32-qspi.c

index 7354f9d68dba13ee142f7bb196adb50ab663e4c9..3e8ca10011ccea859dc4f7f70cb37db992f1f2b5 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/mutex.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/pinctrl/consumer.h>
 #include <linux/platform_device.h>
 #include <linux/reset.h>
 #include <linux/sizes.h>
@@ -101,6 +102,9 @@ struct stm32_qspi {
        struct completion data_completion;
        u32 fmode;
 
+       u32 cr_reg;
+       u32 dcr_reg;
+
        /*
         * to protect device configuration, could be different between
         * 2 flash access (bk1, bk2)
@@ -355,7 +359,7 @@ static int stm32_qspi_setup(struct spi_device *spi)
        struct spi_controller *ctrl = spi->master;
        struct stm32_qspi *qspi = spi_controller_get_devdata(ctrl);
        struct stm32_qspi_flash *flash;
-       u32 cr, presc;
+       u32 presc;
 
        if (ctrl->busy)
                return -EBUSY;
@@ -371,11 +375,12 @@ static int stm32_qspi_setup(struct spi_device *spi)
        flash->presc = presc;
 
        mutex_lock(&qspi->lock);
-       cr = FIELD_PREP(CR_FTHRES_MASK, 3) | CR_SSHIFT | CR_EN;
-       writel_relaxed(cr, qspi->io_base + QSPI_CR);
+       qspi->cr_reg = FIELD_PREP(CR_FTHRES_MASK, 3) | CR_SSHIFT | CR_EN;
+       writel_relaxed(qspi->cr_reg, qspi->io_base + QSPI_CR);
 
        /* set dcr fsize to max address */
-       writel_relaxed(DCR_FSIZE_MASK, qspi->io_base + QSPI_DCR);
+       qspi->dcr_reg = DCR_FSIZE_MASK;
+       writel_relaxed(qspi->dcr_reg, qspi->io_base + QSPI_DCR);
        mutex_unlock(&qspi->lock);
 
        return 0;
@@ -489,6 +494,31 @@ static int stm32_qspi_remove(struct platform_device *pdev)
        return 0;
 }
 
+static int __maybe_unused stm32_qspi_suspend(struct device *dev)
+{
+       struct stm32_qspi *qspi = dev_get_drvdata(dev);
+
+       clk_disable_unprepare(qspi->clk);
+       pinctrl_pm_select_sleep_state(dev);
+
+       return 0;
+}
+
+static int __maybe_unused stm32_qspi_resume(struct device *dev)
+{
+       struct stm32_qspi *qspi = dev_get_drvdata(dev);
+
+       pinctrl_pm_select_default_state(dev);
+       clk_prepare_enable(qspi->clk);
+
+       writel_relaxed(qspi->cr_reg, qspi->io_base + QSPI_CR);
+       writel_relaxed(qspi->dcr_reg, qspi->io_base + QSPI_DCR);
+
+       return 0;
+}
+
+SIMPLE_DEV_PM_OPS(stm32_qspi_pm_ops, stm32_qspi_suspend, stm32_qspi_resume);
+
 static const struct of_device_id stm32_qspi_match[] = {
        {.compatible = "st,stm32f469-qspi"},
        {}
@@ -501,6 +531,7 @@ static struct platform_driver stm32_qspi_driver = {
        .driver = {
                .name = "stm32-qspi",
                .of_match_table = stm32_qspi_match,
+               .pm = &stm32_qspi_pm_ops,
        },
 };
 module_platform_driver(stm32_qspi_driver);