serial: stm32: fix DMA initialization error handling

[ Upstream commit e7997f7ff7 ]

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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Erwan Le Ray 2021-01-06 17:21:56 +01:00 committed by Greg Kroah-Hartman
parent 5f8659adf7
commit 0e44f1e183

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);