/*
 *
 * By Dustin McIntire (dustin@sensoria.com) (c)2001
 *
 * Setup and IRQ handling code for the HD64465 companion chip.
 * by Greg Banks <gbanks@pocketpenguins.com>
 * Copyright (c) 2000 PocketPenguins Inc
 *
 * Derived from setup_hd64465.c which bore the message:
 * Greg Banks <gbanks@pocketpenguins.com>
 * Copyright (c) 2000 PocketPenguins Inc and
 * Copyright (C) 2000 YAEGASHI Takeshi
 * and setup_cqreek.c which bore message:
 * Copyright (C) 2000  Niibe Yutaka
 *
 * May be copied or modified under the terms of the GNU General Public
 * License.  See linux/COPYING for more information.
 *
 * IRQ functions for a Hitachi Big Sur Evaluation Board.
 *
 */

#include <linux/config.h>
#include <linux/sched.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/bitops.h>

#include <asm/io.h>
#include <asm/irq.h>

#include <asm/bigsur/io.h>
#include <asm/hd64465/hd64465.h>
#include <asm/bigsur/bigsur.h>

//#define BIGSUR_DEBUG 3
#undef BIGSUR_DEBUG

#ifdef BIGSUR_DEBUG
#define DPRINTK(args...)        printk(args)
#define DIPRINTK(n, args...)    if (BIGSUR_DEBUG>(n)) printk(args)
#else
#define DPRINTK(args...)
#define DIPRINTK(n, args...)
#endif /* BIGSUR_DEBUG */

#ifdef CONFIG_HD64465
extern int hd64465_irq_demux(int irq);
#endif /* CONFIG_HD64465 */


/*===========================================================*/
//              Big Sur CPLD IRQ Routines
/*===========================================================*/

/* Level 1 IRQ routines */
static void disable_bigsur_l1irq(unsigned int irq)
{
        unsigned long flags;
        unsigned char mask;
        unsigned int mask_port = ((irq - BIGSUR_IRQ_LOW)/8) ? BIGSUR_IRLMR1 : BIGSUR_IRLMR0;
        unsigned char bit =  (1 << ((irq - MGATE_IRQ_LOW)%8) );

        if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
                DPRINTK("Disable L1 IRQ %d\n", irq);
                DIPRINTK(2,"disable_bigsur_l1irq: IMR=0x%08x mask=0x%x\n",
                        mask_port, bit);
                local_irq_save(flags);

                /* Disable IRQ - set mask bit */
                mask = inb(mask_port) | bit;
                outb(mask, mask_port);
                local_irq_restore(flags);
                return;
        }
        DPRINTK("disable_bigsur_l1irq: Invalid IRQ %d\n", irq);
}

static void enable_bigsur_l1irq(unsigned int irq)
{
        unsigned long flags;
        unsigned char mask;
        unsigned int mask_port = ((irq - BIGSUR_IRQ_LOW)/8) ? BIGSUR_IRLMR1 : BIGSUR_IRLMR0;
        unsigned char bit =  (1 << ((irq - MGATE_IRQ_LOW)%8) );

        if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
                DPRINTK("Enable L1 IRQ %d\n", irq);
                DIPRINTK(2,"enable_bigsur_l1irq: IMR=0x%08x mask=0x%x\n",
                        mask_port, bit);
                local_irq_save(flags);
                /* Enable L1 IRQ - clear mask bit */
                mask = inb(mask_port) & ~bit;
                outb(mask, mask_port);
                local_irq_restore(flags);
                return;
        }
        DPRINTK("enable_bigsur_l1irq: Invalid IRQ %d\n", irq);
}


/* Level 2 irq masks and registers for L2 decoding */
/* Level2 bitmasks for each level 1 IRQ */
const u32 bigsur_l2irq_mask[] =
    {0x40,0x80,0x08,0x01,0x01,0x3C,0x3E,0xFF,0x40,0x80,0x06,0x03};
/* Level2 to ISR[n] map for each level 1 IRQ */
const u32 bigsur_l2irq_reg[]  =
    {   2,   2,   3,   3,   1,   2,   1,   0,   1,   1,   3,   2};
/* Level2 to Level 1 IRQ map */
const u32 bigsur_l2_l1_map[]  =
    {7,7,7,7,7,7,7,7, 4,6,6,6,6,6,8,9, 11,11,5,5,5,5,0,1, 3,10,10,2,-1,-1,-1,-1};
/* IRQ inactive level (high or low) */
const u32 bigsur_l2_inactv_state[]  =   {0x00, 0xBE, 0xFC, 0xF7};

