static void tegra_uart_handle_rx_dma(struct tegra_uart_port *tup, unsigned long *flags) { struct dma_tx_state state; struct tty_struct *tty = tty_port_tty_get(&tup->uport.state->port); struct tty_port *port = &tup->uport.state->port; struct uart_port *u = &tup->uport; int count; /* Deactivate flow control to stop sender */ if (tup->rts_active) set_rts(tup, false); dmaengine_terminate_all(tup->rx_dma_chan); dmaengine_tx_status(tup->rx_dma_chan, tup->rx_cookie, &state); async_tx_ack(tup->rx_dma_desc); count = tup->rx_bytes_requested - state.residue; /* If we are here, DMA is stopped */ if (count) tegra_uart_copy_rx_to_tty(tup, port, count); tegra_uart_handle_rx_pio(tup, port); if (tty) { spin_unlock_irqrestore(&u->lock, *flags); tty_flip_buffer_push(port); spin_lock_irqsave(&u->lock, *flags); tty_kref_put(tty); } tegra_uart_start_rx_dma(tup); if (tup->rts_active) set_rts(tup, true); }
static void tegra_uart_rx_dma_complete(void *args) { struct tegra_uart_port *tup = args; struct uart_port *u = &tup->uport; int count = tup->rx_bytes_requested; struct tty_struct *tty = tty_port_tty_get(&tup->uport.state->port); struct tty_port *port = &u->state->port; unsigned long flags; async_tx_ack(tup->rx_dma_desc); spin_lock_irqsave(&u->lock, flags); /* Deactivate flow control to stop sender */ if (tup->rts_active) set_rts(tup, false); /* If we are here, DMA is stopped */ if (count) tegra_uart_copy_rx_to_tty(tup, port, count); tegra_uart_handle_rx_pio(tup, port); if (tty) { spin_unlock_irqrestore(&u->lock, flags); tty_flip_buffer_push(port); spin_lock_irqsave(&u->lock, flags); tty_kref_put(tty); } tegra_uart_start_rx_dma(tup); /* Activate flow control to start transfer */ if (tup->rts_active) set_rts(tup, true); spin_unlock_irqrestore(&u->lock, flags); }
static void tegra_uart_stop_rx(struct uart_port *u) { struct tegra_uart_port *tup = to_tegra_uport(u); struct tty_struct *tty; struct tty_port *port = &u->state->port; struct dma_tx_state state; unsigned long ier; int count; if (tup->rts_active) set_rts(tup, false); if (!tup->rx_in_progress) return; tty = tty_port_tty_get(&tup->uport.state->port); tegra_uart_wait_sym_time(tup, 1); /* wait a character interval */ ier = tup->ier_shadow; 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); tup->rx_in_progress = 0; if (tup->rx_dma_chan && !tup->use_rx_pio) { dmaengine_terminate_all(tup->rx_dma_chan); dmaengine_tx_status(tup->rx_dma_chan, tup->rx_cookie, &state); async_tx_ack(tup->rx_dma_desc); count = tup->rx_bytes_requested - state.residue; if (count) tegra_uart_copy_rx_to_tty(tup, port, count); tegra_uart_handle_rx_pio(tup, port); } else { tegra_uart_handle_rx_pio(tup, port); } if (tty) { tty_flip_buffer_push(port); tty_kref_put(tty); } return; }
static void do_handle_rx_pio(struct tegra_uart_port *tup) { struct tty_struct *tty = tty_port_tty_get(&tup->uport.state->port); struct tty_port *port = &tup->uport.state->port; tegra_uart_handle_rx_pio(tup, port); if (tty) { tty_flip_buffer_push(port); tty_kref_put(tty); } }
static void tegra_uart_rx_dma_complete(void *args) { struct tegra_uart_port *tup = args; struct uart_port *u = &tup->uport; int count = tup->rx_bytes_requested; struct tty_struct *tty = tty_port_tty_get(&tup->uport.state->port); struct tty_port *port = &u->state->port; unsigned long flags; int rx_level = 0; struct dma_tx_state state; enum dma_status status; spin_lock_irqsave(&u->lock, flags); async_tx_ack(tup->rx_dma_desc); status = dmaengine_tx_status(tup->rx_dma_chan, tup->rx_cookie, &state); if (status == DMA_IN_PROGRESS) { dev_info(tup->uport.dev, "RX DMA is in progress\n"); goto done; } /* Deactivate flow control to stop sender */ if (tup->rts_active) set_rts(tup, false); /* If we are here, DMA is stopped */ if (count) tegra_uart_copy_rx_to_tty(tup, port, count); tegra_uart_handle_rx_pio(tup, port); if (tup->enable_rx_buffer_throttle) { rx_level = tty_buffer_get_level(port); if (rx_level > 70) mod_timer(&tup->timer, jiffies + tup->timer_timeout_jiffies); } if (tty) { tty_flip_buffer_push(port); tty_kref_put(tty); } tegra_uart_start_rx_dma(tup); /* Activate flow control to start transfer */ if (tup->enable_rx_buffer_throttle) { if ((rx_level <= 70) && tup->rts_active) set_rts(tup, true); } else if (tup->rts_active) set_rts(tup, true); done: spin_unlock_irqrestore(&u->lock, flags); }
static void tegra_uart_rx_buffer_push(struct tegra_uart_port *tup, unsigned int residue) { struct tty_port *port = &tup->uport.state->port; struct tty_struct *tty = tty_port_tty_get(port); unsigned int count; async_tx_ack(tup->rx_dma_desc); count = tup->rx_bytes_requested - residue; /* If we are here, DMA is stopped */ tegra_uart_copy_rx_to_tty(tup, port, count); tegra_uart_handle_rx_pio(tup, port); if (tty) { tty_flip_buffer_push(port); tty_kref_put(tty); } }
static void tegra_uart_handle_rx_dma(struct tegra_uart_port *tup) { struct dma_tx_state state; struct tty_struct *tty = tty_port_tty_get(&tup->uport.state->port); struct tty_port *port = &tup->uport.state->port; int count; int rx_level = 0; /* Deactivate flow control to stop sender */ if (tup->rts_active) set_rts(tup, false); dmaengine_terminate_all(tup->rx_dma_chan); dmaengine_tx_status(tup->rx_dma_chan, tup->rx_cookie, &state); async_tx_ack(tup->rx_dma_desc); count = tup->rx_bytes_requested - state.residue; /* If we are here, DMA is stopped */ if (count) tegra_uart_copy_rx_to_tty(tup, port, count); tegra_uart_handle_rx_pio(tup, port); if (tup->enable_rx_buffer_throttle) { rx_level = tty_buffer_get_level(port); if (rx_level > 70) mod_timer(&tup->timer, jiffies + tup->timer_timeout_jiffies); } if (tty) { tty_flip_buffer_push(port); tty_kref_put(tty); } tegra_uart_start_rx_dma(tup); if (tup->enable_rx_buffer_throttle) { if ((rx_level <= 70) && tup->rts_active) set_rts(tup, true); } else if (tup->rts_active) set_rts(tup, true); }