From: Apurva Nandan <[email protected]>

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 <[email protected]>
Signed-off-by: Anurag Dutta <[email protected]>
---
 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

Reply via email to