[PATCH 25/58] mtd: rawnand: hisi504: retain open-handle state on removal

From: James Hilliard

Date: Sat Nov 07 2026 - 15:14:23 EST


Keep chip metadata and controller storage alive until the final MTD
reference is released. Unregister and disconnect each published chip
before releasing the resources used by its hardware operations.

Retain the host through its embedded legacy controller.

Signed-off-by: James Hilliard <james.hilliard1@xxxxxxxxx>
---
drivers/mtd/nand/raw/hisi504_nand.c | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/hisi504_nand.c b/drivers/mtd/nand/raw/hisi504_nand.c
index d97270ec1185..36427a242c2b 100644
--- a/drivers/mtd/nand/raw/hisi504_nand.c
+++ b/drivers/mtd/nand/raw/hisi504_nand.c
@@ -731,6 +731,11 @@ static const struct nand_controller_ops hisi_nfc_controller_ops = {
.attach_chip = hisi_nfc_attach_chip,
};

+static void hisi_nfc_release(struct nand_controller *controller)
+{
+ kfree(container_of(controller, struct hinfc_host, chip.legacy.dummy_controller));
+}
+
static int hisi_nfc_probe(struct platform_device *pdev)
{
int ret = 0, irq, max_chips = HINFC504_MAX_CHIP;
@@ -740,9 +745,14 @@ static int hisi_nfc_probe(struct platform_device *pdev)
struct mtd_info *mtd;
struct device_node *np = dev->of_node;

- host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL);
+ host = kzalloc_obj(*host);
if (!host)
return -ENOMEM;
+ chip = &host->chip;
+ chip->controller = &chip->legacy.dummy_controller;
+ ret = devm_nand_controller_init(dev, chip->controller, hisi_nfc_release);
+ if (ret)
+ return ret;
host->dev = dev;

platform_set_drvdata(pdev, host);
@@ -788,10 +798,16 @@ static int hisi_nfc_probe(struct platform_device *pdev)
if (ret)
return ret;

+ ret = nand_set_release(chip, NULL);
+ if (ret) {
+ nand_cleanup(chip);
+ return ret;
+ }
ret = mtd_device_register(mtd, NULL, 0);
if (ret) {
dev_err(dev, "Err MTD partition=%d\n", ret);
- nand_cleanup(chip);
+ nand_disconnect(chip);
+ mtd_put_master(mtd);
return ret;
}

@@ -806,7 +822,8 @@ static void hisi_nfc_remove(struct platform_device *pdev)

ret = mtd_device_unregister(nand_to_mtd(chip));
WARN_ON(ret);
- nand_cleanup(chip);
+ nand_disconnect(chip);
+ mtd_put_master(nand_to_mtd(chip));
}

#ifdef CONFIG_PM_SLEEP

--
2.53.0