[U-Boot] [PATCH PATCH v1] watchdog: Fix Watchdog Reset while in U-Boot Prompt

Andreas J. Reichel
2016-07-13T10:56:51Z

Hardware: CM-FX6 Module from Compulab

This patch fixes unwanted watchdog resets while the user enters
a command at the U-Boot prompt.

As found on the CM-FX6 board from Compulab, when having enabled the
watchdog, a missing WATCHDOG_RESET call in common/console.c causes
this and alike boards to reset when the watchdog's timeout has
elapsed while waiting at the U-Boot prompt.

Despite the user could press several keys within the watchdog
timeout limit, the while loop in cli_readline.c, line 261, does only
call WATCHDOG_RESET if first == 1, which gets set to 0 in the 1st
loop iteration. This leads to a watchdog timeout no matter if the
user presses keys or not.

Although, this affects other boards as well as it touches
common/console.c, the macro WATCHDOG_RESET expands to {} if watchdog
support isn't configured. Hence, there's no harm caused and no need to
surround it by #ifdef in this case.

* Symptom:
U-Boot resets after watchdog times out when in commandline prompt
and watchdog is enabled.

* Reasoning:
When U-Boot shows the commandline prompt, the following function
call stack is executed while waiting for a keypress:

common/main.c:
main_loop => common/cli.c: cli_loop() =>
common/cli_hush.c:
parse_file_outer => parse_stream_outer =>
parse_stream => b_getch(i) =>
i->get(i) => file_get =>
get_user_input => cmdedit_read_input =>
uboot_cli_readline =>
common/cli_readline.c:
cli_readline => cli_readline_into_buffer =>
cread_line => getcmd_getch (== getc) =>
common/console.c:
fgetc => console_tstc

common/console.c:
(with CONFIG_CONSOLE_MUX is set)

- in console_tstc line 181:
If dev->tstc(dev) returns 0, the global tstcdev variable doesn't get
set. This is the case if no character is in the serial buffer.

- in fgetc(int file), line 297:
Program flow keeps looping because tstcdev does not get set.
Therefore WATCHDOG_RESET is not called, as mx_serial_tstc from
drivers/serial/serial_mxc.c does not call it.

* Solution:
Add WATCHDOG_RESET into the loop of console_tstc.

Note: Macro expands to {} if not configured, so no #ifdef is needed.

* Comment:

Signed-off-by: Christian Storm <christian.storm@tngtech.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Andreas J. Reichel <Andreas.Reichel@tngtech.com>
---

common/console.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/common/console.c b/common/console.c
index 12293f3..054b6cd 100644
--- a/common/console.c
+++ b/common/console.c
@@ -16,6 +16,7 @@
#include <stdio_dev.h>
#include <exports.h>
#include <environment.h>
+#include <watchdog.h>

DECLARE_GLOBAL_DATA_PTR;

@@ -294,6 +295,7 @@ int fgetc(int file)
* Effectively poll for input wherever it may be available.
*/
for (;;) {
+ WATCHDOG_RESET();
/*
* Upper layer may have already called tstc() so
* check for that first.
--
2.8.2