Skip to content

Commit 1f69a12

Browse files
digetxgregkh
authored andcommitted
tty: serial: tegra: Handle RX transfer in PIO mode if DMA wasn't started
It is possible to get an instant RX timeout or end-of-transfer interrupt before RX DMA was started, if transaction is less than 16 bytes. Transfer should be handled in PIO mode in this case because DMA can't handle it. This patch brings back the original behaviour of the driver that was changed by accident by a previous commit, it fixes occasional Bluetooth HW initialization failures which I started to notice recently. Fixes: d5e3fad ("tty: serial: tegra: Activate RX DMA transfer by request") Signed-off-by: Dmitry Osipenko <digetx@gmail.com> Link: https://lore.kernel.org/r/20200209164415.9632-1-digetx@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 04b5bfe commit 1f69a12

File tree

1 file changed

+16
-19
lines changed

1 file changed

+16
-19
lines changed

drivers/tty/serial/serial-tegra.c

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -692,11 +692,22 @@ static void tegra_uart_copy_rx_to_tty(struct tegra_uart_port *tup,
692692
count, DMA_TO_DEVICE);
693693
}
694694

695+
static void do_handle_rx_pio(struct tegra_uart_port *tup)
696+
{
697+
struct tty_struct *tty = tty_port_tty_get(&tup->uport.state->port);
698+
struct tty_port *port = &tup->uport.state->port;
699+
700+
tegra_uart_handle_rx_pio(tup, port);
701+
if (tty) {
702+
tty_flip_buffer_push(port);
703+
tty_kref_put(tty);
704+
}
705+
}
706+
695707
static void tegra_uart_rx_buffer_push(struct tegra_uart_port *tup,
696708
unsigned int residue)
697709
{
698710
struct tty_port *port = &tup->uport.state->port;
699-
struct tty_struct *tty = tty_port_tty_get(port);
700711
unsigned int count;
701712

702713
async_tx_ack(tup->rx_dma_desc);
@@ -705,11 +716,7 @@ static void tegra_uart_rx_buffer_push(struct tegra_uart_port *tup,
705716
/* If we are here, DMA is stopped */
706717
tegra_uart_copy_rx_to_tty(tup, port, count);
707718

708-
tegra_uart_handle_rx_pio(tup, port);
709-
if (tty) {
710-
tty_flip_buffer_push(port);
711-
tty_kref_put(tty);
712-
}
719+
do_handle_rx_pio(tup);
713720
}
714721

715722
static void tegra_uart_rx_dma_complete(void *args)
@@ -749,8 +756,10 @@ static void tegra_uart_terminate_rx_dma(struct tegra_uart_port *tup)
749756
{
750757
struct dma_tx_state state;
751758

752-
if (!tup->rx_dma_active)
759+
if (!tup->rx_dma_active) {
760+
do_handle_rx_pio(tup);
753761
return;
762+
}
754763

755764
dmaengine_terminate_all(tup->rx_dma_chan);
756765
dmaengine_tx_status(tup->rx_dma_chan, tup->rx_cookie, &state);
@@ -816,18 +825,6 @@ static void tegra_uart_handle_modem_signal_change(struct uart_port *u)
816825
uart_handle_cts_change(&tup->uport, msr & UART_MSR_CTS);
817826
}
818827

819-
static void do_handle_rx_pio(struct tegra_uart_port *tup)
820-
{
821-
struct tty_struct *tty = tty_port_tty_get(&tup->uport.state->port);
822-
struct tty_port *port = &tup->uport.state->port;
823-
824-
tegra_uart_handle_rx_pio(tup, port);
825-
if (tty) {
826-
tty_flip_buffer_push(port);
827-
tty_kref_put(tty);
828-
}
829-
}
830-
831828
static irqreturn_t tegra_uart_isr(int irq, void *data)
832829
{
833830
struct tegra_uart_port *tup = data;

0 commit comments

Comments
 (0)