From: Greg Kroah-Hartman Date: Mon, 16 Jan 2023 15:17:58 +0000 (+0100) Subject: 4.19-stable patches X-Git-Tag: v4.14.303~21 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d40d9c68e1f01edd46038f258de15559b19b4fce;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches added patches: tty-serial-tegra-handle-rx-transfer-in-pio-mode-if-dma-wasn-t-started.patch --- diff --git a/queue-4.19/series b/queue-4.19/series index 03aea80fc9f..3050a3526ce 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -515,3 +515,4 @@ drm-virtio-fix-gem-handle-creation-uaf.patch arm64-cmpxchg_double-hazard-against-entire-exchange-.patch efi-fix-null-deref-in-init-error-path.patch revert-usb-ulpi-defer-ulpi_register-on-ulpi_read_id-timeout.patch +tty-serial-tegra-handle-rx-transfer-in-pio-mode-if-dma-wasn-t-started.patch diff --git a/queue-4.19/tty-serial-tegra-handle-rx-transfer-in-pio-mode-if-dma-wasn-t-started.patch b/queue-4.19/tty-serial-tegra-handle-rx-transfer-in-pio-mode-if-dma-wasn-t-started.patch new file mode 100644 index 00000000000..eea2f9c8184 --- /dev/null +++ b/queue-4.19/tty-serial-tegra-handle-rx-transfer-in-pio-mode-if-dma-wasn-t-started.patch @@ -0,0 +1,94 @@ +From 1f69a1273b3f204a9c00dc3bbdcc4afcd0787428 Mon Sep 17 00:00:00 2001 +From: Dmitry Osipenko +Date: Sun, 9 Feb 2020 19:44:15 +0300 +Subject: tty: serial: tegra: Handle RX transfer in PIO mode if DMA wasn't started + +From: Dmitry Osipenko + +commit 1f69a1273b3f204a9c00dc3bbdcc4afcd0787428 upstream. + +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: d5e3fadb7012 ("tty: serial: tegra: Activate RX DMA transfer by request") +Signed-off-by: Dmitry Osipenko +Link: https://lore.kernel.org/r/20200209164415.9632-1-digetx@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/serial/serial-tegra.c | 35 ++++++++++++++++------------------- + 1 file changed, 16 insertions(+), 19 deletions(-) + +--- a/drivers/tty/serial/serial-tegra.c ++++ b/drivers/tty/serial/serial-tegra.c +@@ -638,11 +638,22 @@ static void tegra_uart_copy_rx_to_tty(st + TEGRA_UART_RX_DMA_BUFFER_SIZE, DMA_TO_DEVICE); + } + ++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_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); +@@ -651,11 +662,7 @@ static void tegra_uart_rx_buffer_push(st + /* 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); +- } ++ do_handle_rx_pio(tup); + } + + static void tegra_uart_rx_dma_complete(void *args) +@@ -695,8 +702,10 @@ static void tegra_uart_terminate_rx_dma( + { + struct dma_tx_state state; + +- if (!tup->rx_dma_active) ++ if (!tup->rx_dma_active) { ++ do_handle_rx_pio(tup); + return; ++ } + + dmaengine_pause(tup->rx_dma_chan); + dmaengine_tx_status(tup->rx_dma_chan, tup->rx_cookie, &state); +@@ -765,18 +774,6 @@ static void tegra_uart_handle_modem_sign + uart_handle_cts_change(&tup->uport, msr & UART_MSR_CTS); + } + +-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 irqreturn_t tegra_uart_isr(int irq, void *data) + { + struct tegra_uart_port *tup = data;