1 /*
2 * Copyright (c) 2017 Nordic Semiconductor ASA
3 * Copyright (c) 2015 Intel Corporation
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 /**
9 * @file
10 * @brief Public API for watchdog drivers.
11 */
12
13 #ifndef ZEPHYR_INCLUDE_DRIVERS_WATCHDOG_H_
14 #define ZEPHYR_INCLUDE_DRIVERS_WATCHDOG_H_
15
16 /**
17 * @brief Watchdog Interface
18 * @defgroup watchdog_interface Watchdog Interface
19 * @ingroup io_interfaces
20 * @{
21 */
22
23 #include <zephyr/types.h>
24 #include <sys/util.h>
25 #include <device.h>
26
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30
31 /**
32 * @brief Pause watchdog timer when CPU is in sleep state.
33 */
34 #define WDT_OPT_PAUSE_IN_SLEEP BIT(0)
35
36 /**
37 * @brief Pause watchdog timer when CPU is halted by the debugger.
38 */
39 #define WDT_OPT_PAUSE_HALTED_BY_DBG BIT(1)
40
41 /**
42 * @brief Watchdog reset flag bit field mask shift.
43 */
44 #define WDT_FLAG_RESET_SHIFT (0)
45 /**
46 * @brief Watchdog reset flag bit field mask.
47 */
48 #define WDT_FLAG_RESET_MASK (0x3 << WDT_FLAG_RESET_SHIFT)
49
50 /**
51 * @name Watchdog Reset Behavior.
52 * Reset behavior after timeout.
53 * @{
54 */
55 /** No reset */
56 #define WDT_FLAG_RESET_NONE (0 << WDT_FLAG_RESET_SHIFT)
57 /** CPU core reset */
58 #define WDT_FLAG_RESET_CPU_CORE (1 << WDT_FLAG_RESET_SHIFT)
59 /** Global SoC reset */
60 #define WDT_FLAG_RESET_SOC (2 << WDT_FLAG_RESET_SHIFT)
61 /**
62 * @}
63 */
64
65 /**
66 * @brief Watchdog timeout window.
67 *
68 * Each installed timeout needs feeding within the specified time window,
69 * otherwise the watchdog will trigger. If the watchdog instance does not
70 * support window timeouts then min value must be equal to 0.
71 *
72 * @param min Lower limit of watchdog feed timeout in milliseconds.
73 * @param max Upper limit of watchdog feed timeout in milliseconds.
74 *
75 * @note If specified values can not be precisely set they are always
76 * rounded up.
77 */
78 struct wdt_window {
79 uint32_t min;
80 uint32_t max;
81 };
82
83 /** Watchdog callback. */
84 typedef void (*wdt_callback_t)(const struct device *dev, int channel_id);
85
86 /**
87 * @brief Watchdog timeout configuration struct.
88 *
89 * @param window Timing parameters of watchdog timeout.
90 * @param callback Timeout callback. Passing NULL means that no callback
91 * will be run.
92 * @param next Pointer to the next timeout configuration. This pointer is used
93 * for watchdogs with staged timeouts functionality. Value must be
94 * NULL for single stage timeout.
95 * @param flags Bit field with following parts:
96 *
97 * reset [ 0 : 1 ] - perform specified reset after timeout/callback
98 */
99 struct wdt_timeout_cfg {
100 struct wdt_window window;
101 wdt_callback_t callback;
102 #ifdef CONFIG_WDT_MULTISTAGE
103 struct wdt_timeout_cfg *next;
104 #endif
105 uint8_t flags;
106 };
107
108 /**
109 * @typedef wdt_api_setup
110 * @brief Callback API for setting up watchdog instance.
111 * See wdt_setup() for argument descriptions
112 */
113 typedef int (*wdt_api_setup)(const struct device *dev, uint8_t options);
114
115 /**
116 * @typedef wdt_api_disable
117 * @brief Callback API for disabling watchdog instance.
118 * See wdt_disable() for argument descriptions
119 */
120 typedef int (*wdt_api_disable)(const struct device *dev);
121
122 /**
123 * @typedef wdt_api_install_timeout
124 * @brief Callback API for installing new timeout.
125 * See wdt_install_timeout() for argument descriptions
126 */
127 typedef int (*wdt_api_install_timeout)(const struct device *dev,
128 const struct wdt_timeout_cfg *cfg);
129
130 /**
131 * @typedef wdt_api_feed
132 * @brief Callback API for feeding specified watchdog timeout.
133 * See (wdt_feed) for argument descriptions
134 */
135 typedef int (*wdt_api_feed)(const struct device *dev, int channel_id);
136
137 /** @cond INTERNAL_HIDDEN */
138 __subsystem struct wdt_driver_api {
139 wdt_api_setup setup;
140 wdt_api_disable disable;
141 wdt_api_install_timeout install_timeout;
142 wdt_api_feed feed;
143 };
144 /**
145 * @endcond
146 */
147
148 /**
149 * @brief Set up watchdog instance.
150 *
151 * This function is used for configuring global watchdog settings that
152 * affect all timeouts. It should be called after installing timeouts.
153 * After successful return, all installed timeouts are valid and must be
154 * serviced periodically by calling wdt_feed().
155 *
156 * @param dev Pointer to the device structure for the driver instance.
157 * @param options Configuration options as defined by the WDT_OPT_* constants
158 *
159 * @retval 0 If successful.
160 * @retval -ENOTSUP If any of the set options is not supported.
161 * @retval -EBUSY If watchdog instance has been already setup.
162 */
163 __syscall int wdt_setup(const struct device *dev, uint8_t options);
164
z_impl_wdt_setup(const struct device * dev,uint8_t options)165 static inline int z_impl_wdt_setup(const struct device *dev, uint8_t options)
166 {
167 const struct wdt_driver_api *api =
168 (const struct wdt_driver_api *)dev->api;
169
170 return api->setup(dev, options);
171 }
172
173 /**
174 * @brief Disable watchdog instance.
175 *
176 * This function disables the watchdog instance and automatically uninstalls all
177 * timeouts. To set up a new watchdog, install timeouts and call wdt_setup()
178 * again. Not all watchdogs can be restarted after they are disabled.
179 *
180 * @param dev Pointer to the device structure for the driver instance.
181 *
182 * @retval 0 If successful.
183 * @retval -EFAULT If watchdog instance is not enabled.
184 * @retval -EPERM If watchdog can not be disabled directly by application code.
185 */
186 __syscall int wdt_disable(const struct device *dev);
187
z_impl_wdt_disable(const struct device * dev)188 static inline int z_impl_wdt_disable(const struct device *dev)
189 {
190 const struct wdt_driver_api *api =
191 (const struct wdt_driver_api *)dev->api;
192
193 return api->disable(dev);
194 }
195
196 /**
197 * @brief Install new timeout.
198 *
199 * This function must be used before wdt_setup(). Changes applied here
200 * have no effects until wdt_setup() is called.
201 *
202 * @param dev Pointer to the device structure for the driver instance.
203 * @param cfg Pointer to timeout configuration structure.
204 *
205 * @retval channel_id If successful, a non-negative value indicating the index
206 * of the channel to which the timeout was assigned. This
207 * value is supposed to be used as the parameter in calls to
208 * wdt_feed().
209 * @retval -EBUSY If timeout can not be installed while watchdog has already
210 * been setup.
211 * @retval -ENOMEM If no more timeouts can be installed.
212 * @retval -ENOTSUP If any of the set flags is not supported.
213 * @retval -EINVAL If any of the window timeout value is out of possible range.
214 * This value is also returned if watchdog supports only one
215 * timeout value for all timeouts and the supplied timeout
216 * window differs from windows for alarms installed so far.
217 */
wdt_install_timeout(const struct device * dev,const struct wdt_timeout_cfg * cfg)218 static inline int wdt_install_timeout(const struct device *dev,
219 const struct wdt_timeout_cfg *cfg)
220 {
221 const struct wdt_driver_api *api =
222 (const struct wdt_driver_api *) dev->api;
223
224 return api->install_timeout(dev, cfg);
225 }
226
227 /**
228 * @brief Feed specified watchdog timeout.
229 *
230 * @param dev Pointer to the device structure for the driver instance.
231 * @param channel_id Index of the fed channel.
232 *
233 * @retval 0 If successful.
234 * @retval -EAGAIN If completing the feed operation would stall the
235 * caller, for example due to an in-progress watchdog
236 * operation such as a previous @c wdt_feed().
237 * @retval -EINVAL If there is no installed timeout for supplied channel.
238 */
239 __syscall int wdt_feed(const struct device *dev, int channel_id);
240
z_impl_wdt_feed(const struct device * dev,int channel_id)241 static inline int z_impl_wdt_feed(const struct device *dev, int channel_id)
242 {
243 const struct wdt_driver_api *api =
244 (const struct wdt_driver_api *)dev->api;
245
246 return api->feed(dev, channel_id);
247 }
248
249 #ifdef __cplusplus
250 }
251 #endif
252
253 /**
254 * @}
255 */
256
257 #include <syscalls/watchdog.h>
258
259 #endif /* _ZEPHYR_WATCHDOG_H__ */
260