/*
 * arch/arm/mach-ks8695/irq.c
 *
 * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
 * Copyright (C) 2006 Simtec Electronics
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/sysdev.h>
#include <linux/io.h>

#include <mach/hardware.h>
#include <asm/irq.h>

#include <asm/mach/irq.h>

#include <mach/regs-irq.h>
#include <mach/regs-gpio.h>

static void ks8695_irq_mask(unsigned int irqno)
{
	unsigned long inten;

	inten = __raw_readl(KS8695_IRQ_VA + KS8695_INTEN);
	inten &= ~(1 << irqno);

	__raw_writel(inten, KS8695_IRQ_VA + KS8695_INTEN);
}

static void ks8695_irq_unmask(unsigned int irqno)
{
	unsigned long inten;

	inten = __raw_readl(KS8695_IRQ_VA + KS8695_INTEN);
	inten |= (1 << irqno);

	__raw_writel(inten, KS8695_IRQ_VA + KS8695_INTEN);
}

static void ks8695_irq_ack(unsigned int irqno)
{
	__raw_writel((1 << irqno), KS8695_IRQ_VA + KS8695_INTST);
}


static struct irq_chip ks8695_irq_level_chip;
static struct irq_chip ks8695_irq_edge_chip;


static int ks8695_irq_set_type(unsigned int irqno, unsigned int type)
{
	unsigned long ctrl, mode;
	unsigned short level_triggered = 0;

	ctrl = __raw_readl(KS8695_GPIO_VA + KS8695_IOPC);

	switch (type) {
		case IRQ_TYPE_LEVEL_HIGH:
			mode = IOPC_TM_HIGH;
			level_triggered = 1;
			break;
		case IRQ_TYPE_LEVEL_LOW:
			mode = IOPC_TM_LOW;
			level_triggered = 1;
			break;
		case IRQ_TYPE_EDGE_RISING:
			mode = IOPC_TM_RISING;
			break;
		case IRQ_TYPE_EDGE_FALLING:
			mode = IOPC_TM_FALLING;
			break;
		case IRQ_TYPE_EDGE_BOTH:
			mode = IOPC_TM_EDGE;
			break;
		default:
			return -EINVAL;
	}

	switch (irqno) {
		case KS8695_IRQ_EXTERN0:
			ctrl &= ~IOPC_IOEINT0TM;
			ctrl |= IOPC_IOEINT0_MODE(mode);
			break;
		case KS8695_IRQ_EXTERN1:
			ctrl &= ~IOPC_IOEINT1TM;
			ctrl |= IOPC_IOEINT1_MODE(mode);
			break;
		case KS8695_IRQ_EXTERN2:
			ctrl &= ~IOPC_IOEINT2TM;
			ctrl |= IOPC_IOEINT2_MODE(mode);
			break;
		case KS8695_IRQ_EXTERN3:
			ctrl &= ~IOPC_IOEINT3TM;
			ctrl |= IOPC_IOEINT3_MODE(mode);
			break;
		default:
			return -EINVAL;
	}

	if (level_triggered) {
		set_irq_chip(irqno, &ks8695_irq_level_chip);
		set_irq_handler(irqno, handle_level_irq);
	}
	else {
		set_irq_chip(irqno, &ks8695_irq_edge_chip);
		set_irq_handler(irqno, handle_edge_irq);
	}

	__raw_writel(ctrl, KS8695_GPIO_VA + KS8695_IOPC);
	return 0;
}

static struct irq_chip ks8695_irq_level_chip = {
	.ack		= ks8695_irq_mask,
	.mask		= ks8695_irq_mask,
	.unmask		= ks8695_irq_unmask,
	.set_type	= ks8695_irq_set_type,
};

static struct irq_chip ks8695_irq_edge_chip = {
	.ack		= ks8695_irq_ack,
	.mask		= ks8695_irq_mask,
	.unmask		= ks8695_irq_unmask,
	.set_type	= ks8695_irq_set_type,
};

void __init ks8695_init_irq(void)
{
	unsigned int irq;

	/* Disable all interrupts initially */
	__raw_writel(0, KS8695_IRQ_VA + KS8695_INTMC);
	__raw_writel(0, KS8695_IRQ_VA + KS8695_INTEN);

	for (irq = 0; irq < NR_IRQS; irq++) {
		switch (irq) {
			/* Level-triggered interrupts */
			case KS8695_IRQ_BUS_ERROR:
			case KS8695_IRQ_UART_MODEM_STATUS:
			case KS8695_IRQ_UART_LINE_STATUS:
			case KS8695_IRQ_UART_RX:
			case KS8695_IRQ_COMM_TX:
			case KS8695_IRQ_COMM_RX:
				set_irq_chip(irq, &ks8695_irq_level_chip);
				set_irq_handler(irq, handle_level_irq);
				break;

			/* Edge-triggered interrupts */
			default:
				ks8695_irq_ack(irq);	/* clear pending bit */
				set_irq_chip(irq, &ks8695_irq_edge_chip);
				set_irq_handler(irq, handle_edge_irq);
		}

		set_irq_flags(irq, IRQF_VALID);
	}
}
