/*
 * Copyright (c) 2018, Nordic Semiconductor ASA
 *
 * 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>

#define LOG_LEVEL CONFIG_WDT_LOG_LEVEL
#include <zephyr/logging/log.h>
#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 {
	nrfx_wdt_t wdt;
};

static int wdt_nrf_setup(const struct device *dev, uint8_t options)
{
	const struct wdt_nrfx_config *config = dev->config;
	struct wdt_nrfx_data *data = dev->data;
	nrfx_err_t err_code;

	nrfx_wdt_config_t wdt_config = {
		.reload_value = data->m_timeout
	};

#if NRF_WDT_HAS_STOP
	wdt_config.behaviour |= NRF_WDT_BEHAVIOUR_STOP_ENABLE_MASK;
#endif

	if (!(options & WDT_OPT_PAUSE_IN_SLEEP)) {
		wdt_config.behaviour |= NRF_WDT_BEHAVIOUR_RUN_SLEEP_MASK;
	}

	if (!(options & WDT_OPT_PAUSE_HALTED_BY_DBG)) {
		wdt_config.behaviour |= NRF_WDT_BEHAVIOUR_RUN_HALT_MASK;
	}

	err_code = nrfx_wdt_reconfigure(&config->wdt, &wdt_config);

	if (err_code != NRFX_SUCCESS) {
		return -EBUSY;
	}

	nrfx_wdt_enable(&config->wdt);

	data->enabled = true;
	return 0;
}

static int wdt_nrf_disable(const struct device *dev)
{
#if NRFX_WDT_HAS_STOP
	const struct wdt_nrfx_config *config = dev->config;
	struct wdt_nrfx_data *data = dev->data;
	nrfx_err_t err_code;
	int channel_id;

	err_code = nrfx_wdt_stop(&config->wdt);

	if (err_code != NRFX_SUCCESS) {
		/* This can only happen if wdt_nrf_setup() is not called first. */
		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++) {
		data->m_callbacks[channel_id] = NULL;
	}
	data->m_allocated_channels = 0;
	data->enabled = false;

	return 0;
#else
	ARG_UNUSED(dev);
	return -EPERM;
#endif
}

static int wdt_nrf_install_timeout(const struct device *dev,
				   const struct wdt_timeout_cfg *cfg)
{
	const struct wdt_nrfx_config *config = dev->config;
	struct wdt_nrfx_data *data = dev->data;
	nrfx_err_t err_code;
	nrfx_wdt_channel_id channel_id;

	if (data->enabled) {
		return -EBUSY;
	}

	if (cfg->flags != WDT_FLAG_RESET_SOC) {
		return -ENOTSUP;
	}

	if (cfg->window.min != 0U) {
		return -EINVAL;
	}

	if (data->m_allocated_channels == 0U) {
		/* According to relevant Product Specifications, watchdogs
		 * in all nRF chips can use reload values (determining
		 * the timeout) from range 0xF-0xFFFFFFFF given in 32768 Hz
		 * clock ticks. This makes the allowed range of 0x1-0x07CFFFFF
		 * in milliseconds. Check if the provided value is within
		 * this range.
		 */
		if ((cfg->window.max == 0U) || (cfg->window.max > 0x07CFFFFF)) {
			return -EINVAL;
		}

		/* Save timeout value from first registered watchdog channel. */
		data->m_timeout = cfg->window.max;
	} else if (cfg->window.max != data->m_timeout) {
		return -EINVAL;
	}

	err_code = nrfx_wdt_channel_alloc(&config->wdt,
					  &channel_id);

	if (err_code == NRFX_ERROR_NO_MEM) {
		return -ENOMEM;
	}

	if (cfg->callback != NULL) {
		data->m_callbacks[channel_id] = cfg->callback;
	}

	data->m_allocated_channels++;
	return channel_id;
}

