/*
 * This is the serial driver's generic interrupt routine
 */
irqreturn_t rs_interrupt(int irq, void *dev_id)
{
	struct m68k_serial *info = dev_id;
	struct tty_struct *tty = tty_port_tty_get(&info->tport);
	m68328_uart *uart;
	unsigned short rx;
	unsigned short tx;

	uart = &uart_addr[info->line];
	rx = uart->urx.w;

#ifdef USE_INTS
	tx = uart->utx.w;

	if (rx & URX_DATA_READY)
		receive_chars(info, rx);
	if (tx & UTX_TX_AVAIL)
		transmit_chars(info, tty);
#else
	receive_chars(info, rx);
#endif
	tty_kref_put(tty);

	return IRQ_HANDLED;
}
Beispiel #2
0
static void max3110_console_receive(struct uart_max3110 *max)
{
	int loop = 1, num, total = 0;
	u8 recv_buf[512], *pbuf;

	pbuf = recv_buf;
	do {
		num = max3110_read_multi(max, 8, pbuf);

		if (num) {
			loop = 10;
			pbuf += num;
			total += num;

			if (total >= 500) {
				receive_chars(max, recv_buf, total);
				pbuf = recv_buf;
				total = 0;
			}
		}
	} while (--loop);

	if (total)
		receive_chars(max, recv_buf, total);
}
Beispiel #3
0
/*
 * Drain the Rx FIFO, called by interrupt handler.
 */
static void handle_receive(struct tile_uart_port *tile_uart)
{
	struct tty_port *port = &tile_uart->uart.state->port;
	struct tty_struct *tty = tty_port_tty_get(port);
	gxio_uart_context_t *context = &tile_uart->context;

	if (!tty)
		return;

	/* First read UART rx fifo. */
	receive_chars(tile_uart, tty);

	/* Reset RFIFO_WE interrupt. */
	gxio_uart_write(context, UART_INTERRUPT_STATUS,
			UART_INTERRUPT_MASK__RFIFO_WE_MASK);

	/* Final read, if any chars comes between the first read and
	 * the interrupt reset.
	 */
	receive_chars(tile_uart, tty);

	spin_unlock(&tile_uart->uart.lock);
	tty_flip_buffer_push(port);
	spin_lock(&tile_uart->uart.lock);
	tty_kref_put(tty);
}
Beispiel #4
0
/*
 * This is the serial driver's generic interrupt routine
 */
void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs)
{
    struct m68k_serial * info;
    m68328_uart *uart;
    unsigned short rx;
#ifdef USE_INTS
    unsigned short tx;
#endif

    info = IRQ_ports[irq];
    if(!info)
        return;

    uart = &uart_addr[info->line];
    rx = uart->urx.w;

#ifdef USE_INTS
    tx = uart->utx.w;

    if (rx & URX_DATA_READY) receive_chars(info, regs, rx);
    if (tx & UTX_TX_AVAIL)   transmit_chars(info);
#else
    receive_chars(info, regs, rx);
#endif
    return;
}
Beispiel #5
0
/**
 * serial_omap_irq() - This handles the interrupt from one port
 * @irq: uart port irq number
 * @dev_id: uart port info
 */
static inline irqreturn_t serial_omap_irq(int irq, void *dev_id)
{
	struct uart_omap_port *up = dev_id;
	unsigned int iir, lsr;
	unsigned long flags;

	iir = serial_in(up, UART_IIR);
	if (iir & UART_IIR_NO_INT)
		return IRQ_NONE;

	spin_lock_irqsave(&up->port.lock, flags);
	lsr = serial_in(up, UART_LSR);
	if (iir & UART_IIR_RLSI) {
		if (!up->use_dma) {
			if (lsr & UART_LSR_DR)
				receive_chars(up, &lsr);
		} else {
			up->ier &= ~(UART_IER_RDI | UART_IER_RLSI);
			serial_out(up, UART_IER, up->ier);
			if ((serial_omap_start_rxdma(up) != 0) &&
					(lsr & UART_LSR_DR))
				receive_chars(up, &lsr);
		}
	}

	check_modem_status(up);
	if ((lsr & UART_LSR_THRE) && (iir & UART_IIR_THRI))
		transmit_chars(up);

	spin_unlock_irqrestore(&up->port.lock, flags);
	up->port_activity = jiffies;
	return IRQ_HANDLED;
}
/**
 * serial_omap_irq() - This handles the interrupt from one port
 * @irq: uart port irq number
 * @dev_id: uart port info
 */
