99#include <zephyr/drivers/watchdog.h>
1010#include <zephyr/kernel.h>
1111#include <stdint.h>
12+ #include <zephyr/irq.h>
1213
1314#define WDENABLE_KEY 0xa98559da
1415#define WDDISABLE_KEY 0x5312aced
@@ -59,28 +60,28 @@ struct wdt_ti_rti_regs {
5960
6061struct wdt_ti_rti_data {
6162 DEVICE_MMIO_RAM ;
63+ wdt_callback_t callback ;
6264};
6365
6466struct wdt_ti_rti_config {
6567 DEVICE_MMIO_ROM ;
66-
6768 uint64_t freq ;
69+ void (* irq_config_func )(void );
6870};
6971
7072static int wdt_ti_rti_setup (const struct device * dev , uint8_t options )
7173{
7274 ARG_UNUSED (options );
73-
7475 struct wdt_ti_rti_regs * regs = DEV_REGS (dev );
7576
7677 if (options & WDT_OPT_PAUSE_HALTED_BY_DBG ) {
7778 regs -> GCTRL = RTIGCTRL_HALT_BY_DBG ;
7879 } else {
7980 regs -> GCTRL = RTIGCTRL_RUN_BY_DBG ;
8081 }
81-
82+ /* Clear the Watchdog status register before enabling */
83+ regs -> WDSTATUS = 0x3f ;
8284 regs -> DWDCTRL = WDENABLE_KEY ;
83-
8485 return 0 ;
8586}
8687
@@ -112,17 +113,21 @@ static int wdt_ti_rti_window_size(const struct wdt_window window)
112113 break ;
113114 }
114115 }
115-
116116 return - EINVAL ;
117117}
118118
119119static int wdt_ti_rti_timeout (const struct device * dev , const struct wdt_timeout_cfg * cfg )
120120{
121121 const struct wdt_ti_rti_config * config = DEV_CFG (dev );
122+ struct wdt_ti_rti_data * data = DEV_DATA (dev );
122123 struct wdt_ti_rti_regs * regs = DEV_REGS (dev );
123124 uint32_t timer_margin ;
124125 int window_size ;
125126
127+ if (cfg -> callback != NULL ) {
128+ data -> callback = cfg -> callback ;
129+ }
130+
126131 window_size = wdt_ti_rti_window_size (cfg -> window );
127132 if (window_size < 0 ) {
128133 return window_size ;
@@ -134,6 +139,7 @@ static int wdt_ti_rti_timeout(const struct device *dev, const struct wdt_timeout
134139 return - EINVAL ;
135140 }
136141
142+ /* Only NMI is supported */
137143 if (cfg -> flags == WDT_FLAG_RESET_SOC ) {
138144 regs -> WWDRXNCTRL = RTIWWDRX_NMI ;
139145 }
@@ -151,24 +157,36 @@ static int wdt_ti_rti_feed(const struct device *dev, int channel_id)
151157 if (channel_id != 0 ) {
152158 return - EINVAL ;
153159 }
154-
155160 regs -> WDKEY = WDKEY_SEQ0 ;
156161 regs -> WDKEY = WDKEY_SEQ1 ;
157-
158162 return 0 ;
159163}
160164
165+ static void wdt_ti_rti_isr (const struct device * dev )
166+ {
167+ struct wdt_ti_rti_data * data = DEV_DATA (dev );
168+ struct wdt_ti_rti_regs * regs = DEV_REGS (dev );
169+ volatile uint32_t status = regs -> WDSTATUS ;
170+ /* Clear status register before servicing the wathdog */
171+ regs -> WDSTATUS = 0x3f ;
172+ if (status & BIT (5 ) && data -> callback ) {
173+ data -> callback (dev , 0 );
174+ }
175+ regs -> WDKEY = WDKEY_SEQ0 ;
176+ regs -> WDKEY = WDKEY_SEQ1 ;
177+ }
178+
161179static int wdt_ti_rti_init (const struct device * dev )
162180{
181+ const struct wdt_ti_rti_config * config = DEV_CFG (dev );
163182 struct wdt_ti_rti_regs * regs ;
164183
165184 DEVICE_MMIO_MAP (dev , K_MEM_CACHE_NONE );
166-
167185 regs = DEV_REGS (dev );
168186 if (!regs ) {
169187 return - EINVAL ;
170188 }
171-
189+ config -> irq_config_func ();
172190 return 0 ;
173191}
174192
@@ -180,11 +198,18 @@ static DEVICE_API(wdt, wdt_ti_rti_api) = {
180198};
181199
182200#define WDT_TI_RTI_INIT (i ) \
201+ static void wdt_ti_rti_irq_config_##i(void) \
202+ { \
203+ IRQ_CONNECT(DT_INST_IRQN(i), DT_INST_IRQ(i, priority), wdt_ti_rti_isr, \
204+ DEVICE_DT_INST_GET(i), 0); \
205+ irq_enable(DT_INST_IRQN(i)); \
206+ }; \
183207 static struct wdt_ti_rti_data wdt_ti_rti_data_##i = {}; \
184208 \
185209 static struct wdt_ti_rti_config wdt_ti_rti_config_##i = { \
186210 DEVICE_MMIO_ROM_INIT(DT_DRV_INST(i)), \
187211 .freq = DT_INST_PROP(i, clock_frequency), \
212+ .irq_config_func = wdt_ti_rti_irq_config_##i, \
188213 }; \
189214 \
190215 DEVICE_DT_INST_DEFINE(i, wdt_ti_rti_init, NULL, &wdt_ti_rti_data_##i, \
0 commit comments