OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [sh/] [kernel/] [irq_microdev.c] - Rev 1275

Go to most recent revision | Compare with Previous | Blame | View Log

/* 
 * linux/arch/sh/kernel/irq_microdev.c
 *
 * Copyright (C) 2003 Sean McGoogan (Sean.McGoogan@superh.com)
 *
 * SuperH SH4-202 MicroDev board support.
 *
 * May be copied or modified under the terms of the GNU General Public
 * License.  See linux/COPYING for more information.
 */
 
#include <linux/config.h>
#include <linux/init.h>
#include <linux/irq.h>
 
#include <asm/system.h>
#include <asm/io.h>
#include <asm/irq_microdev.h>
 
#define NUM_EXTERNAL_IRQS 16	/* IRL0 .. IRL15 */
 
 
static const struct 
{
	unsigned char fpgaIrq;
	unsigned char mapped;
	const char *name;
}	fpgaIrqTable[NUM_EXTERNAL_IRQS] = 
{
	{ 0,	0,	"unused" },		/* IRQ #0	IRL=15	0x200  */
	{ 0,	0,	"unused" },		/* IRQ #1	IRL=14	0x220  */
	{ 0,	0,	"unused" },		/* IRQ #2	IRL=13	0x240  */
	{ 18,	1,	"Ethernet" },		/* IRQ #3	IRL=12	0x260  */
	{ 0,	0,	"unused" },		/* IRQ #4	IRL=11	0x280  */
	{ 0,	0,	"unused" },		/* IRQ #5	IRL=10	0x2a0  */
	{ 0,	0,	"unused" },		/* IRQ #6	IRL=9	0x2c0  */
	{ 0,	0,	"unused" },		/* IRQ #7	IRL=8	0x2e0  */
	{ 8,	1,	"PCI INTA" },		/* IRQ #8	IRL=7	0x300  */
	{ 9,	1,	"PCI INTB" },		/* IRQ #9	IRL=6	0x320  */
	{ 10,	1,	"PCI INTC" },		/* IRQ #10	IRL=5	0x340  */
	{ 11,	1,	"PCI INTD" },		/* IRQ #11	IRL=4	0x360  */
	{ 0,	0,	"unused" },		/* IRQ #12	IRL=3	0x380  */
	{ 0,	0,	"unused" },		/* IRQ #13	IRL=2	0x3a0  */
	{ 0,	0,	"unused" },		/* IRQ #14	IRL=1	0x3c0  */
	{ 0,	0,	"unused" },		/* IRQ #15	IRL=0	0x3e0  */
};
 
static void enable_microdev_irq(unsigned int irq);
static void disable_microdev_irq(unsigned int irq);
 
	/* shutdown is same as "disable" */
#define shutdown_microdev_irq disable_microdev_irq
 
static void mask_and_ack_microdev(unsigned int);
static void end_microdev_irq(unsigned int irq);
 
static unsigned int startup_microdev_irq(unsigned int irq)
{
	enable_microdev_irq(irq);
	return 0;		/* never anything pending */
}
 
static struct hw_interrupt_type microdev_irq_type = {
	"MicroDev-IRQ",
	startup_microdev_irq,
	shutdown_microdev_irq,
	enable_microdev_irq,
	disable_microdev_irq,
	mask_and_ack_microdev,
	end_microdev_irq
};
 
static void disable_microdev_irq(unsigned int irq)
{
	unsigned int flags; 
	unsigned int fpgaIrq; 
 
	if (irq >= NUM_EXTERNAL_IRQS) return;
	if (!fpgaIrqTable[irq].mapped) return;
 
	fpgaIrq = fpgaIrqTable[irq].fpgaIrq;
 
		/* disable interrupts */
	save_and_cli(flags);
 
		/* disable interupts on the FPGA INTC register */
	ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTDSB_REG);
 
		/* restore interrupts */
	restore_flags(flags);
}
 
static void enable_microdev_irq(unsigned int irq)
{
	unsigned long priorityReg, priorities, pri;
	unsigned int flags; 
	unsigned int fpgaIrq; 
 
 
	if (irq >= NUM_EXTERNAL_IRQS) return;
	if (!fpgaIrqTable[irq].mapped) return;
 
	pri = 15 - irq;
 
	fpgaIrq = fpgaIrqTable[irq].fpgaIrq;
	priorityReg = MICRODEV_FPGA_INTPRI_REG(fpgaIrq);
 
		/* disable interrupts */
	save_and_cli(flags);
 
		/* set priority for the interrupt */
	priorities = ctrl_inl(priorityReg);
	priorities &= ~MICRODEV_FPGA_INTPRI_MASK(fpgaIrq);
	priorities |= MICRODEV_FPGA_INTPRI_LEVEL(fpgaIrq, pri);
	ctrl_outl(priorities, priorityReg);
 
		/* enable interupts on the FPGA INTC register */
	ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTENB_REG);
 
		/* restore interrupts */
	restore_flags(flags);
}
 
	/* This functions sets the desired irq handler to be a MicroDev type */
static void __init make_microdev_irq(unsigned int irq)
{
	disable_irq_nosync(irq);
	irq_desc[irq].handler = &microdev_irq_type;
	disable_microdev_irq(irq);
}
 
static void mask_and_ack_microdev(unsigned int irq)
{
	disable_microdev_irq(irq);
}
 
static void end_microdev_irq(unsigned int irq)
{
	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
	{
		enable_microdev_irq(irq);
	}
}
 
extern void __init init_microdev_irq(void)
{
	int i;
 
		/* disable interupts on the FPGA INTC register */
	ctrl_outl(~0ul, MICRODEV_FPGA_INTDSB_REG);
 
	for (i = 0; i < NUM_EXTERNAL_IRQS; i++)
	{
		make_microdev_irq(i);
	}
}
 
 
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.