Skip to content

Commit

Permalink
spi: fsl-qspi: use devm function instead of driver remove
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Han Xu authored and Mark Brown committed Mar 27, 2025
1 parent d32c4e5 commit 40369bf
Showing 1 changed file with 17 additions and 14 deletions.
31 changes: 17 additions & 14 deletions drivers/spi/spi-fsl-qspi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -1003,7 +1007,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);

Expand Down

0 comments on commit 40369bf

Please sign in to comment.