diff options
author | Evgeny Novikov <novikov@ispras.ru> | 2021-08-17 12:29:30 +0300 |
---|---|---|
committer | Miquel Raynal <miquel.raynal@bootlin.com> | 2021-08-17 19:43:55 +0300 |
commit | 0792ec82175ec45a0f45af6e0f2d3cb49c527cd4 (patch) | |
tree | febc71759f826095826dcdff8242fc37f629dd4b /drivers/mtd | |
parent | 6f802696c2faf0119781fc3b7977a4eedf9ab239 (diff) | |
download | linux-0792ec82175ec45a0f45af6e0f2d3cb49c527cd4.tar.xz |
mtd: rawnand: intel: Fix error handling in probe
ebu_nand_probe() did not invoke ebu_dma_cleanup() and
clk_disable_unprepare() on some error handling paths. The patch fixes
that.
Found by Linux Driver Verification project (linuxtesting.org).
Fixes: 0b1039f016e8 ("mtd: rawnand: Add NAND controller support on Intel LGM SoC")
Signed-off-by: Evgeny Novikov <novikov@ispras.ru>
Co-developed-by: Kirill Shilimanov <kirill.shilimanov@huawei.com>
Signed-off-by: Kirill Shilimanov <kirill.shilimanov@huawei.com>
Co-developed-by: Anton Vasilyev <vasilyev@ispras.ru>
Signed-off-by: Anton Vasilyev <vasilyev@ispras.ru>
Cc: stable@vger.kernel.org
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20210817092930.23040-1-novikov@ispras.ru
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/nand/raw/intel-nand-controller.c | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/drivers/mtd/nand/raw/intel-nand-controller.c b/drivers/mtd/nand/raw/intel-nand-controller.c index 8b49fd56cf96..29e8a546dcd6 100644 --- a/drivers/mtd/nand/raw/intel-nand-controller.c +++ b/drivers/mtd/nand/raw/intel-nand-controller.c @@ -631,19 +631,26 @@ static int ebu_nand_probe(struct platform_device *pdev) ebu_host->clk_rate = clk_get_rate(ebu_host->clk); ebu_host->dma_tx = dma_request_chan(dev, "tx"); - if (IS_ERR(ebu_host->dma_tx)) - return dev_err_probe(dev, PTR_ERR(ebu_host->dma_tx), - "failed to request DMA tx chan!.\n"); + if (IS_ERR(ebu_host->dma_tx)) { + ret = dev_err_probe(dev, PTR_ERR(ebu_host->dma_tx), + "failed to request DMA tx chan!.\n"); + goto err_disable_unprepare_clk; + } ebu_host->dma_rx = dma_request_chan(dev, "rx"); - if (IS_ERR(ebu_host->dma_rx)) - return dev_err_probe(dev, PTR_ERR(ebu_host->dma_rx), - "failed to request DMA rx chan!.\n"); + if (IS_ERR(ebu_host->dma_rx)) { + ret = dev_err_probe(dev, PTR_ERR(ebu_host->dma_rx), + "failed to request DMA rx chan!.\n"); + ebu_host->dma_rx = NULL; + goto err_cleanup_dma; + } resname = devm_kasprintf(dev, GFP_KERNEL, "addr_sel%d", cs); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, resname); - if (!res) - return -EINVAL; + if (!res) { + ret = -EINVAL; + goto err_cleanup_dma; + } ebu_host->cs[cs].addr_sel = res->start; writel(ebu_host->cs[cs].addr_sel | EBU_ADDR_MASK(5) | EBU_ADDR_SEL_REGEN, ebu_host->ebu + EBU_ADDR_SEL(cs)); @@ -653,7 +660,8 @@ static int ebu_nand_probe(struct platform_device *pdev) mtd = nand_to_mtd(&ebu_host->chip); if (!mtd->name) { dev_err(ebu_host->dev, "NAND label property is mandatory\n"); - return -EINVAL; + ret = -EINVAL; + goto err_cleanup_dma; } mtd->dev.parent = dev; @@ -681,6 +689,7 @@ err_clean_nand: nand_cleanup(&ebu_host->chip); err_cleanup_dma: ebu_dma_cleanup(ebu_host); +err_disable_unprepare_clk: clk_disable_unprepare(ebu_host->clk); return ret; |