Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

serial: stm32: update throttle and unthrottle ops for dma mode

Disable DMA request line (if enabled) to switch in PIO mode in throttle
ops, so the RX data gets queues into the FIFO. The hardware flow control
is triggered when the RX FIFO is full.

Switch back to DMA mode (re-enable DMA request line) in unthrottle ops.
Hardware flow control is stopped when FIFO is not full anymore.

Signed-off-by: Valentin Caron <valentin.caron@foss.st.com>
Signed-off-by: Erwan Le Ray <erwan.leray@foss.st.com>
Link: https://lore.kernel.org/r/20211020150332.10214-4-erwan.leray@foss.st.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Erwan Le Ray and committed by
Greg Kroah-Hartman
d1ec8a2e 33bb2f6a

+34 -4
+33 -4
drivers/tty/serial/stm32-usart.c
··· 577 577 * rx errors in dma mode has to be handled ASAP to avoid overrun as the DMA request 578 578 * line has been masked by HW and rx data are stacking in FIFO. 579 579 */ 580 - if (((sr & USART_SR_RXNE) && !stm32_usart_rx_dma_enabled(port)) || 581 - ((sr & USART_SR_ERR_MASK) && stm32_usart_rx_dma_enabled(port))) 582 - stm32_usart_receive_chars(port, false); 580 + if (!stm32_port->throttled) { 581 + if (((sr & USART_SR_RXNE) && !stm32_usart_rx_dma_enabled(port)) || 582 + ((sr & USART_SR_ERR_MASK) && stm32_usart_rx_dma_enabled(port))) { 583 + stm32_usart_receive_chars(port, false); 584 + } 585 + } 583 586 584 587 if ((sr & USART_SR_TXE) && !(stm32_port->tx_ch)) { 585 588 spin_lock(&port->lock); ··· 599 596 static irqreturn_t stm32_usart_threaded_interrupt(int irq, void *ptr) 600 597 { 601 598 struct uart_port *port = ptr; 599 + struct stm32_port *stm32_port = to_stm32_port(port); 602 600 603 601 /* Receiver timeout irq for DMA RX */ 604 - stm32_usart_receive_chars(port, false); 602 + if (!stm32_port->throttled) 603 + stm32_usart_receive_chars(port, false); 605 604 606 605 return IRQ_HANDLED; 607 606 } ··· 716 711 unsigned long flags; 717 712 718 713 spin_lock_irqsave(&port->lock, flags); 714 + 715 + /* 716 + * Disable DMA request line if enabled, so the RX data gets queued into the FIFO. 717 + * Hardware flow control is triggered when RX FIFO is full. 718 + */ 719 + if (stm32_usart_rx_dma_enabled(port)) 720 + stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAR); 721 + 719 722 stm32_usart_clr_bits(port, ofs->cr1, stm32_port->cr1_irq); 720 723 if (stm32_port->cr3_irq) 721 724 stm32_usart_clr_bits(port, ofs->cr3, stm32_port->cr3_irq); 722 725 726 + stm32_port->throttled = true; 723 727 spin_unlock_irqrestore(&port->lock, flags); 724 728 } 725 729 ··· 744 730 if (stm32_port->cr3_irq) 745 731 stm32_usart_set_bits(port, ofs->cr3, stm32_port->cr3_irq); 746 732 733 + /* 734 + * Switch back to DMA mode (re-enable DMA request line). 735 + * Hardware flow control is stopped when FIFO is not full any more. 736 + */ 737 + if (stm32_port->rx_ch) 738 + stm32_usart_set_bits(port, ofs->cr3, USART_CR3_DMAR); 739 + 740 + stm32_port->throttled = false; 747 741 spin_unlock_irqrestore(&port->lock, flags); 748 742 } 749 743 ··· 796 774 /* RX FIFO Flush */ 797 775 if (ofs->rqr != UNDEF_REG) 798 776 writel_relaxed(USART_RQR_RXFRQ, port->membase + ofs->rqr); 777 + 778 + /* 779 + * DMA request line not re-enabled at resume when port is throttled. 780 + * It will be re-enabled by unthrottle ops. 781 + */ 782 + if (!stm32_port->throttled) 783 + stm32_usart_set_bits(port, ofs->cr3, USART_CR3_DMAR); 799 784 800 785 /* RX enabling */ 801 786 val = stm32_port->cr1_irq | USART_CR1_RE | BIT(cfg->uart_enable_bit);
+1
drivers/tty/serial/stm32-usart.h
··· 265 265 u32 cr3_irq; /* USART_CR3_RXFTIE */ 266 266 int last_res; 267 267 bool tx_dma_busy; /* dma tx busy */ 268 + bool throttled; /* port throttled */ 268 269 bool hw_flow_control; 269 270 bool swap; /* swap RX & TX pins */ 270 271 bool fifoen;