/*
 * 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);
	unsigned int i = irq - sm->eim_first_irq;
	u32 mode, edge, level;
	unsigned long flags;
	int ret = 0;

	flow_type &= IRQ_TYPE_SENSE_MASK;

	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;
	}

	sm_writel(sm, EIM_MODE, mode);
	sm_writel(sm, EIM_EDGE, edge);
	sm_writel(sm, EIM_LEVEL, level);

	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;

	spin_lock(&sm->lock);

	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;
		ext_desc->handle_irq(ext_irq, ext_desc);
	}

	spin_unlock(&sm->lock);
}

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);

	sm->eim_chip = &eim_chip;

	for (i = 0; i < nr_irqs; i++) {
		set_irq_chip(sm->eim_first_irq + i, &eim_chip);
		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);