static inline irqreturn_t serial_omap_irq(int irq, void *dev_id)
{
	struct uart_omap_port *up = dev_id;
	unsigned int iir, lsr;
	unsigned long flags;

	spin_lock_irqsave(&up->port.lock, flags);
#ifdef CONFIG_PM
	/*
	 * This will enable the clock for some reason if the
	 * clocks get disabled. This would enable the ICK also
	 * in case if the Idle state is set and the PRCM modul
	 * just shutdown the ICK because of inactivity.
	 */
	omap_uart_enable_clock_from_irq(up->pdev->id);
#endif

	iir = serial_in(up, UART_IIR);
	if (iir & UART_IIR_NO_INT) {
		spin_unlock_irqrestore(&up->port.lock, flags);
		return IRQ_NONE;
	}

	lsr = serial_in(up, UART_LSR);
	if (iir & UART_IIR_RLSI) {
		if (!up->use_dma) {
			if (lsr & UART_LSR_DR) {
				receive_chars(up, &lsr);
				if (omap_is_console_port(&up->port) &&
						(up->plat_hold_wakelock)) {
					spin_unlock(&up->port.lock);
					up->plat_hold_wakelock(up, WAKELK_IRQ);
					spin_lock(&up->port.lock);
				}
			}
		} else {
			up->ier &= ~UART_IER_RDI;
			serial_out(up, UART_IER, up->ier);
			if (serial_omap_start_rxdma(up) != 0)
				if (lsr & UART_LSR_DR)
					receive_chars(up, &lsr);
		}
	}

	check_modem_status(up);
	if ((lsr & UART_LSR_THRE) && (iir & UART_IIR_THRI))
		transmit_chars(up);

	spin_unlock_irqrestore(&up->port.lock, flags);
	up->port_activity = jiffies;
	return IRQ_HANDLED;
}
/**
 * serial_omap_irq() - This handles the interrupt from one port
 * @irq: uart port irq number
 * @dev_id: uart port info
 */
static inline irqreturn_t serial_omap_irq(int irq, void *dev_id)
{
	struct uart_omap_port *up = dev_id;
	unsigned int iir, lsr;
	unsigned int int_id;
	unsigned long flags;
	int ret = IRQ_HANDLED;
	u8 tx_fifo_lvl;

	serial_omap_port_enable(up);
	iir = serial_in(up, UART_IIR);
	if (iir & UART_IIR_NO_INT) {
		serial_omap_port_disable(up);
		return IRQ_NONE;
	}

	int_id = iir & UART_OMAP_IIR_ID;

	spin_lock_irqsave(&up->port.lock, flags);
	lsr = serial_in(up, UART_LSR);
	if (int_id == UART_IIR_RDI || int_id == UART_OMAP_IIR_RX_TIMEOUT ||
	    int_id == UART_IIR_RLSI) {
		if (!up->use_dma) {
			if (lsr & UART_LSR_DR)
				receive_chars(up, &lsr);
		} else {
			up->ier &= ~(UART_IER_RDI | UART_IER_RLSI);
			serial_out(up, UART_IER, up->ier);
			if ((serial_omap_start_rxdma(up) != 0) &&
					(lsr & UART_LSR_DR))
				receive_chars(up, &lsr);
		}
	}

	check_modem_status(up);
	if (int_id == UART_IIR_THRI) {
		tx_fifo_lvl = serial_in(up, UART_OMAP_TXFIFO_LVL);
		if (lsr & UART_LSR_THRE || tx_fifo_lvl < up->port.fifosize)
			transmit_chars(up, tx_fifo_lvl);
		else
			ret = IRQ_NONE;
	}

	spin_unlock_irqrestore(&up->port.lock, flags);
	serial_omap_port_disable(up);

	up->port_activity = jiffies;
	return ret;
}
Beispiel #8
0
/*
 * This handles the interrupt from one port.
 */
