/*
 *  linux/arch/arm/mach-imx/irq.c
 *
 *  Copyright (C) 1999 ARM Limited
 *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
 *
 * 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
 *
 *  03/03/2004   Sascha Hauer <sascha@saschahauer.de>
 *               Copied from the motorola bsp package and added gpio demux
 *               interrupt handler
 */

#include <linux/init.h>
#include <linux/list.h>
#include <linux/timer.h>

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

#include <asm/mach/irq.h>

/*
 *
 * We simply use the ENABLE DISABLE registers inside of the IMX
 * to turn on/off specific interrupts.  FIXME- We should
 * also add support for the accelerated interrupt controller
 * by putting offets to irq jump code in the appropriate
 * places.
 *
 */

#define INTENNUM_OFF              0x8
#define INTDISNUM_OFF             0xC

#define VA_AITC_BASE              IO_ADDRESS(IMX_AITC_BASE)
#define IMX_AITC_INTDISNUM       (VA_AITC_BASE + INTDISNUM_OFF)
#define IMX_AITC_INTENNUM        (VA_AITC_BASE + INTENNUM_OFF)

#if 0
#define DEBUG_IRQ(fmt...)	printk(fmt)
#else
#define DEBUG_IRQ(fmt...)	do { } while (0)
#endif

static void
imx_mask_irq(unsigned int irq)
{
	__raw_writel(irq, IMX_AITC_INTDISNUM);
}

static void
imx_unmask_irq(unsigned int irq)
{
	__raw_writel(irq, IMX_AITC_INTENNUM);
}

static int
imx_gpio_irq_type(unsigned int _irq, unsigned int type)
{
	unsigned int irq_type = 0, irq, reg, bit;

	irq = _irq - IRQ_GPIOA(0);
	reg = irq >> 5;
	bit = 1 << (irq % 32);

	if (type == IRQT_PROBE) {
		/* Don't mess with enabled GPIOs using preconfigured edges or
		   GPIOs set to alternate function during probe */
		/* TODO: support probe */
//              if ((GPIO_IRQ_rising_edge[idx] | GPIO_IRQ_falling_edge[idx]) &
//                  GPIO_bit(gpio))
//                      return 0;
//              if (GAFR(gpio) & (0x3 << (((gpio) & 0xf)*2)))
//                      return 0;
//              type = __IRQT_RISEDGE | __IRQT_FALEDGE;
	}

	GIUS(reg) |= bit;
	DDIR(reg) &= ~(bit);

	DEBUG_IRQ("setting type of irq %d to ", _irq);

	if (type & __IRQT_RISEDGE) {
		DEBUG_IRQ("rising edges\n");
		irq_type = 0x0;
	}
	if (type & __IRQT_FALEDGE) {
		DEBUG_IRQ("falling edges\n");
		irq_type = 0x1;
	}
	if (type & __IRQT_LOWLVL) {
		DEBUG_IRQ("low level\n");
		irq_type = 0x3;
	}
	if (type & __IRQT_HIGHLVL) {
		DEBUG_IRQ("high level\n");
		irq_type = 0x2;
	}

	if (irq % 32 < 16) {
		ICR1(reg) = (ICR1(reg) & ~(0x3 << ((irq % 16) * 2))) |
		    (irq_type << ((irq % 16) * 2));
	} else {
		ICR2(reg) = (ICR2(reg) & ~(0x3 << ((irq % 16) * 2))) |
		    (irq_type << ((irq % 16) * 2));
	}

	return 0;

}

static void
imx_gpio_ack_irq(unsigned int irq)
{
	DEBUG_IRQ("%s: irq %d\n", __FUNCTION__, irq);
	ISR(IRQ_TO_REG(irq)) |= 1 << ((irq - IRQ_GPIOA(0)) % 32);
}

static void
imx_gpio_mask_irq(unsigned int irq)
{
	DEBUG_IRQ("%s: irq %d\n", __FUNCTION__, irq);
	IMR(IRQ_TO_REG(irq)) &= ~( 1 << ((irq - IRQ_GPIOA(0)) % 32));
}

static void
imx_gpio_unmask_irq(unsigned int irq)
{
	DEBUG_IRQ("%s: irq %d\n", __FUNCTION__, irq);
	IMR(IRQ_TO_REG(irq)) |= 1 << ((irq - IRQ_GPIOA(0)) % 32);
}

static void
imx_gpio_handler(unsigned int mask, unsigned int irq,
                 struct irqdesc *desc, struct pt_regs *regs)
{
	desc = irq_desc + irq;
	while (mask) {
		if (mask & 1) {
			DEBUG_IRQ("handling irq %d\n", irq);
			desc->handle(irq, desc, regs);
		}
		irq++;
		desc++;
		mask >>= 1;
	}
}

static void
imx_gpioa_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
			struct pt_regs *regs)
{
	unsigned int mask, irq;

	mask = ISR(0);
	irq = IRQ_GPIOA(0);
	imx_gpio_handler(mask, irq, desc, regs);
}

static void
imx_gpiob_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
			struct pt_regs *regs)
{
	unsigned int mask, irq;

	mask = ISR(1);
	irq = IRQ_GPIOB(0);
	imx_gpio_handler(mask, irq, desc, regs);
}

static void
imx_gpioc_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
			struct pt_regs *regs)
{
	unsigned int mask, irq;

	mask = ISR(2);
	irq = IRQ_GPIOC(0);
	imx_gpio_handler(mask, irq, desc, regs);
}

static void
imx_gpiod_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
			struct pt_regs *regs)
{
	unsigned int mask, irq;

	mask = ISR(3);
	irq = IRQ_GPIOD(0);
	imx_gpio_handler(mask, irq, desc, regs);
}

static struct irqchip imx_internal_chip = {
	.ack = imx_mask_irq,
	.mask = imx_mask_irq,
	.unmask = imx_unmask_irq,
};

static struct irqchip imx_gpio_chip = {
	.ack = imx_gpio_ack_irq,
	.mask = imx_gpio_mask_irq,
	.unmask = imx_gpio_unmask_irq,
	.type = imx_gpio_irq_type,
};

void __init
imx_init_irq(void)
{
	unsigned int irq;

	DEBUG_IRQ("Initializing imx interrupts\n");

	/* Mask all interrupts initially */
	IMR(0) = 0;
	IMR(1) = 0;
	IMR(2) = 0;
	IMR(3) = 0;

	for (irq = 0; irq < IMX_IRQS; irq++) {
		set_irq_chip(irq, &imx_internal_chip);
		set_irq_handler(irq, do_level_IRQ);
		set_irq_flags(irq, IRQF_VALID);
	}

	for (irq = IRQ_GPIOA(0); irq < IRQ_GPIOD(32); irq++) {
		set_irq_chip(irq, &imx_gpio_chip);
		set_irq_handler(irq, do_edge_IRQ);
		set_irq_flags(irq, IRQF_VALID);
	}

	set_irq_chained_handler(GPIO_INT_PORTA, imx_gpioa_demux_handler);
	set_irq_chained_handler(GPIO_INT_PORTB, imx_gpiob_demux_handler);
	set_irq_chained_handler(GPIO_INT_PORTC, imx_gpioc_demux_handler);
	set_irq_chained_handler(GPIO_INT_PORTD, imx_gpiod_demux_handler);

	/* Disable all interrupts initially. */
	/* In IMX this is done in the bootloader. */
}
