From dc3a32e13626c28c53fb79492f53850c87283227 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Stasiak?= Date: Fri, 10 Jan 2025 08:12:44 +0100 Subject: [PATCH] [nrf fromtree] drivers: watchdog: nrfx: add synchronization after stop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 (cherry picked from commit b578ffa49a13f58288e44af5f44a11a3f44b3d00) --- drivers/watchdog/wdt_nrfx.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/drivers/watchdog/wdt_nrfx.c b/drivers/watchdog/wdt_nrfx.c index 277d195f681..62f7104bafa 100644 --- a/drivers/watchdog/wdt_nrfx.c +++ b/drivers/watchdog/wdt_nrfx.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include #include #include @@ -13,11 +14,18 @@ #include LOG_MODULE_REGISTER(wdt_nrfx); +#if !CONFIG_WDT_NRFX_NO_IRQ && NRF_WDT_HAS_STOP +#define WDT_NRFX_SYNC_STOP 1 +#endif + struct wdt_nrfx_data { wdt_callback_t m_callbacks[NRF_WDT_CHANNEL_NUMBER]; uint32_t m_timeout; uint8_t m_allocated_channels; bool enabled; +#if defined(WDT_NRFX_SYNC_STOP) + struct k_sem sync_stop; +#endif }; struct wdt_nrfx_config { @@ -73,6 +81,10 @@ static int wdt_nrf_disable(const struct device *dev) return -EFAULT; } +#if defined(WDT_NRFX_SYNC_STOP) + k_sem_take(&data->sync_stop, K_FOREVER); +#endif + nrfx_wdt_channels_free(&config->wdt); 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 = { static void wdt_event_handler(const struct device *dev, nrf_wdt_event_t event_type, uint32_t requests, void *p_context) { + struct wdt_nrfx_data *data = dev->data; + +#if defined(WDT_NRFX_SYNC_STOP) + if (event_type == NRF_WDT_EVENT_STOPPED) { + k_sem_give(&data->sync_stop); + } +#else (void)event_type; +#endif (void)p_context; - struct wdt_nrfx_data *data = dev->data; - while (requests) { uint8_t i = u32_count_trailing_zeros(requests); @@ -217,7 +235,11 @@ static void wdt_event_handler(const struct device *dev, nrf_wdt_event_t event_ty } \ return 0; \ } \ - static struct wdt_nrfx_data wdt_##idx##_data; \ + static struct wdt_nrfx_data wdt_##idx##_data = { \ + IF_ENABLED(WDT_NRFX_SYNC_STOP, \ + (.sync_stop = Z_SEM_INITIALIZER( \ + wdt_##idx##_data.sync_stop, 0, 1),)) \ + }; \ static const struct wdt_nrfx_config wdt_##idx##z_config = { \ .wdt = NRFX_WDT_INSTANCE(idx), \ }; \