diff mbox series

[RFC,2/2] drivers: dfu: flash firmware to inactive boot area and active it

Message ID 20220125135535.224061-3-grandpaul@gmail.com
State New
Headers show
Series A/B firmware update based in eMMC boot partition. | expand

Commit Message

Ying-Chun Liu Jan. 25, 2022, 1:55 p.m. UTC
From: "Ying-Chun Liu (PaulLiu)" <paul.liu@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.liu@linaro.org>
Cc: Lukasz Majewski <lukma@denx.de>
---
 drivers/dfu/dfu_mmc.c | 32 +++++++++++++++++++++++++++++---
 include/dfu.h         |  1 +
 2 files changed, 30 insertions(+), 3 deletions(-)
diff mbox series

Patch

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;