Merge https://source.denx.de/u-boot/custodians/u-boot-samsung
[platform/kernel/u-boot.git] / drivers / watchdog / gpio_wdt.c
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
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
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
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 };