[PATCH v2 3/4] mtd: rawnand: qcom: unwind registered chips on child probe failure
James Hilliard
james.hilliard1 at gmail.com
Sun Nov 8 14:42:10 PST 2026
qcom_probe_nand_devices() continues after a child initialization error,
allowing a later successful child to hide failures such as -ENOMEM or
-EPROBE_DEFER. If the last child fails, or allocating a subsequent host
fails, probe releases controller resources without unregistering chips
that were already published.
Fail probe on the first error from an enabled NAND child and propagate
that error. Share chip cleanup with removal and run it before releasing
DMA resources or disabling the controller clocks.
Fixes: 89f5127c4b0d ("mtd: nand: qcom: reorganize nand devices probing")
Cc: stable at vger.kernel.org
Signed-off-by: James Hilliard <james.hilliard1 at gmail.com>
---
drivers/mtd/nand/raw/qcom_nandc.c | 29 ++++++++++++++++++-----------
1 file changed, 18 insertions(+), 11 deletions(-)
diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
index 062fba9eaecc..14bb7f3d6c36 100644
--- a/drivers/mtd/nand/raw/qcom_nandc.c
+++ b/drivers/mtd/nand/raw/qcom_nandc.c
@@ -2085,7 +2085,7 @@ static int qcom_probe_nand_devices(struct qcom_nand_controller *nandc)
ret = qcom_nand_host_init_and_register(nandc, host, child);
if (ret) {
devm_kfree(dev, host);
- continue;
+ return ret;
}
list_add_tail(&host->node, &nandc->host_list);
@@ -2094,6 +2094,19 @@ static int qcom_probe_nand_devices(struct qcom_nand_controller *nandc)
return ret;
}
+static void qcom_nandc_cleanup_chips(struct qcom_nand_controller *nandc)
+{
+ struct qcom_nand_host *host, *tmp;
+ int ret;
+
+ list_for_each_entry_safe(host, tmp, &nandc->host_list, node) {
+ ret = mtd_device_unregister(nand_to_mtd(&host->chip));
+ WARN_ON(ret);
+ nand_cleanup(&host->chip);
+ list_del(&host->node);
+ }
+}
+
/* parse custom DT properties here */
static int qcom_nandc_parse_dt(struct platform_device *pdev)
{
@@ -2184,10 +2197,12 @@ static int qcom_nandc_probe(struct platform_device *pdev)
ret = qcom_probe_nand_devices(nandc);
if (ret)
- goto err_setup;
+ goto err_cleanup_chips;
return 0;
+err_cleanup_chips:
+ qcom_nandc_cleanup_chips(nandc);
err_setup:
qcom_nandc_unalloc(nandc);
err_nandc_alloc:
@@ -2204,16 +2219,8 @@ static void qcom_nandc_remove(struct platform_device *pdev)
{
struct qcom_nand_controller *nandc = platform_get_drvdata(pdev);
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- struct qcom_nand_host *host;
- struct nand_chip *chip;
- int ret;
- list_for_each_entry(host, &nandc->host_list, node) {
- chip = &host->chip;
- ret = mtd_device_unregister(nand_to_mtd(chip));
- WARN_ON(ret);
- nand_cleanup(chip);
- }
+ qcom_nandc_cleanup_chips(nandc);
qcom_nandc_unalloc(nandc);
--
2.53.0
More information about the linux-mtd
mailing list