Пример #1
0
static irqreturn_t q40kbd_interrupt(int irq, void *dev_id,
				    struct pt_regs *regs)
{
	if (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG))
		serio_interrupt(&q40kbd_port, master_inb(KEYCODE_REG), 0, regs);

	master_outb(-1, KEYBOARD_UNLOCK_REG);
	return IRQ_HANDLED;
}
Пример #2
0
static void q40kbd_flush(void)
{
 	int maxread = 100;
	unsigned long flags;

	spin_lock_irqsave(&q40kbd_lock, flags);

 	while (maxread-- && (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG)))
 		master_inb(KEYCODE_REG);

	spin_unlock_irqrestore(&q40kbd_lock, flags);
}
Пример #3
0
static int __init kbd_read_input(void)
{
	int retval = KBD_NO_DATA;
	unsigned char status;

	status = IRQ_KEYB_MASK & master_inb(INTERRUPT_REG);
	if (status) {
		unsigned char data = master_inb(KEYCODE_REG);

		retval = data;
		master_outb(-1,KEYBOARD_UNLOCK_REG);
	}
	return retval;
}
Пример #4
0
static irqreturn_t q40kbd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
	unsigned long flags;

	spin_lock_irqsave(&q40kbd_lock, flags);

	if (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG))
		serio_interrupt(q40kbd_port, master_inb(KEYCODE_REG), 0, regs);

	master_outb(-1, KEYBOARD_UNLOCK_REG);

	spin_unlock_irqrestore(&q40kbd_lock, flags);

	return IRQ_HANDLED;
}
Пример #5
0
static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
	unsigned char status;

	spin_lock(&kbd_controller_lock);
	kbd_pt_regs = regs;

	status = IRQ_KEYB_MASK & master_inb(INTERRUPT_REG);
	if (status ) 
	  {
	    unsigned char scancode,qcode;
	    
	    qcode = master_inb(KEYCODE_REG);
	    
	    if (qcode != 0xf0)
	      {
		if (qcode == 0xe0)
		  {
		    qprev=0xe0;
		    handle_scancode(qprev , 1);
		    goto exit;
		  }
		
		scancode=qprev ? q40ecl[qcode] : q40cl[qcode];
#if 0
/* next line is last resort to hanlde some oddities */
		if (qprev && !scancode) scancode=q40cl[qcode];
#endif
		qprev=0;
		if (!scancode)
		  {
		    printk("unknown scancode %x\n",qcode);
		    goto exit;
		  }
		if (scancode==0xff)  /* SySrq */
		  scancode=SYSRQ_KEY;

		handle_scancode(scancode, ! keyup );
		keyup=0;
		tasklet_schedule(&keyboard_tasklet);
	      }
	    else
	      keyup=1;
	  }
exit:
	spin_unlock(&kbd_controller_lock);
	master_outb(-1,KEYBOARD_UNLOCK_REG); /* keyb ints reenabled herewith */
}
Пример #6
0
static int __init q40kbd_init(void)
{
	int maxread = 100;

	if (!MACH_IS_Q40)
		return -EIO;

	/* allocate the IRQ */
	request_irq(Q40_IRQ_KEYBOARD, q40kbd_interrupt, 0, "q40kbd", NULL);

	/* flush any pending input */
	while (maxread-- && (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG)))
		master_inb(KEYCODE_REG);

	/* off we go */
	master_outb(-1,KEYBOARD_UNLOCK_REG);
	master_outb(1,KEY_IRQ_ENABLE_REG);

	serio_register_port(&q40kbd_port);
	printk(KERN_INFO "serio: Q40 kbd registered\n");

	return 0;
}
Пример #7
0
/* got level 2 interrupt, dispatch to ISA or keyboard/timer IRQs */
void q40_irq2_handler (int vec, void *devname, struct pt_regs *fp)
{
  unsigned mir, mer;
  int irq,i;

  mir=master_inb(IIRQ_REG);
  if (mir&Q40_IRQ_FRAME_MASK) {
	  irq_tab[Q40_IRQ_FRAME].count++;
	  irq_tab[Q40_IRQ_FRAME].handler(Q40_IRQ_FRAME,irq_tab[Q40_IRQ_FRAME].dev_id,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 occassionally do
 */
			  if (irq>4 && irq<=15 && mext_disabled) {
				  /*aliased_irq++;*/
				  goto iirq;
			  }
			  if (irq_tab[irq].handler == q40_defhand ) {
				  printk("handler for IRQ %d not defined\n",irq);
				  continue; /* ignore uninited INTs :-( */
			  }
			  if ( irq_tab[irq].state & IRQ_INPROGRESS ) {
				  /* some handlers do sti() 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
				  /*printk("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;
			  }
			  irq_tab[irq].count++; 
			  irq_tab[irq].state |= IRQ_INPROGRESS;
			  irq_tab[irq].handler(irq,irq_tab[irq].dev_id,fp);
			  irq_tab[irq].state &= ~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;
				  /*printk("reenabling irq %d\n",irq); */
#endif
			  }
			  return;
		  }
	  }
	  if (mer && ccleirq>0 && !aliased_irq) 
		  printk("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) {
	  irq_tab[Q40_IRQ_KEYBOARD].count++;
	  irq_tab[Q40_IRQ_KEYBOARD].handler(Q40_IRQ_KEYBOARD,irq_tab[Q40_IRQ_KEYBOARD].dev_id,fp);
  }
}
Пример #8
0
void q40_process_int (int level, struct pt_regs *fp)
{
  printk("unexpected interrupt vec=%x, pc=%lx, d0=%lx, d0_orig=%lx, d1=%lx, d2=%lx\n",
          level, fp->pc, fp->d0, fp->orig_d0, fp->d1, fp->d2);
  printk("\tIIRQ_REG = %x, EIRQ_REG = %x\n",master_inb(IIRQ_REG),master_inb(EIRQ_REG));
}