]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 16 Jan 2023 15:17:58 +0000 (16:17 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 16 Jan 2023 15:17:58 +0000 (16:17 +0100)
added patches:
tty-serial-tegra-handle-rx-transfer-in-pio-mode-if-dma-wasn-t-started.patch

queue-4.19/series
queue-4.19/tty-serial-tegra-handle-rx-transfer-in-pio-mode-if-dma-wasn-t-started.patch [new file with mode: 0644]

index 03aea80fc9f3920b7f54c90a355456e9fcfd3c44..3050a3526ce135a0bc711aa90b277fe465e761ae 100644 (file)
@@ -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 (file)
index 0000000..eea2f9c
--- /dev/null
@@ -0,0 +1,94 @@
+From 1f69a1273b3f204a9c00dc3bbdcc4afcd0787428 Mon Sep 17 00:00:00 2001
+From: Dmitry Osipenko <digetx@gmail.com>
+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 <digetx@gmail.com>
+
+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 <digetx@gmail.com>
+Link: https://lore.kernel.org/r/20200209164415.9632-1-digetx@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;