Commit c0af7cb7 authored by Greg Ungerer's avatar Greg Ungerer Committed by Linus Torvalds

[PATCH] make common m68knommu/68328 specific ints.c

Modify the m68knommu/68328 specific ints.c to be the general ints
handler when building for this sub-architecture. It is just simpler to
have one for each sub-architecture (which means we currently need 3
for the 3 prominant m68knommu families). Each can handle the hardware
setup differences, and there is a few at this level. This doesn't
really add much code overall, since 2 of the 3 m68knommu architectures
already had significant specific int handling code.
parent 06af172c
......@@ -30,8 +30,6 @@
#include <asm/MC68VZ328.h>
#endif
#define INTERNAL_IRQS (32)
/* assembler routines */
asmlinkage void system_call(void);
asmlinkage void buserr(void);
......@@ -64,7 +62,7 @@ asmlinkage void trap44(void);
asmlinkage void trap45(void);
asmlinkage void trap46(void);
asmlinkage void trap47(void);
asmlinkage void bad_interrupt(void);
asmlinkage void bad_interrupt(int, void *, struct pt_regs *);
asmlinkage void inthandler(void);
asmlinkage void inthandler1(void);
asmlinkage void inthandler2(void);
......@@ -76,50 +74,49 @@ asmlinkage void inthandler7(void);
extern e_vector *_ramvec;
/* irq node variables for the 32 (potential) on chip sources */
static irq_node_t *int_irq_list[INTERNAL_IRQS];
static int int_irq_count[INTERNAL_IRQS];
static short int_irq_ablecount[INTERNAL_IRQS];
/* The number of spurious interrupts */
volatile unsigned int num_spurious;
unsigned int local_irq_count[NR_CPUS];
static void int_badint(int irq, void *dev_id, struct pt_regs *fp)
{
num_spurious += 1;
}
/* irq node variables for the 32 (potential) on chip sources */
static irq_node_t int_irq_list[NR_IRQS];
asm ("
.global _start, __ramend
.section .romvec
e_vectors:
.long __ramend-4, _start, buserr, trap, trap, trap, trap, trap
.long trap, trap, trap, trap, trap, trap, trap, trap
.long trap, trap, trap, trap, trap, trap, trap, trap
.long trap, trap, trap, trap
.long trap, trap, trap, trap
/*.long inthandler, inthandler, inthandler, inthandler
.long inthandler4, inthandler, inthandler, inthandler */
/* TRAP #0-15 */
.long system_call, trap, trap, trap, trap, trap, trap, trap
.long trap, trap, trap, trap, trap, trap, trap, trap
.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.text
ignore: rte
");
/*
* This function should be called during kernel startup to initialize
* the amiga IRQ handling routines.
* the IRQ handling routines.
*/
void M68328_init_IRQ(void)
void init_IRQ(void)
{
int i;
/* set up the vectors */
#ifdef CONFIG_DRAGON2
for (i=2; i < 32; ++i)
_ramvec[i] = bad_interrupt;
_ramvec[2] = buserr;
_ramvec[3] = trap3;
_ramvec[4] = trap4;
_ramvec[5] = trap5;
_ramvec[6] = trap6;
_ramvec[7] = trap7;
_ramvec[8] = trap8;
_ramvec[9] = trap9;
_ramvec[10] = trap10;
_ramvec[11] = trap11;
_ramvec[12] = trap12;
_ramvec[13] = trap13;
_ramvec[14] = trap14;
_ramvec[15] = trap15;
#endif
for (i = 72; i < 256; ++i)
_ramvec[i] = (e_vector)bad_interrupt;
_ramvec[32] = system_call;
_ramvec[64] = bad_interrupt;
_ramvec[65] = inthandler1;
_ramvec[66] = inthandler2;
_ramvec[67] = inthandler3;
......@@ -131,148 +128,85 @@ void M68328_init_IRQ(void)
IVR = 0x40; /* Set DragonBall IVR (interrupt base) to 64 */
/* initialize handlers */
for (i = 0; i < INTERNAL_IRQS; i++) {
int_irq_list[i] = NULL;
int_irq_ablecount[i] = 0;
int_irq_count[i] = 0;
for (i = 0; i < NR_IRQS; i++) {
int_irq_list[i].handler = bad_interrupt;
int_irq_list[i].flags = IRQ_FLG_STD;
int_irq_list[i].dev_id = NULL;
int_irq_list[i].devname = NULL;
}
/* turn off all interrupts */
IMR = ~0;
}
void M68328_insert_irq(irq_node_t **list, irq_node_t *node)
{
unsigned long flags;
irq_node_t *cur;
if (!node->dev_id)
printk("%s: Warning: dev_id of %s is zero\n",
__FUNCTION__, node->devname);
local_irq_save(flags);
cur = *list;
while (cur) {
list = &cur->next;
cur = cur->next;
}
node->next = cur;
*list = node;
local_irq_restore(flags);
}
void M68328_delete_irq(irq_node_t **list, void *dev_id)
{
unsigned long flags;
irq_node_t *node;
local_irq_save(flags);
for (node = *list; node; list = &node->next, node = *list) {
if (node->dev_id == dev_id) {
*list = node->next;
/* Mark it as free. */
node->handler = NULL;
local_irq_restore(flags);
return;
}
}
local_irq_restore(flags);
printk("%s: tried to remove invalid irq\n", __FUNCTION__);
}
int M68328_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
unsigned long flags, const char *devname, void *dev_id)
{
if (irq >= INTERNAL_IRQS) {
if (irq >= NR_IRQS) {
printk ("%s: Unknown IRQ %d from %s\n", __FUNCTION__, irq, devname);
return -ENXIO;
}
if (!int_irq_list[irq]) {
int_irq_list[irq] = new_irq_node();
int_irq_list[irq]->flags = IRQ_FLG_STD;
}
if (!(int_irq_list[irq]->flags & IRQ_FLG_STD)) {
if (int_irq_list[irq]->flags & IRQ_FLG_LOCK) {
if (!(int_irq_list[irq].flags & IRQ_FLG_STD)) {
if (int_irq_list[irq].flags & IRQ_FLG_LOCK) {
printk("%s: IRQ %d from %s is not replaceable\n",
__FUNCTION__, irq, int_irq_list[irq]->devname);
__FUNCTION__, irq, int_irq_list[irq].devname);
return -EBUSY;
}
if (flags & IRQ_FLG_REPLACE) {
printk("%s: %s can't replace IRQ %d from %s\n",
__FUNCTION__, devname, irq, int_irq_list[irq]->devname);
__FUNCTION__, devname, irq, int_irq_list[irq].devname);
return -EBUSY;
}
}
int_irq_list[irq]->handler = handler;
int_irq_list[irq]->flags = flags;
int_irq_list[irq]->dev_id = dev_id;
int_irq_list[irq]->devname = devname;
/* enable in the IMR */
if (!int_irq_ablecount[irq])
int_irq_list[irq].handler = handler;
int_irq_list[irq].flags = flags;
int_irq_list[irq].dev_id = dev_id;
int_irq_list[irq].devname = devname;
IMR &= ~(1<<irq);
return 0;
}
void M68328_free_irq(unsigned int irq, void *dev_id)
void free_irq(unsigned int irq, void *dev_id)
{
if (irq >= INTERNAL_IRQS) {
if (irq >= NR_IRQS) {
printk ("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
return;
}
if (int_irq_list[irq]->dev_id != dev_id)
if (int_irq_list[irq].dev_id != dev_id)
printk("%s: removing probably wrong IRQ %d from %s\n",
__FUNCTION__, irq, int_irq_list[irq]->devname);
int_irq_list[irq]->handler = int_badint;
int_irq_list[irq]->flags = IRQ_FLG_STD;
int_irq_list[irq]->dev_id = NULL;
int_irq_list[irq]->devname = NULL;
__FUNCTION__, irq, int_irq_list[irq].devname);
int_irq_list[irq].handler = bad_interrupt;
int_irq_list[irq].flags = IRQ_FLG_STD;
int_irq_list[irq].dev_id = NULL;
int_irq_list[irq].devname = NULL;
IMR |= 1<<irq;
}
/*
* Enable/disable a particular machine specific interrupt source.
* Note that this may affect other interrupts in case of a shared interrupt.
* This function should only be called for a _very_ short time to change some
* internal data, that may not be changed by the interrupt at the same time.
* int_(enable|disable)_irq calls may also be nested.
*/
void M68328_enable_irq(unsigned int irq)
int show_interrupts(struct seq_file *p, void *v)
{
if (irq >= INTERNAL_IRQS) {
printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
return;
}
if (--int_irq_ablecount[irq])
return;
int i;
/* enable the interrupt */
IMR &= ~(1<<irq);
}
for (i = 0; i < NR_IRQS; i++) {
if (int_irq_list[i].flags & IRQ_FLG_STD)
continue;
void M68328_disable_irq(unsigned int irq)
{
if (irq >= INTERNAL_IRQS) {
printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
return;
seq_printf(p, "%3d: %10u ", i, kstat_cpu(0).irqs[i]);
if (int_irq_list[i].flags & IRQ_FLG_LOCK)
seq_printf(p, "L ");
else
seq_printf(p, " ");
seq_printf(p, "%s\n", int_irq_list[i].devname);
}
seq_printf(p, " : %10u spurious", num_spurious);
if (int_irq_ablecount[irq]++)
return;
/* disable the interrupt */
IMR |= 1<<irq;
return 0;
}
/* The 68k family did not have a good way to determine the source
......@@ -281,7 +215,7 @@ void M68328_disable_irq(unsigned int irq)
* into one vector and look in the blasted mask register...
* This code is designed to be fast, almost constant time, not clean!
*/
void M68328_do_irq(int vec, struct pt_regs *fp)
void process_int(int vec, struct pt_regs *fp)
{
int irq;
int mask;
......@@ -332,9 +266,10 @@ void M68328_do_irq(int vec, struct pt_regs *fp)
irq++;
}
if (int_irq_list[irq] && int_irq_list[irq]->handler) {
int_irq_list[irq]->handler(irq, int_irq_list[irq]->dev_id, fp);
int_irq_count[irq]++;
kstat_cpu(0).irqs[irq]++;
if (int_irq_list[irq].handler) {
int_irq_list[irq].handler(irq, int_irq_list[irq].dev_id, fp);
} else {
printk("unregistered interrupt %d!\nTurning it off in the IMR...\n", irq);
IMR |= mask;
......@@ -342,14 +277,3 @@ void M68328_do_irq(int vec, struct pt_regs *fp)
pend &= ~mask;
}
}
void config_M68328_irq(void)
{
mach_default_handler = NULL;
mach_init_IRQ = M68328_init_IRQ;
mach_request_irq = M68328_request_irq;
mach_free_irq = M68328_free_irq;
mach_enable_irq = M68328_enable_irq;
mach_disable_irq = M68328_disable_irq;
mach_process_int = M68328_do_irq;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment