/*
 * TX4939 irq routines
 * Based on linux/arch/mips/kernel/irq_txx9.c,
 *	    and RBTX49xx patch from CELF patch archive.
 *
 * Copyright 2001, 2003-2005 MontaVista Software Inc.
 * Author: MontaVista Software, Inc.
 *         ahennessy@mvista.com
 *         source@mvista.com
 * Copyright (C) 2000-2001,2005-2007 Toshiba Corporation
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 */
/*
 * TX4939 defines 64 IRQs.
 * Similer to irq_txx9.c but different register layouts.
 */
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/types.h>
#include <asm/irq_cpu.h>
#include <asm/txx9irq.h>
#include <asm/txx9/tx4939.h>

/* IRCER : Int. Control Enable */
#define TXx9_IRCER_ICE	0x00000001

/* IRCR : Int. Control */
#define TXx9_IRCR_LOW	0x00000000
#define TXx9_IRCR_HIGH	0x00000001
#define TXx9_IRCR_DOWN	0x00000002
#define TXx9_IRCR_UP	0x00000003
#define TXx9_IRCR_EDGE(cr)	((cr) & 0x00000002)

/* IRSCR : Int. Status Control */
#define TXx9_IRSCR_EIClrE	0x00000100
#define TXx9_IRSCR_EIClr_MASK	0x0000000f

/* IRCSR : Int. Current Status */
#define TXx9_IRCSR_IF	0x00010000

#define irc_dlevel	0
#define irc_elevel	1

static struct {
	unsigned char level;
	unsigned char mode;
} tx4939irq[TX4939_NUM_IR] __read_mostly;

static void tx4939_irq_unmask(unsigned int irq)
{
	unsigned int irq_nr = irq - TXX9_IRQ_BASE;
	u32 __iomem *lvlp;
	int ofs;
	if (irq_nr < 32) {
		irq_nr--;
		lvlp = &tx4939_ircptr->lvl[(irq_nr % 16) / 2].r;
	} else {
		irq_nr -= 32;
		lvlp = &tx4939_ircptr->lvl[8 + (irq_nr % 16) / 2].r;
	}
	ofs = (irq_nr & 16) + (irq_nr & 1) * 8;
	__raw_writel((__raw_readl(lvlp) & ~(0xff << ofs))
		     | (tx4939irq[irq_nr].level << ofs),
		     lvlp);
}

static inline void tx4939_irq_mask(unsigned int irq)
{
	unsigned int irq_nr = irq - TXX9_IRQ_BASE;
	u32 __iomem *lvlp;
	int ofs;
	if (irq_nr < 32) {
		irq_nr--;
		lvlp = &tx4939_ircptr->lvl[(irq_nr % 16) / 2].r;
	} else {
		irq_nr -= 32;
		lvlp = &tx4939_ircptr->lvl[8 + (irq_nr % 16) / 2].r;
	}
	ofs = (irq_nr & 16) + (irq_nr & 1) * 8;
	__raw_writel((__raw_readl(lvlp) & ~(0xff << ofs))
		     | (irc_dlevel << ofs),
		     lvlp);
	mmiowb();
}

static void tx4939_irq_mask_ack(unsigned int irq)
{
	unsigned int irq_nr = irq - TXX9_IRQ_BASE;

	tx4939_irq_mask(irq);
	if (TXx9_IRCR_EDGE(tx4939irq[irq_nr].mode)) {
		irq_nr--;
		/* clear edge detection */
		__raw_writel((TXx9_IRSCR_EIClrE | (irq_nr & 0xf))
			     << (irq_nr & 0x10),
			     &tx4939_ircptr->edc.r);
	}
}

