[PATCH 20/58] mtd: rawnand: socrates: retain open-handle state on removal
James Hilliard
james.hilliard1 at gmail.com
Sat Nov 7 02:16:17 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.
Drain operations before unmapping the FPGA registers.
Signed-off-by: James Hilliard <james.hilliard1 at gmail.com>
---
drivers/mtd/nand/raw/socrates_nand.c | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/drivers/mtd/nand/raw/socrates_nand.c b/drivers/mtd/nand/raw/socrates_nand.c
index 668584683ce5..508e3afac4f2 100644
--- a/drivers/mtd/nand/raw/socrates_nand.c
+++ b/drivers/mtd/nand/raw/socrates_nand.c
@@ -134,6 +134,11 @@ static const struct nand_controller_ops socrates_ops = {
/*
* Probe for the NAND device.
*/
+static void socrates_nand_release(struct nand_controller *controller)
+{
+ kfree(container_of(controller, struct socrates_nand_host, controller));
+}
+
static int socrates_nand_probe(struct platform_device *ofdev)
{
struct socrates_nand_host *host;
@@ -142,9 +147,12 @@ static int socrates_nand_probe(struct platform_device *ofdev)
int res;
/* Allocate memory for the device structure (and zero it) */
- host = devm_kzalloc(&ofdev->dev, sizeof(*host), GFP_KERNEL);
+ host = kzalloc_obj(*host);
if (!host)
return -ENOMEM;
+ res = devm_nand_controller_init(&ofdev->dev, &host->controller, socrates_nand_release);
+ if (res)
+ return res;
host->io_base = of_iomap(ofdev->dev.of_node, 0);
if (host->io_base == NULL) {
@@ -156,7 +164,6 @@ static int socrates_nand_probe(struct platform_device *ofdev)
mtd = nand_to_mtd(nand_chip);
host->dev = &ofdev->dev;
- nand_controller_init(&host->controller);
host->controller.ops = &socrates_ops;
nand_chip->controller = &host->controller;
@@ -188,11 +195,17 @@ static int socrates_nand_probe(struct platform_device *ofdev)
if (res)
goto out;
+ res = nand_set_release(nand_chip, NULL);
+ if (res) {
+ nand_cleanup(nand_chip);
+ goto out;
+ }
res = mtd_device_register(mtd, NULL, 0);
if (!res)
return res;
- nand_cleanup(nand_chip);
+ nand_disconnect(nand_chip);
+ mtd_put_master(mtd);
out:
iounmap(host->io_base);
@@ -210,9 +223,10 @@ static void socrates_nand_remove(struct platform_device *ofdev)
ret = mtd_device_unregister(nand_to_mtd(chip));
WARN_ON(ret);
- nand_cleanup(chip);
+ nand_disconnect(chip);
iounmap(host->io_base);
+ mtd_put_master(nand_to_mtd(chip));
}
static const struct of_device_id socrates_nand_match[] =
--
2.53.0
More information about the linux-mtd
mailing list