[PATCH 46/58] mtd: rawnand: lpc32xx_slc: retain chip state across removal
James Hilliard
james.hilliard1 at gmail.com
Sat Nov 7 02:16:43 PST 2026
Drain chip operations before releasing DMA and changing the controller
and write-protect signals. Retain the embedded NAND chip and controller
until the final MTD reference releases their metadata.
Signed-off-by: James Hilliard <james.hilliard1 at gmail.com>
---
drivers/mtd/nand/raw/lpc32xx_slc.c | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)
diff --git a/drivers/mtd/nand/raw/lpc32xx_slc.c b/drivers/mtd/nand/raw/lpc32xx_slc.c
index b4d90afa9267..85945e1dd25a 100644
--- a/drivers/mtd/nand/raw/lpc32xx_slc.c
+++ b/drivers/mtd/nand/raw/lpc32xx_slc.c
@@ -817,6 +817,12 @@ static const struct nand_controller_ops lpc32xx_nand_controller_ops = {
.attach_chip = lpc32xx_nand_attach_chip,
};
+static void lpc32xx_nand_release(struct nand_controller *controller)
+{
+ kfree(container_of(controller, struct lpc32xx_nand_host,
+ nand_chip.legacy.dummy_controller));
+}
+
/*
* Probe for NAND controller
*/
@@ -829,9 +835,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;
+ chip = &host->nand_chip;
+ chip->controller = &chip->legacy.dummy_controller;
+ res = devm_nand_controller_init(&pdev->dev, chip->controller, lpc32xx_nand_release);
+ if (res)
+ return res;
host->io_base = devm_platform_get_and_ioremap_resource(pdev, 0, &rc);
if (IS_ERR(host->io_base))
@@ -915,10 +926,16 @@ static int lpc32xx_nand_probe(struct platform_device *pdev)
goto release_dma;
mtd->name = "nxp_lpc3220_slc";
- res = mtd_device_register(mtd, host->ncfg->parts,
- host->ncfg->num_parts);
+ res = nand_set_release(chip, NULL);
if (res)
goto cleanup_nand;
+ res = mtd_device_register(mtd, host->ncfg->parts,
+ host->ncfg->num_parts);
+ if (res) {
+ nand_disconnect(chip);
+ mtd_put_master(mtd);
+ goto release_dma;
+ }
return 0;
@@ -944,7 +961,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);
dma_release_channel(host->dma_chan);
/* Force CE high */
@@ -953,6 +970,7 @@ static void lpc32xx_nand_remove(struct platform_device *pdev)
writel(tmp, SLC_CTRL(host->io_base));
lpc32xx_wp_enable(host);
+ mtd_put_master(nand_to_mtd(chip));
}
static int lpc32xx_nand_resume(struct platform_device *pdev)
--
2.53.0
More information about the linux-mtd
mailing list