diff options
author | maxims@google.com <maxims@google.com> | 2017-04-17 12:00:21 -0700 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2017-05-08 11:57:30 -0400 |
commit | 0753bc2d30d7ca4a0ea4ef7f97083961c3a9d0e0 (patch) | |
tree | ddeb5811ed8c1e75572e109c989f0ce593c8b385 /drivers/watchdog | |
parent | 17c5fb195376f5883b7f0fdfbf19e42e3be7de43 (diff) | |
download | u-boot-0753bc2d30d7ca4a0ea4ef7f97083961c3a9d0e0.tar.gz |
dm: Simple Watchdog uclass
This is a simple uclass for Watchdog Timers. It has four operations:
start, restart, reset, stop. Drivers must implement start, restart and
stop operations, while implementing reset is optional: It's default
implementation expires watchdog timer in one clock tick.
Signed-off-by: Maxim Sloyko <maxims@google.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'drivers/watchdog')
-rw-r--r-- | drivers/watchdog/Kconfig | 20 | ||||
-rw-r--r-- | drivers/watchdog/Makefile | 2 | ||||
-rw-r--r-- | drivers/watchdog/sandbox_wdt.c | 76 | ||||
-rw-r--r-- | drivers/watchdog/wdt-uclass.c | 72 |
4 files changed, 169 insertions, 1 deletions
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index dbdaafc149..e8d2dba835 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -1,8 +1,26 @@ -menu "WATCHDOG support" +menu "Watchdog Timer Support" config ULP_WATCHDOG bool "i.MX7ULP watchdog" help Say Y here to enable i.MX7ULP watchdog driver. +config WDT + bool "Enable driver model for watchdog timer drivers" + depends on DM + help + Enable driver model for watchdog timer. At the moment the API + is very simple and only supports four operations: + start, restart, stop and reset (expire immediately). + What exactly happens when the timer expires is up to a particular + device/driver. + +config WDT_SANDBOX + bool "Enable Watchdog Timer support for Sandbox" + depends on SANDBOX && WDT + help + Enable Watchdog Timer support in Sandbox. This is a dummy device that + can be probed and supports all of the methods of WDT, but does not + really do anything. + endmenu diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 36745ca9c9..e891d64849 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -15,3 +15,5 @@ obj-$(CONFIG_XILINX_TB_WATCHDOG) += xilinx_tb_wdt.o obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o obj-$(CONFIG_DESIGNWARE_WATCHDOG) += designware_wdt.o obj-$(CONFIG_ULP_WATCHDOG) += ulp_wdog.o +obj-$(CONFIG_WDT) += wdt-uclass.o +obj-$(CONFIG_WDT_SANDBOX) += sandbox_wdt.o diff --git a/drivers/watchdog/sandbox_wdt.c b/drivers/watchdog/sandbox_wdt.c new file mode 100644 index 0000000000..34d90bee7e --- /dev/null +++ b/drivers/watchdog/sandbox_wdt.c @@ -0,0 +1,76 @@ +/* + * Copyright 2017 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <asm/state.h> +#include <wdt.h> + +DECLARE_GLOBAL_DATA_PTR; + +static int sandbox_wdt_start(struct udevice *dev, u64 timeout, ulong flags) +{ + struct sandbox_state *state = state_get_current(); + + state->wdt.counter = timeout; + state->wdt.running = true; + + return 0; +} + +static int sandbox_wdt_stop(struct udevice *dev) +{ + struct sandbox_state *state = state_get_current(); + + state->wdt.running = false; + + return 0; +} + +static int sandbox_wdt_reset(struct udevice *dev) +{ + struct sandbox_state *state = state_get_current(); + + state->wdt.reset_count++; + + return 0; +} + +static int sandbox_wdt_expire_now(struct udevice *dev, ulong flags) +{ + sandbox_wdt_start(dev, 1, flags); + + return 0; +} + +static int sandbox_wdt_probe(struct udevice *dev) +{ + struct sandbox_state *state = state_get_current(); + + memset(&state->wdt, 0, sizeof(state->wdt)); + + return 0; +} + +static const struct wdt_ops sandbox_wdt_ops = { + .start = sandbox_wdt_start, + .reset = sandbox_wdt_reset, + .stop = sandbox_wdt_stop, + .expire_now = sandbox_wdt_expire_now, +}; + +static const struct udevice_id sandbox_wdt_ids[] = { + { .compatible = "sandbox,wdt" }, + {} +}; + +U_BOOT_DRIVER(wdt_sandbox) = { + .name = "wdt_sandbox", + .id = UCLASS_WDT, + .of_match = sandbox_wdt_ids, + .ops = &sandbox_wdt_ops, + .probe = sandbox_wdt_probe, +}; diff --git a/drivers/watchdog/wdt-uclass.c b/drivers/watchdog/wdt-uclass.c new file mode 100644 index 0000000000..ab8a64c354 --- /dev/null +++ b/drivers/watchdog/wdt-uclass.c @@ -0,0 +1,72 @@ +/* + * Copyright 2017 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <wdt.h> +#include <dm/device-internal.h> +#include <dm/lists.h> + +DECLARE_GLOBAL_DATA_PTR; + +int wdt_start(struct udevice *dev, u64 timeout, ulong flags) +{ + const struct wdt_ops *ops = device_get_ops(dev); + + if (!ops->start) + return -ENOSYS; + + return ops->start(dev, timeout, flags); +} + +int wdt_stop(struct udevice *dev) +{ + const struct wdt_ops *ops = device_get_ops(dev); + + if (!ops->stop) + return -ENOSYS; + + return ops->stop(dev); +} + +int wdt_reset(struct udevice *dev) +{ + const struct wdt_ops *ops = device_get_ops(dev); + + if (!ops->reset) + return -ENOSYS; + + return ops->reset(dev); +} + +int wdt_expire_now(struct udevice *dev, ulong flags) +{ + int ret = 0; + const struct wdt_ops *ops; + + debug("WDT Resettting: %lu\n", flags); + ops = device_get_ops(dev); + if (ops->expire_now) { + return ops->expire_now(dev, flags); + } else { + if (!ops->start) + return -ENOSYS; + + ret = ops->start(dev, 1, flags); + if (ret < 0) + return ret; + + hang(); + } + + return ret; +} + +UCLASS_DRIVER(wdt) = { + .id = UCLASS_WDT, + .name = "wdt", +}; |