static int tx4939_irq_set_type(unsigned int irq, unsigned int flow_type)
{
	unsigned int irq_nr = irq - TXX9_IRQ_BASE;
	u32 cr;
	u32 __iomem *crp;
	int ofs;
	int mode;

	if (flow_type & IRQF_TRIGGER_PROBE)
		return 0;
	switch (flow_type & IRQF_TRIGGER_MASK) {
	case IRQF_TRIGGER_RISING:
		mode = TXx9_IRCR_UP;
		break;
	case IRQF_TRIGGER_FALLING:
		mode = TXx9_IRCR_DOWN;
		break;
	case IRQF_TRIGGER_HIGH:
		mode = TXx9_IRCR_HIGH;
		break;
	case IRQF_TRIGGER_LOW:
		mode = TXx9_IRCR_LOW;
		break;
	default:
		return -EINVAL;
	}
	if (irq_nr < 32) {
		irq_nr--;
		crp = &tx4939_ircptr->dm[(irq_nr & 8) >> 3].r;
	} else {
		irq_nr -= 32;
		crp = &tx4939_ircptr->dm2[((irq_nr & 8) >> 3)].r;
	}
	ofs = (((irq_nr & 16) >> 1) | (irq_nr & (8 - 1))) * 2;
	cr = __raw_readl(crp);
	cr &= ~(0x3 << ofs);
	cr |= (mode & 0x3) << ofs;
	__raw_writel(cr, crp);
	tx4939irq[irq_nr].mode = mode;
	return 0;
}

static struct irq_chip tx4939_irq_chip = {
	.name		= "TX4939",
	.ack		= tx4939_irq_mask_ack,
	.mask		= tx4939_irq_mask,
	.mask_ack	= tx4939_irq_mask_ack,
	.unmask		= tx4939_irq_unmask,
	.set_type	= tx4939_irq_set_type,
};

static int tx4939_irq_set_pri(int irc_irq, int new_pri)
{
	int old_pri;

	if ((unsigned int)irc_irq >= TX4939_NUM_IR)
		return 0;
	old_pri = tx4939irq[irc_irq].level;
	tx4939irq[irc_irq].level = new_pri;
	return old_pri;
}

void __init tx4939_irq_init(void)
{
	int i;

	mips_cpu_irq_init();
	/* disable interrupt control */
	__raw_writel(0, &tx4939_ircptr->den.r);
	__raw_writel(0, &tx4939_ircptr->maskint.r);
	__raw_writel(0, &tx4939_ircptr->maskext.r);
	/* irq_base + 0 is not used */
	for (i = 1; i < TX4939_NUM_IR; i++) {
		tx4939irq[i].level = 4; /* middle level */
		tx4939irq[i].mode = TXx9_IRCR_LOW;
		set_irq_chip_and_handler(TXX9_IRQ_BASE + i,
					 &tx4939_irq_chip, handle_level_irq);
	}

	/* mask all IRC interrupts */
	__raw_writel(0, &tx4939_ircptr->msk.r);
	for (i = 0; i < 16; i++)
		__raw_writel(0, &tx4939_ircptr->lvl[i].r);
	/* setup IRC interrupt mode (Low Active) */
	for (i = 0; i < 2; i++)
		__raw_writel(0, &tx4939_ircptr->dm[i].r);
	for (i = 0; i < 2; i++)
		__raw_writel(0, &tx4939_ircptr->dm2[i].r);
	/* enable interrupt control */
	__raw_writel(TXx9_IRCER_ICE, &tx4939_ircptr->den.r);
	__raw_writel(irc_elevel, &tx4939_ircptr->msk.r);

	set_irq_chained_handler(MIPS_CPU_IRQ_BASE + TX4939_IRC_INT,
				handle_simple_irq);

	/* raise priority for errors, timers, sio */
	tx4939_irq_set_pri(TX4939_IR_WTOERR, 7);
	tx4939_irq_set_pri(TX4939_IR_PCIERR, 7);
	tx4939_irq_set_pri(TX4939_IR_PCIPME, 7);
	for (i = 0; i < TX4939_NUM_IR_TMR; i++)
		tx4939_irq_set_pri(TX4939_IR_TMR(i), 6);
	for (i = 0; i < TX4939_NUM_IR_SIO; i++)
		tx4939_irq_set_pri(TX4939_IR_SIO(i), 5);
}

int tx4939_irq(void)
{
	u32 csr = __raw_readl(&tx4939_ircptr->cs.r);

	if (likely(!(csr & TXx9_IRCSR_IF)))
		return TXX9_IRQ_BASE + (csr & (TX4939_NUM_IR - 1));
	return -1;
}
