diff options
Diffstat (limited to 'drivers/spi/spi-cadence-quadspi.c')
-rw-r--r-- | drivers/spi/spi-cadence-quadspi.c | 45 |
1 files changed, 36 insertions, 9 deletions
diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index 2064dc4ea9..f94e0d370d 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -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,12 +1877,26 @@ static int cqspi_probe(struct platform_device *pdev) goto probe_setup_failed; } + ret = devm_pm_runtime_enable(dev); + if (ret) { + if (cqspi->rx_chan) + dma_release_channel(cqspi->rx_chan); + goto probe_setup_failed; + } + + 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); @@ -1876,9 +1905,6 @@ probe_reset_failed: cqspi_jh7110_disable_clk(pdev, cqspi); clk_disable_unprepare(cqspi->clk); probe_clk_failed: - pm_runtime_put_sync(dev); -probe_pm_failed: - pm_runtime_disable(dev); return ret; } @@ -1930,7 +1956,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, @@ -2014,7 +2041,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, }, }; |