static int wdt_nrf_feed(const struct device *dev, int channel_id)
{
	const struct wdt_nrfx_config *config = dev->config;
	struct wdt_nrfx_data *data = dev->data;

	if ((channel_id >= data->m_allocated_channels) || (channel_id < 0)) {
		return -EINVAL;
	}
	if (!data->enabled) {
		/* Watchdog is not running so does not need to be fed */
		return -EAGAIN;
	}

	nrfx_wdt_channel_feed(&config->wdt,
			      (nrfx_wdt_channel_id)channel_id);

	return 0;
}

static DEVICE_API(wdt, wdt_nrfx_driver_api) = {
	.setup = wdt_nrf_setup,
	.disable = wdt_nrf_disable,
	.install_timeout = wdt_nrf_install_timeout,
	.feed = wdt_nrf_feed,
};

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;

	while (requests) {
		uint8_t i = u32_count_trailing_zeros(requests);

		if (data->m_callbacks[i]) {
			data->m_callbacks[i](dev, i);
		}
		requests &= ~BIT(i);
	}
}

#define WDT(idx) DT_NODELABEL(wdt##idx)

#define WDT_NRFX_WDT_IRQ(idx)						       \
	COND_CODE_1(CONFIG_WDT_NRFX_NO_IRQ,				       \
		(),							       \
		(IRQ_CONNECT(DT_IRQN(WDT(idx)), DT_IRQ(WDT(idx), priority),    \
			     nrfx_isr, nrfx_wdt_##idx##_irq_handler, 0)))

#define WDT_NRFX_WDT_DEVICE(idx)					       \
	static void wdt_##idx##_event_handler(nrf_wdt_event_t event_type,      \
					      uint32_t requests,	       \
					      void *p_context)		       \
	{								       \
		wdt_event_handler(DEVICE_DT_GET(WDT(idx)), event_type,	       \
				  requests, p_context);			       \
	}								       \
	static int wdt_##idx##_init(const struct device *dev)		       \
	{								       \
		const struct wdt_nrfx_config *config = dev->config;	       \
		nrfx_err_t err_code;					       \
		WDT_NRFX_WDT_IRQ(idx);					       \
		err_code = nrfx_wdt_init(&config->wdt,			       \
					 NULL,				       \
					 IS_ENABLED(CONFIG_WDT_NRFX_NO_IRQ)    \
						 ? NULL			       \
						 : wdt_##idx##_event_handler,  \
					 NULL);				       \
		if (err_code != NRFX_SUCCESS) {				       \
			return -EBUSY;					       \
		}							       \
		return 0;						       \
	}								       \
	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),				       \
	};								       \
	DEVICE_DT_DEFINE(WDT(idx),					       \
			    wdt_##idx##_init,				       \
			    NULL,					       \
			    &wdt_##idx##_data,				       \
			    &wdt_##idx##z_config,			       \
			    PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,  \
			    &wdt_nrfx_driver_api)

#ifdef CONFIG_HAS_HW_NRF_WDT0
WDT_NRFX_WDT_DEVICE(0);
#endif

#ifdef CONFIG_HAS_HW_NRF_WDT1
WDT_NRFX_WDT_DEVICE(1);
#endif

#ifdef CONFIG_HAS_HW_NRF_WDT30
WDT_NRFX_WDT_DEVICE(30);
#endif

#ifdef CONFIG_HAS_HW_NRF_WDT31
WDT_NRFX_WDT_DEVICE(31);
#endif

#ifdef CONFIG_HAS_HW_NRF_WDT010
WDT_NRFX_WDT_DEVICE(010);
#endif

#ifdef CONFIG_HAS_HW_NRF_WDT011
WDT_NRFX_WDT_DEVICE(011);
#endif

#ifdef CONFIG_HAS_HW_NRF_WDT130
WDT_NRFX_WDT_DEVICE(130);
#endif

#ifdef CONFIG_HAS_HW_NRF_WDT131
WDT_NRFX_WDT_DEVICE(131);
#endif

#ifdef CONFIG_HAS_HW_NRF_WDT132
WDT_NRFX_WDT_DEVICE(132);
#endif
