mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-12-28 05:34:13 -05:00
spi: nxp-fspi: use devm instead of remove for driver detach
fspi 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. Signed-off-by: Han Xu <han.xu@nxp.com> Signed-off-by: Haibo Chen <haibo.chen@nxp.com> Link: https://patch.msgid.link/20250428-flexspipatch-v3-5-61d5e8f591bc@nxp.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
@@ -1168,6 +1168,24 @@ static const struct spi_controller_mem_caps nxp_fspi_mem_caps = {
|
||||
.per_op_freq = true,
|
||||
};
|
||||
|
||||
static void nxp_fspi_cleanup(void *data)
|
||||
{
|
||||
struct nxp_fspi *f = data;
|
||||
|
||||
/* enable clock first since there is register access */
|
||||
pm_runtime_get_sync(f->dev);
|
||||
|
||||
/* disable the hardware */
|
||||
fspi_writel(f, FSPI_MCR0_MDIS, f->iobase + FSPI_MCR0);
|
||||
|
||||
pm_runtime_disable(f->dev);
|
||||
pm_runtime_put_noidle(f->dev);
|
||||
nxp_fspi_clk_disable_unprep(f);
|
||||
|
||||
if (f->ahb_addr)
|
||||
iounmap(f->ahb_addr);
|
||||
}
|
||||
|
||||
static int nxp_fspi_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct spi_controller *ctlr;
|
||||
@@ -1263,27 +1281,13 @@ static int nxp_fspi_probe(struct platform_device *pdev)
|
||||
ctlr->mem_caps = &nxp_fspi_mem_caps;
|
||||
ctlr->dev.of_node = np;
|
||||
|
||||
ret = devm_add_action_or_reset(dev, nxp_fspi_cleanup, f);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to register nxp_fspi_cleanup\n");
|
||||
|
||||
return devm_spi_register_controller(&pdev->dev, ctlr);
|
||||
}
|
||||
|
||||
static void nxp_fspi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct nxp_fspi *f = platform_get_drvdata(pdev);
|
||||
|
||||
/* enable clock first since there is reigster access */
|
||||
pm_runtime_get_sync(f->dev);
|
||||
|
||||
/* disable the hardware */
|
||||
fspi_writel(f, FSPI_MCR0_MDIS, f->iobase + FSPI_MCR0);
|
||||
|
||||
pm_runtime_disable(f->dev);
|
||||
pm_runtime_put_noidle(f->dev);
|
||||
nxp_fspi_clk_disable_unprep(f);
|
||||
|
||||
if (f->ahb_addr)
|
||||
iounmap(f->ahb_addr);
|
||||
}
|
||||
|
||||
static int nxp_fspi_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct nxp_fspi *f = dev_get_drvdata(dev);
|
||||
@@ -1361,7 +1365,6 @@ static struct platform_driver nxp_fspi_driver = {
|
||||
.pm = pm_ptr(&nxp_fspi_pm_ops),
|
||||
},
|
||||
.probe = nxp_fspi_probe,
|
||||
.remove = nxp_fspi_remove,
|
||||
};
|
||||
module_platform_driver(nxp_fspi_driver);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user