/* Called with u->lock taken */
static void tegra_start_next_tx(struct tegra_uart_port *t)
{
	unsigned long tail;
	unsigned long count;

	struct circ_buf *xmit;

	xmit = &t->uport.state->xmit;
	tail = (unsigned long)&xmit->buf[xmit->tail];
	count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);


	dev_vdbg(t->uport.dev, "+%s %lu %d\n", __func__, count,
		t->tx_in_progress);

	if (count == 0)
		goto out;

	if (!t->use_tx_dma || count < TEGRA_UART_MIN_DMA)
		tegra_start_pio_tx(t, count);
	else if (BYTES_TO_ALIGN(tail) > 0)
		tegra_start_pio_tx(t, BYTES_TO_ALIGN(tail));
	else
		tegra_start_dma_tx(t, count);

out:
	dev_vdbg(t->uport.dev, "-%s", __func__);
}
예제 #2
0
/* Called with u->lock taken */
static void tegra_start_next_tx(struct tegra_uart_port *t)
{
	unsigned long tail;
	unsigned long count;
	unsigned long lsr;
	struct uart_port *u = &t->uport;

	struct circ_buf *xmit;

	xmit = &t->uport.state->xmit;
	tail = (unsigned long)&xmit->buf[xmit->tail];
	count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);


	dev_vdbg(t->uport.dev, "+%s %lu %d\n", __func__, count,
		t->tx_in_progress);

	if (count == 0) {
		if (t->is_irda && !irda_loop) {
			do {
				lsr = uart_readb(t, UART_LSR);
				if (lsr & UART_LSR_TEMT)
					break;
			} while (1);
			tegra_start_rx(u);
		}
		goto out;
	}

	if (t->is_irda && !irda_loop) {
		if (t->rx_in_progress)
			tegra_stop_rx(u);
	}

	if (!t->use_tx_dma || count < TEGRA_UART_MIN_DMA)
		tegra_start_pio_tx(t, count);
	else if (BYTES_TO_ALIGN(tail) > 0)
		tegra_start_pio_tx(t, BYTES_TO_ALIGN(tail));
	else
		tegra_start_dma_tx(t, count);

out:
	dev_vdbg(t->uport.dev, "-%s", __func__);
}