diff options
-rw-r--r-- | arch/m68k/include/asm/ptrace.h | 2 | ||||
-rw-r--r-- | boot/cedit.c | 1 | ||||
-rw-r--r-- | common/cyclic.c | 3 | ||||
-rw-r--r-- | doc/develop/cyclic.rst | 10 | ||||
-rw-r--r-- | drivers/ddr/altera/sdram_n5x.c | 1 | ||||
-rw-r--r-- | drivers/ddr/altera/sdram_soc64.c | 1 | ||||
-rw-r--r-- | drivers/i2c/rz_riic.c | 1 | ||||
-rw-r--r-- | drivers/led/led_sw_blink.c | 1 | ||||
-rw-r--r-- | drivers/watchdog/Kconfig | 16 | ||||
-rw-r--r-- | drivers/watchdog/Makefile | 3 | ||||
-rw-r--r-- | drivers/watchdog/davinci_wdt.c | 131 | ||||
-rw-r--r-- | drivers/watchdog/gpio_wdt.c | 27 | ||||
-rw-r--r-- | fs/cramfs/uncompress.c | 4 | ||||
-rw-r--r-- | include/asm-generic/global_data.h | 1 | ||||
-rw-r--r-- | include/cyclic.h | 24 | ||||
-rw-r--r-- | include/u-boot/schedule.h | 24 | ||||
-rw-r--r-- | include/watchdog.h | 2 | ||||
-rw-r--r-- | lib/sha1.c | 2 | ||||
-rw-r--r-- | lib/sha256.c | 2 | ||||
-rw-r--r-- | lib/sha512.c | 2 | ||||
-rw-r--r-- | test/dm/wdt.c | 14 |
21 files changed, 225 insertions, 47 deletions
diff --git a/arch/m68k/include/asm/ptrace.h b/arch/m68k/include/asm/ptrace.h index d419824806c..5decf73a1d1 100644 --- a/arch/m68k/include/asm/ptrace.h +++ b/arch/m68k/include/asm/ptrace.h @@ -9,6 +9,8 @@ */ #ifndef __ASSEMBLY__ +#include <linux/types.h> + struct pt_regs { ulong d0; ulong d1; diff --git a/boot/cedit.c b/boot/cedit.c index d12892fbc4a..d69290c172e 100644 --- a/boot/cedit.c +++ b/boot/cedit.c @@ -20,6 +20,7 @@ #include <video.h> #include <linux/delay.h> #include "scene_internal.h" +#include <u-boot/schedule.h> enum { CMOS_MAX_BITS = 2048, diff --git a/common/cyclic.c b/common/cyclic.c index ec38fad6775..196797fd61e 100644 --- a/common/cyclic.c +++ b/common/cyclic.c @@ -15,6 +15,7 @@ #include <linux/errno.h> #include <linux/list.h> #include <asm/global_data.h> +#include <u-boot/schedule.h> DECLARE_GLOBAL_DATA_PTR; @@ -44,7 +45,7 @@ void cyclic_unregister(struct cyclic_info *cyclic) hlist_del(&cyclic->list); } -void cyclic_run(void) +static void cyclic_run(void) { struct cyclic_info *cyclic; struct hlist_node *tmp; diff --git a/doc/develop/cyclic.rst b/doc/develop/cyclic.rst index 893c269099a..6f1da6f0d9b 100644 --- a/doc/develop/cyclic.rst +++ b/doc/develop/cyclic.rst @@ -49,8 +49,8 @@ executed all 10ms. How is this cyclic functionality integrated / executed? -------------------------------------------------------- -The cyclic infrastructure integrates the main function responsible for -calling all registered cyclic functions cyclic_run() into the common -WATCHDOG_RESET macro. This guarantees that cyclic_run() is executed -very often, which is necessary for the cyclic functions to get scheduled -and executed at their configured periods. +The cyclic infrastructure integrates cyclic_run(), the main function +responsible for calling all registered cyclic functions, into the +common schedule() function. This guarantees that cyclic_run() is +executed very often, which is necessary for the cyclic functions to +get scheduled and executed at their configured periods. diff --git a/drivers/ddr/altera/sdram_n5x.c b/drivers/ddr/altera/sdram_n5x.c index db09986f64b..d1fc93b6bdd 100644 --- a/drivers/ddr/altera/sdram_n5x.c +++ b/drivers/ddr/altera/sdram_n5x.c @@ -22,6 +22,7 @@ #include <asm/io.h> #include <linux/err.h> #include <linux/sizes.h> +#include <u-boot/schedule.h> DECLARE_GLOBAL_DATA_PTR; diff --git a/drivers/ddr/altera/sdram_soc64.c b/drivers/ddr/altera/sdram_soc64.c index 9e57c2ecfa4..10a8e64af3d 100644 --- a/drivers/ddr/altera/sdram_soc64.c +++ b/drivers/ddr/altera/sdram_soc64.c @@ -24,6 +24,7 @@ #include <asm/io.h> #include <dm/device_compat.h> #include <linux/sizes.h> +#include <u-boot/schedule.h> #define PGTABLE_OFF 0x4000 diff --git a/drivers/i2c/rz_riic.c b/drivers/i2c/rz_riic.c index 5f3f8d1b24b..f292c824362 100644 --- a/drivers/i2c/rz_riic.c +++ b/drivers/i2c/rz_riic.c @@ -14,6 +14,7 @@ #include <linux/bitops.h> #include <linux/delay.h> #include <reset.h> +#include <u-boot/schedule.h> #include <wait_bit.h> #define RIIC_ICCR1 0x00 diff --git a/drivers/led/led_sw_blink.c b/drivers/led/led_sw_blink.c index 06a43db340c..ee1546d02d4 100644 --- a/drivers/led/led_sw_blink.c +++ b/drivers/led/led_sw_blink.c @@ -5,6 +5,7 @@ * Author: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu> */ +#include <cyclic.h> #include <dm.h> #include <led.h> #include <time.h> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 90bc5653ee3..0e45f0a0922 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -175,6 +175,13 @@ config WDT_DA9063 help Enable support for the watchdog timer in Dialog DA9063. +config WDT_DAVINCI + bool "DaVinci watchdog timer support" + depends on WDT + help + Select this to enable the watchdog timer for DaVinci SoCs such as the + OMAP-L138. + config WDT_GPIO bool "External gpio watchdog support" depends on WDT @@ -184,6 +191,15 @@ config WDT_GPIO doc/device-tree-bindings/watchdog/gpio-wdt.txt for information on how to describe the watchdog in device tree. +config SPL_WDT_GPIO + bool "External gpio watchdog support in SPL" + depends on SPL_WDT + depends on SPL_DM_GPIO + depends on SPL_OF_REAL + default WDT_GPIO + help + Support for external watchdog fed by toggling a gpio in SPL. + config WDT_MAX6370 bool "MAX6370 watchdog timer support" depends on WDT diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 51be6ab9abe..0b107c008f7 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -30,8 +30,9 @@ obj-$(CONFIG_WDT_CORTINA) += cortina_wdt.o obj-$(CONFIG_WDT_ORION) += orion_wdt.o obj-$(CONFIG_WDT_CDNS) += cdns_wdt.o obj-$(CONFIG_WDT_DA9063) += da9063-wdt.o +obj-$(CONFIG_WDT_DAVINCI) += davinci_wdt.o obj-$(CONFIG_WDT_FTWDT010) += ftwdt010_wdt.o -obj-$(CONFIG_WDT_GPIO) += gpio_wdt.o +obj-$(CONFIG_$(SPL_TPL_)WDT_GPIO) += gpio_wdt.o obj-$(CONFIG_WDT_MAX6370) += max6370_wdt.o obj-$(CONFIG_WDT_MCF) += mcf_wdt.o obj-$(CONFIG_WDT_MESON_GXBB) += meson_gxbb_wdt.o diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c new file mode 100644 index 00000000000..fa8d7842e94 --- /dev/null +++ b/drivers/watchdog/davinci_wdt.c @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * DaVinci Watchdog driver + * + */ + +#include <asm/io.h> +#include <clk.h> +#include <dm.h> +#include <wdt.h> + +/* Control Register */ +#define DAVINCI_WDT_ID 0x00 +#define DAVINCI_WDT_TIM12 0x10 +#define DAVINCI_WDT_TIM34 0x14 +#define DAVINCI_WDT_PRD12 0x18 +#define DAVINCI_WDT_PRD34 0x1C +#define DAVINCI_WDT_TCR 0x20 +#define DAVINCI_WDT_TGCR 0x24 +#define DAVINCI_WDT_WDTCR 0x28 + +#define DAVINCI_TCR_CONT_EN BIT(7) + +#define DAVINCI_TGCR_PLUSEN BIT(4) +#define DAVINCI_TGCR_WDT_MODE BIT(3) +#define DAVINCI_TGCR_TIM34RS BIT(1) +#define DAVINCI_TGCR_TIM12RS BIT(0) + +#define DAVINCI_WDTCR_INVALID_KEY (0x5555 << 16) +#define DAVINCI_WDTCR_WDKEY0 (0xA5C6 << 16) +#define DAVINCI_WDTCR_WDKEY1 (0xDA7E << 16) +#define DAVINCI_WDTCR_WDFLAG BIT(15) +#define DAVINCI_WDTCR_WDEN BIT(14) + +#define DEFAULT_THRESHOLD 0xA03200000 + +struct davinci_wdt_priv { + void __iomem *base; + struct clk *ref_clk; +}; + +static int davinci_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags) +{ + struct davinci_wdt_priv *priv = dev_get_priv(dev); + ulong rate = clk_get_rate(priv->ref_clk); + u64 threshold; + + if (!rate) + threshold = DEFAULT_THRESHOLD; + else + threshold = rate * timeout_ms / 1000; + + /* Reset control registers */ + writel(0, priv->base + DAVINCI_WDT_TCR); + writel(0, priv->base + DAVINCI_WDT_TGCR); + + /* Enable watchdog mode and timers */ + writel(DAVINCI_TGCR_WDT_MODE | DAVINCI_TGCR_TIM12RS | DAVINCI_TGCR_TIM34RS, + priv->base + DAVINCI_WDT_TGCR); + + /* Reset counters */ + writel(0, priv->base + DAVINCI_WDT_TIM12); + writel(0, priv->base + DAVINCI_WDT_TIM34); + + /* Set timeout threshold */ + writel(threshold & 0xFFFFFFFF, priv->base + DAVINCI_WDT_PRD12); + writel(threshold >> 32, priv->base + DAVINCI_WDT_PRD34); + + /* Enable counter */ + writel(DAVINCI_TCR_CONT_EN, priv->base + DAVINCI_WDT_TCR); + + /* Go to watchdog's active state */ + writel(DAVINCI_WDTCR_WDEN | DAVINCI_WDTCR_WDKEY0, priv->base + DAVINCI_WDT_WDTCR); + writel(DAVINCI_WDTCR_WDEN | DAVINCI_WDTCR_WDKEY1, priv->base + DAVINCI_WDT_WDTCR); + + return 0; +} + +static int davinci_wdt_expire_now(struct udevice *dev, ulong flags) +{ + struct davinci_wdt_priv *priv = dev_get_priv(dev); + + writel(DAVINCI_WDTCR_INVALID_KEY, priv->base + DAVINCI_WDT_WDTCR); + + return 0; +} + +static int davinci_wdt_restart(struct udevice *dev) +{ + struct davinci_wdt_priv *priv = dev_get_priv(dev); + + writel(DAVINCI_WDTCR_WDEN | DAVINCI_WDTCR_WDKEY0, priv->base + DAVINCI_WDT_WDTCR); + writel(DAVINCI_WDTCR_WDEN | DAVINCI_WDTCR_WDKEY1, priv->base + DAVINCI_WDT_WDTCR); + + return 0; +} + +static int davinci_wdt_probe(struct udevice *dev) +{ + struct davinci_wdt_priv *priv = dev_get_priv(dev); + + priv->base = dev_remap_addr_index(dev, 0); + if (!priv->base) + return -EFAULT; + + priv->ref_clk = devm_clk_get(dev, "ref"); + if (IS_ERR(priv->ref_clk)) + return PTR_ERR(priv->ref_clk); + + return 0; +} + +static const struct wdt_ops davinci_wdt_ops = { + .start = davinci_wdt_start, + .reset = davinci_wdt_restart, + .expire_now = davinci_wdt_expire_now, +}; + +static const struct udevice_id davinci_wdt_ids[] = { + {.compatible = "ti,davinci-wdt"}, + {} +}; + +U_BOOT_DRIVER(davinci_wdt) = { + .name = "davinci_wdt", + .id = UCLASS_WDT, + .probe = davinci_wdt_probe, + .of_match = davinci_wdt_ids, + .ops = &davinci_wdt_ops, + .priv_auto = sizeof(struct davinci_wdt_priv), +}; diff --git a/drivers/watchdog/gpio_wdt.c b/drivers/watchdog/gpio_wdt.c index 2920c2c751f..e889861e917 100644 --- a/drivers/watchdog/gpio_wdt.c +++ b/drivers/watchdog/gpio_wdt.c @@ -45,14 +45,32 @@ static int gpio_wdt_start(struct udevice *dev, u64 timeout, ulong flags) if (priv->always_running) return 0; - return -ENOSYS; + dm_gpio_set_dir_flags(&priv->gpio, GPIOD_IS_OUT); + gpio_wdt_reset(dev); + + return 0; +} + +static int gpio_wdt_stop(struct udevice *dev) +{ + struct gpio_wdt_priv *priv = dev_get_priv(dev); + + if (priv->always_running) + return -EOPNOTSUPP; + + if (priv->hw_algo == HW_ALGO_TOGGLE) + dm_gpio_set_dir_flags(&priv->gpio, GPIOD_IS_IN); + else + dm_gpio_set_value(&priv->gpio, 1); + + return 0; } static int dm_probe(struct udevice *dev) { struct gpio_wdt_priv *priv = dev_get_priv(dev); - int ret; const char *algo = dev_read_string(dev, "hw_algo"); + int ret, flags; if (!algo) return -EINVAL; @@ -64,7 +82,9 @@ static int dm_probe(struct udevice *dev) return -EINVAL; priv->always_running = dev_read_bool(dev, "always-running"); - ret = gpio_request_by_name(dev, "gpios", 0, &priv->gpio, GPIOD_IS_OUT); + flags = priv->always_running || priv->hw_algo == HW_ALGO_LEVEL ? + GPIOD_IS_OUT : GPIOD_IS_IN; + ret = gpio_request_by_name(dev, "gpios", 0, &priv->gpio, flags); if (ret < 0) { dev_err(dev, "Request for wdt gpio failed: %d\n", ret); return ret; @@ -78,6 +98,7 @@ static int dm_probe(struct udevice *dev) static const struct wdt_ops gpio_wdt_ops = { .start = gpio_wdt_start, + .stop = gpio_wdt_stop, .reset = gpio_wdt_reset, }; diff --git a/fs/cramfs/uncompress.c b/fs/cramfs/uncompress.c index 2141edf22e4..97af8cb2b4f 100644 --- a/fs/cramfs/uncompress.c +++ b/fs/cramfs/uncompress.c @@ -21,9 +21,9 @@ */ #include <stdio.h> -#include <cyclic.h> #include <malloc.h> #include <watchdog.h> +#include <u-boot/schedule.h> #include <u-boot/zlib.h> static z_stream stream; @@ -63,7 +63,7 @@ int cramfs_uncompress_init (void) stream.avail_in = 0; #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - stream.outcb = (cb_func)cyclic_run; + stream.outcb = (cb_func)schedule; #else stream.outcb = Z_NULL; #endif /* CONFIG_HW_WATCHDOG */ diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index 644a0d77873..b84cc5bbecd 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -21,7 +21,6 @@ #ifndef __ASSEMBLY__ #include <board_f.h> -#include <cyclic.h> #include <event_internal.h> #include <fdtdec.h> #include <membuff.h> diff --git a/include/cyclic.h b/include/cyclic.h index cd95b691d48..c6c463d68e9 100644 --- a/include/cyclic.h +++ b/include/cyclic.h @@ -13,6 +13,7 @@ #include <linux/list.h> #include <asm/types.h> +#include <u-boot/schedule.h> // to be removed later /** * struct cyclic_info - Information about cyclic execution function @@ -86,21 +87,6 @@ int cyclic_unregister_all(void); */ struct hlist_head *cyclic_get_list(void); -/** - * cyclic_run() - Interate over all registered cyclic functions - * - * Interate over all registered cyclic functions and if the it's function - * needs to be executed, then call into these registered functions. - */ -void cyclic_run(void); - -/** - * schedule() - Schedule all potentially waiting tasks - * - * Basically a wrapper for cyclic_run(), pontentially enhanced by some - * other parts, that need to get handled periodically. - */ -void schedule(void); #else static inline void cyclic_register(struct cyclic_info *cyclic, cyclic_func_t func, @@ -112,14 +98,6 @@ static inline void cyclic_unregister(struct cyclic_info *cyclic) { } -static inline void cyclic_run(void) -{ -} - -static inline void schedule(void) -{ -} - static inline int cyclic_unregister_all(void) { return 0; diff --git a/include/u-boot/schedule.h b/include/u-boot/schedule.h new file mode 100644 index 00000000000..4fd34c41229 --- /dev/null +++ b/include/u-boot/schedule.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef _U_BOOT_SCHEDULE_H +#define _U_BOOT_SCHEDULE_H + +#if CONFIG_IS_ENABLED(CYCLIC) +/** + * schedule() - Schedule all potentially waiting tasks + * + * Run all pending tasks registered via the cyclic framework, and + * potentially perform other actions that need to be done + * periodically. + */ +void schedule(void); + +#else + +static inline void schedule(void) +{ +} + +#endif + +#endif diff --git a/include/watchdog.h b/include/watchdog.h index d1956fafca1..0149b44d077 100644 --- a/include/watchdog.h +++ b/include/watchdog.h @@ -10,7 +10,7 @@ #ifndef _WATCHDOG_H_ #define _WATCHDOG_H_ -#include <cyclic.h> +#include <u-boot/schedule.h> // to be removed later /* * Reset the watchdog timer, always returns 0 diff --git a/lib/sha1.c b/lib/sha1.c index 81412283b49..a9d6497c4ce 100644 --- a/lib/sha1.c +++ b/lib/sha1.c @@ -17,7 +17,7 @@ #endif #ifndef USE_HOSTCC -#include <cyclic.h> +#include <u-boot/schedule.h> #endif /* USE_HOSTCC */ #include <string.h> #include <u-boot/sha1.h> diff --git a/lib/sha256.c b/lib/sha256.c index 665ba6f152e..329802fd827 100644 --- a/lib/sha256.c +++ b/lib/sha256.c @@ -6,7 +6,7 @@ */ #ifndef USE_HOSTCC -#include <cyclic.h> +#include <u-boot/schedule.h> #endif /* USE_HOSTCC */ #include <string.h> #include <u-boot/sha256.h> diff --git a/lib/sha512.c b/lib/sha512.c index ffe2c5cd964..ea555ff33eb 100644 --- a/lib/sha512.c +++ b/lib/sha512.c @@ -11,7 +11,7 @@ */ #ifndef USE_HOSTCC -#include <cyclic.h> +#include <u-boot/schedule.h> #endif /* USE_HOSTCC */ #include <compiler.h> #include <u-boot/sha512.h> diff --git a/test/dm/wdt.c b/test/dm/wdt.c index 541bcba1b53..bef29591d5a 100644 --- a/test/dm/wdt.c +++ b/test/dm/wdt.c @@ -3,7 +3,6 @@ * Copyright 2017 Google, Inc */ -#include <cyclic.h> #include <dm.h> #include <time.h> #include <wdt.h> @@ -14,6 +13,7 @@ #include <test/test.h> #include <test/ut.h> #include <linux/delay.h> +#include <u-boot/schedule.h> #include <watchdog.h> /* Test that watchdog driver functions are called */ @@ -71,7 +71,7 @@ static int dm_test_wdt_gpio_toggle(struct unit_test_state *uts) ut_assertok(wdt_reset(wdt)); ut_asserteq(val, sandbox_gpio_get_value(gpio, offset)); - ut_asserteq(-ENOSYS, wdt_stop(wdt)); + ut_asserteq(-EOPNOTSUPP, wdt_stop(wdt)); return 0; } @@ -103,7 +103,7 @@ static int dm_test_wdt_gpio_level(struct unit_test_state *uts) ut_assertok(wdt_reset(wdt)); ut_asserteq(val, sandbox_gpio_get_value(gpio, offset)); - ut_asserteq(-ENOSYS, wdt_stop(wdt)); + ut_asserteq(-EOPNOTSUPP, wdt_stop(wdt)); return 0; } @@ -131,7 +131,7 @@ static int dm_test_wdt_watchdog_reset(struct unit_test_state *uts) /* Neither device should be "started", so watchdog_reset() should be a no-op. */ reset_count = state->wdt.reset_count; val = sandbox_gpio_get_value(gpio, offset); - cyclic_run(); + schedule(); ut_asserteq(reset_count, state->wdt.reset_count); ut_asserteq(val, sandbox_gpio_get_value(gpio, offset)); @@ -141,19 +141,19 @@ static int dm_test_wdt_watchdog_reset(struct unit_test_state *uts) /* Make sure both devices have just been pinged. */ timer_test_add_offset(100); - cyclic_run(); + schedule(); reset_count = state->wdt.reset_count; val = sandbox_gpio_get_value(gpio, offset); /* The gpio watchdog should be pinged, the sandbox one not. */ timer_test_add_offset(30); - cyclic_run(); + schedule(); ut_asserteq(reset_count, state->wdt.reset_count); ut_asserteq(!val, sandbox_gpio_get_value(gpio, offset)); /* After another ~30ms, both devices should get pinged. */ timer_test_add_offset(30); - cyclic_run(); + schedule(); ut_asserteq(reset_count + 1, state->wdt.reset_count); ut_asserteq(val, sandbox_gpio_get_value(gpio, offset)); |