Commit e7997f7f authored by Erwan Le Ray's avatar Erwan Le Ray Committed by Greg Kroah-Hartman

serial: stm32: fix DMA initialization error handling

DMA initialization error handling is not properly implemented in the
driver.
Fix DMA initialization error handling by:
- moving TX DMA descriptor request error handling in a new dedicated
fallback_err label
- adding error handling to TX DMA descriptor submission
- adding error handling to RX DMA descriptor submission

This patch depends on '24832ca3 ("tty: serial: stm32-usart: Remove set
but unused 'cookie' variables")' which unfortunately doesn't include a
"Fixes" tag.

Fixes: 34891872 ("serial: stm32: adding dma support")
Signed-off-by: default avatarErwan Le Ray <erwan.leray@foss.st.com>
Link: https://lore.kernel.org/r/20210106162203.28854-2-erwan.leray@foss.st.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c762a2b8
...@@ -383,17 +383,18 @@ static void stm32_transmit_chars_dma(struct uart_port *port) ...@@ -383,17 +383,18 @@ static void stm32_transmit_chars_dma(struct uart_port *port)
DMA_MEM_TO_DEV, DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT); DMA_PREP_INTERRUPT);
if (!desc) { if (!desc)
for (i = count; i > 0; i--) goto fallback_err;
stm32_transmit_chars_pio(port);
return;
}
desc->callback = stm32_tx_dma_complete; desc->callback = stm32_tx_dma_complete;
desc->callback_param = port; desc->callback_param = port;
/* Push current DMA TX transaction in the pending queue */ /* Push current DMA TX transaction in the pending queue */
dmaengine_submit(desc); if (dma_submit_error(dmaengine_submit(desc))) {
/* dma no yet started, safe to free resources */
dmaengine_terminate_async(stm32port->tx_ch);
goto fallback_err;
}
/* Issue pending DMA TX requests */ /* Issue pending DMA TX requests */
dma_async_issue_pending(stm32port->tx_ch); dma_async_issue_pending(stm32port->tx_ch);
...@@ -402,6 +403,11 @@ static void stm32_transmit_chars_dma(struct uart_port *port) ...@@ -402,6 +403,11 @@ static void stm32_transmit_chars_dma(struct uart_port *port)
xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1); xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1);
port->icount.tx += count; port->icount.tx += count;
return;
fallback_err:
for (i = count; i > 0; i--)
stm32_transmit_chars_pio(port);
} }
static void stm32_transmit_chars(struct uart_port *port) static void stm32_transmit_chars(struct uart_port *port)
...@@ -1130,7 +1136,11 @@ static int stm32_of_dma_rx_probe(struct stm32_port *stm32port, ...@@ -1130,7 +1136,11 @@ static int stm32_of_dma_rx_probe(struct stm32_port *stm32port,
desc->callback_param = NULL; desc->callback_param = NULL;
/* Push current DMA transaction in the pending queue */ /* Push current DMA transaction in the pending queue */
dmaengine_submit(desc); ret = dma_submit_error(dmaengine_submit(desc));
if (ret) {
dmaengine_terminate_sync(stm32port->rx_ch);
goto config_err;
}
/* Issue pending DMA requests */ /* Issue pending DMA requests */
dma_async_issue_pending(stm32port->rx_ch); dma_async_issue_pending(stm32port->rx_ch);
......
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