]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
spi: fsl-qspi: use devm function instead of driver remove
authorHan Xu <han.xu@nxp.com>
Sat, 6 Sep 2025 20:53:20 +0000 (16:53 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 9 Sep 2025 16:56:29 +0000 (18:56 +0200)
[ Upstream commit 40369bfe717e96e26650eeecfa5a6363563df6e4 ]

Driver use devm APIs to manage clk/irq/resources and register the spi
controller, but the legacy remove function will be called first during
device detach and trigger kernel panic. Drop the remove function and use
devm_add_action_or_reset() for driver cleanup to ensure the release
sequence.

Trigger kernel panic on i.MX8MQ by
echo 30bb0000.spi >/sys/bus/platform/drivers/fsl-quadspi/unbind

Cc: stable@vger.kernel.org
Fixes: 8fcb830a00f0 ("spi: spi-fsl-qspi: use devm_spi_register_controller")
Reported-by: Kevin Hao <haokexin@gmail.com>
Signed-off-by: Han Xu <han.xu@nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20250326224152.2147099-1-han.xu@nxp.com
Signed-off-by: Mark Brown <broonie@kernel.org>
[ Adjust context ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/spi/spi-fsl-qspi.c

index 79bac30e79af64c12d8b890a75ef984fb2fa21d1..310350d2c530282fdbe4bc63ee6630bff5698da2 100644 (file)
@@ -839,6 +839,19 @@ static const struct spi_controller_mem_ops fsl_qspi_mem_ops = {
        .get_name = fsl_qspi_get_name,
 };
 
+static void fsl_qspi_cleanup(void *data)
+{
+       struct fsl_qspi *q = data;
+
+       /* disable the hardware */
+       qspi_writel(q, QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR);
+       qspi_writel(q, 0x0, q->iobase + QUADSPI_RSER);
+
+       fsl_qspi_clk_disable_unprep(q);
+
+       mutex_destroy(&q->lock);
+}
+
 static int fsl_qspi_probe(struct platform_device *pdev)
 {
        struct spi_controller *ctlr;
@@ -928,6 +941,10 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 
        ctlr->dev.of_node = np;
 
+       ret = devm_add_action_or_reset(dev, fsl_qspi_cleanup, q);
+       if (ret)
+               goto err_destroy_mutex;
+
        ret = devm_spi_register_controller(dev, ctlr);
        if (ret)
                goto err_destroy_mutex;
@@ -947,19 +964,6 @@ err_put_ctrl:
        return ret;
 }
 
-static void fsl_qspi_remove(struct platform_device *pdev)
-{
-       struct fsl_qspi *q = platform_get_drvdata(pdev);
-
-       /* disable the hardware */
-       qspi_writel(q, QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR);
-       qspi_writel(q, 0x0, q->iobase + QUADSPI_RSER);
-
-       fsl_qspi_clk_disable_unprep(q);
-
-       mutex_destroy(&q->lock);
-}
-
 static int fsl_qspi_suspend(struct device *dev)
 {
        return 0;
@@ -997,7 +1001,6 @@ static struct platform_driver fsl_qspi_driver = {
                .pm =   &fsl_qspi_pm_ops,
        },
        .probe          = fsl_qspi_probe,
-       .remove_new     = fsl_qspi_remove,
 };
 module_platform_driver(fsl_qspi_driver);