Commit 734882a8 authored by Charles Keepax's avatar Charles Keepax Committed by Mark Brown

spi: cadence: Correct initialisation of runtime PM

Currently the driver calls pm_runtime_put_autosuspend but without ever
having done a pm_runtime_get, this causes the reference count in the pm
runtime core to become -1. The bad reference count causes the core to
sometimes suspend whilst an active SPI transfer is in progress.

arizona spi0.1: SPI transfer timed out
spi_master spi0: failed to transfer one message from queue

The correct proceedure is to do all the initialisation that requires the
hardware to be powered up before enabling the PM runtime, then enable
the PM runtime having called pm_runtime_set_active to inform it that the
hardware is currently powered up. The core will then power it down at
it's leisure and no explicit pm_runtime_put is required.

Fixes: d36ccd9f ("spi: cadence: Runtime pm adaptation")
Signed-off-by: default avatarCharles Keepax <ckeepax@opensource.cirrus.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent de43affe
...@@ -522,11 +522,6 @@ static int cdns_spi_probe(struct platform_device *pdev) ...@@ -522,11 +522,6 @@ static int cdns_spi_probe(struct platform_device *pdev)
goto clk_dis_apb; goto clk_dis_apb;
} }
pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT);
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
ret = of_property_read_u32(pdev->dev.of_node, "num-cs", &num_cs); ret = of_property_read_u32(pdev->dev.of_node, "num-cs", &num_cs);
if (ret < 0) if (ret < 0)
master->num_chipselect = CDNS_SPI_DEFAULT_NUM_CS; master->num_chipselect = CDNS_SPI_DEFAULT_NUM_CS;
...@@ -541,8 +536,10 @@ static int cdns_spi_probe(struct platform_device *pdev) ...@@ -541,8 +536,10 @@ static int cdns_spi_probe(struct platform_device *pdev)
/* SPI controller initializations */ /* SPI controller initializations */
cdns_spi_init_hw(xspi); cdns_spi_init_hw(xspi);
pm_runtime_mark_last_busy(&pdev->dev); pm_runtime_set_active(&pdev->dev);
pm_runtime_put_autosuspend(&pdev->dev); pm_runtime_enable(&pdev->dev);
pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT);
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq <= 0) { if (irq <= 0) {
......
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