Exemplo n.º 1
0
static void tegra_stop_rx(struct uart_port *u)
{
	struct tegra_uart_port *t;
	unsigned char ier;

	t = container_of(u, struct tegra_uart_port, uport);

	if (t->rts_active)
		set_rts(t, false);

	if (t->rx_in_progress) {
		wait_sym_time(t, 1); /* wait a character interval */

		ier = t->ier_shadow;
		ier &= ~(UART_IER_RDI | UART_IER_RLSI | UART_IER_RTOIE |
					UART_IER_EORD);
		t->ier_shadow = ier;
		uart_writeb(t, ier, UART_IER);
		t->rx_in_progress = 0;

		if (t->use_rx_dma && t->rx_dma)
			tegra_dma_dequeue_req(t->rx_dma, &t->rx_dma_req);
		else
			do_handle_rx_pio(t);

		tty_flip_buffer_push(u->state->port.tty);
	}

	return;
}
Exemplo n.º 2
0
static void tegra_start_rx(struct uart_port *u)
{
	struct tegra_uart_port *t;
	unsigned char ier;

	t = container_of(u, struct tegra_uart_port, uport);

	if (t->rts_active)
		set_rts(t, true);

	if (!t->rx_in_progress) {
		wait_sym_time(t, 1); /* wait a character interval */

		/* Clear the received Bytes from FIFO */
		tegra_fifo_reset(t, UART_FCR_CLEAR_RCVR);
		uart_readb(t, UART_LSR);
		ier = 0;
		ier |= (UART_IER_RLSI | UART_IER_RTOIE);
		if (t->use_rx_dma)
			ier |= UART_IER_EORD;
		else
			ier |= UART_IER_RDI;
		t->ier_shadow |= ier;
		uart_writeb(t, t->ier_shadow, UART_IER);

		t->rx_in_progress = 1;

		if (t->use_rx_dma && t->rx_dma)
			tegra_dma_enqueue_req(t->rx_dma, &t->rx_dma_req);

		tty_flip_buffer_push(u->state->port.tty);
	}

	return;
}
Exemplo n.º 3
0
/* Flush desired FIFO. */
static void tegra_fifo_reset(struct tegra_uart_port *t, u8 fcr_bits)
{
	unsigned char fcr = t->fcr_shadow;
	fcr |= fcr_bits & (UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
	uart_writeb(t, fcr, UART_FCR);
	uart_readb(t, UART_SCR); /* Dummy read to ensure the write is posted */
	wait_sym_time(t, 1); /* Wait for the flush to propagate. */
}
Exemplo n.º 4
0
static void tegra_set_baudrate(struct tegra_uart_port *t, unsigned int baud)
{
	unsigned long rate;
	unsigned int divisor;
	unsigned char lcr;
	unsigned int baud_actual;
	unsigned int baud_delta;
	unsigned long best_rate;

	if (t->baud == baud)
		return;

	rate = baud * 16;
	best_rate = find_best_clock_source(t, rate);
	clk_set_rate(t->clk, best_rate);

	rate = clk_get_rate(t->clk);

	divisor = rate;
	do_div(divisor, 16);
	divisor += baud/2;
	do_div(divisor, baud);

	/* The allowable baudrate error from desired baudrate is 5% */
	baud_actual = divisor ? rate / (16 * divisor) : 0;
	baud_delta = abs(baud_actual - baud);
	if (WARN_ON(baud_delta * 20 > baud)) {
		dev_err(t->uport.dev, "requested baud %u, actual %u\n",
				baud, baud_actual);
	}

	lcr = t->lcr_shadow;
	lcr |= UART_LCR_DLAB;
	uart_writeb(t, lcr, UART_LCR);

	uart_writel(t, divisor & 0xFF, UART_TX);
	uart_writel(t, ((divisor >> 8) & 0xFF), UART_IER);

	lcr &= ~UART_LCR_DLAB;
	uart_writeb(t, lcr, UART_LCR);
	uart_readb(t, UART_SCR); /* Dummy read to ensure the write is posted */

	t->baud = baud;
	wait_sym_time(t, 2); /* wait two character intervals at new rate */
	dev_dbg(t->uport.dev, "Baud %u clock freq %lu and divisor of %u\n",
		baud, rate, divisor);
}
Exemplo n.º 5
0
/* Flush desired FIFO. */
static void tegra_fifo_reset(struct tegra_uart_port *t, u8 fcr_bits)
{
	unsigned char fcr = t->fcr_shadow;
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
	fcr |= fcr_bits & (UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
	uart_writeb(t, fcr, UART_FCR);
#else
	/*Hw issue: Resetting tx fifo with non-fifo
	mode to avoid any extra character to be sent*/
	fcr &= ~UART_FCR_ENABLE_FIFO;
	uart_writeb(t, fcr, UART_FCR);
	udelay(60);
	fcr |= fcr_bits & (UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
	uart_writeb(t, fcr, UART_FCR);
	fcr |= UART_FCR_ENABLE_FIFO;
	uart_writeb(t, fcr, UART_FCR);
#endif
	uart_readb(t, UART_SCR); /* Dummy read to ensure the write is posted */
	wait_sym_time(t, 1); /* Wait for the flush to propagate. */
}