summaryrefslogtreecommitdiffstats
path: root/arch/m68k/amiga/amiints.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/m68k/amiga/amiints.c')
-rw-r--r--arch/m68k/amiga/amiints.c94
1 files changed, 57 insertions, 37 deletions
diff --git a/arch/m68k/amiga/amiints.c b/arch/m68k/amiga/amiints.c
index 5fe90949e..b527a8c6c 100644
--- a/arch/m68k/amiga/amiints.c
+++ b/arch/m68k/amiga/amiints.c
@@ -97,7 +97,7 @@ void amiga_init_IRQ(void)
cia_init_IRQ(&ciab_base);
}
-void amiga_insert_irq(irq_node_t **list, irq_node_t *node)
+static inline void amiga_insert_irq(irq_node_t **list, irq_node_t *node)
{
unsigned long flags;
irq_node_t *cur;
@@ -135,7 +135,7 @@ void amiga_insert_irq(irq_node_t **list, irq_node_t *node)
restore_flags(flags);
}
-void amiga_delete_irq(irq_node_t **list, void *dev_id)
+static inline void amiga_delete_irq(irq_node_t **list, void *dev_id)
{
unsigned long flags;
irq_node_t *node;
@@ -172,12 +172,16 @@ int amiga_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_r
return -ENXIO;
}
- if (irq >= IRQ_IDX(IRQ_AMIGA_CIAB))
- return cia_request_irq(&ciab_base, irq - IRQ_IDX(IRQ_AMIGA_CIAB),
+ if (irq >= IRQ_AMIGA_AUTO)
+ return sys_request_irq(irq - IRQ_AMIGA_AUTO, handler,
+ flags, devname, dev_id);
+
+ if (irq >= IRQ_AMIGA_CIAB)
+ return cia_request_irq(&ciab_base, irq - IRQ_AMIGA_CIAB,
handler, flags, devname, dev_id);
- if (irq >= IRQ_IDX(IRQ_AMIGA_CIAA))
- return cia_request_irq(&ciaa_base, irq - IRQ_IDX(IRQ_AMIGA_CIAA),
+ if (irq >= IRQ_AMIGA_CIAA)
+ return cia_request_irq(&ciaa_base, irq - IRQ_AMIGA_CIAA,
handler, flags, devname, dev_id);
if (ami_servers[irq]) {
@@ -196,7 +200,7 @@ int amiga_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_r
__FUNCTION__, irq, ami_irq_list[irq]->devname);
return -EBUSY;
}
- if (flags & IRQ_FLG_REPLACE) {
+ if (!(flags & IRQ_FLG_REPLACE)) {
printk("%s: %s can't replace IRQ %d from %s\n",
__FUNCTION__, devname, irq, ami_irq_list[irq]->devname);
return -EBUSY;
@@ -209,7 +213,7 @@ int amiga_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_r
}
/* enable the interrupt */
- if (irq < IRQ_IDX(IRQ_AMIGA_PORTS) && !ami_ablecount[irq])
+ if (irq < IRQ_AMIGA_PORTS && !ami_ablecount[irq])
custom.intena = IF_SETCLR | ami_intena_vals[irq];
return 0;
@@ -222,20 +226,23 @@ void amiga_free_irq(unsigned int irq, void *dev_id)
return;
}
- if (irq >= IRQ_IDX(IRQ_AMIGA_CIAB)) {
- cia_free_irq(&ciab_base, irq - IRQ_IDX(IRQ_AMIGA_CIAB), dev_id);
+ if (irq >= IRQ_AMIGA_AUTO)
+ sys_free_irq(irq - IRQ_AMIGA_AUTO, dev_id);
+
+ if (irq >= IRQ_AMIGA_CIAB) {
+ cia_free_irq(&ciab_base, irq - IRQ_AMIGA_CIAB, dev_id);
return;
}
- if (irq >= IRQ_IDX(IRQ_AMIGA_CIAA)) {
- cia_free_irq(&ciaa_base, irq - IRQ_IDX(IRQ_AMIGA_CIAA), dev_id);
+ if (irq >= IRQ_AMIGA_CIAA) {
+ cia_free_irq(&ciaa_base, irq - IRQ_AMIGA_CIAA, dev_id);
return;
}
if (ami_servers[irq]) {
amiga_delete_irq(&ami_irq_list[irq], dev_id);
/* if server list empty, disable the interrupt */
- if (!ami_irq_list[irq] && irq < IRQ_IDX(IRQ_AMIGA_PORTS))
+ if (!ami_irq_list[irq] && irq < IRQ_AMIGA_PORTS)
custom.intena = ami_intena_vals[irq];
} else {
if (ami_irq_list[irq]->dev_id != dev_id)
@@ -267,15 +274,22 @@ void amiga_enable_irq(unsigned int irq)
if (--ami_ablecount[irq])
return;
- if (irq >= IRQ_IDX(IRQ_AMIGA_CIAB)) {
+ /* No action for auto-vector interrupts */
+ if (irq >= IRQ_AMIGA_AUTO){
+ printk("%s: Trying to enable auto-vector IRQ %i\n",
+ __FUNCTION__, irq - IRQ_AMIGA_AUTO);
+ return;
+ }
+
+ if (irq >= IRQ_AMIGA_CIAB) {
cia_able_irq(&ciab_base, CIA_ICR_SETCLR |
- (1 << (irq - IRQ_IDX(IRQ_AMIGA_CIAB))));
+ (1 << (irq - IRQ_AMIGA_CIAB)));
return;
}
- if (irq >= IRQ_IDX(IRQ_AMIGA_CIAA)) {
+ if (irq >= IRQ_AMIGA_CIAA) {
cia_able_irq(&ciaa_base, CIA_ICR_SETCLR |
- (1 << (irq - IRQ_IDX(IRQ_AMIGA_CIAA))));
+ (1 << (irq - IRQ_AMIGA_CIAA)));
return;
}
@@ -293,13 +307,20 @@ void amiga_disable_irq(unsigned int irq)
if (ami_ablecount[irq]++)
return;
- if (irq >= IRQ_IDX(IRQ_AMIGA_CIAB)) {
- cia_able_irq(&ciab_base, 1 << (irq - IRQ_IDX(IRQ_AMIGA_CIAB)));
+ /* No action for auto-vector interrupts */
+ if (irq >= IRQ_AMIGA_AUTO) {
+ printk("%s: Trying to disable auto-vector IRQ %i\n",
+ __FUNCTION__, irq - IRQ_AMIGA_AUTO);
+ return;
+ }
+
+ if (irq >= IRQ_AMIGA_CIAB) {
+ cia_able_irq(&ciab_base, 1 << (irq - IRQ_AMIGA_CIAB));
return;
}
- if (irq >= IRQ_IDX(IRQ_AMIGA_CIAA)) {
- cia_able_irq(&ciaa_base, 1 << (irq - IRQ_IDX(IRQ_AMIGA_CIAA)));
+ if (irq >= IRQ_AMIGA_CIAA) {
+ cia_able_irq(&ciaa_base, 1 << (irq - IRQ_AMIGA_CIAA));
return;
}
@@ -310,13 +331,12 @@ void amiga_disable_irq(unsigned int irq)
inline void amiga_do_irq(int irq, struct pt_regs *fp)
{
kstat.interrupts[SYS_IRQS + irq]++;
- ami_irq_list[irq]->handler(irq | IRQ_MACHSPEC, ami_irq_list[irq]->dev_id, fp);
+ ami_irq_list[irq]->handler(irq, ami_irq_list[irq]->dev_id, fp);
}
void amiga_do_irq_list(int irq, struct pt_regs *fp, struct irq_server *server)
{
irq_node_t *node, *slow_nodes;
- int mach_irq = irq | IRQ_MACHSPEC;
unsigned short flags;
kstat.interrupts[SYS_IRQS + irq]++;
@@ -326,7 +346,7 @@ void amiga_do_irq_list(int irq, struct pt_regs *fp, struct irq_server *server)
for (node = ami_irq_list[irq];
node && (!(node->flags & IRQ_FLG_SLOW));
node = node->next)
- node->handler(mach_irq, node->dev_id, fp);
+ node->handler(irq, node->dev_id, fp);
custom.intreq = ami_intena_vals[irq];
if (!node) {
server->count--;
@@ -338,7 +358,7 @@ void amiga_do_irq_list(int irq, struct pt_regs *fp, struct irq_server *server)
slow_nodes = node;
for (;;) {
for (; node; node = node->next)
- node->handler(mach_irq, node->dev_id, fp);
+ node->handler(irq, node->dev_id, fp);
/* if reentrance occured, serve slow handlers again */
custom.intena = ami_intena_vals[irq];
if (!server->reentrance) {
@@ -363,19 +383,19 @@ static void ami_int1(int irq, void *dev_id, struct pt_regs *fp)
/* if serial transmit buffer empty, interrupt */
if (ints & IF_TBE) {
custom.intreq = IF_TBE;
- amiga_do_irq(IRQ_IDX(IRQ_AMIGA_TBE), fp);
+ amiga_do_irq(IRQ_AMIGA_TBE, fp);
}
/* if floppy disk transfer complete, interrupt */
if (ints & IF_DSKBLK) {
custom.intreq = IF_DSKBLK;
- amiga_do_irq(IRQ_IDX(IRQ_AMIGA_DSKBLK), fp);
+ amiga_do_irq(IRQ_AMIGA_DSKBLK, fp);
}
/* if software interrupt set, interrupt */
if (ints & IF_SOFT) {
custom.intreq = IF_SOFT;
- amiga_do_irq(IRQ_IDX(IRQ_AMIGA_SOFT), fp);
+ amiga_do_irq(IRQ_AMIGA_SOFT, fp);
}
}
@@ -387,18 +407,18 @@ static void ami_int3(int irq, void *dev_id, struct pt_regs *fp)
/* if a blitter interrupt */
if (ints & IF_BLIT) {
custom.intreq = IF_BLIT;
- amiga_do_irq(IRQ_IDX(IRQ_AMIGA_BLIT), fp);
+ amiga_do_irq(IRQ_AMIGA_BLIT, fp);
}
/* if a copper interrupt */
if (ints & IF_COPER) {
custom.intreq = IF_COPER;
- amiga_do_irq(IRQ_IDX(IRQ_AMIGA_COPPER), fp);
+ amiga_do_irq(IRQ_AMIGA_COPPER, fp);
}
/* if a vertical blank interrupt */
if (ints & IF_VERTB)
- amiga_do_irq_list(IRQ_IDX(IRQ_AMIGA_VERTB), fp, &server);
+ amiga_do_irq_list(IRQ_AMIGA_VERTB, fp, &server);
}
static void ami_int4(int irq, void *dev_id, struct pt_regs *fp)
@@ -408,25 +428,25 @@ static void ami_int4(int irq, void *dev_id, struct pt_regs *fp)
/* if audio 0 interrupt */
if (ints & IF_AUD0) {
custom.intreq = IF_AUD0;
- amiga_do_irq(IRQ_IDX(IRQ_AMIGA_AUD0), fp);
+ amiga_do_irq(IRQ_AMIGA_AUD0, fp);
}
/* if audio 1 interrupt */
if (ints & IF_AUD1) {
custom.intreq = IF_AUD1;
- amiga_do_irq(IRQ_IDX(IRQ_AMIGA_AUD1), fp);
+ amiga_do_irq(IRQ_AMIGA_AUD1, fp);
}
/* if audio 2 interrupt */
if (ints & IF_AUD2) {
custom.intreq = IF_AUD2;
- amiga_do_irq(IRQ_IDX(IRQ_AMIGA_AUD2), fp);
+ amiga_do_irq(IRQ_AMIGA_AUD2, fp);
}
/* if audio 3 interrupt */
if (ints & IF_AUD3) {
custom.intreq = IF_AUD3;
- amiga_do_irq(IRQ_IDX(IRQ_AMIGA_AUD3), fp);
+ amiga_do_irq(IRQ_AMIGA_AUD3, fp);
}
}
@@ -437,13 +457,13 @@ static void ami_int5(int irq, void *dev_id, struct pt_regs *fp)
/* if serial receive buffer full interrupt */
if (ints & IF_RBF) {
/* acknowledge of IF_RBF must be done by the serial interrupt */
- amiga_do_irq(IRQ_IDX(IRQ_AMIGA_RBF), fp);
+ amiga_do_irq(IRQ_AMIGA_RBF, fp);
}
/* if a disk sync interrupt */
if (ints & IF_DSKSYN) {
custom.intreq = IF_DSKSYN;
- amiga_do_irq(IRQ_IDX(IRQ_AMIGA_DSKSYN), fp);
+ amiga_do_irq(IRQ_AMIGA_DSKSYN, fp);
}
}