diff options
author | Jorge Ramirez-Ortiz | 2017-11-06 14:16:37 +0100 |
---|---|---|
committer | Tom Rini | 2017-11-17 07:44:13 -0500 |
commit | c9e87ba66540cf72c164674a71af43853d087ba8 (patch) | |
tree | 0eb815db3ec044ac7221c4ba92f45b5ba2e98dc5 /env/mmc.c | |
parent | b12907f279ca25acb79838ede89905ff5c1dfcc5 (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.c | 62 |
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 |