static inline irqreturn_t serial_omap_irq(int irq, void *dev_id)
{
	struct uart_omap_port *up = dev_id;
	unsigned int iir, lsr;

	iir = serial_in(up, UART_IIR);
	if (iir & UART_IIR_NO_INT)
		return IRQ_NONE;
	lsr = serial_in(up, UART_LSR);
	if ((iir & 0x4) && up->use_dma) {
		up->ier &= ~UART_IER_RDI;
		serial_out(up, UART_IER, up->ier);
		serial_omap_start_rxdma(up);
	} else if (lsr & UART_LSR_DR) {
		receive_chars(up, &lsr);
		/* XXX: After driver resume optimization, lower this */
		wake_lock_timeout(&omap_serial_wakelock, (HZ * 1));
	}
	check_modem_status(up);
	if ((lsr & UART_LSR_THRE) && (iir & 0x2))
		transmit_chars(up);
	isr8250_activity = jiffies;

	return IRQ_HANDLED;
}
/* Write a 16b word to the device */
static int max3110_out(struct uart_max3110 *max, const u16 out)
{
	void *buf;
	u16 *obuf, *ibuf;
	u8  ch;
	int ret;

	buf = kzalloc(8, GFP_KERNEL | GFP_DMA);
	if (!buf)
		return -ENOMEM;

	obuf = buf;
	ibuf = buf + 4;
	*obuf = out;
	ret = max3110_write_then_read(max, obuf, ibuf, 2, 1);
	if (ret) {
		pr_warning(PR_FMT "%s(): get err msg %d when sending 0x%x\n",
				__func__, ret, out);
		goto exit;
	}

	/* If some valid data is read back */
	if (*ibuf & MAX3110_READ_DATA_AVAILABLE) {
		ch = *ibuf & 0xff;
		receive_chars(max, &ch, 1);
	}

exit:
	kfree(buf);
	return ret;
}
/*
 * This handles the interrupt from one port.
 */
static irqreturn_t
dpram_irq_rx(int irq, void *dev_id)
{
	dprintk("dpram_irq_rx\n");
	receive_chars(dev_id);
	return IRQ_HANDLED;
}
/*
 * This handles the interrupt from one port.
 */
static inline irqreturn_t serial_omap_irq(int irq, void *dev_id)
{
	struct uart_omap_port *up = dev_id;
	unsigned int iir, lsr;

	iir = serial_in(up, UART_IIR);
	if (iir & UART_IIR_NO_INT)
		return IRQ_NONE;
	lsr = serial_in(up, UART_LSR);
	if ((iir & 0x4) && up->use_dma) {
		up->ier &= ~UART_IER_RDI;
		serial_out(up, UART_IER, up->ier);
		serial_omap_start_rxdma(up);
	}
	else if (lsr & UART_LSR_DR) {
		receive_chars(up, &lsr);
	}
	check_modem_status(up);
	if ((lsr & UART_LSR_THRE) && (iir & 0x2)) {
		transmit_chars(up);
	}
	isr8250_activity = jiffies;

	return IRQ_HANDLED;
}
/* Write a 16b word to the device */
static int max3110_out(struct uart_max3110 *max, const u16 out)
{
	void *buf;
	u16 *obuf, *ibuf;
	int ret;

	buf = kzalloc(8, GFP_KERNEL | GFP_DMA);
	if (!buf)
		return -ENOMEM;

	obuf = buf;
	ibuf = buf + 4;
	*obuf = out;
	ret = max3110_write_then_read(max, obuf, ibuf, 2, 1);
	if (ret) {
		pr_warning(PR_FMT "%s(): get err msg %d when sending 0x%x\n",
				__func__, ret, out);
		goto exit;
	}

	receive_chars(max, ibuf, 1);

exit:
	kfree(buf);
	return ret;
}
Beispiel #13
0
/*
 * This is usually used to read data from SPIC RX FIFO, which doesn't
 * need any delay like flushing character out. It returns how many
 * valide bytes are read back
 */
static int max3110_read_multi(struct uart_max3110 *max, int len, u8 *buf)
{
	u16 out[MAX_READ_LEN], in[MAX_READ_LEN];
	u8 *pbuf, valid_str[MAX_READ_LEN];
	int i, j, bytelen;

	if (len > MAX_READ_LEN) {
		pr_err(PR_FMT "read len %d is too large\n", len);
		return 0;
	}

	bytelen = len * 2;
	memset(out, 0, bytelen);
	memset(in, 0, bytelen);

	if (max3110_write_then_read(max, (u8 *)out, (u8 *)in, bytelen, 1))
		return 0;

	/* If caller don't provide a buffer, then handle received char */
	pbuf = buf ? buf : valid_str;

	for (i = 0, j = 0; i < len; i++) {
		if (in[i] & MAX3110_READ_DATA_AVAILABLE)
			pbuf[j++] = (u8)(in[i] & 0xff);
	}

	if (j && (pbuf == valid_str))
		receive_chars(max, valid_str, j);

	return j;
}
Beispiel #14
0
/*
 * This is the serial driver's generic interrupt routine
 */
