/*
 * Copyright (c) 2015 Intel Corporation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <errno.h>

#include <nanokernel.h>
#include <device.h>
#include <shared_irq.h>
#include <init.h>
#include <board.h>
#include <sys_io.h>

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

/**
 *  @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(struct device *dev, isr_t isr_func,
				 struct device *isr_dev)
{
	struct shared_irq_runtime *clients = dev->driver_data;
	struct shared_irq_config *config = dev->config->config_info;
	uint32_t i;

	for (i = 0; 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(struct device *dev, struct device *isr_dev)
{
	struct shared_irq_runtime *clients = dev->driver_data;
	struct shared_irq_config *config = dev->config->config_info;
	uint32_t i;

	for (i = 0; i < config->client_count; i++) {
		if (clients->client[i].isr_dev == isr_dev) {
			clients->client[i].enabled = 1;
			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 = 0; 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(struct device *dev, struct device *isr_dev)
{
	struct shared_irq_runtime *clients = dev->driver_data;
	struct shared_irq_config *config = dev->config->config_info;
	uint32_t i;

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

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

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

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


int shared_irq_initialize(struct device *dev)
{
	struct shared_irq_config *config = dev->config->config_info;

	dev->driver_api = &api_funcs;
	config->config();

	return 0;
}

#if CONFIG_SHARED_IRQ_0
void shared_irq_config_0_irq(void);

struct shared_irq_config shared_irq_config_0 = {
	.irq_num = CONFIG_SHARED_IRQ_0_IRQ,
	.client_count = CONFIG_SHARED_IRQ_NUM_CLIENTS,
	.config = shared_irq_config_0_irq
};

struct shared_irq_runtime shared_irq_0_runtime;

DEVICE_INIT(shared_irq_0, CONFIG_SHARED_IRQ_0_NAME, shared_irq_initialize,
				&shared_irq_0_runtime, &shared_irq_config_0,
				SECONDARY, CONFIG_SHARED_IRQ_INIT_PRIORITY);

#if defined(CONFIG_IOAPIC)
#if defined(CONFIG_SHARED_IRQ_0)
	#if defined(CONFIG_SHARED_IRQ_0_FALLING_EDGE)
		#define SHARED_IRQ_0_FLAGS (IOAPIC_EDGE | IOAPIC_LOW)
	#elif defined(CONFIG_SHARED_IRQ_0_RISING_EDGE)
		#define SHARED_IRQ_0_FLAGS (IOAPIC_EDGE | IOAPIC_HIGH)
	#elif defined(CONFIG_SHARED_IRQ_0_LEVEL_HIGH)
		#define SHARED_IRQ_0_FLAGS (IOAPIC_LEVEL | IOAPIC_HIGH)
	#elif defined(CONFIG_SHARED_IRQ_0_LEVEL_LOW)
		#define SHARED_IRQ_0_FLAGS (IOAPIC_LEVEL | IOAPIC_LOW)
	#endif
#endif /* CONFIG_SHARED_IRQ_0 */
#else
	#define SHARED_IRQ_0_FLAGS 0
#endif /* CONFIG_IOAPIC */

void shared_irq_config_0_irq(void)
{
	IRQ_CONNECT(CONFIG_SHARED_IRQ_0_IRQ, CONFIG_SHARED_IRQ_0_PRI,
		    shared_irq_isr, DEVICE_GET(shared_irq_0),
		    SHARED_IRQ_0_FLAGS);
}

#endif /* CONFIG_SHARED_IRQ_0 */

#if CONFIG_SHARED_IRQ_1
void shared_irq_config_1_irq(void);

struct shared_irq_config shared_irq_config_1 = {
	.irq_num = CONFIG_SHARED_IRQ_1_IRQ,
	.client_count = CONFIG_SHARED_IRQ_NUM_CLIENTS,
	.config = shared_irq_config_1_irq
};

struct shared_irq_runtime shared_irq_1_runtime;

DEVICE_INIT(shared_irq_1, CONFIG_SHARED_IRQ_1_NAME, shared_irq_initialize,
				&shared_irq_1_runtime, &shared_irq_config_1,
				SECONDARY, CONFIG_SHARED_IRQ_INIT_PRIORITY);

#if defined(CONFIG_IOAPIC)
#if defined(CONFIG_SHARED_IRQ_1)
	#if defined(CONFIG_SHARED_IRQ_1_FALLING_EDGE)
		#define SHARED_IRQ_1_FLAGS (IOAPIC_EDGE | IOAPIC_LOW)
	#elif defined(CONFIG_SHARED_IRQ_1_RISING_EDGE)
		#define SHARED_IRQ_1_FLAGS (IOAPIC_EDGE | IOAPIC_HIGH)
	#elif defined(CONFIG_SHARED_IRQ_1_LEVEL_HIGH)
		#define SHARED_IRQ_1_FLAGS (IOAPIC_LEVEL | IOAPIC_HIGH)
	#elif defined(CONFIG_SHARED_IRQ_1_LEVEL_LOW)
		#define SHARED_IRQ_1_FLAGS (IOAPIC_LEVEL | IOAPIC_LOW)
	#endif
#endif /* CONFIG_SHARED_IRQ_1 */
#else
	#define SHARED_IRQ_1_FLAGS 0
#endif /* CONFIG_IOAPIC */

void shared_irq_config_1_irq(void)
{
	IRQ_CONNECT(CONFIG_SHARED_IRQ_1_IRQ, CONFIG_SHARED_IRQ_1_PRI,
		    shared_irq_isr, DEVICE_GET(shared_irq_1),
		    SHARED_IRQ_1_FLAGS);
}

#endif /* CONFIG_SHARED_IRQ_1 */

