Beispiel #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;
}
Beispiel #2
0
/* It is expected that the callers take the UART lock when this API is called.
 *
 * There are 2 contexts when this function is called:
 *
 * 1. DMA ISR - DMA ISR triggers the threshold complete calback, which calls the
 * dequue API which in-turn calls this callback. UART lock is taken during
 * the call to the threshold callback.
 *
 * 2. UART ISR - UART calls the dequue API which in-turn will call this API.
 * In this case, UART ISR takes the UART lock.
 * */
static void tegra_rx_dma_complete_callback(struct tegra_dma_req *req)
{
	struct tegra_uart_port *t = req->dev;
	struct uart_port *u = &t->uport;
	struct tty_struct *tty = u->state->port.tty;

	/* If we are here, DMA is stopped */

	dev_dbg(t->uport.dev, "%s: %d %d\n", __func__, req->bytes_transferred,
		req->status);
	if (req->bytes_transferred) {
		t->uport.icount.rx += req->bytes_transferred;
		tty_insert_flip_string(tty,
			((unsigned char *)(req->virt_addr)),
			req->bytes_transferred);
	}

	do_handle_rx_pio(t);

	/* Push the read data later in caller place. */
	if (req->status == -TEGRA_DMA_REQ_ERROR_ABORTED)
		return;

	spin_unlock(&u->lock);
	tty_flip_buffer_push(u->state->port.tty);
	spin_lock(&u->lock);
}
Beispiel #3
0
/*
 * It is expected that the callers take the UART lock when this API is called.
 *
 * There are 2 contexts when this function is called:
 *
 * 1. DMA ISR - DMA ISR triggers the threshold complete calback, which calls the
 * dequue API which in-turn calls this callback. UART lock is taken during
 * the call to the threshold callback.
 *
 * 2. UART ISR - UART calls the dequue API which in-turn will call this API.
 * In this case, UART ISR takes the UART lock.
 */
