mtd: rawnand: atmel: Fix MCK clock leak in atmel_nand_controller_init()

atmel_nand_controller_init() takes a reference to the MCK clock with
of_clk_get() and keeps it in nc->mck for the lifetime of the
controller.  If the "atmel,smc" phandle is missing or the SMC regmap
cannot be obtained afterwards, the error path jumps to out_release_dma
which only releases the DMA channel, so the clock reference is leaked.
The callers return the error directly and never run
atmel_nand_controller_cleanup(), where the clock is normally put.

Release the reference on those error paths.  The path on which
of_clk_get() itself fails keeps jumping to out_release_dma, as nc->mck
only holds an error pointer there.

Fixes: f9ce2eddf1 ("mtd: nand: atmel: Add ->setup_data_interface() hooks")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
This commit is contained in:
Wentao Liang 2026-09-17 10:29:24 +00:00 committed by Miquel Raynal
parent 8a485a40f4
commit 94edcda45d

View File

@ -2085,7 +2085,7 @@ static int atmel_nand_controller_init(struct atmel_nand_controller *nc,
if (!np) {
dev_err(dev, "Missing or invalid atmel,smc property\n");
ret = -EINVAL;
goto out_release_dma;
goto out_put_mck;
}
nc->smc = syscon_node_to_regmap(np);
@ -2093,11 +2093,13 @@ static int atmel_nand_controller_init(struct atmel_nand_controller *nc,
if (IS_ERR(nc->smc)) {
ret = PTR_ERR(nc->smc);
dev_err(dev, "Could not get SMC regmap (err = %d)\n", ret);
goto out_release_dma;
goto out_put_mck;
}
return 0;
out_put_mck:
clk_put(nc->mck);
out_release_dma:
if (nc->dmac)
dma_release_channel(nc->dmac);