[PATCH 2/7] spl: mtd: Remove MTD device after loading images

Anurag Dutta a-dutta at ti.com
Tue Feb 17 12:21:51 CET 2026


From: Apurva Nandan <a-nandan at ti.com>

Releasing the flash into proper state, after the loading completes,
is important for the next stage bootloader/kernel to be able to use
the MTD device. This would enable to reset the device for fresh
use by next boot stage.

Signed-off-by: Apurva Nandan <a-nandan at ti.com>
Signed-off-by: Anurag Dutta <a-dutta at ti.com>
---
 common/spl/spl_mtd.c        | 19 ++++++++++---------
 common/spl/spl_mtd_nand.c   | 10 +++++++---
 drivers/mtd/mtd-uclass.c    | 12 ++++++++++++
 drivers/mtd/nand/spi/core.c | 12 ++++++++----
 include/mtd.h               |  2 +-
 5 files changed, 38 insertions(+), 17 deletions(-)

diff --git a/common/spl/spl_mtd.c b/common/spl/spl_mtd.c
index 341e1a73392..95c0c8ce8cd 100644
--- a/common/spl/spl_mtd.c
+++ b/common/spl/spl_mtd.c
@@ -62,7 +62,7 @@ int spl_mtd_load(struct spl_image_info *spl_image,
 	err = mtd_read(mtd, spl_mtd_get_uboot_offs(), sizeof(*header),
 		       &ret_len, (void *)header);
 	if (err)
-		return err;
+		goto out_err;
 
 	if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
 	    image_get_magic(header) == FDT_MAGIC) {
@@ -70,21 +70,22 @@ int spl_mtd_load(struct spl_image_info *spl_image,
 		load.priv = mtd;
 		load.bl_len = 1;
 		load.read = spl_mtd_fit_read;
-		return spl_load_simple_fit(spl_image, &load,
-					   spl_mtd_get_uboot_offs(), header);
+		err = spl_load_simple_fit(spl_image, &load,
+					  spl_mtd_get_uboot_offs(), header);
 	} else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER)) {
 		load.priv = mtd;
 		load.bl_len = 1;
 		load.read = spl_mtd_fit_read;
-		return spl_load_imx_container(spl_image, &load,
-					      spl_mtd_get_uboot_offs());
+		err = spl_load_imx_container(spl_image, &load,
+					     spl_mtd_get_uboot_offs());
 	} else {
 		err = spl_parse_image_header(spl_image, bootdev, header);
 		if (err)
-			return err;
-		return mtd_read(mtd, spl_mtd_get_uboot_offs(), spl_image->size,
-				&ret_len, (void *)(ulong)spl_image->load_addr);
+			goto out_err;
+		err = mtd_read(mtd, spl_mtd_get_uboot_offs(), spl_image->size,
+			       &ret_len, (void *)(ulong)spl_image->load_addr);
 	}
 
-	return -EINVAL;
+out_err:
+	return err;
 }
diff --git a/common/spl/spl_mtd_nand.c b/common/spl/spl_mtd_nand.c
index 9bc6ff86ee8..2eb7458e599 100644
--- a/common/spl/spl_mtd_nand.c
+++ b/common/spl/spl_mtd_nand.c
@@ -16,16 +16,20 @@ static int spl_mtd_load_image(struct spl_image_info *spl_image,
 			      struct spl_boot_device *bootdev)
 {
 	struct mtd_info *mtd;
-	int ret;
+	int err;
 
 	mtd = spl_prepare_mtd(BOOT_DEVICE_SPINAND);
 	if (IS_ERR_OR_NULL(mtd)) {
 		printf("MTD device %s not found, ret %ld\n", "spi-nand",
 		       PTR_ERR(mtd));
-		return -EINVAL;
+		err = PTR_ERR(mtd);
+		goto remove_mtd_device;
 	}
 
-	return spl_mtd_load(spl_image, mtd, bootdev);
+	err = spl_mtd_load(spl_image, mtd, bootdev);
+remove_mtd_device:
+	mtd_remove(mtd);
+	return err;
 }
 
 SPL_LOAD_IMAGE_METHOD("SPINAND", 0, BOOT_DEVICE_SPINAND, spl_mtd_load_image);
diff --git a/drivers/mtd/mtd-uclass.c b/drivers/mtd/mtd-uclass.c
index 720bd824c4d..598eedae6a5 100644
--- a/drivers/mtd/mtd-uclass.c
+++ b/drivers/mtd/mtd-uclass.c
@@ -10,6 +10,18 @@
 #include <errno.h>
 #include <mtd.h>
 
+/**
+ * mtd_remove - Remove the device @dev
+ *
+ * @dev: U-Boot device to probe
+ *
+ * @return 0 on success, an error otherwise.
+ */
+int mtd_remove(struct mtd_info *mtd)
+{
+	return device_remove(mtd->dev, DM_REMOVE_NORMAL);
+}
+
 /*
  * Implement a MTD uclass which should include most flash drivers.
  * The uclass private is pointed to mtd_info.
diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 14af4264612..9bd8cce58f2 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -1718,26 +1718,28 @@ err_spinand_cleanup:
 	return ret;
 }
 
-#ifndef __UBOOT__
 static int spinand_remove(struct udevice *slave)
 {
 	struct spinand_device *spinand;
 	struct mtd_info *mtd;
-	int ret;
+	int ret = 0;
 
-	spinand = spi_mem_get_drvdata(slave);
+	spinand = dev_get_priv(slave);
 	mtd = spinand_to_mtd(spinand);
 	free(mtd->name);
 
+#ifndef __UBOOT__
 	ret = mtd_device_unregister(mtd);
 	if (ret)
 		return ret;
 
+#endif
 	spinand_cleanup(spinand);
 
-	return 0;
+	return ret;
 }
 
+#ifndef __UBOOT__
 static const struct spi_device_id spinand_ids[] = {
 	{ .name = "spi-nand" },
 	{ /* sentinel */ },
@@ -1783,4 +1785,6 @@ U_BOOT_DRIVER(spinand) = {
 	.probe = spinand_probe,
 	.bind = spinand_bind,
 	.plat_auto = sizeof(struct spinand_plat),
+	.remove = spinand_remove,
+	.flags = DM_FLAG_OS_PREPARE,
 };
diff --git a/include/mtd.h b/include/mtd.h
index f9e5082446a..740f1bb76db 100644
--- a/include/mtd.h
+++ b/include/mtd.h
@@ -11,7 +11,7 @@
 #include <linux/mtd/mtd.h>
 
 int mtd_probe_devices(void);
-
+int mtd_remove(struct mtd_info *mtd);
 void board_mtdparts_default(const char **mtdids, const char **mtdparts);
 
 /* compute the max size for the string associated to a dev type */
-- 
2.34.1



More information about the U-Boot mailing list