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 '24832ca3ee85 ("tty: serial: stm32-usart: Remove set
but unused 'cookie' variables")' which unfortunately doesn't include a
"Fixes" tag.

Fixes: 3489187204 ("serial: stm32: adding dma support")
Signed-off-by: Erwan Le Ray <erwan.leray@foss.st.com>
Link: https://lore.kernel.org/r/20210106162203.28854-2-erwan.leray@foss.st.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Erwan Le Ray 2021-01-06 17:21:56 +01:00 committed by Greg Kroah-Hartman
parent c762a2b846
commit e7997f7ff7
1 changed files with 17 additions and 7 deletions

View File

@ -383,17 +383,18 @@ static void stm32_transmit_chars_dma(struct uart_port *port)
DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT);
if (!desc) {
for (i = count; i > 0; i--)
stm32_transmit_chars_pio(port);
return;
}
if (!desc)
goto fallback_err;
desc->callback = stm32_tx_dma_complete;
desc->callback_param = port;
/* 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 */
dma_async_issue_pending(stm32port->tx_ch);
@ -402,6 +403,11 @@ static void stm32_transmit_chars_dma(struct uart_port *port)
xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1);
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)
@ -1130,7 +1136,11 @@ static int stm32_of_dma_rx_probe(struct stm32_port *stm32port,
desc->callback_param = NULL;
/* 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 */
dma_async_issue_pending(stm32port->rx_ch);