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