Exemplo n.º 1
0
void via1_irq(int irq, void *dev_id, struct pt_regs *regs)
{
	int irq_bit, i;
	unsigned char events, mask;

	mask = via1[vIER] & 0x7F;
	if (!(events = via1[vIFR] & mask)) return;

	for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1)
		if (events & irq_bit) {
			via1[vIER] = irq_bit;
			mac_do_irq_list(VIA1_SOURCE_BASE + i, regs);
			via1[vIFR] = irq_bit;
			via1[vIER] = irq_bit | 0x80;
		}

#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);
		mac_do_irq_list(IRQ_MAC_NUBUS, regs);
		via_irq_enable(IRQ_MAC_NUBUS);
	}
#endif
}
Exemplo n.º 2
0
void mac_scc_dispatch(int irq, void *dev_id, struct pt_regs *regs)
{
	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) mac_do_irq_list(IRQ_SCCA, regs);
	if (reg & 0x07) mac_do_irq_list(IRQ_SCCB, regs);
}
Exemplo n.º 3
0
void 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;

#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;
		mac_do_irq_list(IRQ_MAC_SCSI, regs);
		oss->irq_pending &= ~OSS_IP_SCSI;
		oss->irq_level[OSS_SCSI] = OSS_IRQLEV_SCSI;
	} else {
		/* FIXME: error check here? */
	}
}
Exemplo n.º 4
0
void psc_irq(int irq, void *dev_id, struct pt_regs *regs)
{
	int pIFR	= pIFRbase + ((int) dev_id);
	int pIER	= pIERbase + ((int) dev_id);
	int base_irq;
	int irq_bit,i;
	unsigned char events;

	irq -= VEC_SPUR;
	base_irq = irq << 3;

#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;

	for (i = 0, irq_bit = 1 ; i < 4 ; i++, irq_bit <<= 1) {
	        if (events & irq_bit) {
			psc_write_byte(pIER, irq_bit);
			mac_do_irq_list(base_irq + i, regs);
			psc_write_byte(pIFR, irq_bit);
			psc_write_byte(pIER, irq_bit | 0x80);
		}
	}
}
Exemplo n.º 5
0
void via_nubus_irq(int irq, void *dev_id, struct pt_regs *regs)
{
	int irq_bit, i;
	unsigned char events;

	if (!(events = ~via2[gBufA] & nubus_active)) return;

	for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1) {
		if (events & irq_bit) {
			via_irq_disable(NUBUS_SOURCE_BASE + i);
			mac_do_irq_list(NUBUS_SOURCE_BASE + i, regs);
			via_irq_enable(NUBUS_SOURCE_BASE + i);
		}
	}
}
Exemplo n.º 6
0
void via2_irq(int irq, void *dev_id, struct pt_regs *regs)
{
	int irq_bit, i;
	unsigned char events, mask;

	mask = via2[gIER] & 0x7F;
	if (!(events = via2[gIFR] & mask)) return;

	for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1)
		if (events & irq_bit) {
			via2[gIER] = irq_bit;
			mac_do_irq_list(VIA2_SOURCE_BASE + i, regs);
			via2[gIFR] = irq_bit | rbv_clear;
			via2[gIER] = irq_bit | 0x80;
		}
}
Exemplo n.º 7
0
void 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;

#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;
			mac_do_irq_list(NUBUS_SOURCE_BASE + i, regs);
			oss->irq_pending &= ~irq_bit;
			oss->irq_level[i] = OSS_IRQLEV_NUBUS;
		}
	}
}