/*
 * 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);
}
示例#3
0
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");
}
示例#4
0
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;
}
示例#5
0
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);
}