summaryrefslogtreecommitdiffstats
path: root/common/bootchooser.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/bootchooser.c')
-rw-r--r--common/bootchooser.c70
1 files changed, 32 insertions, 38 deletions
diff --git a/common/bootchooser.c b/common/bootchooser.c
index c08db03eba..022e225165 100644
--- a/common/bootchooser.c
+++ b/common/bootchooser.c
@@ -1,16 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2012 Jan Luebbe <j.luebbe@pengutronix.de>
* Copyright (C) 2015 Marc Kleine-Budde <mkl@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
*/
#define pr_fmt(fmt) "bootchooser: " fmt
@@ -22,7 +13,7 @@
#include <libfile.h>
#include <common.h>
#include <malloc.h>
-#include <printk.h>
+#include <linux/printk.h>
#include <xfuncs.h>
#include <envfs.h>
#include <errno.h>
@@ -86,6 +77,7 @@ struct bootchooser_target {
enum reset_attempts {
RESET_ATTEMPTS_POWER_ON,
RESET_ATTEMPTS_ALL_ZERO,
+ RESET_ATTEMPTS_SRC_RST,
};
static unsigned long reset_attempts;
@@ -137,7 +129,7 @@ static void pr_target(struct bootchooser_target *target)
printf(" disabled due to %s\n", reason);
}
-static int pr_setenv(struct bootchooser *bc, const char *fmt, ...)
+static int bc_setenv(struct bootchooser *bc, const char *fmt, ...)
{
va_list ap;
int ret = 0;
@@ -151,14 +143,12 @@ static int pr_setenv(struct bootchooser *bc, const char *fmt, ...)
if (!str)
return -ENOMEM;
- val = strchr(str, '=');
+ val = parse_assignment(str);
if (!val) {
ret = -EINVAL;
goto err;
}
- *val++ = '\0';
-
oldval = getenv(str);
if (!oldval || strcmp(oldval, val)) {
if (bc->state)
@@ -173,7 +163,7 @@ err:
return ret;
}
-static const char *pr_getenv(const char *fmt, ...)
+static const char *bc_getenv(const char *fmt, ...)
{
va_list ap;
char *str;
@@ -269,7 +259,7 @@ static struct bootchooser_target *bootchooser_target_new(struct bootchooser *bc,
target->remaining_attempts = 0;
}
- val = pr_getenv("%s.boot", target->prefix);
+ val = bc_getenv("%s.boot", target->prefix);
if (!val)
val = target->name;
target->boot = xstrdup(val);
@@ -450,6 +440,13 @@ struct bootchooser *bootchooser_get(void)
attempts_resetted = 1;
}
+ if (test_bit(RESET_ATTEMPTS_SRC_RST, &reset_attempts) &&
+ reset_source_get() == RESET_RST && !attempts_resetted) {
+ pr_info("RST Reset, resetting remaining attempts\n");
+ bootchooser_reset_attempts(bc);
+ attempts_resetted = 1;
+ }
+
if (test_bit(RESET_ATTEMPTS_ALL_ZERO, &reset_attempts)) {
int attempts = 0;
@@ -508,17 +505,17 @@ int bootchooser_save(struct bootchooser *bc)
int ret;
if (bc->last_chosen)
- pr_setenv(bc, "%s.last_chosen=%d", bc->state_prefix,
+ bc_setenv(bc, "%s.last_chosen=%d", bc->state_prefix,
bc->last_chosen->id);
list_for_each_entry(target, &bc->targets, list) {
- ret = pr_setenv(bc, "%s.remaining_attempts=%d",
+ ret = bc_setenv(bc, "%s.remaining_attempts=%d",
target->state_prefix,
target->remaining_attempts);
if (ret)
return ret;
- ret = pr_setenv(bc, "%s.priority=%d",
+ ret = bc_setenv(bc, "%s.priority=%d",
target->state_prefix, target->priority);
if (ret)
return ret;
@@ -926,6 +923,7 @@ static int bootchooser_add_entry(struct bootentries *entries, const char *name)
static const char * const reset_attempts_names[] = {
[RESET_ATTEMPTS_POWER_ON] = "power-on",
[RESET_ATTEMPTS_ALL_ZERO] = "all-zero",
+ [RESET_ATTEMPTS_SRC_RST] = "reset",
};
static const char * const reset_priorities_names[] = {
@@ -954,21 +952,17 @@ static int bootchooser_init(void)
}
device_initcall(bootchooser_init);
-BAREBOX_MAGICVAR_NAMED(global_bootchooser_disable_on_zero_attempts,
- global.bootchooser.disable_on_zero_attempts,
- "bootchooser: Disable target when remaining attempts counter reaches 0");
-BAREBOX_MAGICVAR_NAMED(global_bootchooser_retry,
- global.bootchooser.retry,
- "bootchooser: Try again when booting a target fails");
-BAREBOX_MAGICVAR_NAMED(global_bootchooser_targets,
- global.bootchooser.targets,
- "bootchooser: Space separated list of target names");
-BAREBOX_MAGICVAR_NAMED(global_bootchooser_default_attempts,
- global.bootchooser.default_attempts,
- "bootchooser: Default number of attempts for a target");
-BAREBOX_MAGICVAR_NAMED(global_bootchooser_default_priority,
- global.bootchooser.default_priority,
- "bootchooser: Default priority for a target");
-BAREBOX_MAGICVAR_NAMED(global_bootchooser_state_prefix,
- global.bootchooser.state_prefix,
- "bootchooser: state name prefix, empty for nv backend");
+BAREBOX_MAGICVAR(global.bootchooser.disable_on_zero_attempts,
+ "bootchooser: Disable target when remaining attempts counter reaches 0");
+BAREBOX_MAGICVAR(global.bootchooser.retry,
+ "bootchooser: Try again when booting a target fails");
+BAREBOX_MAGICVAR(global.bootchooser.targets,
+ "bootchooser: Space separated list of target names");
+BAREBOX_MAGICVAR(global.bootchooser.default_attempts,
+ "bootchooser: Default number of attempts for a target");
+BAREBOX_MAGICVAR(global.bootchooser.reset_attempts,
+ "bootchooser: Choose condition to reset number of attempts for all enabled targets ('power-on', 'all-zero', 'reset')");
+BAREBOX_MAGICVAR(global.bootchooser.default_priority,
+ "bootchooser: Default priority for a target");
+BAREBOX_MAGICVAR(global.bootchooser.state_prefix,
+ "bootchooser: state name prefix, empty for nv backend");