[PATCH 19/58] mtd: rawnand: orion: retain open-handle state on removal
James Hilliard
james.hilliard1 at gmail.com
Sat Nov 7 02:16:16 PST 2026
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 embedded chip and its copied name through the shared
allocation.
Signed-off-by: James Hilliard <james.hilliard1 at gmail.com>
---
drivers/mtd/nand/raw/orion_nand.c | 27 ++++++++++++++++++++-------
1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/drivers/mtd/nand/raw/orion_nand.c b/drivers/mtd/nand/raw/orion_nand.c
index 47e80d5e58c5..aae054e47db5 100644
--- a/drivers/mtd/nand/raw/orion_nand.c
+++ b/drivers/mtd/nand/raw/orion_nand.c
@@ -96,6 +96,11 @@ static const struct nand_controller_ops orion_nand_ops = {
.attach_chip = orion_nand_attach_chip,
};
+static void orion_nand_release(struct nand_controller *controller)
+{
+ kfree(container_of(controller, struct orion_nand_info, controller));
+}
+
static int __init orion_nand_probe(struct platform_device *pdev)
{
struct orion_nand_info *info;
@@ -106,15 +111,15 @@ static int __init orion_nand_probe(struct platform_device *pdev)
int ret = 0;
u32 val = 0;
- info = devm_kzalloc(&pdev->dev,
- sizeof(struct orion_nand_info),
- GFP_KERNEL);
+ info = kzalloc_obj(*info);
if (!info)
return -ENOMEM;
+ ret = devm_nand_controller_init(&pdev->dev, &info->controller, orion_nand_release);
+ if (ret)
+ return ret;
nc = &info->chip;
mtd = nand_to_mtd(nc);
- nand_controller_init(&info->controller);
info->controller.ops = &orion_nand_ops;
nc->controller = &info->controller;
@@ -186,9 +191,16 @@ static int __init orion_nand_probe(struct platform_device *pdev)
return ret;
mtd->name = "orion_nand";
- ret = mtd_device_register(mtd, board->parts, board->nr_parts);
- if (ret)
+ ret = nand_set_release(nc, NULL);
+ if (ret) {
nand_cleanup(nc);
+ return ret;
+ }
+ ret = mtd_device_register(mtd, board->parts, board->nr_parts);
+ if (ret) {
+ nand_disconnect(nc);
+ mtd_put_master(mtd);
+ }
return ret;
}
@@ -202,7 +214,8 @@ static void orion_nand_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_OF
--
2.53.0
More information about the linux-mtd
mailing list