[PATCH 45/58] mtd: rawnand: sh_flctl: retain chip state across removal
James Hilliard
james.hilliard1 at gmail.com
Sat Nov 7 02:16:42 PST 2026
Unregister and disconnect the NAND chip before releasing the DMA
channel. Retain chip and controller storage until the last MTD reference
is dropped.
Signed-off-by: James Hilliard <james.hilliard1 at gmail.com>
---
drivers/mtd/nand/raw/sh_flctl.c | 25 +++++++++++++++++++++----
1 file changed, 21 insertions(+), 4 deletions(-)
diff --git a/drivers/mtd/nand/raw/sh_flctl.c b/drivers/mtd/nand/raw/sh_flctl.c
index 97f733e481ff..291d809d0ea1 100644
--- a/drivers/mtd/nand/raw/sh_flctl.c
+++ b/drivers/mtd/nand/raw/sh_flctl.c
@@ -1109,6 +1109,11 @@ static struct sh_flctl_platform_data *flctl_parse_dt(struct device *dev)
return pdata;
}
+static void flctl_release(struct nand_controller *controller)
+{
+ kfree(container_of(controller, struct sh_flctl, chip.legacy.dummy_controller));
+}
+
static int flctl_probe(struct platform_device *pdev)
{
struct resource *res;
@@ -1119,9 +1124,14 @@ static int flctl_probe(struct platform_device *pdev)
int ret;
int irq;
- flctl = devm_kzalloc(&pdev->dev, sizeof(struct sh_flctl), GFP_KERNEL);
+ flctl = kzalloc_obj(*flctl);
if (!flctl)
return -ENOMEM;
+ nand = &flctl->chip;
+ nand->controller = &nand->legacy.dummy_controller;
+ ret = devm_nand_controller_init(&pdev->dev, nand->controller, flctl_release);
+ if (ret)
+ return ret;
flctl->reg = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
if (IS_ERR(flctl->reg))
@@ -1187,9 +1197,15 @@ static int flctl_probe(struct platform_device *pdev)
if (ret)
goto err_chip;
- ret = mtd_device_register(flctl_mtd, pdata->parts, pdata->nr_parts);
+ ret = nand_set_release(nand, NULL);
if (ret)
goto cleanup_nand;
+ ret = mtd_device_register(flctl_mtd, pdata->parts, pdata->nr_parts);
+ if (ret) {
+ nand_disconnect(nand);
+ mtd_put_master(flctl_mtd);
+ goto err_chip;
+ }
return 0;
@@ -1207,11 +1223,12 @@ static void flctl_remove(struct platform_device *pdev)
struct nand_chip *chip = &flctl->chip;
int ret;
- flctl_release_dma(flctl);
ret = mtd_device_unregister(nand_to_mtd(chip));
WARN_ON(ret);
- nand_cleanup(chip);
+ nand_disconnect(chip);
+ flctl_release_dma(flctl);
pm_runtime_disable(&pdev->dev);
+ mtd_put_master(nand_to_mtd(chip));
}
static struct platform_driver flctl_driver = {
--
2.53.0
More information about the linux-mtd
mailing list