Skip to content

Commit dc3a32e

Browse files
mstasiaknordicnordicjm
authored andcommitted
[nrf fromtree] drivers: watchdog: nrfx: add synchronization after stop
In order to ensure that watchdog channels are freed in proper driver state, synchronization in form of simple loop needs to be added after stopping. In no irq variant, it is already done on nrfx level. NRFY function can be replaced by NRFX one in the future. Signed-off-by: Michał Stasiak <[email protected]> (cherry picked from commit b578ffa)
1 parent 5f2a1de commit dc3a32e

File tree

1 file changed

+25
-3
lines changed

1 file changed

+25
-3
lines changed

drivers/watchdog/wdt_nrfx.c

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7+
#include <zephyr/kernel.h>
78
#include <zephyr/sys/math_extras.h>
89
#include <nrfx_wdt.h>
910
#include <zephyr/drivers/watchdog.h>
@@ -13,11 +14,18 @@
1314
#include <zephyr/irq.h>
1415
LOG_MODULE_REGISTER(wdt_nrfx);
1516

17+
#if !CONFIG_WDT_NRFX_NO_IRQ && NRF_WDT_HAS_STOP
18+
#define WDT_NRFX_SYNC_STOP 1
19+
#endif
20+
1621
struct wdt_nrfx_data {
1722
wdt_callback_t m_callbacks[NRF_WDT_CHANNEL_NUMBER];
1823
uint32_t m_timeout;
1924
uint8_t m_allocated_channels;
2025
bool enabled;
26+
#if defined(WDT_NRFX_SYNC_STOP)
27+
struct k_sem sync_stop;
28+
#endif
2129
};
2230

2331
struct wdt_nrfx_config {
@@ -73,6 +81,10 @@ static int wdt_nrf_disable(const struct device *dev)
7381
return -EFAULT;
7482
}
7583

84+
#if defined(WDT_NRFX_SYNC_STOP)
85+
k_sem_take(&data->sync_stop, K_FOREVER);
86+
#endif
87+
7688
nrfx_wdt_channels_free(&config->wdt);
7789

7890
for (channel_id = 0; channel_id < data->m_allocated_channels; channel_id++) {
@@ -170,11 +182,17 @@ static const struct wdt_driver_api wdt_nrfx_driver_api = {
170182
static void wdt_event_handler(const struct device *dev, nrf_wdt_event_t event_type,
171183
uint32_t requests, void *p_context)
172184
{
185+
struct wdt_nrfx_data *data = dev->data;
186+
187+
#if defined(WDT_NRFX_SYNC_STOP)
188+
if (event_type == NRF_WDT_EVENT_STOPPED) {
189+
k_sem_give(&data->sync_stop);
190+
}
191+
#else
173192
(void)event_type;
193+
#endif
174194
(void)p_context;
175195

176-
struct wdt_nrfx_data *data = dev->data;
177-
178196
while (requests) {
179197
uint8_t i = u32_count_trailing_zeros(requests);
180198

@@ -217,7 +235,11 @@ static void wdt_event_handler(const struct device *dev, nrf_wdt_event_t event_ty
217235
} \
218236
return 0; \
219237
} \
220-
static struct wdt_nrfx_data wdt_##idx##_data; \
238+
static struct wdt_nrfx_data wdt_##idx##_data = { \
239+
IF_ENABLED(WDT_NRFX_SYNC_STOP, \
240+
(.sync_stop = Z_SEM_INITIALIZER( \
241+
wdt_##idx##_data.sync_stop, 0, 1),)) \
242+
}; \
221243
static const struct wdt_nrfx_config wdt_##idx##z_config = { \
222244
.wdt = NRFX_WDT_INSTANCE(idx), \
223245
}; \

0 commit comments

Comments
 (0)