mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
synced 2025-08-28 18:10:32 +00:00
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: 8fcb830a00
("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>
This commit is contained in:
parent
d32c4e5854
commit
40369bfe71
@ -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 = fsl_qspi_remove,
|
||||
};
|
||||
module_platform_driver(fsl_qspi_driver);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user