[PATCH v4 47/58] mtd: rawnand: lpc32xx_mlc: retain chip state across removal
From: James Hilliard
Date: Fri Nov 13 2026 - 16:05:26 EST
Drain chip operations before releasing interrupts, DMA and controller
resources. Retain the embedded NAND chip and controller until the final
MTD reference releases their metadata.
Run NAND cleanup during disconnection; the final core-owned put only
releases retained allocation and layout data.
Cc: linux-arm-kernel@xxxxxxxxxxxxxxxxxxx
Cc: Piotr Wojtaszczyk <piotr.wojtaszczyk@xxxxxxxxxxx>
Cc: Vladimir Zapolskiy <vz@xxxxxxxxx>
Signed-off-by: James Hilliard <james.hilliard1@xxxxxxxxx>
---
drivers/mtd/nand/raw/lpc32xx_mlc.c | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/drivers/mtd/nand/raw/lpc32xx_mlc.c b/drivers/mtd/nand/raw/lpc32xx_mlc.c
index 408b2aba2fdd..633d09471760 100644
--- a/drivers/mtd/nand/raw/lpc32xx_mlc.c
+++ b/drivers/mtd/nand/raw/lpc32xx_mlc.c
@@ -687,9 +687,14 @@ static int lpc32xx_nand_probe(struct platform_device *pdev)
int res;
/* Allocate memory for the device structure (and zero it) */
- host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
+ host = kzalloc_obj(*host);
if (!host)
return -ENOMEM;
+ nand_chip = &host->nand_chip;
+ nand_chip->controller = &nand_chip->legacy.dummy_controller;
+ res = devm_nand_controller_init(&pdev->dev, nand_chip->controller, host);
+ if (res)
+ return res;
host->pdev = pdev;
@@ -794,10 +799,16 @@ static int lpc32xx_nand_probe(struct platform_device *pdev)
mtd->name = DRV_NAME;
- res = mtd_device_register(mtd, host->ncfg->parts,
- host->ncfg->num_parts);
+ res = nand_set_lifetime(nand_chip, NULL);
if (res)
goto cleanup_nand;
+ res = mtd_device_register(mtd, host->ncfg->parts,
+ host->ncfg->num_parts);
+ if (res) {
+ nand_disconnect(nand_chip);
+ mtd_put_master(mtd);
+ goto free_irq;
+ }
return 0;
@@ -830,7 +841,7 @@ static void lpc32xx_nand_remove(struct platform_device *pdev)
ret = mtd_device_unregister(nand_to_mtd(chip));
WARN_ON(ret);
- nand_cleanup(chip);
+ nand_disconnect(chip);
free_irq(host->irq, host);
if (use_dma)
@@ -841,6 +852,7 @@ static void lpc32xx_nand_remove(struct platform_device *pdev)
lpc32xx_wp_enable(host);
gpiod_put(host->wp_gpio);
+ mtd_put_master(nand_to_mtd(chip));
}
static int lpc32xx_nand_resume(struct platform_device *pdev)
--
2.53.0