/* CPLD external status and mask registers base and offsets */
static const u32 isr_base = BIGSUR_IRQ0;
static const u32 isr_offset = BIGSUR_IRQ0 - BIGSUR_IRQ1;
static const u32 imr_base = BIGSUR_IMR0;
static const u32 imr_offset = BIGSUR_IMR0 - BIGSUR_IMR1;

#define REG_NUM(irq)  ((irq-BIGSUR_2NDLVL_IRQ_LOW)/8 )

/* Level 2 IRQ routines */
static void disable_bigsur_l2irq(unsigned int irq)
{
        unsigned long flags;
        unsigned char mask;
        unsigned char bit = 1 << ((irq-BIGSUR_2NDLVL_IRQ_LOW)%8);
        unsigned int mask_port = imr_base - REG_NUM(irq)*imr_offset;

    if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) {
                DPRINTK("Disable L2 IRQ %d\n", irq);
                DIPRINTK(2,"disable_bigsur_l2irq: IMR=0x%08x mask=0x%x\n",
                        mask_port, bit);
                local_irq_save(flags);

                /* Disable L2 IRQ - set mask bit */
                mask = inb(mask_port) | bit;
                outb(mask, mask_port);
                local_irq_restore(flags);
                return;
        }
        DPRINTK("disable_bigsur_l2irq: Invalid IRQ %d\n", irq);
}

static void enable_bigsur_l2irq(unsigned int irq)
{
        unsigned long flags;
        unsigned char mask;
        unsigned char bit = 1 << ((irq-BIGSUR_2NDLVL_IRQ_LOW)%8);
        unsigned int mask_port = imr_base - REG_NUM(irq)*imr_offset;

    if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) {
                DPRINTK("Enable L2 IRQ %d\n", irq);
                DIPRINTK(2,"enable_bigsur_l2irq: IMR=0x%08x mask=0x%x\n",
                        mask_port, bit);
                local_irq_save(flags);

                /* Enable L2 IRQ - clear mask bit */
                mask = inb(mask_port) & ~bit;
                outb(mask, mask_port);
                local_irq_restore(flags);
                return;
        }
        DPRINTK("enable_bigsur_l2irq: Invalid IRQ %d\n", irq);
}

static void mask_and_ack_bigsur(unsigned int irq)
{
        DPRINTK("mask_and_ack_bigsur IRQ %d\n", irq);
        if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH)
                disable_bigsur_l1irq(irq);
        else
                disable_bigsur_l2irq(irq);
}

static void end_bigsur_irq(unsigned int irq)
{
        DPRINTK("end_bigsur_irq IRQ %d\n", irq);
        if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
                if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH)
                        enable_bigsur_l1irq(irq);
                else
                        enable_bigsur_l2irq(irq);
        }
}

static unsigned int startup_bigsur_irq(unsigned int irq)
{
        u8 mask;
        u32 reg;

        DPRINTK("startup_bigsur_irq IRQ %d\n", irq);

        if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
                /* Enable the L1 IRQ */
                enable_bigsur_l1irq(irq);
                /* Enable all L2 IRQs in this L1 IRQ */
                mask = ~(bigsur_l2irq_mask[irq-BIGSUR_IRQ_LOW]);
                reg = imr_base - bigsur_l2irq_reg[irq-BIGSUR_IRQ_LOW] * imr_offset;
                mask &= inb(reg);
                outb(mask,reg);
                DIPRINTK(2,"startup_bigsur_irq: IMR=0x%08x mask=0x%x\n",reg,inb(reg));
        }
        else {
                /* Enable the L2 IRQ - clear mask bit */
                enable_bigsur_l2irq(irq);
                /* Enable the L1 bit masking this L2 IRQ */
                enable_bigsur_l1irq(bigsur_l2_l1_map[irq-BIGSUR_2NDLVL_IRQ_LOW]);
                DIPRINTK(2,"startup_bigsur_irq: L1=%d L2=%d\n",
                        bigsur_l2_l1_map[irq-BIGSUR_2NDLVL_IRQ_LOW],irq);
        }
        return 0;
}

static void shutdown_bigsur_irq(unsigned int irq)
{
        DPRINTK("shutdown_bigsur_irq IRQ %d\n", irq);
        if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH)
                disable_bigsur_l1irq(irq);
        else
                disable_bigsur_l2irq(irq);
}

/* Define the IRQ structures for the L1 and L2 IRQ types */
static struct hw_interrupt_type bigsur_l1irq_type = {
	.typename  = "BigSur-CPLD-Level1-IRQ",
	.startup = startup_bigsur_irq,
	.shutdown = shutdown_bigsur_irq,
	.enable = enable_bigsur_l1irq,
	.disable = disable_bigsur_l1irq,
	.ack = mask_and_ack_bigsur,
	.end = end_bigsur_irq
};

