static void iomd_dma_handle(int irq, void *dev_id, struct pt_regs *regs) { dma_t *dma = (dma_t *)dev_id; unsigned int status = 0, no_buffer = dma->sg == NULL; do { switch (dma->state) { case state_prog_a: iomd_get_next_sg(&dma->cur_sg, dma); iomd_setup_dma_a(&dma->cur_sg, dma); dma->state = state_wait_a; case state_wait_a: status = iomd_readb(dma->dma_base + ST); switch (status & (DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB)) { case DMA_ST_OFL|DMA_ST_INT: iomd_get_next_sg(&dma->cur_sg, dma); iomd_setup_dma_a(&dma->cur_sg, dma); break; case DMA_ST_INT: iomd_get_next_sg(&dma->cur_sg, dma); iomd_setup_dma_b(&dma->cur_sg, dma); dma->state = state_wait_b; break; case DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB: iomd_setup_dma_b(&dma->cur_sg, dma); dma->state = state_wait_b; break; } break; case state_wait_b: status = iomd_readb(dma->dma_base + ST); switch (status & (DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB)) { case DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB: iomd_get_next_sg(&dma->cur_sg, dma); iomd_setup_dma_b(&dma->cur_sg, dma); break; case DMA_ST_INT|DMA_ST_AB: iomd_get_next_sg(&dma->cur_sg, dma); iomd_setup_dma_a(&dma->cur_sg, dma); dma->state = state_wait_a; break; case DMA_ST_OFL|DMA_ST_INT: iomd_setup_dma_a(&dma->cur_sg, dma); dma->state = state_wait_a; break; } break; } } while (dma->sg && (status & DMA_ST_INT)); if (no_buffer) disable_irq(irq); }
static irqreturn_t rpckbd_rx(int irq, void *dev_id, struct pt_regs *regs) { struct serio *port = dev_id; unsigned int byte; int handled = IRQ_NONE; while (iomd_readb(IOMD_KCTRL) & (1 << 5)) { byte = iomd_readb(IOMD_KARTRX); serio_interrupt(port, byte, 0, regs); handled = IRQ_HANDLED; } return handled; }
static void psaux_interrupt(int irq, void *dev_id, struct pt_regs *regs) { int val = iomd_readb(IOMD_MSEDAT); if (mouse_reply_expected) { if (val == AUX_ACK) { mouse_reply_expected--; return; } mouse_reply_expected = 0; } add_mouse_randomness(val); if (aux_count) { int head = queue->head; queue->buf[head] = val; head = (head + 1) & (AUX_BUF_SIZE-1); if (head != queue->tail) { queue->head = head; kill_fasync(&queue->fasync, SIGIO, POLL_IN); wake_up_interruptible(&queue->proc_list); } } }
static void iomd_mask_irq_fiq(unsigned int irq) { unsigned int val, mask; mask = 1 << (irq & 7); val = iomd_readb(IOMD_FIQMASK); iomd_writeb(val & ~mask, IOMD_FIQMASK); }
/* * Send a byte to the mouse & handle returned ack */ static void aux_write_ack(int val) { while (!(iomd_readb(IOMD_MSECTL) & 0x80)); iomd_writeb(val, IOMD_MSEDAT); /* we expect an ACK in response. */ mouse_reply_expected++; }
static void iomd_unmask_irq_a(struct irq_data *d) { unsigned int val, mask; mask = 1 << d->irq; val = iomd_readb(IOMD_IRQMASKA); iomd_writeb(val | mask, IOMD_IRQMASKA); }
static void iomd_unmask_irq_a(unsigned int irq) { unsigned int val, mask; mask = 1 << irq; val = iomd_readb(IOMD_IRQMASKA); iomd_writeb(val | mask, IOMD_IRQMASKA); }
static void cl7500_unmask_irq_c(unsigned int irq) { unsigned int val, mask; mask = 1 << (irq & 7); val = iomd_readb(IOMD_IRQMASKC); iomd_writeb(val | mask, IOMD_IRQMASKC); }
static void iomd_unmask_irq_fiq(struct irq_data *d) { unsigned int val, mask; mask = 1 << (d->irq & 7); val = iomd_readb(IOMD_FIQMASK); iomd_writeb(val | mask, IOMD_FIQMASK); }
static void cl7500_mask_irq_b(unsigned int irq) { unsigned int val, mask; mask = 1 << (irq & 7); val = iomd_readb(IOMD_IRQMASKB); iomd_writeb(val & ~mask, IOMD_IRQMASKB); }
static void iomd_mask_irq_dma(struct irq_data *d) { unsigned int val, mask; mask = 1 << (d->irq & 7); val = iomd_readb(IOMD_DMAMASK); iomd_writeb(val & ~mask, IOMD_DMAMASK); }
static void iomd_unmask_irq_dma(unsigned int irq) { unsigned int val, mask; mask = 1 << (irq & 7); val = iomd_readb(IOMD_DMAMASK); iomd_writeb(val | mask, IOMD_DMAMASK); }
static void cl7500_ack_irq_a(unsigned int irq) { unsigned int val, mask; mask = 1 << irq; val = iomd_readb(IOMD_IRQMASKA); iomd_writeb(val & ~mask, IOMD_IRQMASKA); iomd_writeb(mask, IOMD_IRQCLRA); }
static int rpckbd_write(struct serio *port, unsigned char val) { while (!(iomd_readb(IOMD_KCTRL) & (1 << 7))) cpu_relax(); iomd_writeb(val, IOMD_KARTTX); return 0; }
static void iomd_disable_dma(dmach_t channel, dma_t *dma) { unsigned long dma_base = dma->dma_base; unsigned int ctrl; disable_irq(dma->dma_irq); ctrl = iomd_readb(dma_base + CR); iomd_writeb(ctrl & ~DMA_CR_E, dma_base + CR); }
static int rpckbd_open(struct serio *port) { /* Reset the keyboard state machine. */ iomd_writeb(0, IOMD_KCTRL); iomd_writeb(8, IOMD_KCTRL); iomd_readb(IOMD_KARTRX); if (request_irq(IRQ_KEYBOARDRX, rpckbd_rx, 0, "rpckbd", port) != 0) { printk(KERN_ERR "rpckbd.c: Could not allocate keyboard receive IRQ\n"); return -EBUSY; } if (request_irq(IRQ_KEYBOARDTX, rpckbd_tx, 0, "rpckbd", port) != 0) { printk(KERN_ERR "rpckbd.c: Could not allocate keyboard transmit IRQ\n"); free_irq(IRQ_KEYBOARDRX, NULL); return -EBUSY; } return 0; }
static irqreturn_t iomd_dma_handle(int irq, void *dev_id, struct pt_regs *regs) { dma_t *dma = (dma_t *)dev_id; unsigned long base = dma->dma_base; do { unsigned int status; status = iomd_readb(base + ST); if (!(status & DMA_ST_INT)) return IRQ_HANDLED; if ((dma->state ^ status) & DMA_ST_AB) iomd_get_next_sg(&dma->cur_sg, dma); switch (status & (DMA_ST_OFL | DMA_ST_AB)) { case DMA_ST_OFL: /* OIA */ case DMA_ST_AB: /* .IB */ iomd_writel(dma->cur_sg.dma_address, base + CURA); iomd_writel(dma->cur_sg.length, base + ENDA); dma->state = DMA_ST_AB; break; case DMA_ST_OFL | DMA_ST_AB: /* OIB */ case 0: /* .IA */ iomd_writel(dma->cur_sg.dma_address, base + CURB); iomd_writel(dma->cur_sg.length, base + ENDB); dma->state = 0; break; } if (status & DMA_ST_OFL && dma->cur_sg.length == (DMA_END_S|DMA_END_L)) break; } while (1); dma->state = ~DMA_ST_AB; disable_irq(irq); return IRQ_HANDLED; }
static int iomd_set_dma_speed(dmach_t channel, dma_t *dma, int cycle) { int tcr, speed; if (cycle < 188) speed = 3; else if (cycle <= 250) speed = 2; else if (cycle < 438) speed = 1; else speed = 0; tcr = iomd_readb(IOMD_DMATCR); speed &= 3; switch (channel) { case DMA_0: tcr = (tcr & ~0x03) | speed; break; case DMA_1: tcr = (tcr & ~0x0c) | (speed << 2); break; case DMA_2: tcr = (tcr & ~0x30) | (speed << 4); break; case DMA_3: tcr = (tcr & ~0xc0) | (speed << 6); break; default: break; } iomd_writeb(tcr, IOMD_DMATCR); return speed; }
static irqreturn_t iomd_dma_handle(int irq, void *dev_id) { struct iomd_dma *idma = dev_id; unsigned long base = idma->base; do { unsigned int status; status = iomd_readb(base + ST); if (!(status & DMA_ST_INT)) return IRQ_HANDLED; if ((idma->state ^ status) & DMA_ST_AB) iomd_get_next_sg(&idma->cur_sg, idma); switch (status & (DMA_ST_OFL | DMA_ST_AB)) { case DMA_ST_OFL: case DMA_ST_AB: iomd_writel(idma->cur_sg.dma_address, base + CURA); iomd_writel(idma->cur_sg.length, base + ENDA); idma->state = DMA_ST_AB; break; case DMA_ST_OFL | DMA_ST_AB: case 0: iomd_writel(idma->cur_sg.dma_address, base + CURB); iomd_writel(idma->cur_sg.length, base + ENDB); idma->state = 0; break; } if (status & DMA_ST_OFL && idma->cur_sg.length == (DMA_END_S|DMA_END_L)) break; } while (1); idma->state = ~DMA_ST_AB; disable_irq(irq); return IRQ_HANDLED; }
static int rpckbd_open(struct serio *port) { struct rpckbd_data *rpckbd = port->port_data; iomd_writeb(0, IOMD_KCTRL); iomd_writeb(8, IOMD_KCTRL); iomd_readb(IOMD_KARTRX); if (request_irq(rpckbd->rx_irq, rpckbd_rx, 0, "rpckbd", port) != 0) { printk(KERN_ERR "rpckbd.c: Could not allocate keyboard receive IRQ\n"); return -EBUSY; } if (request_irq(rpckbd->tx_irq, rpckbd_tx, 0, "rpckbd", port) != 0) { printk(KERN_ERR "rpckbd.c: Could not allocate keyboard transmit IRQ\n"); free_irq(rpckbd->rx_irq, port); return -EBUSY; } return 0; }
/* * Send a byte to the mouse. */ static void aux_write_dev(int val) { while (!(iomd_readb(IOMD_MSECTL) & 0x80)); iomd_writeb(val, IOMD_MSEDAT); }