Beispiel #1
0
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);
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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);
}
Beispiel #6
0
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;
}
Beispiel #9
0
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;
}
Beispiel #10
0
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;
}
Beispiel #11
0
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;
}
Beispiel #12
0
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;
}
Beispiel #13
0
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;
}
Beispiel #14
0
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;
}
Beispiel #15
0
static void sun3_inthandle(unsigned int irq, struct pt_regs *fp)
{
        *sun3_intreg &= ~(1 << irq);

	m68k_handle_int(irq, fp);
}