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