[U-Boot] [PATCH 1/4 v5] watchdog: Implement generic watchdog_reset() version
Simon Goldschmidt
simon.k.r.goldschmidt at gmail.com
Tue Aug 13 20:16:44 UTC 2019
Hi Stefan,
Am 25.04.2019 um 09:17 schrieb Stefan Roese:
> This patch tries to implement a generic watchdog_reset() function that
> can be used by all boards that want to service the watchdog device in
> U-Boot. This watchdog servicing is enabled via CONFIG_WATCHDOG.
>
> Without this approach, new boards or platforms needed to implement a
> board specific version of this functionality, mostly copy'ing the same
> code over and over again into their board or platforms code base.
>
> With this new generic function, the scattered other functions are now
> removed to be replaced by the generic one. The new version also enables
> the configuration of the watchdog timeout via the DT "timeout-sec"
> property (if enabled via CONFIG_OF_CONTROL).
>
> This patch also adds a new flag to the GD flags, to flag that the
> watchdog is ready to use and adds the pointer to the watchdog device
> to the GD. This enables us to remove the global "watchdog_dev"
> variable, which was prone to cause problems because of its potentially
> very early use in watchdog_reset(), even before the BSS is cleared.
>
> Signed-off-by: Stefan Roese <sr at denx.de>
<snip>
> --- a/include/asm-generic/global_data.h
> +++ b/include/asm-generic/global_data.h
> @@ -133,6 +133,9 @@ typedef struct global_data {
> struct spl_handoff *spl_handoff;
> # endif
> #endif
> +#if defined(CONFIG_WDT)
> + struct udevice *watchdog_dev;
> +#endif
> } gd_t;
> #endif
>
> @@ -161,5 +164,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 */
Sorry to warm up a thread that is more than 4 months old, but I just
stumbled accross this line when searching for space in 'gd':
The comment some lines above in global_data.h clearly states that the
top 16 bits of flags are reserved for arch-specific flags, and your
patch here uses the lowest of these 16 arch-specific flags for generic code.
Is this a problem? Does any arch code use the upper 16 bits? I would
have thought you'd at least need to adjust the comment to reflect your
new usage...
The reason I ask is that I'd need a place to put some (~5?)
'is_initialized' bits for some code running in SPL in the 'board_init_f'
code where BSS shouldn't be used. gd->flags would be ideal for that, but
I'm hesistant to dive in further into the 'arch-specific' upper 16 bits...
Regards,
Simon
>
> #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_ */
>
More information about the U-Boot
mailing list