static irqreturn_t am_uart_interrupt(int irq, void *dev, struct pt_regs *regs)
{
    struct am_uart_port *info=(struct am_uart_port *)dev;
    am_uart_t *uart = NULL;
    struct tty_struct *tty = NULL;

    if (!info)
        goto out;

    tty = info->port.state->port.tty;
    if (!tty)
    {
        goto out;
    }

    uart = uart_addr[info->line];
    if (!uart)
        goto out;

    if (!(readl(&uart->status) & UART_RXEMPTY)){

        receive_chars(info, 0, readl(&uart->rdata));
    }

    if ((readl(&uart->mode) & UART_TXENB)&&!(readl(&uart->status) & UART_TXFULL)) {
        transmit_chars(info);
    }
out:
    am_uart_sched_event(info, 0);
    return IRQ_HANDLED;

}
Beispiel #15
0
static void rs_interrupt_elsa(struct IsdnCardState *cs)
{
	int status, iir, msr;
	int pass_counter = 0;
	
#ifdef SERIAL_DEBUG_INTR
;
#endif

	do {
		status = serial_inp(cs, UART_LSR);
		debugl1(cs,"rs LSR %02x", status);
#ifdef SERIAL_DEBUG_INTR
;
#endif
		if (status & UART_LSR_DR)
			receive_chars(cs, &status);
		if (status & UART_LSR_THRE)
			transmit_chars(cs, NULL);
		if (pass_counter++ > RS_ISR_PASS_LIMIT) {
;
			break;
		}
		iir = serial_inp(cs, UART_IIR);
		debugl1(cs,"rs IIR %02x", iir);
		if ((iir & 0xf) == 0) {
			msr = serial_inp(cs, UART_MSR);
			debugl1(cs,"rs MSR %02x", msr);
		}
	} while (!(iir & UART_IIR_NO_INT));
#ifdef SERIAL_DEBUG_INTR
;
#endif
}
Beispiel #16
0
static void sci_rx_interrupt(int irq, void *dev_id, struct pt_regs * regs)
{
	int ch;
	for(ch=0;ch<NR_PORTS;ch++)
		if(rs_table[ch].irq+1==irq)
			receive_chars(&rs_table[ch]);
}
/*
 * This is usually used to read data from SPIC RX FIFO, which doesn't
 * need any delay like flushing character out.
 *
 * Return how many valide bytes are read back
 */
static int max3110_read_multi(struct uart_max3110 *max)
{
	void *buf;
	u16 *obuf, *ibuf;
	int ret, blen;

	blen = M3110_RX_FIFO_DEPTH * sizeof(u16);
	buf = kzalloc(blen * 2, GFP_KERNEL | GFP_DMA);
	if (!buf) {
		pr_warning(PR_FMT "%s(): fail to alloc dma buffer\n", __func__);
		return 0;
	}

	/* tx/rx always have the same length */
	obuf = buf;
	ibuf = buf + blen;

	if (max3110_write_then_read(max, obuf, ibuf, blen, 1)) {
		kfree(buf);
		return 0;
	}

	ret = receive_chars(max, ibuf, M3110_RX_FIFO_DEPTH);

	kfree(buf);
	return ret;
}
void rs_interrupt(int irq, void * dev_id, struct pt_regs * regs)
{
	char status;

	struct cnxt_serial * info = &uart_info;
  	struct uart_regs *uart = uart_info.uart;
  	
	status = (uart->iir & 0x0f); /* only concerned w/ lower nibble */
	
	if (status == ISR_Tx_Rdy_Source) {
		transmit_chars(info);
	}
	if ((status == ISR_Rx_Rdy_Source) ||
            (status == ISR_Rx_Rdy_TO_Src )){
		receive_chars(info,status);
	}
	#if 0
		if(!info->use_ints){
			serialpoll.data = (void *)&sp_uart_info;		
			queue_task_irq_off(&serialpoll, &tq_timer);
		}
	#endif


	return;
}
/*
 * This is the serial driver's interrupt routine for a single port
 */
static irqreturn_t rs_interrupt_single(int irq, void *dev_id)
{
	struct serial_state *info = dev_id;

	receive_chars(&info->port);

	return IRQ_HANDLED;
}
Beispiel #20
0
/*
 * This is the serial driver's generic interrupt routine
 */
