/*
 * Copyright (c) 2015 Intel Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT shared_irq

#include <errno.h>

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/shared_irq.h>
#include <zephyr/init.h>
#include <zephyr/sys/sys_io.h>

#ifdef CONFIG_IOAPIC
#include <zephyr/drivers/interrupt_controller/ioapic.h>
#endif

typedef void (*shared_irq_config_irq_t)(void);

struct shared_irq_config {
	uint32_t irq_num;
	shared_irq_config_irq_t config;
	uint32_t client_count;
};

struct shared_irq_client {
	const struct device *isr_dev;
	isr_t isr_func;
	uint32_t enabled;
};

struct shared_irq_runtime {
	struct shared_irq_client *const client;
};

/**
 *  @brief Register a device ISR
 *  @param dev Pointer to device structure for SHARED_IRQ driver instance.
 *  @param isr_func Pointer to the ISR function for the device.
 *  @param isr_dev Pointer to the device that will service the interrupt.
 */
static int isr_register(const struct device *dev, isr_t isr_func,
				 const struct device *isr_dev)
{
	struct shared_irq_runtime *clients = dev->data;
	const struct shared_irq_config *config = dev->config;
	uint32_t i;

	for (i = 0U; i < config->client_count; i++) {
		if (!clients->client[i].isr_dev) {
			clients->client[i].isr_dev = isr_dev;
			clients->client[i].isr_func = isr_func;
			return 0;
		}
	}
	return -EIO;
}

/**
 *  @brief Enable ISR for device
 *  @param dev Pointer to device structure for SHARED_IRQ driver instance.
 *  @param isr_dev Pointer to the device that will service the interrupt.
 */
static inline int enable(const struct device *dev,
			 const struct device *isr_dev)
{
	struct shared_irq_runtime *clients = dev->data;
	const struct shared_irq_config *config = dev->config;
	uint32_t i;

	for (i = 0U; i < config->client_count; i++) {
		if (clients->client[i].isr_dev == isr_dev) {
			clients->client[i].enabled = 1U;
			irq_enable(config->irq_num);
			return 0;
		}
	}
	return -EIO;
}

static int last_enabled_isr(struct shared_irq_runtime *clients, int count)
{
	uint32_t i;

	for (i = 0U; i < count; i++) {
		if (clients->client[i].enabled) {
			return 0;
		}
	}
	return 1;
}
/**
 *  @brief Disable ISR for device
 *  @param dev Pointer to device structure for SHARED_IRQ driver instance.
 *  @param isr_dev Pointer to the device that will service the interrupt.
 */
static inline int disable(const struct device *dev,
			  const struct device *isr_dev)
{
	struct shared_irq_runtime *clients = dev->data;
	const struct shared_irq_config *config = dev->config;
	uint32_t i;

	for (i = 0U; i < config->client_count; i++) {
		if (clients->client[i].isr_dev == isr_dev) {
			clients->client[i].enabled = 0U;
			if (last_enabled_isr(clients, config->client_count)) {
				irq_disable(config->irq_num);
			}
			return 0;
		}
	}
	return -EIO;
}

void shared_irq_isr(const struct device *dev)
{
	struct shared_irq_runtime *clients = dev->data;
	const struct shared_irq_config *config = dev->config;
	uint32_t i;

	for (i = 0U; i < config->client_count; i++) {
		if (clients->client[i].isr_dev) {
			clients->client[i].isr_func(clients->client[i].isr_dev);
		}
	}
}

static const struct shared_irq_driver_api api_funcs = {
	.isr_register = isr_register,
	.enable = enable,
	.disable = disable,
};


int shared_irq_initialize(const struct device *dev)
{
	const struct shared_irq_config *config = dev->config;
	config->config();
	return 0;
}

/*
 * INST_SUPPORTS_DEP_ORDS_CNT: Counts the number of "elements" in
 * DT_SUPPORTS_DEP_ORDS(n). There is a comma after each ordinal(inc. the last)
 * Hence FOR_EACH adds "+1" once too often which has to be subtracted in the end.
 */
#define F1(x) 1
#define INST_SUPPORTS_DEP_ORDS_CNT(n)  \
	(FOR_EACH(F1, (+), DT_INST_SUPPORTS_DEP_ORDS(n)) - 1)

#define SHARED_IRQ_CONFIG_FUNC(n)					\
void shared_irq_config_func_##n(void)					\
{									\
	IRQ_CONNECT(DT_INST_IRQN(n),					\
		    DT_INST_IRQ(n, priority),				\
		    shared_irq_isr,					\
		    DEVICE_DT_INST_GET(n),				\
		    COND_CODE_1(DT_INST_IRQ_HAS_CELL(n, sense),		\
				(DT_INST_IRQ(n, sense)),		\
				(0)));					\
}

#define SHARED_IRQ_INIT(n)						\
	SHARED_IRQ_CONFIG_FUNC(n)					\
	struct shared_irq_client clients_##n[INST_SUPPORTS_DEP_ORDS_CNT(n)]; \
	struct shared_irq_runtime shared_irq_data_##n = {		\
		.client = clients_##n					\
	};								\
									\
	const struct shared_irq_config shared_irq_config_##n = {	\
		.irq_num = DT_INST_IRQN(n),				\
		.client_count = INST_SUPPORTS_DEP_ORDS_CNT(n),		\
		.config = shared_irq_config_func_##n			\
	};								\
	DEVICE_DT_INST_DEFINE(n, shared_irq_initialize,			\
			      NULL,					\
			      &shared_irq_data_##n,			\
			      &shared_irq_config_##n, POST_KERNEL,	\
			      CONFIG_SHARED_IRQ_INIT_PRIORITY,		\
			      &api_funcs);

DT_INST_FOREACH_STATUS_OKAY(SHARED_IRQ_INIT)
