diff options
-rw-r--r-- | arch/mips/mach-mt7620/cpu.c | 36 | ||||
-rw-r--r-- | board/CZ.NIC/turris_mox/turris_mox.c | 30 | ||||
-rw-r--r-- | board/CZ.NIC/turris_omnia/turris_omnia.c | 35 | ||||
-rw-r--r-- | board/alliedtelesis/x530/x530.c | 36 | ||||
-rw-r--r-- | board/xilinx/microblaze-generic/microblaze-generic.c | 40 | ||||
-rw-r--r-- | board/xilinx/zynq/board.c | 39 | ||||
-rw-r--r-- | board/xilinx/zynqmp/zynqmp.c | 39 | ||||
-rw-r--r-- | common/board_r.c | 4 | ||||
-rw-r--r-- | common/spl/spl.c | 5 | ||||
-rw-r--r-- | drivers/watchdog/Kconfig | 1 | ||||
-rw-r--r-- | drivers/watchdog/wdt-uclass.c | 26 | ||||
-rw-r--r-- | include/asm-generic/global_data.h | 4 | ||||
-rw-r--r-- | include/configs/turris_omnia.h | 5 | ||||
-rw-r--r-- | include/wdt.h | 41 |
14 files changed, 82 insertions, 259 deletions
diff --git a/arch/mips/mach-mt7620/cpu.c b/arch/mips/mach-mt7620/cpu.c index fe74f26a54..fcd0484a6d 100644 --- a/arch/mips/mach-mt7620/cpu.c +++ b/arch/mips/mach-mt7620/cpu.c @@ -69,28 +69,6 @@ int print_cpuinfo(void) return 0; } -#ifdef CONFIG_WATCHDOG -static struct udevice *watchdog_dev __attribute__((section(".data"))) = NULL; - -/* Called by macro WATCHDOG_RESET */ -void watchdog_reset(void) -{ - static ulong next_reset; - ulong now; - - if (!watchdog_dev) - return; - - now = get_timer(0); - - /* Do not reset the watchdog too often */ - if (now > next_reset) { - next_reset = now + 1000; /* reset every 1000ms */ - wdt_reset(watchdog_dev); - } -} -#endif - int arch_misc_init(void) { /* @@ -103,19 +81,5 @@ int arch_misc_init(void) flush_dcache_range(gd->bd->bi_memstart, gd->bd->bi_memstart + gd->ram_size - 1); -#ifdef CONFIG_WATCHDOG - /* Init watchdog */ - if (uclass_get_device_by_seq(UCLASS_WDT, 0, &watchdog_dev)) { - debug("Watchdog: Not found by seq!\n"); - if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) { - puts("Watchdog: Not found!\n"); - return 0; - } - } - - wdt_start(watchdog_dev, 60000, 0); /* 60 seconds */ - printf("Watchdog: Started\n"); -#endif - return 0; } diff --git a/board/CZ.NIC/turris_mox/turris_mox.c b/board/CZ.NIC/turris_mox/turris_mox.c index 96cb9c7e5c..8a4872343b 100644 --- a/board/CZ.NIC/turris_mox/turris_mox.c +++ b/board/CZ.NIC/turris_mox/turris_mox.c @@ -119,41 +119,11 @@ int board_fix_fdt(void *blob) } #endif -#ifdef CONFIG_WDT_ARMADA_37XX -static struct udevice *watchdog_dev __attribute__((section(".data"))) = NULL; - -void watchdog_reset(void) -{ - static ulong next_reset; - ulong now; - - if (!watchdog_dev) - return; - - now = timer_get_us(); - - /* Do not reset the watchdog too often */ - if (now > next_reset) { - wdt_reset(watchdog_dev); - next_reset = now + 100000; - } -} -#endif - int board_init(void) { /* address of boot parameters */ gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; -#ifdef CONFIG_WDT_ARMADA_37XX - if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) { - printf("Cannot find Armada 3720 watchdog!\n"); - } else { - printf("Enabling Armada 3720 watchdog (3 minutes timeout).\n"); - wdt_start(watchdog_dev, 180000, 0); - } -#endif - return 0; } diff --git a/board/CZ.NIC/turris_omnia/turris_omnia.c b/board/CZ.NIC/turris_omnia/turris_omnia.c index 0287f23283..4c08f810a2 100644 --- a/board/CZ.NIC/turris_omnia/turris_omnia.c +++ b/board/CZ.NIC/turris_omnia/turris_omnia.c @@ -364,25 +364,12 @@ static bool disable_mcu_watchdog(void) } #endif -#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT_ORION) -static struct udevice *watchdog_dev __attribute__((section(".data"))) = NULL; -#endif - int board_init(void) { /* adress of boot parameters */ gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100; #ifndef CONFIG_SPL_BUILD -# ifdef CONFIG_WDT_ORION - if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) { - puts("Cannot find Armada 385 watchdog!\n"); - } else { - puts("Enabling Armada 385 watchdog.\n"); - wdt_start(watchdog_dev, 120000, 0); - } -# endif - if (disable_mcu_watchdog()) puts("Disabled MCU startup watchdog.\n"); @@ -392,28 +379,6 @@ int board_init(void) return 0; } -#ifdef CONFIG_WATCHDOG -/* Called by macro WATCHDOG_RESET */ -void watchdog_reset(void) -{ -# if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT_ORION) - static ulong next_reset = 0; - ulong now; - - if (!watchdog_dev) - return; - - now = timer_get_us(); - - /* Do not reset the watchdog too often */ - if (now > next_reset) { - wdt_reset(watchdog_dev); - next_reset = now + 1000; - } -# endif -} -#endif - int board_late_init(void) { #ifndef CONFIG_SPL_BUILD diff --git a/board/alliedtelesis/x530/x530.c b/board/alliedtelesis/x530/x530.c index 6934fd8017..97dbed79dd 100644 --- a/board/alliedtelesis/x530/x530.c +++ b/board/alliedtelesis/x530/x530.c @@ -25,10 +25,6 @@ DECLARE_GLOBAL_DATA_PTR; #define CONFIG_NVS_LOCATION 0xf4800000 #define CONFIG_NVS_SIZE (512 << 10) -#ifdef CONFIG_WATCHDOG -static struct udevice *watchdog_dev; -#endif - static struct serdes_map board_serdes_map[] = { {PEX0, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0}, {DEFAULT_SERDES, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0}, @@ -80,10 +76,6 @@ struct mv_ddr_topology_map *mv_ddr_topology_map_get(void) int board_early_init_f(void) { -#ifdef CONFIG_WATCHDOG - watchdog_dev = NULL; -#endif - /* Configure MPP */ writel(0x00001111, MVEBU_MPP_BASE + 0x00); writel(0x00000000, MVEBU_MPP_BASE + 0x04); @@ -99,13 +91,6 @@ int board_early_init_f(void) void spl_board_init(void) { -#ifdef CONFIG_WATCHDOG - int ret; - - ret = uclass_get_device(UCLASS_WDT, 0, &watchdog_dev); - if (!ret) - wdt_start(watchdog_dev, 120000, 0); -#endif } int board_init(void) @@ -128,29 +113,10 @@ int board_init(void) void arch_preboot_os(void) { #ifdef CONFIG_WATCHDOG - wdt_stop(watchdog_dev); + wdt_stop(gd->watchdog_dev); #endif } -#ifdef CONFIG_WATCHDOG -void watchdog_reset(void) -{ - static ulong next_reset = 0; - ulong now; - - if (!watchdog_dev) - return; - - now = timer_get_us(); - - /* Do not reset the watchdog too often */ - if (now > next_reset) { - wdt_reset(watchdog_dev); - next_reset = now + 1000; - } -} -#endif - static int led_7seg_init(unsigned int segments) { int node; diff --git a/board/xilinx/microblaze-generic/microblaze-generic.c b/board/xilinx/microblaze-generic/microblaze-generic.c index 28c9efa3a2..ba82292e35 100644 --- a/board/xilinx/microblaze-generic/microblaze-generic.c +++ b/board/xilinx/microblaze-generic/microblaze-generic.c @@ -24,10 +24,6 @@ DECLARE_GLOBAL_DATA_PTR; -#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT) -static struct udevice *watchdog_dev __attribute__((section(".data"))) = NULL; -#endif /* !CONFIG_SPL_BUILD && CONFIG_WDT */ - ulong ram_base; int dram_init_banksize(void) @@ -43,44 +39,8 @@ int dram_init(void) return 0; }; -#ifdef CONFIG_WDT -/* Called by macro WATCHDOG_RESET */ -void watchdog_reset(void) -{ -#if !defined(CONFIG_SPL_BUILD) - ulong now; - static ulong next_reset; - - if (!watchdog_dev) - return; - - now = timer_get_us(); - - /* Do not reset the watchdog too often */ - if (now > next_reset) { - wdt_reset(watchdog_dev); - next_reset = now + 1000; - } -#endif /* !CONFIG_SPL_BUILD */ -} -#endif /* CONFIG_WDT */ - int board_late_init(void) { -#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT) - watchdog_dev = NULL; - - if (uclass_get_device_by_seq(UCLASS_WDT, 0, &watchdog_dev)) { - debug("Watchdog: Not found by seq!\n"); - if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) { - puts("Watchdog: Not found!\n"); - return 0; - } - } - - wdt_start(watchdog_dev, 0, 0); - puts("Watchdog: Started\n"); -#endif /* !CONFIG_SPL_BUILD && CONFIG_WDT */ #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SYSRESET_MICROBLAZE) int ret; diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c index ea26aad16f..6857f2c0b8 100644 --- a/board/xilinx/zynq/board.c +++ b/board/xilinx/zynq/board.c @@ -18,10 +18,6 @@ DECLARE_GLOBAL_DATA_PTR; -#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT) -static struct udevice *watchdog_dev __attribute__((section(".data"))) = NULL; -#endif - #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_BOARD_EARLY_INIT_F) int board_early_init_f(void) { @@ -31,19 +27,6 @@ int board_early_init_f(void) int board_init(void) { -#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT) - if (uclass_get_device_by_seq(UCLASS_WDT, 0, &watchdog_dev)) { - debug("Watchdog: Not found by seq!\n"); - if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) { - puts("Watchdog: Not found!\n"); - return 0; - } - } - - wdt_start(watchdog_dev, 0, 0); - puts("Watchdog: Started\n"); -# endif - return 0; } @@ -127,25 +110,3 @@ int dram_init(void) return 0; } #endif - -#if defined(CONFIG_WATCHDOG) -/* Called by macro WATCHDOG_RESET */ -void watchdog_reset(void) -{ -# if !defined(CONFIG_SPL_BUILD) - static ulong next_reset; - ulong now; - - if (!watchdog_dev) - return; - - now = timer_get_us(); - - /* Do not reset the watchdog too often */ - if (now > next_reset) { - wdt_reset(watchdog_dev); - next_reset = now + 1000; - } -# endif -} -#endif diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c index 5189925beb..c840e92d9c 100644 --- a/board/xilinx/zynqmp/zynqmp.c +++ b/board/xilinx/zynqmp/zynqmp.c @@ -24,10 +24,6 @@ DECLARE_GLOBAL_DATA_PTR; -#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT) -static struct udevice *watchdog_dev __attribute__((section(".data"))) = NULL; -#endif - #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \ !defined(CONFIG_SPL_BUILD) static xilinx_desc zynqmppl = XILINX_ZYNQMP_DESC; @@ -344,44 +340,9 @@ int board_init(void) } #endif -#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT) - if (uclass_get_device_by_seq(UCLASS_WDT, 0, &watchdog_dev)) { - debug("Watchdog: Not found by seq!\n"); - if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) { - puts("Watchdog: Not found!\n"); - return 0; - } - } - - wdt_start(watchdog_dev, 0, 0); - puts("Watchdog: Started\n"); -#endif - return 0; } -#ifdef CONFIG_WATCHDOG -/* Called by macro WATCHDOG_RESET */ -void watchdog_reset(void) -{ -# if !defined(CONFIG_SPL_BUILD) - static ulong next_reset; - ulong now; - - if (!watchdog_dev) - return; - - now = timer_get_us(); - - /* Do not reset the watchdog too often */ - if (now > next_reset) { - wdt_reset(watchdog_dev); - next_reset = now + 1000; - } -# endif -} -#endif - int board_early_init_r(void) { u32 val; diff --git a/common/board_r.c b/common/board_r.c index 1ad44bbe3f..150e8cd424 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -48,6 +48,7 @@ #include <linux/compiler.h> #include <linux/err.h> #include <efi_loader.h> +#include <wdt.h> DECLARE_GLOBAL_DATA_PTR; @@ -677,6 +678,9 @@ static init_fnc_t init_sequence_r[] = { #ifdef CONFIG_DM initr_dm, #endif +#if defined(CONFIG_WDT) + initr_watchdog, +#endif #if defined(CONFIG_ARM) || defined(CONFIG_NDS32) || defined(CONFIG_RISCV) || \ defined(CONFIG_SANDBOX) board_init, /* Setup chipselects */ diff --git a/common/spl/spl.c b/common/spl/spl.c index 88d4b8a9bf..0a6a47c202 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -22,6 +22,7 @@ #include <linux/compiler.h> #include <fdt_support.h> #include <bootcount.h> +#include <wdt.h> DECLARE_GLOBAL_DATA_PTR; @@ -600,6 +601,10 @@ void board_init_r(gd_t *dummy1, ulong dummy2) spl_board_init(); #endif +#if defined(CONFIG_SPL_WATCHDOG_SUPPORT) && defined(CONFIG_WDT) + initr_watchdog(); +#endif + if (IS_ENABLED(CONFIG_SPL_OS_BOOT) || CONFIG_IS_ENABLED(HANDOFF)) dram_init_banksize(); diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 9d7f503b69..aa8e725573 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -51,6 +51,7 @@ config ULP_WATCHDOG config WDT bool "Enable driver model for watchdog timer drivers" depends on DM + imply WATCHDOG help Enable driver model for watchdog timer. At the moment the API is very simple and only supports four operations: diff --git a/drivers/watchdog/wdt-uclass.c b/drivers/watchdog/wdt-uclass.c index 23b7e3360d..bbfac4f0f9 100644 --- a/drivers/watchdog/wdt-uclass.c +++ b/drivers/watchdog/wdt-uclass.c @@ -10,6 +10,8 @@ #include <dm/device-internal.h> #include <dm/lists.h> +DECLARE_GLOBAL_DATA_PTR; + int wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags) { const struct wdt_ops *ops = device_get_ops(dev); @@ -63,6 +65,30 @@ int wdt_expire_now(struct udevice *dev, ulong flags) return ret; } +#if defined(CONFIG_WATCHDOG) +/* + * Called by macro WATCHDOG_RESET. This function be called *very* early, + * so we need to make sure, that the watchdog driver is ready before using + * it in this function. + */ +void watchdog_reset(void) +{ + static ulong next_reset; + ulong now; + + /* Exit if GD is not ready or watchdog is not initialized yet */ + if (!gd || !(gd->flags & GD_FLG_WDT_READY)) + return; + + /* Do not reset the watchdog too often */ + now = get_timer(0); + if (now > next_reset) { + next_reset = now + 1000; /* reset every 1000ms */ + wdt_reset(gd->watchdog_dev); + } +} +#endif + static int wdt_post_bind(struct udevice *dev) { #if defined(CONFIG_NEEDS_MANUAL_RELOC) diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index 65ee3e5d5a..02a3ed6838 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -137,6 +137,9 @@ typedef struct global_data { #if defined(CONFIG_TRANSLATION_OFFSET) fdt_addr_t translation_offset; /* optional translation offset */ #endif +#if defined(CONFIG_WDT) + struct udevice *watchdog_dev; +#endif } gd_t; #endif @@ -165,5 +168,6 @@ typedef struct global_data { #define GD_FLG_ENV_DEFAULT 0x02000 /* Default variable flag */ #define GD_FLG_SPL_EARLY_INIT 0x04000 /* Early SPL init is done */ #define GD_FLG_LOG_READY 0x08000 /* Log system is ready for use */ +#define GD_FLG_WDT_READY 0x10000 /* Watchdog is ready for use */ #endif /* __ASM_GENERIC_GBL_DATA_H */ diff --git a/include/configs/turris_omnia.h b/include/configs/turris_omnia.h index c7805cf36b..0e65a12345 100644 --- a/include/configs/turris_omnia.h +++ b/include/configs/turris_omnia.h @@ -29,11 +29,6 @@ #define CONFIG_SPL_I2C_MUX #define CONFIG_SYS_I2C_MVTWSI -/* Watchdog support */ -#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT_ORION) -# define CONFIG_WATCHDOG -#endif - /* * SDIO/MMC Card Configuration */ diff --git a/include/wdt.h b/include/wdt.h index e9a7c5355a..aa77d3e9b4 100644 --- a/include/wdt.h +++ b/include/wdt.h @@ -6,6 +6,9 @@ #ifndef _WDT_H_ #define _WDT_H_ +#include <dm.h> +#include <dm/read.h> + /* * Implement a simple watchdog uclass. Watchdog is basically a timer that * is used to detect or recover from malfunction. During normal operation @@ -103,4 +106,42 @@ struct wdt_ops { int (*expire_now)(struct udevice *dev, ulong flags); }; +#if defined(CONFIG_WDT) +#ifndef CONFIG_WATCHDOG_TIMEOUT_MSECS +#define CONFIG_WATCHDOG_TIMEOUT_MSECS (60 * 1000) +#endif +#define WATCHDOG_TIMEOUT_SECS (CONFIG_WATCHDOG_TIMEOUT_MSECS / 1000) + +static inline int initr_watchdog(void) +{ + u32 timeout = WATCHDOG_TIMEOUT_SECS; + + /* + * Init watchdog: This will call the probe function of the + * watchdog driver, enabling the use of the device + */ + if (uclass_get_device_by_seq(UCLASS_WDT, 0, + (struct udevice **)&gd->watchdog_dev)) { + debug("WDT: Not found by seq!\n"); + if (uclass_get_device(UCLASS_WDT, 0, + (struct udevice **)&gd->watchdog_dev)) { + printf("WDT: Not found!\n"); + return 0; + } + } + + if (CONFIG_IS_ENABLED(OF_CONTROL)) { + timeout = dev_read_u32_default(gd->watchdog_dev, "timeout-sec", + WATCHDOG_TIMEOUT_SECS); + } + + wdt_start(gd->watchdog_dev, timeout * 1000, 0); + gd->flags |= GD_FLG_WDT_READY; + printf("WDT: Started with%s servicing (%ds timeout)\n", + IS_ENABLED(CONFIG_WATCHDOG) ? "" : "out", timeout); + + return 0; +} +#endif + #endif /* _WDT_H_ */ |