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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [sh/] [stboards/] [irq.c] - Rev 1765

Compare with Previous | Blame | View Log

/* 
 * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
 *
 * May be copied or modified under the terms of the GNU General Public
 * License.  See linux/COPYING for more information.                            
 *
 * Looks after interrupts on the HARP board.
 *
 * Bases on the IPR irq system
 */
 
#include <linux/config.h>
#include <linux/init.h>
#include <linux/irq.h>
 
#include <asm/system.h>
#include <asm/io.h>
 
#include "harp.h"
 
 
#define NUM_EXTERNAL_IRQS 16
 
// Early versions of the STB1 Overdrive required this nasty frig
//#define INVERT_INTMASK_WRITES
 
static void enable_harp_irq(unsigned int irq);
static void disable_harp_irq(unsigned int irq);
 
/* shutdown is same as "disable" */
#define shutdown_harp_irq disable_harp_irq
 
static void mask_and_ack_harp(unsigned int);
static void end_harp_irq(unsigned int irq);
 
static unsigned int startup_harp_irq(unsigned int irq)
{
	enable_harp_irq(irq);
	return 0;		/* never anything pending */
}
 
static struct hw_interrupt_type harp_irq_type = {
	"Harp-IRQ",
	startup_harp_irq,
	shutdown_harp_irq,
	enable_harp_irq,
	disable_harp_irq,
	mask_and_ack_harp,
	end_harp_irq
};
 
static void disable_harp_irq(unsigned int irq)
{
	unsigned val, flags;
	unsigned maskReg;
	unsigned mask;
	int pri;
 
	if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
		return;
 
	pri = 15 - irq;
 
	if (pri < 8) {
		maskReg = EPLD_INTMASK0;
	} else {
		maskReg = EPLD_INTMASK1;
		pri -= 8;
	}
 
	save_and_cli(flags);
	mask = ctrl_inl(maskReg);
	mask &= (~(1 << pri));
#if defined(INVERT_INTMASK_WRITES)
	mask ^= 0xff;
#endif
	ctrl_outl(mask, maskReg);
	restore_flags(flags);
}
 
static void enable_harp_irq(unsigned int irq)
{
	unsigned flags;
	unsigned maskReg;
	unsigned mask;
	int pri;
 
	if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
		return;
 
	pri = 15 - irq;
 
	if (pri < 8) {
		maskReg = EPLD_INTMASK0;
	} else {
		maskReg = EPLD_INTMASK1;
		pri -= 8;
	}
 
	save_and_cli(flags);
	mask = ctrl_inl(maskReg);
 
 
	mask |= (1 << pri);
 
#if defined(INVERT_INTMASK_WRITES)
	mask ^= 0xff;
#endif
	ctrl_outl(mask, maskReg);
 
	restore_flags(flags);
}
 
/* This functions sets the desired irq handler to be an overdrive type */
static void __init make_harp_irq(unsigned int irq)
{
	disable_irq_nosync(irq);
	irq_desc[irq].handler = &harp_irq_type;
	disable_harp_irq(irq);
}
 
static void mask_and_ack_harp(unsigned int irq)
{
	disable_harp_irq(irq);
}
 
static void end_harp_irq(unsigned int irq)
{
	enable_harp_irq(irq);
}
 
void __init init_harp_irq(void)
{
	int i;
 
#if !defined(INVERT_INTMASK_WRITES)
	// On the harp these are set to enable an interrupt
	ctrl_outl(0x00, EPLD_INTMASK0);
	ctrl_outl(0x00, EPLD_INTMASK1);
#else
	// On the Overdrive the data is inverted before being stored in the reg
	ctrl_outl(0xff, EPLD_INTMASK0);
	ctrl_outl(0xff, EPLD_INTMASK1);
#endif
 
	for (i = 0; i < NUM_EXTERNAL_IRQS; i++) {
		make_harp_irq(i);
	}
}
 

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.