/*
 * External interrupt handling for AT32AP CPUs
 *
 * Copyright (C) 2006 Atmel Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/errno.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/random.h>

#include <asm/io.h>

#include <asm/arch/sm.h>

#include "sm.h"

static void eim_ack_irq(unsigned int irq)
{
	struct at32_sm *sm = get_irq_chip_data(irq);
	sm_writel(sm, EIM_ICR, 1 << (irq - sm->eim_first_irq));
}

static void eim_mask_irq(unsigned int irq)
{
	struct at32_sm *sm = get_irq_chip_data(irq);
	sm_writel(sm, EIM_IDR, 1 << (irq - sm->eim_first_irq));
}

static void eim_mask_ack_irq(unsigned int irq)
{
	struct at32_sm *sm = get_irq_chip_data(irq);
	sm_writel(sm, EIM_ICR, 1 << (irq - sm->eim_first_irq));
	sm_writel(sm, EIM_IDR, 1 << (irq - sm->eim_first_irq));
}

static void eim_unmask_irq(unsigned int irq)
{
	struct at32_sm *sm = get_irq_chip_data(irq);
	sm_writel(sm, EIM_IER, 1 << (irq - sm->eim_first_irq));
}

static int eim_set_irq_type(unsigned int irq, unsigned int flow_type)
{
	struct at32_sm *sm = get_irq_chip_data(irq);
	struct irq_desc *desc;
	unsigned int i = irq - sm->eim_first_irq;
	u32 mode, edge, level;
	unsigned long flags;
	int ret = 0;

	flow_type &= IRQ_TYPE_SENSE_MASK;
	if (flow_type == IRQ_TYPE_NONE)
		flow_type = IRQ_TYPE_LEVEL_LOW;

	desc = &irq_desc[irq];
	spin_lock_irqsave(&sm->lock, flags);

	mode = sm_readl(sm, EIM_MODE);
	edge = sm_readl(sm, EIM_EDGE);
	level = sm_readl(sm, EIM_LEVEL);

	switch (flow_type) {
	case IRQ_TYPE_LEVEL_LOW:
		mode |= 1 << i;
		level &= ~(1 << i);
		break;
	case IRQ_TYPE_LEVEL_HIGH:
		mode |= 1 << i;
		level |= 1 << i;
		break;
	case IRQ_TYPE_EDGE_RISING:
		mode &= ~(1 << i);
		edge |= 1 << i;
		break;
	case IRQ_TYPE_EDGE_FALLING:
		mode &= ~(1 << i);
		edge &= ~(1 << i);
		break;
	default:
		ret = -EINVAL;
		break;
	}

	if (ret == 0) {
		sm_writel(sm, EIM_MODE, mode);
		sm_writel(sm, EIM_EDGE, edge);
		sm_writel(sm, EIM_LEVEL, level);

		if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
			flow_type |= IRQ_LEVEL;
		desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
		desc->status |= flow_type;
	}

	spin_unlock_irqrestore(&sm->lock, flags);

	return ret;
}

struct irq_chip eim_chip = {
	.name		= "eim",
	.ack		= eim_ack_irq,
	.mask		= eim_mask_irq,
	.mask_ack	= eim_mask_ack_irq,
	.unmask		= eim_unmask_irq,
	.set_type	= eim_set_irq_type,
};

static void demux_eim_irq(unsigned int irq, struct irq_desc *desc)
{
	struct at32_sm *sm = desc->handler_data;
	struct irq_desc *ext_desc;
	unsigned long status, pending;
	unsigned int i, ext_irq;

	status = sm_readl(sm, EIM_ISR);
	pending = status & sm_readl(sm, EIM_IMR);

	while (pending) {
		i = fls(pending) - 1;
		pending &= ~(1 << i);

		ext_irq = i + sm->eim_first_irq;
		ext_desc = irq_desc + ext_irq;
		if (ext_desc->status & IRQ_LEVEL)
			handle_level_irq(ext_irq, ext_desc);
		else
			handle_edge_irq(ext_irq, ext_desc);
	}
}

static int __init eim_init(void)
{
	struct at32_sm *sm = &system_manager;
	unsigned int i;
	unsigned int nr_irqs;
	unsigned int int_irq;
	u32 pattern;

	/*
	 * The EIM is really the same module as SM, so register
	 * mapping, etc. has been taken care of already.
	 */

	/*
	 * Find out how many interrupt lines that are actually
	 * implemented in hardware.
	 */
	sm_writel(sm, EIM_IDR, ~0UL);
	sm_writel(sm, EIM_MODE, ~0UL);
	pattern = sm_readl(sm, EIM_MODE);
	nr_irqs = fls(pattern);

	/* Trigger on falling edge unless overridden by driver */
	sm_writel(sm, EIM_MODE, 0UL);
	sm_writel(sm, EIM_EDGE, 0UL);

	sm->eim_chip = &eim_chip;

	for (i = 0; i < nr_irqs; i++) {
		/* NOTE the handler we set here is ignored by the demux */
		set_irq_chip_and_handler(sm->eim_first_irq + i, &eim_chip,
					 handle_level_irq);
		set_irq_chip_data(sm->eim_first_irq + i, sm);
	}

	int_irq = platform_get_irq_byname(sm->pdev, "eim");

	set_irq_chained_handler(int_irq, demux_eim_irq);
	set_irq_data(int_irq, sm);

	printk("EIM: External Interrupt Module at 0x%p, IRQ %u\n",
	       sm->regs, int_irq);
	printk("EIM: Handling %u external IRQs, starting with IRQ %u\n",
	       nr_irqs, sm->eim_first_irq);

	return 0;
}
arch_initcall(eim_init);
