[PATCH 58/58] mtd: rawnand: diskonchip: retain chip state across removal
James Hilliard
james.hilliard1 at gmail.com
Sat Nov 7 02:16:55 PST 2026
MTD device references may outlive unregistration during module removal.
Disconnect before unmapping the device and freeing the hardware ECC
codec, while retaining chip metadata until the final MTD reference is
released. Install lifetime ownership before the late initializer
publishes partitions.
Signed-off-by: James Hilliard <james.hilliard1 at gmail.com>
---
drivers/mtd/nand/raw/diskonchip.c | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/drivers/mtd/nand/raw/diskonchip.c b/drivers/mtd/nand/raw/diskonchip.c
index 540b6baf8bb1..a4338b51b49d 100644
--- a/drivers/mtd/nand/raw/diskonchip.c
+++ b/drivers/mtd/nand/raw/diskonchip.c
@@ -1296,6 +1296,11 @@ static const struct nand_controller_ops doc2001plus_ops = {
.attach_chip = doc200x_attach_chip,
};
+static void doc_chip_release(struct nand_chip *chip)
+{
+ kfree(chip);
+}
+
static int __init doc_probe(unsigned long physadr)
{
struct nand_chip *nand = NULL;
@@ -1494,13 +1499,21 @@ static int __init doc_probe(unsigned long physadr)
ret = nand_scan(nand, numchips);
if (ret)
goto fail;
-
- ret = doc->late_init(mtd);
+ ret = nand_set_release(nand, doc_chip_release);
if (ret) {
nand_cleanup(nand);
goto fail;
}
+ ret = doc->late_init(mtd);
+ if (ret) {
+ nand_disconnect(nand);
+ free_rs(doc->rs_decoder);
+ iounmap(virtadr);
+ mtd_put_master(mtd);
+ goto error_ioremap;
+ }
+
/* Success! */
doclist = mtd;
return 0;
@@ -1535,11 +1548,11 @@ static void release_nanddoc(void)
nextmtd = doc->nextdoc;
ret = mtd_device_unregister(mtd);
WARN_ON(ret);
- nand_cleanup(nand);
+ nand_disconnect(nand);
iounmap(doc->virtadr);
release_mem_region(doc->physadr, DOC_IOREMAP_LEN);
free_rs(doc->rs_decoder);
- kfree(nand);
+ mtd_put_master(mtd);
}
}
--
2.53.0
More information about the linux-mtd
mailing list