]> 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>
Wed, 26 Mar 2025 22:41:51 +0000 (17:41 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 20 Apr 2025 08:18:27 +0000 (10:18 +0200)
commit 40369bfe717e96e26650eeecfa5a6363563df6e4 upstream.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/spi/spi-fsl-qspi.c

index 9ec53bf0dda8ead27bc7a11a9bb09a08efe2ea05..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         = fsl_qspi_remove,
 };
 module_platform_driver(fsl_qspi_driver);