/*
 *  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/arch/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 INTCNTL_OFF               0x00
#define NIMASK_OFF                0x04
#define INTENNUM_OFF              0x08
#define INTDISNUM_OFF             0x0C
#define INTENABLEH_OFF            0x10
#define INTENABLEL_OFF            0x14
#define INTTYPEH_OFF              0x18
#define INTTYPEL_OFF              0x1C
#define NIPRIORITY_OFF(x)         (0x20+4*(7-(x)))
#define NIVECSR_OFF               0x40
#define FIVECSR_OFF               0x44
#define INTSRCH_OFF               0x48
#define INTSRCL_OFF               0x4C
#define INTFRCH_OFF               0x50
#define INTFRCL_OFF               0x54
#define NIPNDH_OFF                0x58
#define NIPNDL_OFF                0x5C
#define FIPNDH_OFF                0x60
#define FIPNDL_OFF                0x64

#define VA_AITC_BASE              IO_ADDRESS(IMX_AITC_BASE)
#define IMX_AITC_INTCNTL         (VA_AITC_BASE + INTCNTL_OFF)
#define IMX_AITC_NIMASK          (VA_AITC_BASE + NIMASK_OFF)
#define IMX_AITC_INTENNUM        (VA_AITC_BASE + INTENNUM_OFF)
#define IMX_AITC_INTDISNUM       (VA_AITC_BASE + INTDISNUM_OFF)
#define IMX_AITC_INTENABLEH      (VA_AITC_BASE + INTENABLEH_OFF)
#define IMX_AITC_INTENABLEL      (VA_AITC_BASE + INTENABLEL_OFF)
#define IMX_AITC_INTTYPEH        (VA_AITC_BASE + INTTYPEH_OFF)
#define IMX_AITC_INTTYPEL        (VA_AITC_BASE + INTTYPEL_OFF)
#define IMX_AITC_NIPRIORITY(x)   (VA_AITC_BASE + NIPRIORITY_OFF(x))
#define IMX_AITC_NIVECSR         (VA_AITC_BASE + NIVECSR_OFF)
#define IMX_AITC_FIVECSR         (VA_AITC_BASE + FIVECSR_OFF)
#define IMX_AITC_INTSRCH         (VA_AITC_BASE + INTSRCH_OFF)
#define IMX_AITC_INTSRCL         (VA_AITC_BASE + INTSRCL_OFF)
#define IMX_AITC_INTFRCH         (VA_AITC_BASE + INTFRCH_OFF)
#define IMX_AITC_INTFRCL         (VA_AITC_BASE + INTFRCL_OFF)
#define IMX_AITC_NIPNDH          (VA_AITC_BASE + NIPNDH_OFF)
#define IMX_AITC_NIPNDL          (VA_AITC_BASE + NIPNDL_OFF)
#define IMX_AITC_FIPNDH          (VA_AITC_BASE + FIPNDH_OFF)
#define IMX_AITC_FIPNDL          (VA_AITC_BASE + FIPNDL_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 == IRQ_TYPE_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 = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
	}

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

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

	if (type & IRQ_TYPE_EDGE_RISING) {
		DEBUG_IRQ("rising edges\n");
		irq_type = 0x0;
	}
	if (type & IRQ_TYPE_EDGE_FALLING) {
		DEBUG_IRQ("falling edges\n");
		irq_type = 0x1;
	}
	if (type & IRQ_TYPE_LEVEL_LOW) {
		DEBUG_IRQ("low level\n");
		irq_type = 0x3;
	}
	if (type & IRQ_TYPE_LEVEL_HIGH) {
		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", __func__, 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", __func__, 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", __func__, irq);
	IMR(IRQ_TO_REG(irq)) |= 1 << ((irq - IRQ_GPIOA(0)) % 32);
}

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

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

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

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

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

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

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

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

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

static struct irq_chip imx_internal_chip = {
	.name = "MPU",
	.ack = imx_mask_irq,
	.mask = imx_mask_irq,
	.unmask = imx_unmask_irq,
};

static struct irq_chip imx_gpio_chip = {
	.name = "GPIO",
	.ack = imx_gpio_ack_irq,
	.mask = imx_gpio_mask_irq,
	.unmask = imx_gpio_unmask_irq,
	.set_type = imx_gpio_irq_type,
};

void __init
imx_init_irq(void)
{
	unsigned int irq;

	DEBUG_IRQ("Initializing imx interrupts\n");

	/* Disable all interrupts initially. */
	/* Do not rely on the bootloader. */
	__raw_writel(0, IMX_AITC_INTENABLEH);
	__raw_writel(0, IMX_AITC_INTENABLEL);

	/* Mask all GPIO interrupts as well */
	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, handle_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, handle_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);

	/* Release masking of interrupts according to priority */
	__raw_writel(-1, IMX_AITC_NIMASK);
}
