diff mbox series

[1/2] env: Save environment at the end of an MMC partition

Message ID 1509974198-14831-1-git-send-email-jorge.ramirez-ortiz@linaro.org
State Accepted
Commit c9e87ba66540cf72c164674a71af43853d087ba8
Headers show
Series [1/2] env: Save environment at the end of an MMC partition | expand

Commit Message

Jorge Ramirez-Ortiz Nov. 6, 2017, 1:16 p.m. UTC
Allow the platform to define a partition by name at the end of which
the environment data will be located.

Signed-off-by: Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
---
 doc/device-tree-bindings/config.txt |  9 ++++++
 env/mmc.c                           | 62 ++++++++++++++++++++++++++++++++++---
 2 files changed, 67 insertions(+), 4 deletions(-)

Comments

Tom Rini Nov. 17, 2017, 3:45 p.m. UTC | #1
On Mon, Nov 06, 2017 at 02:16:37PM +0100, Jorge Ramirez-Ortiz wrote:

> Allow the platform to define a partition by name at the end of which

> the environment data will be located.

> 

> Signed-off-by: Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>


Applied to u-boot/master, thanks!

-- 
Tom
diff mbox series

Patch

diff --git a/doc/device-tree-bindings/config.txt b/doc/device-tree-bindings/config.txt
index fe0e04a..15e4349 100644
--- a/doc/device-tree-bindings/config.txt
+++ b/doc/device-tree-bindings/config.txt
@@ -21,6 +21,15 @@  u-boot,efi-partition-entries-offset
 
 	This setting will override any values configured via Kconfig.
 
+u-boot,mmc-env-partition
+	if present, the environment shall be placed at the last
+	CONFIG_ENV_SIZE blocks of the partition on the
+	CONFIG_SYS_MMC_ENV_DEV.
+
+	if u-boot,mmc-env-offset* is present, this setting will take
+	precedence. In that case, only if the partition is not found,
+	mmc-env-offset* will be tried.
+
 u-boot,mmc-env-offset
 u-boot,mmc-env-offset-redundant
 	If present, the values of the 'u-boot,mmc-env-offset' and/or
diff --git a/env/mmc.c b/env/mmc.c
index 3f3092d..3343f9e 100644
--- a/env/mmc.c
+++ b/env/mmc.c
@@ -15,9 +15,13 @@ 
 #include <malloc.h>
 #include <memalign.h>
 #include <mmc.h>
+#include <part.h>
 #include <search.h>
 #include <errno.h>
 
+#define __STR(X) #X
+#define STR(X) __STR(X)
+
 #if defined(CONFIG_ENV_SIZE_REDUND) &&  \
 	(CONFIG_ENV_SIZE_REDUND != CONFIG_ENV_SIZE)
 #error CONFIG_ENV_SIZE_REDUND should be the same as CONFIG_ENV_SIZE
@@ -30,18 +34,68 @@  DECLARE_GLOBAL_DATA_PTR;
 #endif
 
 #if CONFIG_IS_ENABLED(OF_CONTROL)
+static inline int mmc_offset_try_partition(const char *str, s64 *val)
+{
+	disk_partition_t info;
+	struct blk_desc *desc;
+	int len, i, ret;
+
+	ret = blk_get_device_by_str("mmc", STR(CONFIG_SYS_MMC_ENV_DEV), &desc);
+	if (ret < 0)
+		return (ret);
+
+	for (i = 1;;i++) {
+		ret = part_get_info(desc, i, &info);
+		if (ret < 0)
+			return ret;
+
+		if (!strncmp((const char *)info.name, str, sizeof(str)))
+			break;
+	}
+
+	/* round up to info.blksz */
+	len = (CONFIG_ENV_SIZE + info.blksz - 1) & ~(info.blksz - 1);
+
+	/* use the top of the partion for the environment */
+	*val = (info.start + info.size - 1) - len / info.blksz;
+
+	return 0;
+}
+
 static inline s64 mmc_offset(int copy)
 {
-	const char *propname = "u-boot,mmc-env-offset";
-	s64 defvalue = CONFIG_ENV_OFFSET;
+	const struct {
+		const char *offset_redund;
+		const char *partition;
+		const char *offset;
+	} dt_prop = {
+		.offset_redund = "u-boot,mmc-env-offset-redundant",
+		.partition = "u-boot,mmc-env-partition",
+		.offset = "u-boot,mmc-env-offset",
+	};
+	s64 val, defvalue;
+	const char *propname;
+	const char *str;
+	int err;
+
+	/* look for the partition in mmc CONFIG_SYS_MMC_ENV_DEV */
+	str = fdtdec_get_config_string(gd->fdt_blob, dt_prop.partition);
+	if (str) {
+		/* try to place the environment at end of the partition */
+		err = mmc_offset_try_partition(str, &val);
+		if (!err)
+			return val;
+	}
+
+	defvalue = CONFIG_ENV_OFFSET;
+	propname = dt_prop.offset;
 
 #if defined(CONFIG_ENV_OFFSET_REDUND)
 	if (copy) {
-		propname = "u-boot,mmc-env-offset-redundant";
 		defvalue = CONFIG_ENV_OFFSET_REDUND;
+		propname = dt_prop.offset_redund;
 	}
 #endif
-
 	return fdtdec_get_config_int(gd->fdt_blob, propname, defvalue);
 }
 #else