Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | /*
* linux/arch/m68k/sun3/sun3ints.c -- Sun-3 Linux interrupt handling code
*
* 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/kernel_stat.h>
#include <linux/interrupt.h>
#include <asm/segment.h>
#include <asm/intersil.h>
#include <asm/oplib.h>
#include <asm/sun3ints.h>
extern void sun3_leds (unsigned char);
void sun3_disable_interrupts(void)
{
sun3_disable_irq(0);
}
void sun3_enable_interrupts(void)
{
sun3_enable_irq(0);
}
int led_pattern[8] = {
~(0x80), ~(0x01),
~(0x40), ~(0x02),
~(0x20), ~(0x04),
~(0x10), ~(0x08)
};
unsigned char* sun3_intreg;
void sun3_init_IRQ(void)
{
}
void sun3_insert_irq(irq_node_t **list, irq_node_t *node)
{
}
void sun3_delete_irq(irq_node_t **list, void *dev_id)
{
}
void sun3_free_irq(unsigned int irq, void *dev_id)
{
}
void sun3_enable_irq(unsigned int irq)
{
*sun3_intreg |= (1<<irq);
}
void sun3_disable_irq(unsigned int irq)
{
*sun3_intreg &= ~(1<<irq);
}
inline void sun3_do_irq(int irq, struct pt_regs *fp)
{
kstat.irqs[0][SYS_IRQS + irq]++;
*sun3_intreg &= ~(1<<irq);
*sun3_intreg |= (1<<irq);
}
int sun3_get_irq_list(char *buf)
{
return 0;
}
static void sun3_int5(int irq, void *dev_id, struct pt_regs *fp)
{
kstat.irqs[0][SYS_IRQS + irq]++;
*sun3_intreg &= ~(1<<irq);
intersil_clear();
*sun3_intreg |= (1<<irq);
do_timer(fp);
if(!(kstat.irqs[0][SYS_IRQS + irq] % 20))
sun3_leds(led_pattern[(kstat.irqs[0][SYS_IRQS+irq]%160)
/20]);
}
static void sun3_int7(int irq, void *dev_id, struct pt_regs *fp)
{
sun3_do_irq(irq,fp);
if(!(kstat.irqs[0][SYS_IRQS + irq] % 2000))
sun3_leds(led_pattern[(kstat.irqs[0][SYS_IRQS+irq]%16000)/2000]);
}
/* handle requested ints, excepting 5 and 7, which always do the same
thing */
static void *dev_ids[SYS_IRQS];
static void (*inthandler[SYS_IRQS])(int, void *, struct pt_regs *) = {
NULL, NULL, NULL, NULL, NULL, sun3_int5, NULL, sun3_int7
};
static void sun3_inthandle(int irq, void *dev_id, struct pt_regs *fp)
{
if(inthandler[irq] == NULL)
panic ("bad interrupt %d received (id %p)\n",irq, dev_id);
kstat.irqs[0][SYS_IRQS + irq]++;
*sun3_intreg &= ~(1<<irq);
inthandler[irq](irq, dev_ids[irq], fp);
}
void (*sun3_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = {
sun3_inthandle, sun3_inthandle, sun3_inthandle, sun3_inthandle,
sun3_inthandle, sun3_int5, sun3_inthandle, sun3_int7
};
int sun3_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
unsigned long flags, const char *devname, void *dev_id)
{
if(inthandler[irq] != NULL)
return -1;
inthandler[irq] = handler;
dev_ids[irq] = dev_id;
return 0;
}
|