From: Ludovic Barre <ludovic.ba...@st.com>

This patch adds suspend and resume support for spi-stm32-qspi
drivers.

Signed-off-by: Ludovic Barre <ludovic.ba...@st.com>
---
 drivers/spi/spi-stm32-qspi.c | 39 +++++++++++++++++++++++++++++++++++----
 1 file changed, 35 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-stm32-qspi.c b/drivers/spi/spi-stm32-qspi.c
index 7354f9d..3e8ca10 100644
--- a/drivers/spi/spi-stm32-qspi.c
+++ b/drivers/spi/spi-stm32-qspi.c
@@ -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);
-- 
2.7.4

Reply via email to