From: "Ying-Chun Liu (PaulLiu)" <paul....@linaro.org>

This commit implement flash to the inactive boot partition of eMMC
when dfu_alt_info set mmcpart to "inactive". After flash to the inactive
boot partition. It will switch the active partition to the one that
just flashed.

Signed-off-by: Ying-Chun Liu (PaulLiu) <paul....@linaro.org>
Cc: Lukasz Majewski <lu...@denx.de>
---
 drivers/dfu/dfu_mmc.c | 32 +++++++++++++++++++++++++++++---
 include/dfu.h         |  1 +
 2 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c
index 3dab5a5f63..3c1f2018d3 100644
--- a/drivers/dfu/dfu_mmc.c
+++ b/drivers/dfu/dfu_mmc.c
@@ -198,6 +198,7 @@ int dfu_write_medium_mmc(struct dfu_entity *dfu,
                u64 offset, void *buf, long *len)
 {
        int ret = -1;
+       struct mmc *mmc;
 
        switch (dfu->layout) {
        case DFU_RAW_ADDR:
@@ -218,6 +219,17 @@ int dfu_write_medium_mmc(struct dfu_entity *dfu,
                       dfu_get_layout(dfu->layout));
        }
 
+       if (!ret && dfu->data.mmc.hw_partition_inactive) {
+               mmc = find_mmc_device(dfu->data.mmc.dev_num);
+               if (!mmc) {
+                       pr_err("Device MMC %d - not found!",
+                              dfu->data.mmc.dev_num);
+                       return -ENODEV;
+               }
+
+               mmc_set_part_conf(mmc, 0, dfu->data.mmc.hw_partition, 0);
+       }
+
        return ret;
 }
 
@@ -384,15 +396,29 @@ int dfu_fill_entity_mmc(struct dfu_entity *dfu, char 
*devstr, char *s)
                dfu->data.mmc.lba_start         = second_arg;
                dfu->data.mmc.lba_size          = third_arg;
                dfu->data.mmc.lba_blk_size      = mmc->read_bl_len;
+               dfu->data.mmc.hw_partition_inactive = false;
 
                /*
                 * Check for an extra entry at dfu_alt_info env variable
                 * specifying the mmc HW defined partition number
                 */
                if (s)
-                       if (!strcmp(strsep(&s, " "), "mmcpart"))
-                               dfu->data.mmc.hw_partition =
-                                       simple_strtoul(s, NULL, 0);
+                       if (!strcmp(strsep(&s, " "), "mmcpart")) {
+                               if (!strcmp(s, "inactive")) {
+                                       u8 part_boot;
+                                       u8 part_target;
+
+                                       part_boot = 
EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config);
+                                       part_target = 3 - part_boot;
+                                       dfu->data.mmc.hw_partition =
+                                               part_target;
+                                       dfu->data.mmc.hw_partition_inactive =
+                                               true;
+                               } else {
+                                       dfu->data.mmc.hw_partition =
+                                               simple_strtoul(s, NULL, 0);
+                               }
+                       }
 
        } else if (!strcmp(entity_type, "part")) {
                struct disk_partition partinfo;
diff --git a/include/dfu.h b/include/dfu.h
index f6868982df..7fbcf03063 100644
--- a/include/dfu.h
+++ b/include/dfu.h
@@ -53,6 +53,7 @@ struct mmc_internal_data {
 
        /* eMMC HW partition access */
        int hw_partition;
+       bool hw_partition_inactive;
 
        /* FAT/EXT */
        unsigned int dev;
-- 
2.34.1

Reply via email to