/*
 * Toshiba RBTX4927 specific interrupt handlers
 *
 * Author: MontaVista Software, Inc.
 *         source@mvista.com
 *
 * Copyright 2001-2002 MontaVista Software Inc.
 *
 *  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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
 *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *  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.,
 *  675 Mass Ave, Cambridge, MA 02139, USA.
 */
/*
 * I8259A_IRQ_BASE+00
 * I8259A_IRQ_BASE+01 PS2/Keyboard
 * I8259A_IRQ_BASE+02 Cascade RBTX4927-ISA (irqs 8-15)
 * I8259A_IRQ_BASE+03
 * I8259A_IRQ_BASE+04
 * I8259A_IRQ_BASE+05
 * I8259A_IRQ_BASE+06
 * I8259A_IRQ_BASE+07
 * I8259A_IRQ_BASE+08
 * I8259A_IRQ_BASE+09
 * I8259A_IRQ_BASE+10
 * I8259A_IRQ_BASE+11
 * I8259A_IRQ_BASE+12 PS2/Mouse (not supported at this time)
 * I8259A_IRQ_BASE+13
 * I8259A_IRQ_BASE+14 IDE
 * I8259A_IRQ_BASE+15
 *
 * MIPS_CPU_IRQ_BASE+00 Software 0
 * MIPS_CPU_IRQ_BASE+01 Software 1
 * MIPS_CPU_IRQ_BASE+02 Cascade TX4927-CP0
 * MIPS_CPU_IRQ_BASE+03 Multiplexed -- do not use
 * MIPS_CPU_IRQ_BASE+04 Multiplexed -- do not use
 * MIPS_CPU_IRQ_BASE+05 Multiplexed -- do not use
 * MIPS_CPU_IRQ_BASE+06 Multiplexed -- do not use
 * MIPS_CPU_IRQ_BASE+07 CPU TIMER
 *
 * TXX9_IRQ_BASE+00
 * TXX9_IRQ_BASE+01
 * TXX9_IRQ_BASE+02
 * TXX9_IRQ_BASE+03 Cascade RBTX4927-IOC
 * TXX9_IRQ_BASE+04
 * TXX9_IRQ_BASE+05 RBTX4927 RTL-8019AS ethernet
 * TXX9_IRQ_BASE+06
 * TXX9_IRQ_BASE+07
 * TXX9_IRQ_BASE+08 TX4927 SerialIO Channel 0
 * TXX9_IRQ_BASE+09 TX4927 SerialIO Channel 1
 * TXX9_IRQ_BASE+10
 * TXX9_IRQ_BASE+11
 * TXX9_IRQ_BASE+12
 * TXX9_IRQ_BASE+13
 * TXX9_IRQ_BASE+14
 * TXX9_IRQ_BASE+15
 * TXX9_IRQ_BASE+16 TX4927 PCI PCI-C
 * TXX9_IRQ_BASE+17
 * TXX9_IRQ_BASE+18
 * TXX9_IRQ_BASE+19
 * TXX9_IRQ_BASE+20
 * TXX9_IRQ_BASE+21
 * TXX9_IRQ_BASE+22 TX4927 PCI PCI-ERR
 * TXX9_IRQ_BASE+23 TX4927 PCI PCI-PMA (not used)
 * TXX9_IRQ_BASE+24
 * TXX9_IRQ_BASE+25
 * TXX9_IRQ_BASE+26
 * TXX9_IRQ_BASE+27
 * TXX9_IRQ_BASE+28
 * TXX9_IRQ_BASE+29
 * TXX9_IRQ_BASE+30
 * TXX9_IRQ_BASE+31
 *
 * RBTX4927_IRQ_IOC+00 FPCIB0 PCI-D (SouthBridge)
 * RBTX4927_IRQ_IOC+01 FPCIB0 PCI-C (SouthBridge)
 * RBTX4927_IRQ_IOC+02 FPCIB0 PCI-B (SouthBridge/IDE/pin=1,INTR)
 * RBTX4927_IRQ_IOC+03 FPCIB0 PCI-A (SouthBridge/USB/pin=4)
 * RBTX4927_IRQ_IOC+04
 * RBTX4927_IRQ_IOC+05
 * RBTX4927_IRQ_IOC+06
 * RBTX4927_IRQ_IOC+07
 *
 * NOTES:
 * SouthBridge/INTR is mapped to SouthBridge/A=PCI-B/#58
 * SouthBridge/ISA/pin=0 no pci irq used by this device
 * SouthBridge/IDE/pin=1 no pci irq used by this device, using INTR
 * via ISA IRQ14
 * SouthBridge/USB/pin=4 using pci irq SouthBridge/D=PCI-A=#59
 * SouthBridge/PMC/pin=0 no pci irq used by this device
 * SuperIO/PS2/Keyboard, using INTR via ISA IRQ1
 * SuperIO/PS2/Mouse, using INTR via ISA IRQ12 (mouse not currently supported)
 * JP7 is not bus master -- do NOT use -- only 4 pci bus master's
 * allowed -- SouthBridge, JP4, JP5, JP6
 */

