Skip to content

Commit 40369bf

Browse files
hanxu-nxpbroonie
authored andcommitted
spi: fsl-qspi: use devm function instead of driver remove
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: 8fcb830 ("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>
1 parent d32c4e5 commit 40369bf

File tree

1 file changed

+17
-14
lines changed

1 file changed

+17
-14
lines changed

drivers/spi/spi-fsl-qspi.c

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,19 @@ static const struct spi_controller_mem_caps fsl_qspi_mem_caps = {
844844
.per_op_freq = true,
845845
};
846846

847+
static void fsl_qspi_cleanup(void *data)
848+
{
849+
struct fsl_qspi *q = data;
850+
851+
/* disable the hardware */
852+
qspi_writel(q, QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR);
853+
qspi_writel(q, 0x0, q->iobase + QUADSPI_RSER);
854+
855+
fsl_qspi_clk_disable_unprep(q);
856+
857+
mutex_destroy(&q->lock);
858+
}
859+
847860
static int fsl_qspi_probe(struct platform_device *pdev)
848861
{
849862
struct spi_controller *ctlr;
@@ -934,6 +947,10 @@ static int fsl_qspi_probe(struct platform_device *pdev)
934947

935948
ctlr->dev.of_node = np;
936949

950+
ret = devm_add_action_or_reset(dev, fsl_qspi_cleanup, q);
951+
if (ret)
952+
goto err_destroy_mutex;
953+
937954
ret = devm_spi_register_controller(dev, ctlr);
938955
if (ret)
939956
goto err_destroy_mutex;
@@ -953,19 +970,6 @@ static int fsl_qspi_probe(struct platform_device *pdev)
953970
return ret;
954971
}
955972

956-
static void fsl_qspi_remove(struct platform_device *pdev)
957-
{
958-
struct fsl_qspi *q = platform_get_drvdata(pdev);
959-
960-
/* disable the hardware */
961-
qspi_writel(q, QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR);
962-
qspi_writel(q, 0x0, q->iobase + QUADSPI_RSER);
963-
964-
fsl_qspi_clk_disable_unprep(q);
965-
966-
mutex_destroy(&q->lock);
967-
}
968-
969973
static int fsl_qspi_suspend(struct device *dev)
970974
{
971975
return 0;
@@ -1003,7 +1007,6 @@ static struct platform_driver fsl_qspi_driver = {
10031007
.pm = &fsl_qspi_pm_ops,
10041008
},
10051009
.probe = fsl_qspi_probe,
1006-
.remove = fsl_qspi_remove,
10071010
};
10081011
module_platform_driver(fsl_qspi_driver);
10091012

0 commit comments

Comments
 (0)