summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWealian Liao <whliao@nuvoton.corp-partner.google.com>2021-01-06 09:41:01 +0800
committerCommit Bot <commit-bot@chromium.org>2021-02-22 23:41:29 +0000
commit4d8e52a348b4b03549d75048e920a1b4a0aec75b (patch)
treeec8f2a4827c3434d536587fa652201d98a3667ea
parente0b50372154ff2f0cdc094548e563de330d13018 (diff)
downloadchrome-ec-4d8e52a348b4b03549d75048e920a1b4a0aec75b.tar.gz
zephyr: add watchdog
In npcx7 series, the Timer and Watchdog module (TWD) generates the clocks and interrupts used for timing periodic functions in the system. It also provides watchdog reset signal generation in response to a failure detection. This CL enables the watchdog functionality in zephyr system. BUG=b:176523207, b:177604307 BRANCH=None. TEST=add stall function to check the system can reset by the watchdog Signed-off-by: Wealian Liao <whliao@nuvoton.corp-partner.google.com> Change-Id: Iee0312dd6132ce76e622178b3a666aa415bc735a Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2659135 Reviewed-by: Simon Glass <sjg@chromium.org> Tested-by: Simon Glass <sjg@chromium.org> Commit-Queue: Simon Glass <sjg@chromium.org>
-rw-r--r--include/config.h9
-rw-r--r--zephyr/Kconfig23
-rw-r--r--zephyr/app/ec/main.c5
-rw-r--r--zephyr/shim/include/config_chip.h24
-rw-r--r--zephyr/shim/src/CMakeLists.txt1
-rw-r--r--zephyr/shim/src/watchdog.c74
6 files changed, 135 insertions, 1 deletions
diff --git a/include/config.h b/include/config.h
index adf582a834..eb1b178a25 100644
--- a/include/config.h
+++ b/include/config.h
@@ -4862,7 +4862,9 @@
* if the hook task (which is the lowest-priority task on the system) gets
* starved for CPU time and isn't able to fire its HOOK_TICK event.
*/
+#ifndef CONFIG_ZEPHYR
#define CONFIG_WATCHDOG
+#endif
/*
* Try to detect a watchdog that is about to fire, and print a trace. This is
@@ -5812,9 +5814,16 @@
* Validity checks to make sure some of the configs above make sense.
*/
+/*
+ * Chromium ec uses hook tick to reload the watchdog. The interval between
+ * reloads of the watchdog timer should be less than half of the watchdog
+ * period.
+ */
+#if !defined(CONFIG_ZEPHYR) && defined(CONFIG_WATCHDOG)
#if (CONFIG_AUX_TIMER_PERIOD_MS) < ((HOOK_TICK_INTERVAL_MS) * 2)
#error "CONFIG_AUX_TIMER_PERIOD_MS must be at least 2x HOOK_TICK_INTERVAL_MS"
#endif
+#endif
#ifdef CONFIG_USB_SERIALNO
#define CONFIG_SERIALNO_LEN 28
diff --git a/zephyr/Kconfig b/zephyr/Kconfig
index 76656db3e7..3b46a307e9 100644
--- a/zephyr/Kconfig
+++ b/zephyr/Kconfig
@@ -853,4 +853,27 @@ config PLATFORM_EC_SYSTEM_UNLOCKED
Also, this enables PD in RO for TCPMv2.
+menuconfig PLATFORM_EC_WATCHDOG
+ bool "watchdog"
+ depends on WATCHDOG
+ default y
+ help
+ Enable the watchdog functionality. The watchdog timer will reboot the
+ system if the hook task (which is the lowest-priority task on the
+ system) gets starved for CPU time and isn't able to fire its
+ HOOK_TICK event.
+
+if PLATFORM_EC_WATCHDOG
+
+config PLATFORM_EC_WATCHDOG_PERIOD_MS
+ int "Watchdog timeout in ms"
+ default 1600
+ help
+ Set the timeout of the watchdog timer. The watchdog timer reboots
+ the system if no one reloads the watchdog timer before the timeout.
+ The interval between reloads of the watchdog timer should be less than
+ half of the watchdog period.
+
+endif # PLATFORM_EC_WATCHDOG
+
endif # PLATFORM_EC
diff --git a/zephyr/app/ec/main.c b/zephyr/app/ec/main.c
index 9311aa60be..f1b3d24c69 100644
--- a/zephyr/app/ec/main.c
+++ b/zephyr/app/ec/main.c
@@ -11,6 +11,7 @@
#include "hooks.h"
#include "keyboard_scan.h"
#include "system.h"
+#include "watchdog.h"
#include "zephyr_espi_shim.h"
void main(void)
@@ -30,6 +31,10 @@ void main(void)
init_reset_log();
}
+ if (IS_ENABLED(CONFIG_PLATFORM_EC_WATCHDOG)) {
+ watchdog_init();
+ }
+
if (IS_ENABLED(HAS_TASK_KEYSCAN)) {
keyboard_scan_init();
}
diff --git a/zephyr/shim/include/config_chip.h b/zephyr/shim/include/config_chip.h
index fbc7689c34..9c40654d13 100644
--- a/zephyr/shim/include/config_chip.h
+++ b/zephyr/shim/include/config_chip.h
@@ -48,6 +48,13 @@
/*
* ECOS specific options, not used in Zephyr.
*/
+
+ /*
+ * The Zephyr npcx watchdog driver provider a delay set by
+ * CONFIG_WDT_NPCX_DELAY_CYCLES for displaying the warning message.
+ * CONFIG_AUX_TIMER_PERIOD_MS isn't used by the Zephyr code.
+ */
+#undef CONFIG_AUX_TIMER_PERIOD_MS
#undef CONFIG_CONSOLE_UART /* Only used by the Chromium EC chip drivers */
#undef CONFIG_I2C_MULTI_PORT_CONTROLLER /* Not required by I2C shim */
#undef CONFIG_IRQ_COUNT /* Only used by Chromium EC core drivers */
@@ -55,6 +62,9 @@
#ifndef CONFIG_FPU
#undef CONFIG_FPU /* Used in Zephyr as well, enabled in Kconfig directly */
#endif
+#ifndef CONFIG_WATCHDOG
+#undef CONFIG_WATCHDOG /* Used in Zephyr as well, enabled in Kconfig directly */
+#endif
/*
* This not used by the Zephyr code since we always make cros_crc8() available.
@@ -72,6 +82,7 @@
/* EC chipset configuration */
#define HOOK_TICK_INTERVAL CONFIG_CROS_EC_HOOK_TICK_INTERVAL
+#define HOOK_TICK_INTERVAL_MS (HOOK_TICK_INTERVAL / 1000)
/* Chipset and power configuration */
#ifdef CONFIG_AP_X86_INTEL_CML
@@ -453,7 +464,6 @@ enum battery_type {
#ifdef CONFIG_PLATFORM_EC_TIMER
#define CONFIG_HWTIMER_64BIT
#define CONFIG_HW_SPECIFIC_UDELAY
-#undef CONFIG_WATCHDOG
#undef CONFIG_CMD_GETTIME
#ifdef CONFIG_PLATFORM_EC_CONSOLE_CMD_GETTIME
@@ -1139,4 +1149,16 @@ enum battery_type {
#define CONFIG_CMD_SYSJUMP
#endif
+#undef CONFIG_WATCHDOG_PERIOD_MS
+#ifdef CONFIG_PLATFORM_EC_WATCHDOG_PERIOD_MS
+#define CONFIG_WATCHDOG_PERIOD_MS CONFIG_PLATFORM_EC_WATCHDOG_PERIOD_MS
+/*
+ * Chromium ec uses hook tick to reload the watchdog. Interval between reloads
+ * of the watchdog timer should be less than half of the watchdog period.
+ */
+#if (CONFIG_WATCHDOG_PERIOD_MS) < ((HOOK_TICK_INTERVAL_MS) * 2)
+#error "CONFIG_WATCHDOG_PERIOD_MS must be at least 2x HOOK_TICK_INTERVAL_MS"
+#endif
+#endif
+
#endif /* __CROS_EC_CONFIG_CHIP_H */
diff --git a/zephyr/shim/src/CMakeLists.txt b/zephyr/shim/src/CMakeLists.txt
index aba067bca7..38955f65d4 100644
--- a/zephyr/shim/src/CMakeLists.txt
+++ b/zephyr/shim/src/CMakeLists.txt
@@ -31,3 +31,4 @@ zephyr_sources_ifdef(CONFIG_PLATFORM_EC_TEMP_SENSOR temp_sensors.c)
zephyr_sources_ifdef(CONFIG_PLATFORM_EC_TIMER hwtimer.c)
zephyr_sources_ifdef(CONFIG_PLATFORM_EC_I2C i2c.c)
zephyr_sources_ifdef(CONFIG_SHIMMED_TASKS tasks.c)
+zephyr_sources_ifdef(CONFIG_PLATFORM_EC_WATCHDOG watchdog.c)
diff --git a/zephyr/shim/src/watchdog.c b/zephyr/shim/src/watchdog.c
new file mode 100644
index 0000000000..8487fd1d75
--- /dev/null
+++ b/zephyr/shim/src/watchdog.c
@@ -0,0 +1,74 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <device.h>
+#include <drivers/watchdog.h>
+#include <logging/log.h>
+#include <zephyr.h>
+
+#include "config.h"
+#include "hooks.h"
+#include "watchdog.h"
+
+LOG_MODULE_REGISTER(watchdog_shim, LOG_LEVEL_ERR);
+
+static void wdt_warning_handler(const struct device *wdt_dev, int channel_id)
+{
+ /* TODO(b/176523207): watchdog warning message */
+ LOG_INF("Watchdog is expired");
+}
+
+int watchdog_init(void)
+{
+ int err;
+ const struct device *wdt;
+ struct wdt_timeout_cfg wdt_config;
+
+ wdt = device_get_binding(DT_LABEL(DT_NODELABEL(twd0)));
+ if (!wdt) {
+ LOG_ERR("Watchdog get binding failed");
+ return -1;
+ }
+
+ /* Reset SoC when watchdog timer expires. */
+ wdt_config.flags = WDT_FLAG_RESET_SOC;
+
+ /*
+ * The Warning timer = CONFIG_WATCHDOG_PERIOD_MS.
+ * The watchdog reset time
+ * = CONFIG_WATCHDOG_PERIOD_MS + time of CONFIG_WDT_NPCX_DELAY_CYCLES
+ */
+ wdt_config.window.min = 0U;
+ wdt_config.window.max = CONFIG_WATCHDOG_PERIOD_MS;
+ wdt_config.callback = wdt_warning_handler;
+
+ err = wdt_install_timeout(wdt, &wdt_config);
+ if (err < 0) {
+ LOG_ERR("Watchdog install error");
+ return err;
+ }
+
+ err = wdt_setup(wdt, 0);
+ if (err < 0) {
+ LOG_ERR("Watchdog setup error");
+ return err;
+ }
+
+ return EC_SUCCESS;
+}
+
+void watchdog_reload(void)
+{
+ const struct device *wdt;
+
+ wdt = device_get_binding(DT_LABEL(DT_NODELABEL(twd0)));
+ if (!wdt) {
+ LOG_ERR("Watchdog get binding failed");
+ return;
+ }
+
+ wdt_feed(wdt, 0);
+}
+DECLARE_HOOK(HOOK_TICK, watchdog_reload, HOOK_PRIO_DEFAULT);