void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs)
{
	struct LEON_serial * info = &LEON_soft;
	unsigned int stat = leon->uartstatus1;

	if (stat & USTAT_DR) receive_chars(info, regs, stat);
	if (stat & USTAT_TH) transmit_chars(info);
	return;
}
Beispiel #21
0
/* static void rs_360_interrupt(void *dev_id) */ /* until and if we start servicing irqs here */
static void rs_360_interrupt(int vec, void *dev_id)
{
	u_char	events;
	int	idx;
	ser_info_t *info;
	volatile struct smc_regs *smcp;
	volatile struct scc_regs *sccp;
	
	info = dev_id;

	idx = PORT_NUM(info->state->smc_scc_num);
	if (info->state->smc_scc_num & NUM_IS_SCC) {
		sccp = &pquicc->scc_regs[idx];
		events = sccp->scc_scce;
		if (events & SCCM_RX)
			receive_chars(info);
		if (events & SCCM_TX)
			transmit_chars(info);
		sccp->scc_scce = events;
	} else {
		smcp = &pquicc->smc_regs[idx];
		events = smcp->smc_smce;
		if (events & SMCM_BRKE)
			receive_break(info);
		if (events & SMCM_RX)
			receive_chars(info);
		if (events & SMCM_TX)
			transmit_chars(info);
		smcp->smc_smce = events;
	}
	
#ifdef SERIAL_DEBUG_INTR
	printk("rs_interrupt_single(%d, %x)...",
					info->state->smc_scc_num, events);
#endif
#ifdef modem_control
	check_modem_status(info);
#endif
	info->last_active = jiffies;
#ifdef SERIAL_DEBUG_INTR
	printk("end.\n");
#endif
}
Beispiel #22
0
/*
 * This handles the interrupt from one port.
 */
static inline void m32r_sio_handle_port(struct uart_sio_port *up,
	unsigned int status)
{
	pr_debug("status = %x...\n", status);

	if (status & 0x04)
		receive_chars(up, &status);
	if (status & 0x01)
		transmit_chars(up);
}
/*
 * This is the serial driver's generic interrupt routine
 */
void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs)
{
	struct NIOS_serial * info = (struct NIOS_serial *) dev_id;
	np_uart *	uart= (np_uart *)(info->port);
	unsigned short stat = uart->np_uartstatus;
	uart->np_uartstatus = 0;		/* clear any error status */

	if (stat & np_uartstatus_rrdy_mask) receive_chars(info, regs, stat);
	if (stat & np_uartstatus_trdy_mask) transmit_chars(info);
	return;
}
Beispiel #24
0
/*
 * This is the serial driver's generic interrupt routine
 */
void gbatxt_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
    struct gbatxt_serial	*info;
    unsigned char		isr;

    info = &gbatxt_table[(irq - IRQBASE)];
    isr = (((volatile unsigned char *)info->addr)[MCFUART_UISR]) & info->imr;

    if (isr & MCFUART_UIR_RXREADY)
        receive_chars(info, regs, isr);
    if (isr & MCFUART_UIR_TXREADY)
        transmit_chars(info);
#if 0
    if (isr & MCFUART_UIR_DELTABREAK) {
        printk("%s(%d): delta break!\n", __FILE__, __LINE__);
        receive_chars(info, regs, isr);
    }
#endif

    return;
}
Beispiel #25
0
/*
 * This handles the interrupt from one port.
 */
static inline void
serial8250_handle_port(struct uart_8250_port *up, struct pt_regs *regs)
{
	unsigned int status = serial_inp(up, UART_LSR);

	DEBUG_INTR("status = %x...", status);

	if (status & UART_LSR_DR)
		receive_chars(up, &status, regs);
	check_modem_status(up);
	if (status & UART_LSR_THRE)
		transmit_chars(up);
}
static void send_circ_buf(struct uart_max3110 *max,
				struct circ_buf *xmit)
{
	void *buf;
	u16 *obuf, *ibuf;
	u8 valid_str[WORDS_PER_XFER];
	int i, j, len, blen, dma_size, left, ret = 0;


	dma_size = WORDS_PER_XFER * sizeof(u16) * 2;
	buf = kzalloc(dma_size, GFP_KERNEL | GFP_DMA);
	if (!buf)
		return;
	obuf = buf;
	ibuf = buf + dma_size/2;

