Skip to content

Commit d92aca3

Browse files
jonhuntergregkh
authored andcommitted
serial: tegra: Correct shutdown of UARTs
There are two issues in the shutdown path of the UARTs which are: 1. The function tegra_uart_shutdown() calls tegra_uart_flush_buffer() to stop DMA TX transfers. However, tegra_uart_flush_buffer() is called after the DMA channels have already been freed and so actually does nothing. 2. The function that frees the DMA channels (tegra_uart_dma_channel_free()), unmaps the dma buffer before freeing the DMA channel and does not ensure the DMA has been stopped. Resolve this by fixing the code in tegra_uart_dma_channel_free() to ensure the DMA is stopped, free the DMA channel and then unmap the DMA buffer. Finally, remove the unnecessary call to tegra_uart_flush_buffer(). Signed-off-by: Jon Hunter <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 49433c8 commit d92aca3

File tree

1 file changed

+4
-7
lines changed

1 file changed

+4
-7
lines changed

drivers/tty/serial/serial-tegra.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,24 +1020,23 @@ static int tegra_uart_dma_channel_allocate(struct tegra_uart_port *tup,
10201020
static void tegra_uart_dma_channel_free(struct tegra_uart_port *tup,
10211021
bool dma_to_memory)
10221022
{
1023-
struct dma_chan *dma_chan;
1024-
10251023
if (dma_to_memory) {
1024+
dmaengine_terminate_all(tup->rx_dma_chan);
1025+
dma_release_channel(tup->rx_dma_chan);
10261026
dma_free_coherent(tup->uport.dev, TEGRA_UART_RX_DMA_BUFFER_SIZE,
10271027
tup->rx_dma_buf_virt, tup->rx_dma_buf_phys);
1028-
dma_chan = tup->rx_dma_chan;
10291028
tup->rx_dma_chan = NULL;
10301029
tup->rx_dma_buf_phys = 0;
10311030
tup->rx_dma_buf_virt = NULL;
10321031
} else {
1032+
dmaengine_terminate_all(tup->tx_dma_chan);
1033+
dma_release_channel(tup->tx_dma_chan);
10331034
dma_unmap_single(tup->uport.dev, tup->tx_dma_buf_phys,
10341035
UART_XMIT_SIZE, DMA_TO_DEVICE);
1035-
dma_chan = tup->tx_dma_chan;
10361036
tup->tx_dma_chan = NULL;
10371037
tup->tx_dma_buf_phys = 0;
10381038
tup->tx_dma_buf_virt = NULL;
10391039
}
1040-
dma_release_channel(dma_chan);
10411040
}
10421041

10431042
static int tegra_uart_startup(struct uart_port *u)
@@ -1104,8 +1103,6 @@ static void tegra_uart_shutdown(struct uart_port *u)
11041103
tegra_uart_dma_channel_free(tup, true);
11051104
tegra_uart_dma_channel_free(tup, false);
11061105
free_irq(u->irq, tup);
1107-
1108-
tegra_uart_flush_buffer(u);
11091106
}
11101107

11111108
static void tegra_uart_enable_ms(struct uart_port *u)

0 commit comments

Comments
 (0)