void mac_scc_dispatch(int irq, void *dev_id) { volatile unsigned char *scc = (unsigned char *) mac_bi_data.sccbase + 2; unsigned char reg; unsigned long flags; /* Read RR3 from the chip. Always do this on channel A */ /* This must be an atomic operation so disable irqs. */ local_irq_save(flags); *scc = 3; reg = *scc; local_irq_restore(flags); /* Now dispatch. Bits 0-2 are for channel B and */ /* bits 3-5 are for channel A. We can safely */ /* ignore the remaining bits here. */ /* */ /* Note that we're ignoring scc_mask for now. */ /* If we actually mask the ints then we tend to */ /* get hammered by very persistent SCC irqs, */ /* and since they're autovector interrupts they */ /* pretty much kill the system. */ if (reg & 0x38) m68k_handle_int(IRQ_SCCA); if (reg & 0x07) m68k_handle_int(IRQ_SCCB); }
static irqreturn_t ami_int4(int irq, void *dev_id) { unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; /* if audio 0 interrupt */ if (ints & IF_AUD0) { amiga_custom.intreq = IF_AUD0; m68k_handle_int(IRQ_AMIGA_AUD0); } /* if audio 1 interrupt */ if (ints & IF_AUD1) { amiga_custom.intreq = IF_AUD1; m68k_handle_int(IRQ_AMIGA_AUD1); } /* if audio 2 interrupt */ if (ints & IF_AUD2) { amiga_custom.intreq = IF_AUD2; m68k_handle_int(IRQ_AMIGA_AUD2); } /* if audio 3 interrupt */ if (ints & IF_AUD3) { amiga_custom.intreq = IF_AUD3; m68k_handle_int(IRQ_AMIGA_AUD3); } return IRQ_HANDLED; }
irqreturn_t oss_nubus_irq(int irq, void *dev_id, struct pt_regs *regs) { int events, irq_bit, i; events = oss->irq_pending & OSS_IP_NUBUS; if (!events) return IRQ_NONE; #ifdef DEBUG_NUBUS_INT if (console_loglevel > 7) { printk("oss_nubus_irq: events = 0x%04X\n", events); } #endif /* There are only six slots on the OSS, not seven */ for (i = 0, irq_bit = 1 ; i < 6 ; i++, irq_bit <<= 1) { if (events & irq_bit) { oss->irq_level[i] = OSS_IRQLEV_DISABLED; m68k_handle_int(NUBUS_SOURCE_BASE + i, regs); oss->irq_pending &= ~irq_bit; oss->irq_level[i] = OSS_IRQLEV_NUBUS; } } return IRQ_HANDLED; }
irqreturn_t oss_irq(int irq, void *dev_id, struct pt_regs *regs) { int events; events = oss->irq_pending & (OSS_IP_SOUND|OSS_IP_SCSI); if (!events) return IRQ_NONE; #ifdef DEBUG_IRQS if ((console_loglevel == 10) && !(events & OSS_IP_SCSI)) { printk("oss_irq: irq %d events = 0x%04X\n", irq, (int) oss->irq_pending); } #endif /* FIXME: how do you clear a pending IRQ? */ if (events & OSS_IP_SOUND) { /* FIXME: call sound handler */ oss->irq_pending &= ~OSS_IP_SOUND; } else if (events & OSS_IP_SCSI) { oss->irq_level[OSS_SCSI] = OSS_IRQLEV_DISABLED; m68k_handle_int(IRQ_MAC_SCSI, regs); oss->irq_pending &= ~OSS_IP_SCSI; oss->irq_level[OSS_SCSI] = OSS_IRQLEV_SCSI; } else { /* FIXME: error check here? */ } return IRQ_HANDLED; }
asmlinkage void __m68k_handle_int(unsigned int irq, struct pt_regs *regs) { struct pt_regs *old_regs; old_regs = set_irq_regs(regs); m68k_handle_int(irq); set_irq_regs(old_regs); }
irqreturn_t baboon_irq(int irq, void *dev_id) { int irq_bit, irq_num; unsigned char events; #ifdef DEBUG_IRQS printk("baboon_irq: mb_control %02X mb_ifr %02X mb_status %02X\n", (uint) baboon->mb_control, (uint) baboon->mb_ifr, (uint) baboon->mb_status); #endif if (!(events = baboon->mb_ifr & 0x07)) return IRQ_NONE; irq_num = IRQ_BABOON_0; irq_bit = 1; do { if (events & irq_bit) { baboon->mb_ifr &= ~irq_bit; m68k_handle_int(irq_num); } irq_bit <<= 1; irq_num++; } while(events >= irq_bit); #if 0 if (baboon->mb_ifr & 0x02) macide_ack_intr(NULL); /* for now we need to smash all interrupts */ baboon->mb_ifr &= ~events; #endif return IRQ_HANDLED; }
irqreturn_t psc_irq(int irq, void *dev_id) { int pIFR = pIFRbase + ((int) dev_id); int pIER = pIERbase + ((int) dev_id); int irq_num; unsigned char irq_bit, events; #ifdef DEBUG_IRQS printk("psc_irq: irq %d pIFR = 0x%02X pIER = 0x%02X\n", irq, (int) psc_read_byte(pIFR), (int) psc_read_byte(pIER)); #endif events = psc_read_byte(pIFR) & psc_read_byte(pIER) & 0xF; if (!events) return IRQ_NONE; irq_num = irq << 3; irq_bit = 1; do { if (events & irq_bit) { psc_write_byte(pIFR, irq_bit); m68k_handle_int(irq_num); } irq_num++; irq_bit <<= 1; } while (events >= irq_bit); return IRQ_HANDLED; }
static irqreturn_t oss_nubus_irq(int irq, void *dev_id) { int events, irq_bit, i; events = oss->irq_pending & OSS_IP_NUBUS; if (!events) return IRQ_NONE; #ifdef DEBUG_NUBUS_INT if (console_loglevel > 7) { printk("oss_nubus_irq: events = 0x%04X\n", events); } #endif /* There are only six slots on the OSS, not seven */ i = 6; irq_bit = 0x40; do { --i; irq_bit >>= 1; if (events & irq_bit) { oss->irq_pending &= ~irq_bit; m68k_handle_int(NUBUS_SOURCE_BASE + i); } } while(events & (irq_bit - 1)); return IRQ_HANDLED; }
irqreturn_t via_nubus_irq(int irq, void *dev_id) { int slot_irq; unsigned char slot_bit, events; events = ~via2[gBufA] & 0x7F; if (rbv_present) events &= via2[rSIER]; else events &= ~via2[vDirA]; if (!events) return IRQ_NONE; do { slot_irq = IRQ_NUBUS_F; slot_bit = 0x40; do { if (events & slot_bit) { events &= ~slot_bit; m68k_handle_int(slot_irq); } --slot_irq; slot_bit >>= 1; } while (events); /* clear the CA1 interrupt and make certain there's no more. */ via2[gIFR] = 0x02 | rbv_clear; events = ~via2[gBufA] & 0x7F; if (rbv_present) events &= via2[rSIER]; else events &= ~via2[vDirA]; } while (events); return IRQ_HANDLED; }
static irqreturn_t ami_int5(int irq, void *dev_id) { unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; /* if serial receive buffer full interrupt */ if (ints & IF_RBF) { /* acknowledge of IF_RBF must be done by the serial interrupt */ m68k_handle_int(IRQ_AMIGA_RBF); } /* if a disk sync interrupt */ if (ints & IF_DSKSYN) { amiga_custom.intreq = IF_DSKSYN; m68k_handle_int(IRQ_AMIGA_DSKSYN); } return IRQ_HANDLED; }
static irqreturn_t ami_int3(int irq, void *dev_id) { unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; /* if a blitter interrupt */ if (ints & IF_BLIT) { amiga_custom.intreq = IF_BLIT; m68k_handle_int(IRQ_AMIGA_BLIT); } /* if a copper interrupt */ if (ints & IF_COPER) { amiga_custom.intreq = IF_COPER; m68k_handle_int(IRQ_AMIGA_COPPER); } /* if a vertical blank interrupt */ if (ints & IF_VERTB) { amiga_custom.intreq = IF_VERTB; m68k_handle_int(IRQ_AMIGA_VERTB); } return IRQ_HANDLED; }
static irqreturn_t ami_int1(int irq, void *dev_id) { unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; /* if serial transmit buffer empty, interrupt */ if (ints & IF_TBE) { amiga_custom.intreq = IF_TBE; m68k_handle_int(IRQ_AMIGA_TBE); } /* if floppy disk transfer complete, interrupt */ if (ints & IF_DSKBLK) { amiga_custom.intreq = IF_DSKBLK; m68k_handle_int(IRQ_AMIGA_DSKBLK); } /* if software interrupt set, interrupt */ if (ints & IF_SOFT) { amiga_custom.intreq = IF_SOFT; m68k_handle_int(IRQ_AMIGA_SOFT); } return IRQ_HANDLED; }
irqreturn_t via1_irq(int irq, void *dev_id) { int irq_num; unsigned char irq_bit, events; events = via1[vIFR] & via1[vIER] & 0x7F; if (!events) return IRQ_NONE; irq_num = VIA1_SOURCE_BASE; irq_bit = 1; do { if (events & irq_bit) { via1[vIFR] = irq_bit; m68k_handle_int(irq_num); } ++irq_num; irq_bit <<= 1; } while (events >= irq_bit); #if 0 /* freakin' pmu is doing weird stuff */ if (!oss_present) { /* This (still) seems to be necessary to get IDE working. However, if you enable VBL interrupts, you're screwed... */ /* FIXME: should we check the SLOTIRQ bit before pulling this stunt? */ /* No, it won't be set. that's why we're doing this. */ via_irq_disable(IRQ_MAC_NUBUS); via_irq_clear(IRQ_MAC_NUBUS); m68k_handle_int(IRQ_MAC_NUBUS); via_irq_enable(IRQ_MAC_NUBUS); } #endif return IRQ_HANDLED; }
irqreturn_t via2_irq(int irq, void *dev_id) { int irq_num; unsigned char irq_bit, events; events = via2[gIFR] & via2[gIER] & 0x7F; if (!events) return IRQ_NONE; irq_num = VIA2_SOURCE_BASE; irq_bit = 1; do { if (events & irq_bit) { via2[gIFR] = irq_bit | rbv_clear; m68k_handle_int(irq_num); } ++irq_num; irq_bit <<= 1; } while (events >= irq_bit); return IRQ_HANDLED; }
static void sun3_inthandle(unsigned int irq, struct pt_regs *fp) { *sun3_intreg &= ~(1 << irq); m68k_handle_int(irq, fp); }