/* * arch/m68k/q40/q40ints.c * * Copyright (C) 1999,2001 Richard Zidlicky * * 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. * * .. used to be loosely based on bvme6000ints.c *
*/
/* test for ISA ints not implemented by HW */ switch (irq) { case 1: case 2: case 8: case 9: case 11: case 12: case 13:
pr_warn("%s: ISA IRQ %d not implemented by HW\n", __func__,
irq); /* FIXME return -ENXIO; */
} return 0;
}
/* * void q40_init_IRQ (void) * * Parameters: None * * Returns: Nothing * * This function is called during kernel startup to initialize * the q40 IRQ handling routines.
*/
/* now enable some ints.. */
master_outb(1, EXT_ENABLE_REG); /* ISA IRQ 5-15 */
/* make sure keyboard IRQ is disabled */
master_outb(0, KEY_IRQ_ENABLE_REG);
}
/* * this stuff doesn't really belong here..
*/
int ql_ticks; /* 200Hz ticks since last jiffy */ staticint sound_ticks;
#define SVOL 45
void q40_mksound(unsignedint hz, unsignedint ticks)
{ /* for now ignore hz, except that hz==0 switches off sound */ /* simply alternate the ampl (128-SVOL)-(128+SVOL)-..-.. at 200Hz */ if (hz == 0) { if (sound_ticks)
sound_ticks = 1;
*DAC_LEFT = 128;
*DAC_RIGHT = 128;
return;
} /* sound itself is done in q40_timer_int */ if (sound_ticks == 0)
sound_ticks = 1000; /* pretty long beep */
sound_ticks = ticks << 1;
}
#define IRQ_INPROGRESS 1 /*static unsigned short saved_mask;*/ //static int do_tint=0;
#define DEBUG_Q40INT /*#define IP_USE_DISABLE *//* would be nice, but crashes ???? */
staticint mext_disabled; /* ext irq disabled by master chip? */ staticint aliased_irq; /* how many times inside handler ?*/
/* got interrupt, dispatch to ISA or keyboard/timer IRQs */ staticvoid q40_irq_handler(unsignedint irq, struct pt_regs *fp)
{ unsigned mir, mer; int i;
//repeat:
mir = master_inb(IIRQ_REG); #ifdef CONFIG_BLK_DEV_FD if ((mir & Q40_IRQ_EXT_MASK) &&
(master_inb(EIRQ_REG) & Q40_IRQ6_MASK)) {
floppy_hardint(); return;
} #endif switch (irq) { case 4: case 6:
do_IRQ(Q40_IRQ_SAMPLE, fp); return;
} if (mir & Q40_IRQ_FRAME_MASK) {
do_IRQ(Q40_IRQ_FRAME, fp);
master_outb(-1, FRAME_CLEAR_REG);
} if ((mir & Q40_IRQ_SER_MASK) || (mir & Q40_IRQ_EXT_MASK)) {
mer = master_inb(EIRQ_REG); for (i = 0; eirqs[i].mask; i++) { if (mer & eirqs[i].mask) {
irq = eirqs[i].irq; /* * There is a little mess wrt which IRQ really caused this irq request. The * main problem is that IIRQ_REG and EIRQ_REG reflect the state when they * are read - which is long after the request came in. In theory IRQs should * not just go away but they occasionally do
*/ if (irq > 4 && irq <= 15 && mext_disabled) { /*aliased_irq++;*/ goto iirq;
} if (q40_state[irq] & IRQ_INPROGRESS) { /* some handlers do local_irq_enable() for irq latency reasons, */ /* however reentering an active irq handler is not permitted */ #ifdef IP_USE_DISABLE /* in theory this is the better way to do it because it still */ /* lets through eg the serial irqs, unfortunately it crashes */
disable_irq(irq);
disabled = 1; #else /*pr_warn("IRQ_INPROGRESS detected for irq %d, disabling - %s disabled\n",
irq, disabled ? "already" : "not yet"); */
fp->sr = (((fp->sr) & (~0x700))+0x200);
disabled = 1; #endif goto iirq;
}
q40_state[irq] |= IRQ_INPROGRESS;
do_IRQ(irq, fp);
q40_state[irq] &= ~IRQ_INPROGRESS;
/* naively enable everything, if that fails than */ /* this function will be reentered immediately thus */ /* getting another chance to disable the IRQ */
if (disabled) { #ifdef IP_USE_DISABLE if (irq > 4) {
disabled = 0;
enable_irq(irq);
} #else
disabled = 0; /*pr_info("reenabling irq %d\n", irq); */ #endif
} // used to do 'goto repeat;' here, this delayed bh processing too long return;
}
} if (mer && ccleirq > 0 && !aliased_irq) {
pr_warn("ISA interrupt from unknown source? EIRQ_REG = %x\n",
mer);
ccleirq--;
}
}
iirq:
mir = master_inb(IIRQ_REG); /* should test whether keyboard irq is really enabled, doing it in defhand */ if (mir & Q40_IRQ_KEYB_MASK)
do_IRQ(Q40_IRQ_KEYBOARD, fp);
/* disable ISA iqs : only do something if the driver has been * verified to be Q40 "compatible" - right now IDE, NE2K * Any driver should not attempt to sleep across disable_irq !!
*/
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.