/* * TX interrupt handler */ static inline void rs_tx_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned long flags, status; save_and_cli(flags); rs_dprintk(TX3912_UART_DEBUG_INTERRUPTS, "rs_tx_interrupt..."); /* Get the interrupts */ status = inl(TX3912_INT2_STATUS); if(!rs_port || !rs_port->gs.tty) { restore_flags(flags); return; } /* Clear interrupts */ outl(TX3912_INT2_UARTA_TX_BITS, TX3912_INT2_CLEAR); /* TX holding register empty - transmit a byte */ if(status & TX3912_INT2_UARTAEMPTYINT) { transmit_char_pio(rs_port); } /* TX Transmit Holding Register Overrun (shouldn't happen) */ if(status & TX3912_INT2_UARTATXOVERRUNINT) { printk( "rs_tx_interrupt: TX overrun\n"); } restore_flags(flags); rs_dprintk(TX3912_UART_DEBUG_INTERRUPTS, "end.\n"); }
static void rs_enable_tx_interrupts (void * ptr) { unsigned long flags; save_and_cli(flags); outl(TX3912_INT2_UARTA_TX_BITS, TX3912_INT2_CLEAR); outl(inl(TX3912_INT2_ENABLE) | TX3912_INT2_UARTA_TX_BITS, TX3912_INT2_ENABLE); transmit_char_pio(rs_port); restore_flags(flags); }
static inline void rs_tx_interrupt(int irq, void *dev_id, struct pt_regs * regs, int intshift) { struct rs_port * port; unsigned long int2status; unsigned long flags; unsigned long ints; save_and_cli(flags); port = (struct rs_port *)dev_id; rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "rs_interrupt (port %p, shift %d)...", port, intshift); /* Get the interrrupts we have enabled */ int2status = IntStatus2 & IntEnable2; if (!port || !port->gs.tty) { restore_flags(flags); return; } /* Get interrupts in easy to use form */ ints = int2status >> intshift; /* Clear any interrupts we might be about to handle */ IntClear2 = int2status & ( (INTTYPE(UART_TX_INT) | INTTYPE(UART_EMPTY_INT) | INTTYPE(UART_TXOVERRUN_INT)) << intshift); /* TX holding register empty, so transmit byte (non-DMA) */ if (ints & (INTTYPE(UART_TX_INT) | INTTYPE(UART_EMPTY_INT))) { transmit_char_pio(port); } /* TX Transmit Holding Register Overrun (shouldn't happen) */ if (ints & INTTYPE(UART_TXOVERRUN_INT)) { printk ( "rs: TX overrun\n"); } /* check_modem_status(); */ restore_flags(flags); rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "end.\n"); }
static irqreturn_t duart_int(int irq, void *dev_id, struct pt_regs *regs) { uart_state_t *us = (uart_state_t *)dev_id; struct tty_struct *tty = us->tty; unsigned int status = READ_SERCSR(us->status, us->line); #ifdef DUART_SPEW printk("DUART INT\n"); #endif if (status & M_DUART_RX_RDY) { int counter = 2048; unsigned int ch; if (status & M_DUART_OVRUN_ERR) tty_insert_flip_char(tty, 0, TTY_OVERRUN); if (status & M_DUART_PARITY_ERR) { printk("Parity error!\n"); } else if (status & M_DUART_FRM_ERR) { printk("Frame error!\n"); } while (counter > 0) { if (!(READ_SERCSR(us->status, us->line) & M_DUART_RX_RDY)) break; ch = READ_SERCSR(us->rx_hold, us->line); if (tty->flip.count < TTY_FLIPBUF_SIZE) { *tty->flip.char_buf_ptr++ = ch; *tty->flip.flag_buf_ptr++ = 0; tty->flip.count++; } udelay(1); counter--; } tty_flip_buffer_push(tty); } if (status & M_DUART_TX_RDY) { transmit_char_pio(us); } return IRQ_HANDLED; }
static void rs_enable_tx_interrupts (void * ptr) { struct rs_port *port = ptr; unsigned long flags; save_and_cli(flags); IntClear2 = (INTTYPE(UART_TX_INT) | INTTYPE(UART_EMPTY_INT) | INTTYPE(UART_TXOVERRUN_INT)) << port->intshift; IntEnable2 |= (INTTYPE(UART_TX_INT) | INTTYPE(UART_EMPTY_INT) | INTTYPE(UART_TXOVERRUN_INT)) << port->intshift; /* Send a char to start TX interrupts happening */ transmit_char_pio(port); restore_flags(flags); }