#include <linux/init.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <asm/io.h>
#include <asm/mipsregs.h>
#include <asm/txx9/generic.h>
#include <asm/txx9/rbtx4927.h>

static int toshiba_rbtx4927_irq_nested(int sw_irq)
{
	u8 level3;

	level3 = readb(rbtx4927_imstat_addr) & 0x1f;
	if (unlikely(!level3))
		return -1;
	return RBTX4927_IRQ_IOC + __fls8(level3);
}

static void toshiba_rbtx4927_irq_ioc_enable(struct irq_data *d)
{
	unsigned char v;

	v = readb(rbtx4927_imask_addr);
	v |= (1 << (d->irq - RBTX4927_IRQ_IOC));
	writeb(v, rbtx4927_imask_addr);
}

static void toshiba_rbtx4927_irq_ioc_disable(struct irq_data *d)
{
	unsigned char v;

	v = readb(rbtx4927_imask_addr);
	v &= ~(1 << (d->irq - RBTX4927_IRQ_IOC));
	writeb(v, rbtx4927_imask_addr);
	mmiowb();
}

#define TOSHIBA_RBTX4927_IOC_NAME "RBTX4927-IOC"
static struct irq_chip toshiba_rbtx4927_irq_ioc_type = {
	.name = TOSHIBA_RBTX4927_IOC_NAME,
	.irq_mask = toshiba_rbtx4927_irq_ioc_disable,
	.irq_unmask = toshiba_rbtx4927_irq_ioc_enable,
};

static void __init toshiba_rbtx4927_irq_ioc_init(void)
{
	int i;

	/* mask all IOC interrupts */
	writeb(0, rbtx4927_imask_addr);
	/* clear SoftInt interrupts */
	writeb(0, rbtx4927_softint_addr);

	for (i = RBTX4927_IRQ_IOC;
	     i < RBTX4927_IRQ_IOC + RBTX4927_NR_IRQ_IOC; i++)
		irq_set_chip_and_handler(i, &toshiba_rbtx4927_irq_ioc_type,
					 handle_level_irq);
	irq_set_chained_handler(RBTX4927_IRQ_IOCINT, handle_simple_irq);
}

static int rbtx4927_irq_dispatch(int pending)
{
	int irq;

	if (pending & STATUSF_IP7)			/* cpu timer */
		irq = MIPS_CPU_IRQ_BASE + 7;
	else if (pending & STATUSF_IP2) {		/* tx4927 pic */
		irq = txx9_irq();
		if (irq == RBTX4927_IRQ_IOCINT)
			irq = toshiba_rbtx4927_irq_nested(irq);
	} else if (pending & STATUSF_IP0)		/* user line 0 */
		irq = MIPS_CPU_IRQ_BASE + 0;
	else if (pending & STATUSF_IP1)			/* user line 1 */
		irq = MIPS_CPU_IRQ_BASE + 1;
	else
		irq = -1;
	return irq;
}

void __init rbtx4927_irq_setup(void)
{
	txx9_irq_dispatch = rbtx4927_irq_dispatch;
	tx4927_irq_init();
	toshiba_rbtx4927_irq_ioc_init();
	/* Onboard 10M Ether: High Active */
	irq_set_irq_type(RBTX4927_RTL_8019_IRQ, IRQF_TRIGGER_HIGH);
}
