aboutsummaryrefslogtreecommitdiff
path: root/env/mmc.c
diff options
context:
space:
mode:
authorJorge Ramirez-Ortiz2017-11-06 14:16:37 +0100
committerTom Rini2017-11-17 07:44:13 -0500
commitc9e87ba66540cf72c164674a71af43853d087ba8 (patch)
tree0eb815db3ec044ac7221c4ba92f45b5ba2e98dc5 /env/mmc.c
parentb12907f279ca25acb79838ede89905ff5c1dfcc5 (diff)
env: Save environment at the end of an MMC partition
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>
Diffstat (limited to 'env/mmc.c')
-rw-r--r--env/mmc.c62
1 files changed, 58 insertions, 4 deletions
diff --git a/env/mmc.c b/env/mmc.c
index 3f3092d9756..3343f9e9f6c 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