spi: fsl-qspi: Fix double cleanup in probe error path

Merge series from Kevin Hao <haokexin@gmail.com>:

This patch series fixes double cleanup issues in the fsl-qspi probe
error path and also simplifies the probe error handling using managed APIs.
This commit is contained in:
Mark Brown 2025-04-10 15:08:38 +01:00
commit ed4db69169
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0

View File

@ -844,13 +844,18 @@ static const struct spi_controller_mem_caps fsl_qspi_mem_caps = {
.per_op_freq = true,
};
static void fsl_qspi_cleanup(void *data)
static void fsl_qspi_disable(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);
}
static void fsl_qspi_cleanup(void *data)
{
struct fsl_qspi *q = data;
fsl_qspi_clk_disable_unprep(q);
@ -866,7 +871,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
struct fsl_qspi *q;
int ret;
ctlr = spi_alloc_host(&pdev->dev, sizeof(*q));
ctlr = devm_spi_alloc_host(&pdev->dev, sizeof(*q));
if (!ctlr)
return -ENOMEM;
@ -876,68 +881,60 @@ static int fsl_qspi_probe(struct platform_device *pdev)
q = spi_controller_get_devdata(ctlr);
q->dev = dev;
q->devtype_data = of_device_get_match_data(dev);
if (!q->devtype_data) {
ret = -ENODEV;
goto err_put_ctrl;
}
if (!q->devtype_data)
return -ENODEV;
platform_set_drvdata(pdev, q);
/* find the resources */
q->iobase = devm_platform_ioremap_resource_byname(pdev, "QuadSPI");
if (IS_ERR(q->iobase)) {
ret = PTR_ERR(q->iobase);
goto err_put_ctrl;
}
if (IS_ERR(q->iobase))
return PTR_ERR(q->iobase);
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"QuadSPI-memory");
if (!res) {
ret = -EINVAL;
goto err_put_ctrl;
}
if (!res)
return -EINVAL;
q->memmap_phy = res->start;
/* Since there are 4 cs, map size required is 4 times ahb_buf_size */
q->ahb_addr = devm_ioremap(dev, q->memmap_phy,
(q->devtype_data->ahb_buf_size * 4));
if (!q->ahb_addr) {
ret = -ENOMEM;
goto err_put_ctrl;
}
if (!q->ahb_addr)
return -ENOMEM;
/* find the clocks */
q->clk_en = devm_clk_get(dev, "qspi_en");
if (IS_ERR(q->clk_en)) {
ret = PTR_ERR(q->clk_en);
goto err_put_ctrl;
}
if (IS_ERR(q->clk_en))
return PTR_ERR(q->clk_en);
q->clk = devm_clk_get(dev, "qspi");
if (IS_ERR(q->clk)) {
ret = PTR_ERR(q->clk);
goto err_put_ctrl;
}
if (IS_ERR(q->clk))
return PTR_ERR(q->clk);
mutex_init(&q->lock);
ret = fsl_qspi_clk_prep_enable(q);
if (ret) {
dev_err(dev, "can not enable the clock\n");
goto err_put_ctrl;
return ret;
}
ret = devm_add_action_or_reset(dev, fsl_qspi_cleanup, q);
if (ret)
return ret;
/* find the irq */
ret = platform_get_irq(pdev, 0);
if (ret < 0)
goto err_disable_clk;
return ret;
ret = devm_request_irq(dev, ret,
fsl_qspi_irq_handler, 0, pdev->name, q);
if (ret) {
dev_err(dev, "failed to request irq: %d\n", ret);
goto err_disable_clk;
return ret;
}
mutex_init(&q->lock);
ctlr->bus_num = -1;
ctlr->num_chipselect = 4;
ctlr->mem_ops = &fsl_qspi_mem_ops;
@ -947,27 +944,15 @@ 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);
ret = devm_add_action_or_reset(dev, fsl_qspi_disable, q);
if (ret)
goto err_destroy_mutex;
return ret;
ret = devm_spi_register_controller(dev, ctlr);
if (ret)
goto err_destroy_mutex;
return ret;
return 0;
err_destroy_mutex:
mutex_destroy(&q->lock);
err_disable_clk:
fsl_qspi_clk_disable_unprep(q);
err_put_ctrl:
spi_controller_put(ctlr);
dev_err(dev, "Freescale QuadSPI probe failed\n");
return ret;
}
static int fsl_qspi_suspend(struct device *dev)