1#include <dm.h>
2#include <os.h>
3#include <wdt.h>
4
5struct alarm_wdt_priv {
6	unsigned int timeout_sec;
7};
8
9static void alarm_handler(int sig)
10{
11	const char *msg = "!!! ALARM !!!\n";
12
13	os_write(2, msg, strlen(msg));
14	os_fd_restore();
15	os_set_alarm_handler(NULL);
16	os_raise_sigalrm();
17}
18
19static int alarm_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
20{
21	struct alarm_wdt_priv *priv = dev_get_priv(dev);
22	unsigned int sec;
23
24	timeout = DIV_ROUND_UP(timeout, 1000);
25	sec = min_t(u64, UINT_MAX, timeout);
26	priv->timeout_sec = sec;
27
28	os_alarm(0);
29	os_set_alarm_handler(alarm_handler);
30	os_alarm(sec);
31
32	return 0;
33}
34
35static int alarm_wdt_stop(struct udevice *dev)
36{
37	os_alarm(0);
38	os_set_alarm_handler(NULL);
39
40	return 0;
41}
42
43static int alarm_wdt_reset(struct udevice *dev)
44{
45	struct alarm_wdt_priv *priv = dev_get_priv(dev);
46
47	os_alarm(priv->timeout_sec);
48
49	return 0;
50}
51
52static int alarm_wdt_expire_now(struct udevice *dev, ulong flags)
53{
54	alarm_handler(0);
55
56	return 0;
57}
58
59
60static const struct wdt_ops alarm_wdt_ops = {
61	.start = alarm_wdt_start,
62	.reset = alarm_wdt_reset,
63	.stop = alarm_wdt_stop,
64	.expire_now = alarm_wdt_expire_now,
65};
66
67static const struct udevice_id alarm_wdt_ids[] = {
68	{ .compatible = "sandbox,alarm-wdt" },
69	{}
70};
71
72U_BOOT_DRIVER(alarm_wdt_sandbox) = {
73	.name = "alarm_wdt_sandbox",
74	.id = UCLASS_WDT,
75	.of_match = alarm_wdt_ids,
76	.ops = &alarm_wdt_ops,
77	.priv_auto = sizeof(struct alarm_wdt_priv),
78};
79