static struct hw_interrupt_type bigsur_l2irq_type = {
	.typename  = "BigSur-CPLD-Level2-IRQ",
	.startup = startup_bigsur_irq,
	.shutdown  =shutdown_bigsur_irq,
	.enable = enable_bigsur_l2irq,
	.disable = disable_bigsur_l2irq,
	.ack = mask_and_ack_bigsur,
	.end = end_bigsur_irq
};


static void make_bigsur_l1isr(unsigned int irq) {

        /* sanity check first */
        if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
                /* save the handler in the main description table */
                irq_desc[irq].chip = &bigsur_l1irq_type;
                irq_desc[irq].status = IRQ_DISABLED;
                irq_desc[irq].action = 0;
                irq_desc[irq].depth = 1;

                disable_bigsur_l1irq(irq);
                return;
        }
        DPRINTK("make_bigsur_l1isr: bad irq, %d\n", irq);
        return;
}

static void make_bigsur_l2isr(unsigned int irq) {

        /* sanity check first */
        if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) {
                /* save the handler in the main description table */
                irq_desc[irq].chip = &bigsur_l2irq_type;
                irq_desc[irq].status = IRQ_DISABLED;
                irq_desc[irq].action = 0;
                irq_desc[irq].depth = 1;

                disable_bigsur_l2irq(irq);
                return;
        }
        DPRINTK("make_bigsur_l2isr: bad irq, %d\n", irq);
        return;
}

/* The IRQ's will be decoded as follows:
 * If a level 2 handler exists and there is an unmasked active
 * IRQ, the 2nd level handler will be called.
 * If a level 2 handler does not exist for the active IRQ
 * the 1st level handler will be called.
 */

int bigsur_irq_demux(int irq)
{
        int dmux_irq = irq;
        u8 mask, actv_irqs;
        u32 reg_num;

        DIPRINTK(3,"bigsur_irq_demux, irq=%d\n", irq);
        /* decode the 1st level IRQ */
        if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
                /* Get corresponding L2 ISR bitmask and ISR number */
                mask = bigsur_l2irq_mask[irq-BIGSUR_IRQ_LOW];
                reg_num = bigsur_l2irq_reg[irq-BIGSUR_IRQ_LOW];
                /* find the active IRQ's (XOR with inactive level)*/
                actv_irqs = inb(isr_base-reg_num*isr_offset) ^
                                        bigsur_l2_inactv_state[reg_num];
                /* decode active IRQ's */
                actv_irqs = actv_irqs & mask & ~(inb(imr_base-reg_num*imr_offset));
                /* if NEZ then we have an active L2 IRQ */
                if(actv_irqs) dmux_irq = ffz(~actv_irqs) + reg_num*8+BIGSUR_2NDLVL_IRQ_LOW;
                /* if no 2nd level IRQ action, but has 1st level, use 1st level handler */
                if(!irq_desc[dmux_irq].action && irq_desc[irq].action)
                        dmux_irq = irq;
                DIPRINTK(1,"bigsur_irq_demux: irq=%d dmux_irq=%d mask=0x%04x reg=%d\n",
                        irq, dmux_irq, mask, reg_num);
        }
#ifdef CONFIG_HD64465
        dmux_irq = hd64465_irq_demux(dmux_irq);
#endif /* CONFIG_HD64465 */
        DIPRINTK(3,"bigsur_irq_demux, demux_irq=%d\n", dmux_irq);

        return dmux_irq;
}

/*===========================================================*/
//              Big Sur Init Routines
/*===========================================================*/
void __init init_bigsur_IRQ(void)
{
        int i;

        if (!MACH_BIGSUR) return;

        /* Create ISR's for Big Sur CPLD IRQ's */
        /*==============================================================*/
        for(i=BIGSUR_IRQ_LOW;i<BIGSUR_IRQ_HIGH;i++)
                make_bigsur_l1isr(i);

        printk(KERN_INFO "Big Sur CPLD L1 interrupts %d to %d.\n",
                BIGSUR_IRQ_LOW,BIGSUR_IRQ_HIGH);

        for(i=BIGSUR_2NDLVL_IRQ_LOW;i<BIGSUR_2NDLVL_IRQ_HIGH;i++)
                make_bigsur_l2isr(i);

        printk(KERN_INFO "Big Sur CPLD L2 interrupts %d to %d.\n",
                BIGSUR_2NDLVL_IRQ_LOW,BIGSUR_2NDLVL_IRQ_HIGH);

}
