spi: spi-cadence-quadspi: add runtime pm support
authorDhruva Gole <d-gole@ti.com>
Tue, 29 Aug 2023 06:27:08 +0000 (11:57 +0530)
committerMark Brown <broonie@kernel.org>
Mon, 11 Sep 2023 00:32:21 +0000 (01:32 +0100)
Add runtime pm support to cadence-qspi driver, this allows the driver to
suspend whenever it's is not actively being used thus reducing active
power consumed by the system.

Also, with the use of devm_pm_runtime_enable we no longer need the
fallback probe_pm_failed that used to pm_runtime_disable

Co-developed-by: Apurva Nandan <a-nandan@ti.com>
Signed-off-by: Apurva Nandan <a-nandan@ti.com>
Signed-off-by: Dhruva Gole <d-gole@ti.com>
Link: https://lore.kernel.org/r/20230829062706.786637-1-d-gole@ti.com
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/spi/spi-cadence-quadspi.c

index b50db71ac4cccc58f7f936180fb2b9f9cf741a4b..4828da4587c56480059aa13e5a2082f0b5c6097d 100644 (file)
@@ -116,6 +116,9 @@ struct cqspi_driver_platdata {
 #define CQSPI_TIMEOUT_MS                       500
 #define CQSPI_READ_TIMEOUT_MS                  10
 
+/* Runtime_pm autosuspend delay */
+#define CQSPI_AUTOSUSPEND_TIMEOUT              2000
+
 #define CQSPI_DUMMY_CLKS_PER_BYTE              8
 #define CQSPI_DUMMY_BYTES_MAX                  4
 #define CQSPI_DUMMY_CLKS_MAX                   31
@@ -1407,8 +1410,20 @@ static int cqspi_mem_process(struct spi_mem *mem, const struct spi_mem_op *op)
 static int cqspi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op)
 {
        int ret;
+       struct cqspi_st *cqspi = spi_master_get_devdata(mem->spi->master);
+       struct device *dev = &cqspi->pdev->dev;
+
+       ret = pm_runtime_resume_and_get(dev);
+       if (ret) {
+               dev_err(&mem->spi->dev, "resume failed with %d\n", ret);
+               return ret;
+       }
 
        ret = cqspi_mem_process(mem, op);
+
+       pm_runtime_mark_last_busy(dev);
+       pm_runtime_put_autosuspend(dev);
+
        if (ret)
                dev_err(&mem->spi->dev, "operation failed with %d\n", ret);
 
@@ -1753,10 +1768,10 @@ static int cqspi_probe(struct platform_device *pdev)
        if (irq < 0)
                return -ENXIO;
 
-       pm_runtime_enable(dev);
-       ret = pm_runtime_resume_and_get(dev);
-       if (ret < 0)
-               goto probe_pm_failed;
+       ret = pm_runtime_set_active(dev);
+       if (ret)
+               return ret;
+
 
        ret = clk_prepare_enable(cqspi->clk);
        if (ret) {
@@ -1862,21 +1877,29 @@ static int cqspi_probe(struct platform_device *pdev)
                        goto probe_setup_failed;
        }
 
+       ret = devm_pm_runtime_enable(dev);
+       if (ret)
+               return ret;
+
+       pm_runtime_set_autosuspend_delay(dev, CQSPI_AUTOSUSPEND_TIMEOUT);
+       pm_runtime_use_autosuspend(dev);
+       pm_runtime_get_noresume(dev);
+
        ret = spi_register_controller(host);
        if (ret) {
                dev_err(&pdev->dev, "failed to register SPI ctlr %d\n", ret);
                goto probe_setup_failed;
        }
 
+       pm_runtime_mark_last_busy(dev);
+       pm_runtime_put_autosuspend(dev);
+
        return 0;
 probe_setup_failed:
        cqspi_controller_enable(cqspi, 0);
 probe_reset_failed:
        clk_disable_unprepare(cqspi->clk);
 probe_clk_failed:
-       pm_runtime_put_sync(dev);
-probe_pm_failed:
-       pm_runtime_disable(dev);
        return ret;
 }
 
@@ -1928,7 +1951,8 @@ static int cqspi_resume(struct device *dev)
        return spi_controller_resume(host);
 }
 
-static DEFINE_SIMPLE_DEV_PM_OPS(cqspi_dev_pm_ops, cqspi_suspend, cqspi_resume);
+static DEFINE_RUNTIME_DEV_PM_OPS(cqspi_dev_pm_ops, cqspi_suspend,
+                                cqspi_resume, NULL);
 
 static const struct cqspi_driver_platdata cdns_qspi = {
        .quirks = CQSPI_DISABLE_DAC_MODE,
@@ -2012,7 +2036,7 @@ static struct platform_driver cqspi_platform_driver = {
        .remove_new = cqspi_remove,
        .driver = {
                .name = CQSPI_NAME,
-               .pm = &cqspi_dev_pm_ops,
+               .pm = pm_ptr(&cqspi_dev_pm_ops),
                .of_match_table = cqspi_dt_ids,
        },
 };