static void tegra_rx_dma_complete_callback(struct tegra_dma_req *req)
{
	struct tegra_uart_port *t = req->dev;
	struct uart_port *u = &t->uport;
	struct tty_struct *tty = u->state->port.tty;
	int copied;

	/* If we are here, DMA is stopped */

	dev_dbg(t->uport.dev, "%s: %d %d\n", __func__, req->bytes_transferred,
		req->status);
	if (req->bytes_transferred) {
		t->uport.icount.rx += req->bytes_transferred;
		dma_sync_single_for_cpu(t->uport.dev, req->dest_addr,
				req->size, DMA_FROM_DEVICE);
		copied = tty_insert_flip_string(tty,
			((unsigned char *)(req->virt_addr)),
			req->bytes_transferred);
		if (copied != req->bytes_transferred) {
			WARN_ON(1);
			dev_err(t->uport.dev, "Not able to copy uart data "
				"to tty layer Req %d and coped %d\n",
				req->bytes_transferred, copied);
		}
		dma_sync_single_for_device(t->uport.dev, req->dest_addr,
				req->size, DMA_TO_DEVICE);
	}

	do_handle_rx_pio(t);

	/* Push the read data later in caller place. */
	if (req->status == -TEGRA_DMA_REQ_ERROR_ABORTED)
		return;

	printk(KERN_ERR "%s: tegra_uart_%d: DMA_REQ: buf_stat(%d),stat(%d)\n",
		__func__, req->instance, req->buffer_status, req->status);

	/* Not out of sync err from dma_isr/dbl_dma */
	if (req->status != -TEGRA_DMA_REQ_ERROR_STOPPED)
		spin_unlock(&u->lock);
	tty_flip_buffer_push(u->state->port.tty);
	/* Not out of sync err from dma_isr/dbl_dma */
	if (req->status != -TEGRA_DMA_REQ_ERROR_STOPPED)
		spin_lock(&u->lock);
}
Beispiel #4
0
static irqreturn_t tegra_uart_isr(int irq, void *data)
{
	struct tegra_uart_port *t = data;
	struct uart_port *u = &t->uport;
	unsigned char iir;
	unsigned char ier;
	bool is_rx_int = false;
	unsigned long flags;

	spin_lock_irqsave(&u->lock, flags);
	t  = container_of(u, struct tegra_uart_port, uport);
	while (1) {
		iir = uart_readb(t, UART_IIR);
		if (iir & UART_IIR_NO_INT) {
			if (likely(t->use_rx_dma) && is_rx_int) {
				do_handle_rx_dma(t);

				if (t->rx_in_progress) {
					ier = t->ier_shadow;
					ier |= (UART_IER_RLSI | UART_IER_RTOIE |
								UART_IER_EORD);
					t->ier_shadow = ier;
					uart_writeb(t, ier, UART_IER);
				}
			}
			spin_unlock_irqrestore(&u->lock, flags);
			return IRQ_HANDLED;
		}

		dev_dbg(u->dev, "tegra_uart_isr iir = 0x%x (%d)\n", iir,
			(iir >> 1) & 0x7);
		switch ((iir >> 1) & 0x7) {
		case 0: /* Modem signal change interrupt */
			do_handle_modem_signal(u);
			break;
		case 1: /* Transmit interrupt only triggered when using PIO */
			t->ier_shadow &= ~UART_IER_THRI;
			uart_writeb(t, t->ier_shadow, UART_IER);
			do_handle_tx_pio(t);
			break;
		case 4: /* End of data */
		case 6: /* Rx timeout */
		case 2: /* Receive */
			if (likely(t->use_rx_dma)) {
				if (!is_rx_int) {
					is_rx_int = true;
					/* Disable interrups */
					ier = t->ier_shadow;
					ier |= UART_IER_RDI;
					uart_writeb(t, ier, UART_IER);
					ier &= ~(UART_IER_RDI | UART_IER_RLSI |
						UART_IER_RTOIE | UART_IER_EORD);
					t->ier_shadow = ier;
					uart_writeb(t, ier, UART_IER);
				}
			} else {
				do_handle_rx_pio(t);

				spin_unlock_irqrestore(&u->lock, flags);
				tty_flip_buffer_push(u->state->port.tty);
				spin_lock_irqsave(&u->lock, flags);
			}
			break;
		case 3: /* Receive error */
			/* FIXME how to handle this? Why do we get here */
			do_decode_rx_error(t, uart_readb(t, UART_LSR));
			break;
		case 5: /* break nothing to handle */
		case 7: /* break nothing to handle */
			break;
		}
	}
}
static irqreturn_t tegra_uart_isr(int irq, void *data)
{
	struct tegra_uart_port *tup = data;
	struct uart_port *u = &tup->uport;
	unsigned long iir;
	unsigned long ier;
	bool is_rx_int = false;
	unsigned long flags;

	spin_lock_irqsave(&u->lock, flags);
	while (1) {
		iir = tegra_uart_read(tup, UART_IIR);
		if (iir & UART_IIR_NO_INT) {
			if (!tup->use_rx_pio && is_rx_int) {
				tegra_uart_handle_rx_dma(tup);
				if (tup->rx_in_progress) {
					ier = tup->ier_shadow;
					ier |= (UART_IER_RLSI | UART_IER_RTOIE |
						TEGRA_UART_IER_EORD);
					tup->ier_shadow = ier;
					tegra_uart_write(tup, ier, UART_IER);
				}
			}
			spin_unlock_irqrestore(&u->lock, flags);
			return IRQ_HANDLED;
		}

		switch ((iir >> 1) & 0x7) {
		case 0: /* Modem signal change interrupt */
			tegra_uart_handle_modem_signal_change(u);
			break;

		case 1: /* Transmit interrupt only triggered when using PIO */
			tup->ier_shadow &= ~UART_IER_THRI;
			tegra_uart_write(tup, tup->ier_shadow, UART_IER);
			tegra_uart_handle_tx_pio(tup);
			break;

		case 4: /* End of data */
		case 6: /* Rx timeout */
		case 2: /* Receive */
			if (!tup->use_rx_pio && !is_rx_int) {
				is_rx_int = true;
				/* Disable Rx interrupts */
				ier = tup->ier_shadow;
				ier |= UART_IER_RDI;
				tegra_uart_write(tup, ier, UART_IER);
				ier &= ~(UART_IER_RDI | UART_IER_RLSI |
						UART_IER_RTOIE |
						TEGRA_UART_IER_EORD);
				tup->ier_shadow = ier;
				tegra_uart_write(tup, ier, UART_IER);
			} else
				do_handle_rx_pio(tup);
			break;

		case 3: /* Receive error */
			tegra_uart_decode_rx_error(tup,
					tegra_uart_read(tup, UART_LSR));
			break;

		case 5: /* break nothing to handle */
		case 7: /* break nothing to handle */
			break;
		}
	}
}