From 1c879ae1f822f59d74cec9dd7ed10790279ad65b Mon Sep 17 00:00:00 2001 From: James Feist Date: Wed, 31 Jul 2019 16:01:49 -0700 Subject: [PATCH] Reboot into UBOOT on Watchdog Failures We use watchdog1 to reboot when there is a watchdog error. Reboot into u-boot as we are using that as safe mode. Tested: watchdog -T 0 -F /dev/watchdog1 reboots into uboot after 3 times Signed-off-by: James Feist Signed-off-by: Jae Hyun Yoo --- board/aspeed/ast2600_intel/intel.c | 61 ++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/board/aspeed/ast2600_intel/intel.c b/board/aspeed/ast2600_intel/intel.c index 7664ac0ddfc6..24ae48fc62e7 100644 --- a/board/aspeed/ast2600_intel/intel.c +++ b/board/aspeed/ast2600_intel/intel.c @@ -9,6 +9,55 @@ #include #define SYS_PWR_RESET_FLAG BIT(0) /* from scu_info.c */ +#define WATCHDOG_RESET_BIT BIT(20) +#define BOOT_FAILURE_LIMIT 3 + +static int get_boot_failures(void) +{ + return env_get_ulong("bootfailures", 10, 0); +} + +static void set_boot_failures(u32 count) +{ + if (count > BOOT_FAILURE_LIMIT) + return; + + env_set_ulong("bootfailures", count); + env_save(); +} + +int intel_failed_boot(void) +{ + struct udevice *dev; + int ret; + + ret = get_boot_failures() >= BOOT_FAILURE_LIMIT; + if (ret) { + /* + * Failure Recovery state: + * ChassisID - Solid Blue, StatusLED - Blinking Amber at 3Hz + */ + ret = led_get_by_label("green", &dev); + if (!ret) + led_set_state(dev, LEDST_OFF); + +#ifdef CONFIG_LED_BLINK + ret = led_get_by_label("amber", &dev); + if (!ret) { + led_set_period(dev, 160); + led_set_state(dev, LEDST_BLINK); + } +#endif + + ret = led_get_by_label("id", &dev); + if (!ret) + led_set_state(dev, LEDST_ON); + + return 1; + } + + return 0; +} /* use GPIOC0 on intel boards */ #define FFUJ_GPIO "gpio@1e78000016" @@ -56,6 +105,10 @@ int read_ffuj(void) int gpio_abort(void) { int value; + + if (intel_failed_boot()) + return 1; + /* check ffuj to abort the autoboot */ value = read_ffuj(); printf("FFUJ: %d\n", value); @@ -473,6 +526,7 @@ int board_late_init(void) #define REV_ID_AST2600A0 0x05000303 /* AST2600 A0 */ #define ONE_MSEC_IN_USEC 1000 char value[11]; + u32 boot_failures; if (readl(SCU_BASE | SCU_014) == REV_ID_AST2600A0) timer_enable(0, ONE_MSEC_IN_USEC, timer_callback, (void *)0); @@ -488,6 +542,13 @@ int board_late_init(void) snprintf(value, sizeof(value), "0x%x", gd->reset_reason); update_bootargs_cmd("resetreason", value); + boot_failures = get_boot_failures(); + + if (gd->reset_reason & WATCHDOG_RESET_BIT) + set_boot_failures(boot_failures + 1); + else + set_boot_failures(0); + /* Update the special mode in bootargs */ if (gd->reset_reason & SYS_PWR_RESET_FLAG && is_mfg_mode_phy_req()) update_bootargs_cmd("special", "mfg"); -- 2.17.1