/*
 *  arch/arm/mach-vt8500/irq.c
 *
 *  Copyright (C) 2010 Alexey Charkov <alchark@gmail.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
 */

#include <linux/io.h>
#include <linux/irq.h>
#include <linux/interrupt.h>

#include <asm/irq.h>

#include "devices.h"

#define VT8500_IC_DCTR		0x40		/* Destination control
						register, 64*u8 */
#define VT8500_INT_ENABLE	(1 << 3)
#define VT8500_TRIGGER_HIGH	(0 << 4)
#define VT8500_TRIGGER_RISING	(1 << 4)
#define VT8500_TRIGGER_FALLING	(2 << 4)
#define VT8500_EDGE		( VT8500_TRIGGER_RISING \
				| VT8500_TRIGGER_FALLING)
#define VT8500_IC_STATUS	0x80		/* Interrupt status, 2*u32 */

static void __iomem *ic_regbase;
static void __iomem *sic_regbase;

static void vt8500_irq_mask(unsigned int irq)
{
	void __iomem *base = ic_regbase;
	u8 edge;

	if (irq >= 64) {
		base = sic_regbase;
		irq -= 64;
	}
	edge = readb(base + VT8500_IC_DCTR + irq) & VT8500_EDGE;
	if (edge) {
		void __iomem *stat_reg = base + VT8500_IC_STATUS
						+ (irq < 32 ? 0 : 4);
		unsigned status = readl(stat_reg);

		status |= (1 << (irq & 0x1f));
		writel(status, stat_reg);
	} else {
		u8 dctr = readb(base + VT8500_IC_DCTR + irq);

		dctr &= ~VT8500_INT_ENABLE;
		writeb(dctr, base + VT8500_IC_DCTR + irq);
	}
}

static void vt8500_irq_unmask(unsigned int irq)
{
	void __iomem *base = ic_regbase;
	u8 dctr;

	if (irq >= 64) {
		base = sic_regbase;
		irq -= 64;
	}
	dctr = readb(base + VT8500_IC_DCTR + irq);
	dctr |= VT8500_INT_ENABLE;
	writeb(dctr, base + VT8500_IC_DCTR + irq);
}

static int vt8500_irq_set_type(unsigned int irq, unsigned int flow_type)
{
	void __iomem *base = ic_regbase;
	unsigned int orig_irq = irq;
	u8 dctr;

	if (irq >= 64) {
		base = sic_regbase;
		irq -= 64;
	}

	dctr = readb(base + VT8500_IC_DCTR + irq);
	dctr &= ~VT8500_EDGE;

	switch (flow_type) {
	case IRQF_TRIGGER_LOW:
		return -EINVAL;
	case IRQF_TRIGGER_HIGH:
		dctr |= VT8500_TRIGGER_HIGH;
		irq_desc[orig_irq].handle_irq = handle_level_irq;
		break;
	case IRQF_TRIGGER_FALLING:
		dctr |= VT8500_TRIGGER_FALLING;
		irq_desc[orig_irq].handle_irq = handle_edge_irq;
		break;
	case IRQF_TRIGGER_RISING:
		dctr |= VT8500_TRIGGER_RISING;
		irq_desc[orig_irq].handle_irq = handle_edge_irq;
		break;
	}
	writeb(dctr, base + VT8500_IC_DCTR + irq);

	return 0;
}

static struct irq_chip vt8500_irq_chip = {
	.name      = "vt8500",
	.ack       = vt8500_irq_mask,
	.mask      = vt8500_irq_mask,
	.unmask    = vt8500_irq_unmask,
	.set_type  = vt8500_irq_set_type,
};

void __init vt8500_init_irq(void)
{
	unsigned int i;

	ic_regbase = ioremap(wmt_ic_base, SZ_64K);

	if (ic_regbase) {
		/* Enable rotating priority for IRQ */
		writel((1 << 6), ic_regbase + 0x20);
		writel(0, ic_regbase + 0x24);

		for (i = 0; i < wmt_nr_irqs; i++) {
			/* Disable all interrupts and route them to IRQ */
			writeb(0x00, ic_regbase + VT8500_IC_DCTR + i);

			set_irq_chip(i, &vt8500_irq_chip);
			set_irq_handler(i, handle_level_irq);
			set_irq_flags(i, IRQF_VALID);
		}
	} else {
		printk(KERN_ERR "Unable to remap the Interrupt Controller registers, not enabling IRQs!\n");
	}
}

void __init wm8505_init_irq(void)
{
	unsigned int i;

	ic_regbase = ioremap(wmt_ic_base, SZ_64K);
	sic_regbase = ioremap(wmt_sic_base, SZ_64K);

	if (ic_regbase && sic_regbase) {
		/* Enable rotating priority for IRQ */
		writel((1 << 6), ic_regbase + 0x20);
		writel(0, ic_regbase + 0x24);
		writel((1 << 6), sic_regbase + 0x20);
		writel(0, sic_regbase + 0x24);

		for (i = 0; i < wmt_nr_irqs; i++) {
			/* Disable all interrupts and route them to IRQ */
			if (i < 64)
				writeb(0x00, ic_regbase + VT8500_IC_DCTR + i);
			else
				writeb(0x00, sic_regbase + VT8500_IC_DCTR
								+ i - 64);

			set_irq_chip(i, &vt8500_irq_chip);
			set_irq_handler(i, handle_level_irq);
			set_irq_flags(i, IRQF_VALID);
		}
	} else {
		printk(KERN_ERR "Unable to remap the Interrupt Controller registers, not enabling IRQs!\n");
	}
}
