1 // SPDX-License-Identifier: GPL-2.0+
2
3 #include <dm.h>
4 #include <dm/device_compat.h>
5 #include <wdt.h>
6 #include <asm/gpio.h>
7
8 struct gpio_wdt_priv {
9 struct gpio_desc gpio;
10 bool always_running;
11 int state;
12 };
13
gpio_wdt_reset(struct udevice * dev)14 static int gpio_wdt_reset(struct udevice *dev)
15 {
16 struct gpio_wdt_priv *priv = dev_get_priv(dev);
17
18 priv->state = !priv->state;
19
20 return dm_gpio_set_value(&priv->gpio, priv->state);
21 }
22
gpio_wdt_start(struct udevice * dev,u64 timeout,ulong flags)23 static int gpio_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
24 {
25 struct gpio_wdt_priv *priv = dev_get_priv(dev);
26
27 if (priv->always_running)
28 return 0;
29
30 return -ENOSYS;
31 }
32
dm_probe(struct udevice * dev)33 static int dm_probe(struct udevice *dev)
34 {
35 struct gpio_wdt_priv *priv = dev_get_priv(dev);
36 int ret;
37
38 priv->always_running = dev_read_bool(dev, "always-running");
39 ret = gpio_request_by_name(dev, "gpios", 0, &priv->gpio, GPIOD_IS_OUT);
40 if (ret < 0) {
41 dev_err(dev, "Request for wdt gpio failed: %d\n", ret);
42 return ret;
43 }
44
45 if (priv->always_running)
46 ret = gpio_wdt_reset(dev);
47
48 return ret;
49 }
50
51 static const struct wdt_ops gpio_wdt_ops = {
52 .start = gpio_wdt_start,
53 .reset = gpio_wdt_reset,
54 };
55
56 static const struct udevice_id gpio_wdt_ids[] = {
57 { .compatible = "linux,wdt-gpio" },
58 {}
59 };
60
61 U_BOOT_DRIVER(wdt_gpio) = {
62 .name = "wdt_gpio",
63 .id = UCLASS_WDT,
64 .of_match = gpio_wdt_ids,
65 .ops = &gpio_wdt_ops,
66 .probe = dm_probe,
67 .priv_auto = sizeof(struct gpio_wdt_priv),
68 };
69