]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
spi: axiado: fix runtime pm imbalance on probe failure
authorJohan Hovold <johan@kernel.org>
Tue, 21 Apr 2026 14:39:23 +0000 (16:39 +0200)
committerMark Brown <broonie@kernel.org>
Wed, 22 Apr 2026 14:05:51 +0000 (15:05 +0100)
Make sure that the controller is active before disabling clocks on late
probe failure and on driver unbind to avoid a clock disable imbalance.

Also make sure that the usage count is balanced on probe failure (e.g.
probe deferral) so that the controller can be suspended when a driver is
later bound.

Note that the runtime PM state can only be set when runtime PM is
disabled.

Fixes: e75a6b00ad79 ("spi: axiado: Add driver for Axiado SPI DB controller")
Cc: stable@vger.kernel.org # 7.0
Cc: Vladimir Moravcevic <vmoravcevic@axiado.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
Link: https://patch.msgid.link/20260421143925.1551781-2-johan@kernel.org
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/spi/spi-axiado.c

index dc55c55ae63c8121d807f192aa95804c8b39c86e..6449b376a3a8817e56c3ddd46f2e5b13ef734b16 100644 (file)
@@ -842,8 +842,6 @@ static int ax_spi_probe(struct platform_device *pdev)
 
        ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
 
-       pm_runtime_put_autosuspend(&pdev->dev);
-
        ctlr->mem_ops = &ax_spi_mem_ops;
 
        ret = spi_register_controller(ctlr);
@@ -852,11 +850,16 @@ static int ax_spi_probe(struct platform_device *pdev)
                goto clk_dis_all;
        }
 
+       pm_runtime_put_autosuspend(&pdev->dev);
+
        return ret;
 
 clk_dis_all:
-       pm_runtime_set_suspended(&pdev->dev);
        pm_runtime_disable(&pdev->dev);
+       pm_runtime_put_noidle(&pdev->dev);
+       pm_runtime_set_suspended(&pdev->dev);
+       pm_runtime_dont_use_autosuspend(&pdev->dev);
+
        clk_disable_unprepare(xspi->ref_clk);
 clk_dis_apb:
        clk_disable_unprepare(xspi->pclk);
@@ -877,10 +880,14 @@ static void ax_spi_remove(struct platform_device *pdev)
        struct spi_controller *ctlr = platform_get_drvdata(pdev);
        struct ax_spi *xspi = spi_controller_get_devdata(ctlr);
 
+       pm_runtime_get_sync(&pdev->dev);
+
        spi_unregister_controller(ctlr);
 
-       pm_runtime_set_suspended(&pdev->dev);
        pm_runtime_disable(&pdev->dev);
+       pm_runtime_put_noidle(&pdev->dev);
+       pm_runtime_set_suspended(&pdev->dev);
+       pm_runtime_dont_use_autosuspend(&pdev->dev);
 
        clk_disable_unprepare(xspi->ref_clk);
        clk_disable_unprepare(xspi->pclk);