Commit 32ede4a5 authored by Jon Hunter's avatar Jon Hunter Committed by Greg Kroah-Hartman

serial: tegra: Add helper function for handling RX buffer

In the tegra UART driver there are three places where the RX DMA buffer
is handled and pushed up to the tty layer. In all three instances the
same functions are called and so instead of duplicating the code in three
places, move this code to a new helper function and use this new function.
Signed-off-by: default avatarJon Hunter <jonathanh@nvidia.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent b0e066cc
...@@ -569,13 +569,30 @@ static void tegra_uart_copy_rx_to_tty(struct tegra_uart_port *tup, ...@@ -569,13 +569,30 @@ static void tegra_uart_copy_rx_to_tty(struct tegra_uart_port *tup,
TEGRA_UART_RX_DMA_BUFFER_SIZE, DMA_TO_DEVICE); TEGRA_UART_RX_DMA_BUFFER_SIZE, DMA_TO_DEVICE);
} }
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_rx_dma_complete(void *args) static void tegra_uart_rx_dma_complete(void *args)
{ {
struct tegra_uart_port *tup = args; struct tegra_uart_port *tup = args;
struct uart_port *u = &tup->uport; struct uart_port *u = &tup->uport;
unsigned 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; unsigned long flags;
struct dma_tx_state state; struct dma_tx_state state;
enum dma_status status; enum dma_status status;
...@@ -589,20 +606,11 @@ static void tegra_uart_rx_dma_complete(void *args) ...@@ -589,20 +606,11 @@ static void tegra_uart_rx_dma_complete(void *args)
goto done; goto done;
} }
async_tx_ack(tup->rx_dma_desc);
/* Deactivate flow control to stop sender */ /* Deactivate flow control to stop sender */
if (tup->rts_active) if (tup->rts_active)
set_rts(tup, false); set_rts(tup, false);
/* If we are here, DMA is stopped */ tegra_uart_rx_buffer_push(tup, 0);
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);
}
tegra_uart_start_rx_dma(tup); tegra_uart_start_rx_dma(tup);
/* Activate flow control to start transfer */ /* Activate flow control to start transfer */
...@@ -616,9 +624,6 @@ static void tegra_uart_rx_dma_complete(void *args) ...@@ -616,9 +624,6 @@ static void tegra_uart_rx_dma_complete(void *args)
static void tegra_uart_handle_rx_dma(struct tegra_uart_port *tup) static void tegra_uart_handle_rx_dma(struct tegra_uart_port *tup)
{ {
struct dma_tx_state state; 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;
unsigned int count;
/* Deactivate flow control to stop sender */ /* Deactivate flow control to stop sender */
if (tup->rts_active) if (tup->rts_active)
...@@ -626,17 +631,7 @@ static void tegra_uart_handle_rx_dma(struct tegra_uart_port *tup) ...@@ -626,17 +631,7 @@ static void tegra_uart_handle_rx_dma(struct tegra_uart_port *tup)
dmaengine_terminate_all(tup->rx_dma_chan); dmaengine_terminate_all(tup->rx_dma_chan);
dmaengine_tx_status(tup->rx_dma_chan, tup->rx_cookie, &state); dmaengine_tx_status(tup->rx_dma_chan, tup->rx_cookie, &state);
async_tx_ack(tup->rx_dma_desc); tegra_uart_rx_buffer_push(tup, state.residue);
count = tup->rx_bytes_requested - state.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);
}
tegra_uart_start_rx_dma(tup); tegra_uart_start_rx_dma(tup);
if (tup->rts_active) if (tup->rts_active)
...@@ -755,11 +750,8 @@ static irqreturn_t tegra_uart_isr(int irq, void *data) ...@@ -755,11 +750,8 @@ static irqreturn_t tegra_uart_isr(int irq, void *data)
static void tegra_uart_stop_rx(struct uart_port *u) static void tegra_uart_stop_rx(struct uart_port *u)
{ {
struct tegra_uart_port *tup = to_tegra_uport(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; struct dma_tx_state state;
unsigned long ier; unsigned long ier;
int count;
if (tup->rts_active) if (tup->rts_active)
set_rts(tup, false); set_rts(tup, false);
...@@ -767,8 +759,6 @@ static void tegra_uart_stop_rx(struct uart_port *u) ...@@ -767,8 +759,6 @@ static void tegra_uart_stop_rx(struct uart_port *u)
if (!tup->rx_in_progress) if (!tup->rx_in_progress)
return; return;
tty = tty_port_tty_get(&tup->uport.state->port);
tegra_uart_wait_sym_time(tup, 1); /* wait a character interval */ tegra_uart_wait_sym_time(tup, 1); /* wait a character interval */
ier = tup->ier_shadow; ier = tup->ier_shadow;
...@@ -779,15 +769,7 @@ static void tegra_uart_stop_rx(struct uart_port *u) ...@@ -779,15 +769,7 @@ static void tegra_uart_stop_rx(struct uart_port *u)
tup->rx_in_progress = 0; tup->rx_in_progress = 0;
dmaengine_terminate_all(tup->rx_dma_chan); dmaengine_terminate_all(tup->rx_dma_chan);
dmaengine_tx_status(tup->rx_dma_chan, tup->rx_cookie, &state); dmaengine_tx_status(tup->rx_dma_chan, tup->rx_cookie, &state);
async_tx_ack(tup->rx_dma_desc); tegra_uart_rx_buffer_push(tup, state.residue);
count = tup->rx_bytes_requested - state.residue;
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_hw_deinit(struct tegra_uart_port *tup) static void tegra_uart_hw_deinit(struct tegra_uart_port *tup)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment