windcharger: add partition failover to uboot
This also adds the command "reset_failover" to the uboot environment
which is automatically run when the kernel or filesystem is upgraded.
Change-Id: I59162bb81b099ed841e3204d4299d20ee1f7f228
diff --git a/board/atheros/board953x/extra.c b/board/atheros/board953x/extra.c
index 71e7f06..841b15e 100755
--- a/board/atheros/board953x/extra.c
+++ b/board/atheros/board953x/extra.c
@@ -28,6 +28,51 @@
#include <version.h>
#include <atheros.h>
+static int atoi(const char *nptr)
+{
+ int val = 0;
+ while (*nptr >= '0' && *nptr <= '9') {
+ val *= 10;
+ val += *nptr-'0';
+ nptr++;
+ }
+ return val;
+}
+
+static void __do_failover(void)
+{
+ const char *newp;
+ const char *curp = getenv("ACTIVATED_KERNEL_NAME");
+ if (curp && strncmp(curp, "kernel1", strlen("kernel1")) == 0) {
+ newp = "kernel0";
+ } else {
+ newp = "kernel1";
+ }
+ setenv("ACTIVATED_KERNEL_NAME", newp);
+ printf("*** Warning *** failover: switched to %s\n", newp);
+}
+
+void ath_check_failover(void)
+{
+ uint32_t sticky_reg = ath_reg_rd(SPARE_STKY_ADDRESS);
+ const char *threshold_str = getenv("FAILOVER_THRESHOLD");
+ int threshold;
+
+ if (threshold_str) {
+ threshold = atoi(threshold_str);
+ } else {
+ threshold = 3;
+ }
+
+ printf("failover counter: %lu\n", sticky_reg);
+ sticky_reg++;
+ if (sticky_reg > threshold) {
+ __do_failover();
+ sticky_reg = 0;
+ }
+ ath_reg_wr(SPARE_STKY_ADDRESS, sticky_reg);
+}
+
void ath_set_tuning_caps(void)
{
typedef struct {
diff --git a/common/cmd_sysvar.c b/common/cmd_sysvar.c
index 49bab01..6519f63 100644
--- a/common/cmd_sysvar.c
+++ b/common/cmd_sysvar.c
@@ -29,6 +29,10 @@
.sysvar_name = MAC_ADDR1_SV,
.uboot_name = MAC_ADDR1_UB,
},
+ {
+ .sysvar_name = FAILOVER_THRESHOLD_SV,
+ .uboot_name = FAILOVER_THRESHOLD_UB,
+ },
};
// Some bit twiddling for erasing the correct sector on Atheros flash. This
diff --git a/common/main.c b/common/main.c
index 80e16bb..45a4d26 100755
--- a/common/main.c
+++ b/common/main.c
@@ -425,8 +425,6 @@
// debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");
- sysvar_init();
-
if (bootdelay >= 0 && s && !abortboot (bootdelay)) {
# ifdef CONFIG_AUTOBOOT_KEYED
int prev = disable_ctrlc(1); /* disable Control C checking */
diff --git a/include/953x.h b/include/953x.h
index 77d226b..2fa46ec 100755
--- a/include/953x.h
+++ b/include/953x.h
@@ -3039,6 +3039,8 @@
#define RST_BOOTSTRAP_DDR_SELECT_RESET 0x0 // 0
#define RST_BOOTSTRAP_ADDRESS 0x180600b0
+#define SPARE_STKY_ADDRESS 0x180600b8
+
#define RST_CLKGAT_EN_SPARE_MSB 31
#define RST_CLKGAT_EN_SPARE_LSB 12
#define RST_CLKGAT_EN_SPARE_MASK 0xfffff000
diff --git a/include/common.h b/include/common.h
index 2d7aa6c..f49ac34 100755
--- a/include/common.h
+++ b/include/common.h
@@ -218,6 +218,8 @@
#define ACTIVATED_KERNEL_NAME_UB ACTIVATED_KERNEL_NAME_SV
#define MAC_ADDR1_SV "MAC_ADDR1"
#define MAC_ADDR1_UB "ethaddr"
+#define FAILOVER_THRESHOLD_SV "FAILOVER_THRESHOLD"
+#define FAILOVER_THRESHOLD_UB FAILOVER_THRESHOLD_SV
int sysvar_init(void);
int is_sysvar_shared(const char *var);
const char *get_uboot_name(const char *sysvar_name);
diff --git a/include/configs/board953x.h b/include/configs/board953x.h
index 1b81b53..96a3712 100755
--- a/include/configs/board953x.h
+++ b/include/configs/board953x.h
@@ -143,6 +143,7 @@
*/
#define __gen_dualboot_cmd(n, a1, a2, f, ec1, ec2, cc1, cc2, el) \
#n "=" \
+ "run reset_failover; " \
__if_booting_to_partition_2 \
__gen_cmd_nn(n, a2, f, ec2, cc2, el) ";" \
__else \
@@ -266,8 +267,12 @@
# define ATH_K_CMD gen_dualboot_cmd(lk, ATH_K_ADDR, ATH_K_ADDR_2, ATH_K_FILE)
#endif
+#ifndef ATH_RESET_FAILOVER_CMD
+# define ATH_RESET_FAILOVER_CMD "reset_failover=mw 0x180600b8 0\0"
+#endif
+
#define CONFIG_EXTRA_ENV_SETTINGS \
- "dir=\0" "ACTIVATED_KERNEL_NAME=kernel0\0" "extra_bootargs=debug=1 factory=0 wifical=0\0" ATH_U_CMD ATH_F_CMD ATH_K_CMD
+ "dir=\0" "ACTIVATED_KERNEL_NAME=kernel0\0" "extra_bootargs=debug=1 factory=0 wifical=0\0" ATH_U_CMD ATH_F_CMD ATH_K_CMD ATH_RESET_FAILOVER_CMD
#define CONFIG_BOOTARGS "console=ttyS0,115200 root=" ATH_ROOT_DEV " rootfstype=squashfs init=/init " MTDPARTS_DEFAULT
diff --git a/lib_mips/board.c b/lib_mips/board.c
index 3ddf12f..4f57a70 100755
--- a/lib_mips/board.c
+++ b/lib_mips/board.c
@@ -53,6 +53,11 @@
#define ath_set_tuning_caps() /* nothing */
#endif
+#if defined(CONFIG_MACH_QCA953x)
+void ath_check_failover(void);
+#else
+#define ath_check_failover() /* nothing */
+#endif
extern ulong uboot_end_data;
extern ulong uboot_end;
@@ -458,7 +463,10 @@
ath_nand_init();
#endif
- ath_set_tuning_caps(); /* Needed here not to mess with Ethernet clocks */
+ ath_set_tuning_caps(); /* Needed here not to mess with Ethernet clocks */
+
+ sysvar_init();
+ ath_check_failover();
/* main_loop() can return to retry autoboot, if so just run it again. */
for (;;) {