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