	while (!uart_circ_empty(xmit)) {
		left = uart_circ_chars_pending(xmit);
		while (left) {
			len = min(left, WORDS_PER_XFER);
			blen = len * sizeof(u16);
			memset(ibuf, 0, blen);

			for (i = 0; i < len; i++) {
				obuf[i] = (u8)xmit->buf[xmit->tail] | WD_TAG;
				xmit->tail = (xmit->tail + 1) &
						(UART_XMIT_SIZE - 1);
			}

			/* Fail to send msg to console is not very critical */

			ret = max3110_write_then_read(max, obuf, ibuf, blen, 0);
			if (ret)
				pr_warning(PR_FMT "%s(): get err msg %d\n",
						__func__, ret);

			for (i = 0, j = 0; i < len; i++) {
				if (ibuf[i] & MAX3110_READ_DATA_AVAILABLE)
					valid_str[j++] = ibuf[i] & 0xff;
			}

			if (j)
				receive_chars(max, valid_str, j);

			max->port.icount.tx += len;
			left -= len;
		}
	}

	kfree(buf);
}
Beispiel #27
0
/*
 * This is the serial driver's generic interrupt routine
 */
irqreturn_t mcfrs_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
	struct mcf_serial	*info;
	unsigned char		isr;

	info = &mcfrs_table[(irq - IRQBASE)];
	isr = info->addr[MCFUART_UISR] & info->imr;

	if (isr & MCFUART_UIR_RXREADY)
		receive_chars(info);
	if (isr & MCFUART_UIR_TXREADY)
		transmit_chars(info);
	return IRQ_HANDLED;
}
static irqreturn_t sc26xx_interrupt(int irq, void *dev_id)
{
	struct uart_sc26xx_port *up = dev_id;
	unsigned long flags;
	bool push;
	u8 isr;

	spin_lock_irqsave(&up->port[0].lock, flags);

	push = false;
	isr = READ_SC(&up->port[0], ISR);
	if (isr & ISR_TXRDYA)
	    transmit_chars(&up->port[0]);
	if (isr & ISR_RXRDYA)
	    push = receive_chars(&up->port[0]);

	spin_unlock(&up->port[0].lock);

	if (push)
		tty_flip_buffer_push(&up->port[0].state->port);

	spin_lock(&up->port[1].lock);

	push = false;
	if (isr & ISR_TXRDYB)
	    transmit_chars(&up->port[1]);
	if (isr & ISR_RXRDYB)
	    push = receive_chars(&up->port[1]);

	spin_unlock_irqrestore(&up->port[1].lock, flags);

	if (push)
		tty_flip_buffer_push(&up->port[1].state->port);

	return IRQ_HANDLED;
}
/*
 * ------------------------------------------------------------
 * dz_interrupt ()
 *
 * this is the main interrupt routine for the DZ chip.
 * It deals with the multiple ports.
 * ------------------------------------------------------------
 */
static void dz_interrupt(int irq, void *dev, struct pt_regs *regs)
{
	struct dz_serial *info;
	unsigned short status;

	/* get the reason why we just got an irq */
	status = dz_in((struct dz_serial *) dev, DZ_CSR);
	info = lines[LINE(status)];	/* re-arrange info the proper port */

	if (status & DZ_RDONE)
		receive_chars(info);	/* the receive function */

	if (status & DZ_TRDY)
		transmit_chars(info);
}
static irqreturn_t sc26xx_interrupt(int irq, void *dev_id)
{
	struct uart_sc26xx_port *up = dev_id;
	struct tty_struct *tty;
	unsigned long flags;
	u8 isr;

	spin_lock_irqsave(&up->port[0].lock, flags);

	tty = NULL;
	isr = READ_SC(&up->port[0], ISR);
	if (isr & ISR_TXRDYA)
	    transmit_chars(&up->port[0]);
	if (isr & ISR_RXRDYA)
	    tty = receive_chars(&up->port[0]);

	spin_unlock(&up->port[0].lock);

	if (tty)
		tty_flip_buffer_push(tty);

	spin_lock(&up->port[1].lock);

	tty = NULL;
	if (isr & ISR_TXRDYB)
	    transmit_chars(&up->port[1]);
	if (isr & ISR_RXRDYB)
	    tty = receive_chars(&up->port[1]);

	spin_unlock_irqrestore(&up->port[1].lock, flags);

	if (tty)
		tty_flip_buffer_push(tty);

	return IRQ_HANDLED;
}