Commit 0578a6db authored by Dhruva Gole's avatar Dhruva Gole Committed by Mark Brown

spi: spi-cadence-quadspi: add runtime pm support

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: default avatarApurva Nandan <a-nandan@ti.com>
Signed-off-by: default avatarApurva Nandan <a-nandan@ti.com>
Signed-off-by: default avatarDhruva Gole <d-gole@ti.com>
Link: https://lore.kernel.org/r/20230829062706.786637-1-d-gole@ti.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent eb9913b5
...@@ -116,6 +116,9 @@ struct cqspi_driver_platdata { ...@@ -116,6 +116,9 @@ struct cqspi_driver_platdata {
#define CQSPI_TIMEOUT_MS 500 #define CQSPI_TIMEOUT_MS 500
#define CQSPI_READ_TIMEOUT_MS 10 #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_CLKS_PER_BYTE 8
#define CQSPI_DUMMY_BYTES_MAX 4 #define CQSPI_DUMMY_BYTES_MAX 4
#define CQSPI_DUMMY_CLKS_MAX 31 #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) ...@@ -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) static int cqspi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op)
{ {
int ret; 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); ret = cqspi_mem_process(mem, op);
pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev);
if (ret) if (ret)
dev_err(&mem->spi->dev, "operation failed with %d\n", ret); dev_err(&mem->spi->dev, "operation failed with %d\n", ret);
...@@ -1753,10 +1768,10 @@ static int cqspi_probe(struct platform_device *pdev) ...@@ -1753,10 +1768,10 @@ static int cqspi_probe(struct platform_device *pdev)
if (irq < 0) if (irq < 0)
return -ENXIO; return -ENXIO;
pm_runtime_enable(dev); ret = pm_runtime_set_active(dev);
ret = pm_runtime_resume_and_get(dev); if (ret)
if (ret < 0) return ret;
goto probe_pm_failed;
ret = clk_prepare_enable(cqspi->clk); ret = clk_prepare_enable(cqspi->clk);
if (ret) { if (ret) {
...@@ -1862,21 +1877,29 @@ static int cqspi_probe(struct platform_device *pdev) ...@@ -1862,21 +1877,29 @@ static int cqspi_probe(struct platform_device *pdev)
goto probe_setup_failed; 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); ret = spi_register_controller(host);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to register SPI ctlr %d\n", ret); dev_err(&pdev->dev, "failed to register SPI ctlr %d\n", ret);
goto probe_setup_failed; goto probe_setup_failed;
} }
pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev);
return 0; return 0;
probe_setup_failed: probe_setup_failed:
cqspi_controller_enable(cqspi, 0); cqspi_controller_enable(cqspi, 0);
probe_reset_failed: probe_reset_failed:
clk_disable_unprepare(cqspi->clk); clk_disable_unprepare(cqspi->clk);
probe_clk_failed: probe_clk_failed:
pm_runtime_put_sync(dev);
probe_pm_failed:
pm_runtime_disable(dev);
return ret; return ret;
} }
...@@ -1928,7 +1951,8 @@ static int cqspi_resume(struct device *dev) ...@@ -1928,7 +1951,8 @@ static int cqspi_resume(struct device *dev)
return spi_controller_resume(host); 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 = { static const struct cqspi_driver_platdata cdns_qspi = {
.quirks = CQSPI_DISABLE_DAC_MODE, .quirks = CQSPI_DISABLE_DAC_MODE,
...@@ -2012,7 +2036,7 @@ static struct platform_driver cqspi_platform_driver = { ...@@ -2012,7 +2036,7 @@ static struct platform_driver cqspi_platform_driver = {
.remove_new = cqspi_remove, .remove_new = cqspi_remove,
.driver = { .driver = {
.name = CQSPI_NAME, .name = CQSPI_NAME,
.pm = &cqspi_dev_pm_ops, .pm = pm_ptr(&cqspi_dev_pm_ops),
.of_match_table = cqspi_dt_ids, .of_match_table = cqspi_dt_ids,
}, },
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment