/*
 *
 * Copyright 2002 Momentum Computer
 * Author: mdharm@momenco.com
 *
 * arch/mips/momentum/ocelot_g/gt_irq.c
 *     Interrupt routines for gt64240.  Currently it only handles timer irq.
 *
 * 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.
 */
#include <linux/config.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <asm/ptrace.h>
#include <linux/sched.h>
#include <linux/kernel_stat.h>
#include <asm/gt64240.h>
#include <asm/io.h>

unsigned long bus_clock;

/*
 * These are interrupt handlers for the GT on-chip interrupts.  They
 * all come in to the MIPS on a single interrupt line, and have to
 * be handled and ack'ed differently than other MIPS interrupts.
 */

#if CURRENTLY_UNUSED

struct tq_struct irq_handlers[MAX_CAUSE_REGS][MAX_CAUSE_REG_WIDTH];
void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr);

/*
 * Hooks IRQ handler to the system. When the system is interrupted
 * the interrupt service routine is called.
 *
 * Inputs :
 * int_cause - The interrupt cause number. In EVB64120 two parameters
 *             are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH.
 * bit_num   - Indicates which bit number in the cause register
 * isr_ptr   - Pointer to the interrupt service routine
 */
void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr)
{
	irq_handlers[int_cause][bit_num].routine = isr_ptr;
}


/*
 * Enables the IRQ on Galileo Chip
 *
 * Inputs :
 * int_cause - The interrupt cause number. In EVB64120 two parameters
 *             are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH.
 * bit_num   - Indicates which bit number in the cause register
 *
 * Outputs :
 * 1 if succesful, 0 if failure
 */
int enable_galileo_irq(int int_cause, int bit_num)
{
	if (int_cause == INT_CAUSE_MAIN)
		SET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER, (1 << bit_num));
	else if (int_cause == INT_CAUSE_HIGH)
		SET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER,
			     (1 << bit_num));
	else
		return 0;

	return 1;
}

/*
 * Disables the IRQ on Galileo Chip
 *
 * Inputs :
 * int_cause - The interrupt cause number. In EVB64120 two parameters
 *             are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH.
 * bit_num   - Indicates which bit number in the cause register
 *
 * Outputs :
 * 1 if succesful, 0 if failure
 */
int disable_galileo_irq(int int_cause, int bit_num)
{
	if (int_cause == INT_CAUSE_MAIN)
		RESET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER,
			       (1 << bit_num));
	else if (int_cause == INT_CAUSE_HIGH)
		RESET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER,
			       (1 << bit_num));
	else
		return 0;
	return 1;
}
#endif				/*  UNUSED  */

/*
 * Interrupt handler for interrupts coming from the Galileo chip via P0_INT#.
 *
 * We route the timer interrupt to P0_INT# (IRQ 6), and that's all this
 * routine can handle, for now.
 *
 * In the future, we'll route more interrupts to this pin, and that's why
 * we keep this particular structure in the function.
 */

static irqreturn_t gt64240_p0int_irq(int irq, void *dev, struct pt_regs *regs)
{
	uint32_t irq_src, irq_src_mask;
	int handled;

	/* get the low interrupt cause register */
	irq_src = MV_READ(LOW_INTERRUPT_CAUSE_REGISTER);

	/* get the mask register for this pin */
	irq_src_mask = MV_READ(PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW);

	/* mask off only the interrupts we're interested in */
	irq_src = irq_src & irq_src_mask;

	handled = IRQ_NONE;

	/* Check for timer interrupt */
	if (irq_src & 0x00000100) {
		handled = IRQ_HANDLED;
		irq_src &= ~0x00000100;

		/* Clear any pending cause bits */
		MV_WRITE(TIMER_COUNTER_0_3_INTERRUPT_CAUSE, 0x0);

		/* handle the timer call */
		do_timer(regs);
#ifndef CONFIG_SMP
		update_process_times(user_mode(regs));
#endif
	}

	if (irq_src) {
		printk(KERN_INFO
		       "UNKNOWN P0_INT# interrupt received, irq_src=0x%x\n",
		       irq_src);
	}

	return handled;
}

/*
 * Initializes timer using galileo's built in timer.
 */

/*
 * This will ignore the standard MIPS timer interrupt handler
 * that is passed in as *irq (=irq0 in ../kernel/time.c).
 * We will do our own timer interrupt handling.
 */
void gt64240_time_init(void)
{
	static struct irqaction timer;

	/* Stop the timer -- we'll use timer #0 */
	MV_WRITE(TIMER_COUNTER_0_3_CONTROL, 0x0);

	/* Load timer value for 100 Hz */
	MV_WRITE(TIMER_COUNTER0, bus_clock / 100);

	/*
	 * Create the IRQ structure entry for the timer.  Since we're too early
	 * in the boot process to use the "request_irq()" call, we'll hard-code
	 * the values to the correct interrupt line.
	 */
	timer.handler = &gt64240_p0int_irq;
	timer.flags = SA_SHIRQ | SA_INTERRUPT;
	timer.name = "timer";
	timer.dev_id = NULL;
	timer.next = NULL;
	timer.mask = 0;
	irq_desc[6].action = &timer;

	enable_irq(6);

	/* Clear any pending cause bits */
	MV_WRITE(TIMER_COUNTER_0_3_INTERRUPT_CAUSE, 0x0);

	/* Enable the interrupt for timer 0 */
	MV_WRITE(TIMER_COUNTER_0_3_INTERRUPT_MASK, 0x1);

	/* Enable the timer interrupt for GT-64240 pin P0_INT# */
	MV_WRITE (PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW, 0x100);

	/* Configure and start the timer */
	MV_WRITE(TIMER_COUNTER_0_3_CONTROL, 0x3);
}

void gt64240_irq_init(void)
{
#if CURRENTLY_UNUSED
	int i, j;

	/* Reset irq handlers pointers to NULL */
	for (i = 0; i < MAX_CAUSE_REGS; i++) {
		for (j = 0; j < MAX_CAUSE_REG_WIDTH; j++) {
			irq_handlers[i][j].next = NULL;
			irq_handlers[i][j].sync = 0;
			irq_handlers[i][j].routine = NULL;
			irq_handlers[i][j].data = NULL;
		}
	}
#endif
}
