static void Q40PlayNextFrame(int index) { u_char *start; u_long size; u_char speed; /* used by Q40Play() if all doubts whether there really is something * to be played are already wiped out. */ start = write_sq.buffers[write_sq.front]; size = (write_sq.count == index ? write_sq.rear_size : write_sq.block_size); q40_pp=start; q40_sc=size; write_sq.front = (write_sq.front+1) % write_sq.max_count; write_sq.active++; speed=(dmasound.hard.speed==10000 ? 0 : 1); master_outb( 0,SAMPLE_ENABLE_REG); free_irq(Q40_IRQ_SAMPLE, Q40Interrupt); if (dmasound.soft.stereo) request_irq(Q40_IRQ_SAMPLE, Q40StereoInterrupt, 0, "Q40 sound", Q40Interrupt); else request_irq(Q40_IRQ_SAMPLE, Q40MonoInterrupt, 0, "Q40 sound", Q40Interrupt); master_outb( speed, SAMPLE_RATE_REG); master_outb( 1,SAMPLE_CLEAR_REG); master_outb( 1,SAMPLE_ENABLE_REG); }
void q40_init_IRQ (void) { int i; disabled=0; for (i = 0; i <= Q40_IRQ_MAX; i++) { irq_tab[i].handler = q40_defhand; irq_tab[i].flags = 0; irq_tab[i].dev_id = NULL; /* irq_tab[i].next = NULL;*/ irq_tab[i].devname[0] = 0; irq_tab[i].count = 0; irq_tab[i].state =0; q40_ablecount[i]=0; /* all enabled */ } /* setup handler for ISA ints */ sys_request_irq(IRQ2,q40_irq2_handler, 0, "q40 ISA and master chip", NULL); /* 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); }
static void __exit q40kbd_exit(void) { master_outb(0,KEY_IRQ_ENABLE_REG); master_outb(-1,KEYBOARD_UNLOCK_REG); serio_unregister_port(&q40kbd_port); free_irq(Q40_IRQ_KEYBOARD, NULL); }
static void q40kbd_close(struct serio *port) { master_outb(0, KEY_IRQ_ENABLE_REG); master_outb(-1, KEYBOARD_UNLOCK_REG); free_irq(Q40_IRQ_KEYBOARD, NULL); q40kbd_flush(); }
void q40_disable_irqs(void) { unsigned i,j; j=0; while((i=serports[j++])) outb(0,i+UART_IER); master_outb(0,EXT_ENABLE_REG); master_outb(0,KEY_IRQ_ENABLE_REG); }
static int q40kbd_open(struct serio *port) { struct q40kbd *q40kbd = port->port_data; q40kbd_flush(q40kbd); /* off we go */ master_outb(-1, KEYBOARD_UNLOCK_REG); master_outb(1, KEY_IRQ_ENABLE_REG); return 0; }
int __init q40kbd_init_hw(void) { /* Flush any pending input. */ kbd_clear_input(); /* Ok, finally allocate the IRQ, and off we go.. */ request_irq(Q40_IRQ_KEYBOARD, keyboard_interrupt, 0, "keyboard", NULL); master_outb(-1,KEYBOARD_UNLOCK_REG); master_outb(1,KEY_IRQ_ENABLE_REG); return 0; }
void q40_sched_init (void (*timer_routine)(int, void *, struct pt_regs *)) { int timer_irq; q40_timer_routine = timer_routine; timer_irq=Q40_IRQ_FRAME; if (request_irq(timer_irq, q40_timer_int, 0, "timer", q40_timer_int)) panic ("Couldn't register timer int"); master_outb(-1,FRAME_CLEAR_REG); master_outb( 1,FRAME_RATE_REG); }
void q40_sched_init (irq_handler_t timer_routine) { int timer_irq; q40_timer_routine = timer_routine; timer_irq = Q40_IRQ_FRAME; if (request_irq(timer_irq, q40_timer_int, 0, "timer", q40_timer_int)) panic("Couldn't register timer int"); master_outb(-1, FRAME_CLEAR_REG); master_outb( 1, FRAME_RATE_REG); }
void __init q40kbd_init_hw(void) { #if 0 /* Get the keyboard controller registers (incomplete decode) */ request_region(0x60, 16, "keyboard"); #endif /* Flush any pending input. */ kbd_clear_input(); /* Ok, finally allocate the IRQ, and off we go.. */ request_irq(Q40_IRQ_KEYBOARD, keyboard_interrupt, 0, "keyboard", NULL); master_outb(-1,KEYBOARD_UNLOCK_REG); master_outb(1,KEY_IRQ_ENABLE_REG); }
static int q40kbd_open(struct serio *port) { q40kbd_flush(); if (request_irq(Q40_IRQ_KEYBOARD, q40kbd_interrupt, 0, "q40kbd", NULL)) { printk(KERN_ERR "q40kbd.c: Can't get irq %d.\n", Q40_IRQ_KEYBOARD); return -1; } /* off we go */ master_outb(-1, KEYBOARD_UNLOCK_REG); master_outb(1, KEY_IRQ_ENABLE_REG); return 0; }
void __init q40_init_IRQ(void) { m68k_setup_irq_controller(&q40_irq_controller, 1, Q40_IRQ_MAX); /* setup handler for ISA ints */ m68k_setup_auto_interrupt(q40_irq_handler); m68k_irq_startup(IRQ_AUTO_2); m68k_irq_startup(IRQ_AUTO_4); /* 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); }
void __init q40_init_IRQ(void) { m68k_setup_irq_controller(&q40_irq_chip, handle_simple_irq, 1, Q40_IRQ_MAX); /* */ m68k_setup_auto_interrupt(q40_irq_handler); m68k_irq_startup_irq(IRQ_AUTO_2); m68k_irq_startup_irq(IRQ_AUTO_4); /* */ master_outb(1, EXT_ENABLE_REG); /* */ /* */ master_outb(0, KEY_IRQ_ENABLE_REG); }
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; }
void q40_enable_irq (unsigned int irq) { if ( irq>=5 && irq<=15 ) { mext_disabled--; if (mext_disabled>0) printk("q40_enable_irq : nested disable/enable\n"); if (mext_disabled==0) master_outb(1,EXT_ENABLE_REG); } }
static irqreturn_t Q40MonoInterrupt(int irq, void *dummy) { spin_lock(&dmasound.lock); if (q40_sc>0){ *DAC_LEFT=*q40_pp; *DAC_RIGHT=*q40_pp++; q40_sc --; master_outb(1,SAMPLE_CLEAR_REG); }else Q40Interrupt(); spin_unlock(&dmasound.lock); return IRQ_HANDLED; }
static irqreturn_t Q40StereoInterrupt(int irq, void *dummy, struct pt_regs *fp) { spin_lock(&dmasound.lock); if (q40_sc>1){ *DAC_LEFT=*q40_pp++; *DAC_RIGHT=*q40_pp++; q40_sc -=2; master_outb(1,SAMPLE_CLEAR_REG); }else Q40Interrupt(); spin_unlock(&dmasound.lock); return IRQ_HANDLED; }
void q40_disable_irq (unsigned int irq) { /* 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 !! */ if ( irq>=5 && irq<=15 ) { master_outb(0,EXT_ENABLE_REG); mext_disabled++; if (mext_disabled>1) printk("disable_irq nesting count %d\n",mext_disabled); } }
static void Q40Interrupt(void) { if (!write_sq.active) { /* playing was interrupted and sq_reset() has already cleared * the sq variables, so better don't do anything here. */ WAKE_UP(write_sq.sync_queue); master_outb(0,SAMPLE_ENABLE_REG); /* better safe */ goto exit; } else write_sq.active=0; write_sq.count--; Q40Play(); if (q40_sc<2) { /* there was nothing to play, disable irq */ master_outb(0,SAMPLE_ENABLE_REG); *DAC_LEFT=*DAC_RIGHT=127; } WAKE_UP(write_sq.action_queue); exit: master_outb(1,SAMPLE_CLEAR_REG); }
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; }
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; }
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; }
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 */ }
static int __init q40fb_probe(struct device *device) { struct platform_device *dev = to_platform_device(device); struct fb_info *info; if (!MACH_IS_Q40) return -ENXIO; /* mapped in q40/config.c */ q40fb_fix.smem_start = Q40_PHYS_SCREEN_ADDR; info = framebuffer_alloc(sizeof(u32) * 256, &dev->dev); if (!info) return -ENOMEM; info->var = q40fb_var; info->fix = q40fb_fix; info->fbops = &q40fb_ops; info->flags = FBINFO_FLAG_DEFAULT; /* not as module for now */ info->pseudo_palette = info->par; info->par = NULL; info->screen_base = (char *) q40fb_fix.smem_start; if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { framebuffer_release(info); return -ENOMEM; } master_outb(3, DISPLAY_CONTROL_REG); if (register_framebuffer(info) < 0) { printk(KERN_ERR "Unable to register Q40 frame buffer\n"); fb_dealloc_cmap(&info->cmap); framebuffer_release(info); return -EINVAL; } printk(KERN_INFO "fb%d: Q40 frame buffer alive and kicking !\n", info->node); return 0; }
static void q40kbd_stop(void) { master_outb(0, KEY_IRQ_ENABLE_REG); master_outb(-1, KEYBOARD_UNLOCK_REG); }
/* 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); } }
static void q40_defhand (int irq, void *dev_id, struct pt_regs *fp) { if (irq!=Q40_IRQ_KEYBOARD) printk ("Unknown q40 interrupt %d\n", irq); else master_outb(-1,KEYBOARD_UNLOCK_REG); }
static void Q40IrqCleanUp(void) { master_outb(0,SAMPLE_ENABLE_REG); free_irq(Q40_IRQ_SAMPLE, Q40Interrupt); }
static void Q40Silence(void) { master_outb(0,SAMPLE_ENABLE_REG); *DAC_LEFT=*DAC_RIGHT=127; }