[PATCH 56/58] mtd: rawnand: nandsim: retain chip state across removal
James Hilliard
james.hilliard1 at gmail.com
Sat Nov 7 02:16:53 PST 2026
MTD device references can outlive device unregistration even when no
open file pins the simulator module. Disconnect before freeing the
simulated media, and retain the chip metadata until the final MTD put.
The lifetime core waits for remaining device references during module
unload.
Signed-off-by: James Hilliard <james.hilliard1 at gmail.com>
---
drivers/mtd/nand/raw/nandsim.c | 24 ++++++++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/drivers/mtd/nand/raw/nandsim.c b/drivers/mtd/nand/raw/nandsim.c
index fe968037f75a..39fefd83cd85 100644
--- a/drivers/mtd/nand/raw/nandsim.c
+++ b/drivers/mtd/nand/raw/nandsim.c
@@ -2253,6 +2253,11 @@ static const struct nand_controller_ops ns_controller_ops = {
.exec_op = ns_exec_op,
};
+static void ns_chip_release(struct nand_chip *chip)
+{
+ kfree(nand_get_controller_data(chip));
+}
+
/*
* Module initialization function
*/
@@ -2262,6 +2267,7 @@ static int __init ns_init_module(void)
struct nand_chip *chip;
struct nandsim *ns;
int ret;
+ bool retained = false;
if (bus_width != 8 && bus_width != 16) {
NS_ERR("wrong bus width (%d), use only 8 or 16\n", bus_width);
@@ -2376,6 +2382,10 @@ static int __init ns_init_module(void)
ret = ns_parse_badblocks(ns, nsmtd);
if (ret)
goto free_ns_object;
+ ret = nand_set_release(chip, ns_chip_release);
+ if (ret)
+ goto free_ns_object;
+ retained = true;
/* Register NAND partitions */
ret = mtd_device_register(nsmtd, &ns->partitions[0], ns->nbparts);
@@ -2391,11 +2401,16 @@ static int __init ns_init_module(void)
unregister_mtd:
WARN_ON(mtd_device_unregister(nsmtd));
free_ns_object:
+ if (retained)
+ nand_disconnect(chip);
ns_free(ns);
free_ebw:
kfree(erase_block_wear);
cleanup_nand:
- nand_cleanup(chip);
+ if (retained)
+ mtd_put_master(nsmtd);
+ else
+ nand_cleanup(chip);
free_gp_list:
list_for_each_safe(pos, n, &grave_pages) {
list_del(pos);
@@ -2412,7 +2427,8 @@ static int __init ns_init_module(void)
kfree(list_entry(pos, struct weak_block, list));
}
free_ns_struct:
- kfree(ns);
+ if (!retained)
+ kfree(ns);
return ret;
}
@@ -2430,9 +2446,9 @@ static void __exit ns_cleanup_module(void)
ns_debugfs_remove(ns);
WARN_ON(mtd_device_unregister(nsmtd));
+ nand_disconnect(chip);
ns_free(ns);
kfree(erase_block_wear);
- nand_cleanup(chip);
list_for_each_safe(pos, n, &grave_pages) {
list_del(pos);
@@ -2449,7 +2465,7 @@ static void __exit ns_cleanup_module(void)
kfree(list_entry(pos, struct weak_block, list));
}
- kfree(ns);
+ mtd_put_master(nsmtd);
}
module_exit(ns_cleanup_module);
--
2.53.0
More information about the linux-mtd
mailing list