/*
 *  linux/arch/m68k/amiga/cia.c - CIA support
 *
 *  Copyright (C) 1996 Roman Zippel
 *
 *  The concept of some functions bases on the original Amiga OS function
 *
 * 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.
 */

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/kernel_stat.h>
#include <linux/init.h>

#include <asm/irq.h>
#include <asm/amigahw.h>
#include <asm/amigaints.h>

struct ciabase {
	volatile struct CIA *cia;
	u_char icr_mask, icr_data;
	u_short int_mask;
	int handler_irq, cia_irq, server_irq;
	char *name;
} ciaa_base = {
	&ciaa, 0, 0, IF_PORTS,
	IRQ_AMIGA_AUTO_2, IRQ_AMIGA_CIAA,
	IRQ_AMIGA_PORTS,
	"CIAA handler"
}, ciab_base = {
	&ciab, 0, 0, IF_EXTER,
	IRQ_AMIGA_AUTO_6, IRQ_AMIGA_CIAB,
	IRQ_AMIGA_EXTER,
	"CIAB handler"
};

#define CIA_SET_BASE_ADJUST_IRQ(base, irq)	\
do {						\
	if (irq >= IRQ_AMIGA_CIAB) {		\
		base = &ciab_base;		\
		irq -= IRQ_AMIGA_CIAB;		\
	} else {				\
		base = &ciaa_base;		\
		irq -= IRQ_AMIGA_CIAA;		\
	}					\
} while (0)

/*
 *  Cause or clear CIA interrupts, return old interrupt status.
 */

static unsigned char cia_set_irq_private(struct ciabase *base,
					 unsigned char mask)
{
	u_char old;

	old = (base->icr_data |= base->cia->icr);
	if (mask & CIA_ICR_SETCLR)
		base->icr_data |= mask;
	else
		base->icr_data &= ~mask;
	if (base->icr_data & base->icr_mask)
		custom.intreq = IF_SETCLR | base->int_mask;
	return old & base->icr_mask;
}

unsigned char cia_set_irq(unsigned int irq, int set)
{
	struct ciabase *base;
	unsigned char mask;

	if (irq >= IRQ_AMIGA_CIAB)
		mask = (1 << (irq - IRQ_AMIGA_CIAB));
	else
		mask = (1 << (irq - IRQ_AMIGA_CIAA));
	mask |= (set) ? CIA_ICR_SETCLR : 0;

	CIA_SET_BASE_ADJUST_IRQ(base, irq);

	return cia_set_irq_private(base, mask);
}

unsigned char cia_get_irq_mask(unsigned int irq)
{
	struct ciabase *base;

	CIA_SET_BASE_ADJUST_IRQ(base, irq);

	return base->cia->icr;
}

/*
 *  Enable or disable CIA interrupts, return old interrupt mask.
 */

static unsigned char cia_able_irq_private(struct ciabase *base,
					  unsigned char mask)
{
	u_char old;

	old = base->icr_mask;
	base->icr_data |= base->cia->icr;
	base->cia->icr = mask;
	if (mask & CIA_ICR_SETCLR)
		base->icr_mask |= mask;
	else
		base->icr_mask &= ~mask;
	base->icr_mask &= CIA_ICR_ALL;

	if (base->icr_data & base->icr_mask)
		custom.intreq = IF_SETCLR | base->int_mask;
	return old;
}

unsigned char cia_able_irq(unsigned int irq, int enable)
{
	struct ciabase *base;
	unsigned char mask;

	if (irq >= IRQ_AMIGA_CIAB)
		mask = (1 << (irq - IRQ_AMIGA_CIAB));
	else
		mask = (1 << (irq - IRQ_AMIGA_CIAA));
	mask |= (enable) ? CIA_ICR_SETCLR : 0;

	CIA_SET_BASE_ADJUST_IRQ(base, irq);

	return cia_able_irq_private(base, mask);
}

static void cia_handler(int irq, void *dev_id, struct pt_regs *fp)
{
	struct ciabase *base = (struct ciabase *)dev_id;
	irq_desc_t *desc;
	struct irqaction *action;
	int i;
	unsigned char ints;

	irq = base->cia_irq;
	desc = irq_desc + irq;
	ints = cia_set_irq_private(base, CIA_ICR_ALL);
	custom.intreq = base->int_mask;
	for (i = 0; i < CIA_IRQS; i++, irq++) {
		if (ints & 1) {
			kstat.irqs[0][irq]++;
			action = desc->action;
			action->handler(irq, action->dev_id, fp);
		}
		ints >>= 1;
		desc++;
	}
	amiga_do_irq_list(base->server_irq, fp);
}

void __init cia_init_IRQ(struct ciabase *base)
{
	extern struct irqaction amiga_sys_irqaction[AUTO_IRQS];
	struct irqaction *action;

	/* clear any pending interrupt and turn off all interrupts */
	cia_set_irq_private(base, CIA_ICR_ALL);
	cia_able_irq_private(base, CIA_ICR_ALL);

	/* install CIA handler */
	action = &amiga_sys_irqaction[base->handler_irq-IRQ_AMIGA_AUTO];
	action->handler = cia_handler;
	action->dev_id = base;
	action->name = base->name;
	setup_irq(base->handler_irq, &amiga_sys_irqaction[base->handler_irq-IRQ_AMIGA_AUTO]);

	custom.intena = IF_SETCLR | base->int_mask;
}
