summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHan Xu <han.xu@nxp.com>2025-04-28 18:06:47 +0800
committerMark Brown <broonie@kernel.org>2025-05-06 23:17:31 +0900
commit9f7cd1bcb6363368abc954ff4e727b579813c697 (patch)
tree39ef1e3055bbd593a2ad87de30435a7e62905a2b
parente0558eb74c6e082b60e03981eb7cbf0fc3780ef4 (diff)
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>
-rw-r--r--drivers/spi/spi-nxp-fspi.c41
1 files changed, 22 insertions, 19 deletions
diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
index 0ea04e77a968..e63c77e41823 100644
--- a/drivers/spi/spi-nxp-fspi.c
+++ b/drivers/spi/spi-nxp-fspi.c
@@ -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,25 +1281,11 @@ static int nxp_fspi_probe(struct platform_device *pdev)
ctlr->mem_caps = &nxp_fspi_mem_caps;
ctlr->dev.of_node = np;
- 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);
+ 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");
- if (f->ahb_addr)
- iounmap(f->ahb_addr);
+ return devm_spi_register_controller(&pdev->dev, ctlr);
}
static int nxp_fspi_runtime_suspend(struct device *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);