From: Johan Hovold Date: Tue, 21 Apr 2026 12:53:52 +0000 (+0200) Subject: spi: cadence-quadspi: fix runtime pm and clock imbalance on unbind X-Git-Tag: v7.0.9~79 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=004cce9adbdff676a401ea207e62a8a26db151b1;p=thirdparty%2Fkernel%2Fstable.git spi: cadence-quadspi: fix runtime pm and clock imbalance on unbind commit 5e8bb0cc72f1d52d8ac2a88f4c952e2e98056aed upstream. Make sure to balance the runtime PM usage count before returning on probe failure (to allow the controller to suspend after a probe deferral) and to only drop the usage count on driver unbind to avoid a clock disable imbalance. Also restore the autosuspend setting. Fixes: 0578a6dbfe75 ("spi: spi-cadence-quadspi: add runtime pm support") Cc: stable@vger.kernel.org # 6.7 Cc: Dhruva Gole Signed-off-by: Johan Hovold Link: https://patch.msgid.link/20260421125354.1534871-5-johan@kernel.org Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index b79f48f2420c..e5e02457d44c 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -1864,10 +1864,6 @@ static int cqspi_probe(struct platform_device *pdev) if (irq < 0) return -ENXIO; - ret = pm_runtime_set_active(dev); - if (ret) - return ret; - ret = clk_bulk_prepare_enable(CLK_QSPI_NUM, cqspi->clks); if (ret) { dev_err(dev, "Cannot enable QSPI clocks.\n"); @@ -1966,10 +1962,11 @@ static int cqspi_probe(struct platform_device *pdev) cqspi->sclk = 0; if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) { - pm_runtime_enable(dev); pm_runtime_set_autosuspend_delay(dev, CQSPI_AUTOSUSPEND_TIMEOUT); pm_runtime_use_autosuspend(dev); pm_runtime_get_noresume(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); } host->num_chipselect = cqspi->num_chipselect; @@ -2000,8 +1997,12 @@ release_dma_chan: if (cqspi->rx_chan) dma_release_channel(cqspi->rx_chan); disable_rpm: - if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) + if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) { pm_runtime_disable(dev); + pm_runtime_set_suspended(dev); + pm_runtime_put_noidle(dev); + pm_runtime_dont_use_autosuspend(dev); + } cqspi_controller_enable(cqspi, 0); disable_clks: clk_bulk_disable_unprepare(CLK_QSPI_NUM, cqspi->clks); @@ -2038,8 +2039,10 @@ static void cqspi_remove(struct platform_device *pdev) clk_bulk_disable_unprepare(CLK_QSPI_NUM, cqspi->clks); if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) { - pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + pm_runtime_put_noidle(&pdev->dev); + pm_runtime_dont_use_autosuspend(&pdev->dev); } }