diff options
Diffstat (limited to 'queue-6.12/spi-fsl-qspi-use-devm-function-instead-of-driver-rem.patch')
-rw-r--r-- | queue-6.12/spi-fsl-qspi-use-devm-function-instead-of-driver-rem.patch | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/queue-6.12/spi-fsl-qspi-use-devm-function-instead-of-driver-rem.patch b/queue-6.12/spi-fsl-qspi-use-devm-function-instead-of-driver-rem.patch new file mode 100644 index 0000000000..9217c93921 --- /dev/null +++ b/queue-6.12/spi-fsl-qspi-use-devm-function-instead-of-driver-rem.patch @@ -0,0 +1,96 @@ +From 201bd9e3cb2e7ccdd87022ea46227dd746514823 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Wed, 26 Mar 2025 17:41:51 -0500 +Subject: spi: fsl-qspi: use devm function instead of driver remove + +From: Han Xu <han.xu@nxp.com> + +[ 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> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/spi/spi-fsl-qspi.c | 31 +++++++++++++++++-------------- + 1 file changed, 17 insertions(+), 14 deletions(-) + +diff --git a/drivers/spi/spi-fsl-qspi.c b/drivers/spi/spi-fsl-qspi.c +index ce86f44b0e93f..5c59fddb32c1b 100644 +--- a/drivers/spi/spi-fsl-qspi.c ++++ b/drivers/spi/spi-fsl-qspi.c +@@ -844,6 +844,19 @@ static const struct spi_controller_mem_caps fsl_qspi_mem_caps = { + .per_op_freq = true, + }; + ++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; +@@ -934,6 +947,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; +@@ -953,19 +970,6 @@ static int fsl_qspi_probe(struct platform_device *pdev) + 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; +@@ -1003,7 +1007,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); + +-- +2.39.5 + |