mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 01:53:29 +02:00
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:
commit
ed4db69169
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user