static enum env_location env_load_location = ENVL_UNKNOWN;
+static bool env_has_inited(enum env_location location)
+{
+ return gd->env_has_init & BIT(location);
+}
+
+static void env_set_inited(enum env_location location)
+{
+ /*
+ * We're using a 32-bits bitmask stored in gd (env_has_init)
+ * using the above enum value as the bit index. We need to
+ * make sure that we're not overflowing it.
+ */
+ BUILD_BUG_ON(ARRAY_SIZE(env_locations) > BITS_PER_LONG);
+
+ gd->env_has_init |= BIT(location);
+}
+
/**
* env_get_location() - Returns the best env location for a board
* @op: operations performed on the environment
* highest priority
*
* This will return the preferred environment for the given priority.
+ * This is overridable by boards if they need to.
*
* All implementations are free to use the operation, the priority and
* any other data relevant to their choice, but must take into account
* Returns:
* an enum env_location value on success, a negative error code otherwise
*/
-static enum env_location env_get_location(enum env_operation op, int prio)
+__weak enum env_location env_get_location(enum env_operation op, int prio)
{
switch (op) {
case ENVOP_GET_CHAR:
if (!drv->get_char)
continue;
+ if (!env_has_inited(drv->location))
+ continue;
+
ret = drv->get_char(index);
if (!ret)
return 0;
if (!drv->load)
continue;
+ if (!env_has_inited(drv->location))
+ continue;
+
printf("Loading Environment from %s... ", drv->name);
ret = drv->load();
if (ret)
if (!drv->save)
continue;
+ if (!env_has_inited(drv->location))
+ continue;
+
printf("Saving Environment to %s... ", drv->name);
ret = drv->save();
if (ret)
int prio;
for (prio = 0; (drv = env_driver_lookup(ENVOP_INIT, prio)); prio++) {
- if (!drv->init)
- continue;
-
- ret = drv->init();
- if (!ret)
- return 0;
+ if (!drv->init || !(ret = drv->init()))
+ env_set_inited(drv->location);
- debug("%s: Environment %s failed to init (err=%d)\n", __func__,
+ debug("%s: Environment %s init done (ret=%d)\n", __func__,
drv->name, ret);
}