Browse Source

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 <michal.stasiak@nordicsemi.no>
pull/83944/head
Michał Stasiak 6 months ago committed by Benjamin Cabé
parent
commit
b578ffa49a
  1. 28
      drivers/watchdog/wdt_nrfx.c

28
drivers/watchdog/wdt_nrfx.c

@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <zephyr/sys/math_extras.h>
#include <nrfx_wdt.h>
#include <zephyr/drivers/watchdog.h>
@ -13,11 +14,18 @@ @@ -13,11 +14,18 @@
#include <zephyr/irq.h>
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) @@ -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 DEVICE_API(wdt, wdt_nrfx_driver_api) = { @@ -170,11 +182,17 @@ static DEVICE_API(wdt, 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 @@ -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), \
}; \

Loading…
Cancel
Save