From ff8593d94b2b5023546ec18c4e01d825d5440f72 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 27 Oct 2022 09:37:59 +0200 Subject: [PATCH] drop stm32 patches from 5.15 Broke the build and was too big for stable --- ...ssert-transmit-enable-on-rs485_confi.patch | 172 -------- ...tor-out-gpio-rts-toggling-into-separ.patch | 122 ------ ...introduce-an-irq-flag-condition-in-u.patch | 88 ---- .../serial-stm32-rework-rx-over-dma.patch | 403 ------------------ ...-tc-interrupt-to-deassert-gpio-rts-i.patch | 136 ------ queue-5.15/series | 5 - 6 files changed, 926 deletions(-) delete mode 100644 queue-5.15/serial-stm32-deassert-transmit-enable-on-rs485_confi.patch delete mode 100644 queue-5.15/serial-stm32-factor-out-gpio-rts-toggling-into-separ.patch delete mode 100644 queue-5.15/serial-stm32-re-introduce-an-irq-flag-condition-in-u.patch delete mode 100644 queue-5.15/serial-stm32-rework-rx-over-dma.patch delete mode 100644 queue-5.15/serial-stm32-use-tc-interrupt-to-deassert-gpio-rts-i.patch diff --git a/queue-5.15/serial-stm32-deassert-transmit-enable-on-rs485_confi.patch b/queue-5.15/serial-stm32-deassert-transmit-enable-on-rs485_confi.patch deleted file mode 100644 index 9ee1860617e..00000000000 --- a/queue-5.15/serial-stm32-deassert-transmit-enable-on-rs485_confi.patch +++ /dev/null @@ -1,172 +0,0 @@ -From edf11620c93fc1a9a7b3dbbdb5eccb8e45608c79 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Sun, 11 Sep 2022 11:02:03 +0200 -Subject: serial: stm32: Deassert Transmit Enable on ->rs485_config() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -From: Lukas Wunner - -[ Upstream commit adafbbf6895eb0ce41a313c6ee68870ab9aa93cd ] - -The STM32 USART can control RS-485 Transmit Enable in hardware. Since -commit 7df5081cbf5e ("serial: stm32: Add RS485 RTS GPIO control"), -it can alternatively be controlled in software. That was done to allow -RS-485 even if the RTS pin is unavailable because it's pinmuxed to a -different function. - -However the commit neglected to deassert Transmit Enable upon invocation -of the ->rs485_config() callback. Fix it. - -Avoid forward declarations by moving stm32_usart_tx_empty(), -stm32_usart_rs485_rts_enable() and stm32_usart_rs485_rts_disable() -further up in the driver. - -Fixes: 7df5081cbf5e ("serial: stm32: Add RS485 RTS GPIO control") -Cc: stable@vger.kernel.org # v5.9+ -Cc: Marek Vasut -Reviewed-by: Ilpo Järvinen -Signed-off-by: Lukas Wunner -Link: https://lore.kernel.org/r/6059eab35dba394468335ef640df8b0050fd9dbd.1662886616.git.lukas@wunner.de -Signed-off-by: Greg Kroah-Hartman -Signed-off-by: Sasha Levin ---- - drivers/tty/serial/stm32-usart.c | 100 ++++++++++++++++--------------- - 1 file changed, 53 insertions(+), 47 deletions(-) - -diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c -index 4a4108ef23e8..c2daf8c151e6 100644 ---- a/drivers/tty/serial/stm32-usart.c -+++ b/drivers/tty/serial/stm32-usart.c -@@ -61,6 +61,53 @@ static void stm32_usart_clr_bits(struct uart_port *port, u32 reg, u32 bits) - writel_relaxed(val, port->membase + reg); - } - -+static unsigned int stm32_usart_tx_empty(struct uart_port *port) -+{ -+ struct stm32_port *stm32_port = to_stm32_port(port); -+ const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; -+ -+ if (readl_relaxed(port->membase + ofs->isr) & USART_SR_TC) -+ return TIOCSER_TEMT; -+ -+ return 0; -+} -+ -+static void stm32_usart_rs485_rts_enable(struct uart_port *port) -+{ -+ struct stm32_port *stm32_port = to_stm32_port(port); -+ struct serial_rs485 *rs485conf = &port->rs485; -+ -+ if (stm32_port->hw_flow_control || -+ !(rs485conf->flags & SER_RS485_ENABLED)) -+ return; -+ -+ if (rs485conf->flags & SER_RS485_RTS_ON_SEND) { -+ mctrl_gpio_set(stm32_port->gpios, -+ stm32_port->port.mctrl | TIOCM_RTS); -+ } else { -+ mctrl_gpio_set(stm32_port->gpios, -+ stm32_port->port.mctrl & ~TIOCM_RTS); -+ } -+} -+ -+static void stm32_usart_rs485_rts_disable(struct uart_port *port) -+{ -+ struct stm32_port *stm32_port = to_stm32_port(port); -+ struct serial_rs485 *rs485conf = &port->rs485; -+ -+ if (stm32_port->hw_flow_control || -+ !(rs485conf->flags & SER_RS485_ENABLED)) -+ return; -+ -+ if (rs485conf->flags & SER_RS485_RTS_ON_SEND) { -+ mctrl_gpio_set(stm32_port->gpios, -+ stm32_port->port.mctrl & ~TIOCM_RTS); -+ } else { -+ mctrl_gpio_set(stm32_port->gpios, -+ stm32_port->port.mctrl | TIOCM_RTS); -+ } -+} -+ - static void stm32_usart_config_reg_rs485(u32 *cr1, u32 *cr3, u32 delay_ADE, - u32 delay_DDE, u32 baud) - { -@@ -149,6 +196,12 @@ static int stm32_usart_config_rs485(struct uart_port *port, - - stm32_usart_set_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit)); - -+ /* Adjust RTS polarity in case it's driven in software */ -+ if (stm32_usart_tx_empty(port)) -+ stm32_usart_rs485_rts_disable(port); -+ else -+ stm32_usart_rs485_rts_enable(port); -+ - return 0; - } - -@@ -436,42 +489,6 @@ static void stm32_usart_tc_interrupt_disable(struct uart_port *port) - stm32_usart_clr_bits(port, ofs->cr1, USART_CR1_TCIE); - } - --static void stm32_usart_rs485_rts_enable(struct uart_port *port) --{ -- struct stm32_port *stm32_port = to_stm32_port(port); -- struct serial_rs485 *rs485conf = &port->rs485; -- -- if (stm32_port->hw_flow_control || -- !(rs485conf->flags & SER_RS485_ENABLED)) -- return; -- -- if (rs485conf->flags & SER_RS485_RTS_ON_SEND) { -- mctrl_gpio_set(stm32_port->gpios, -- stm32_port->port.mctrl | TIOCM_RTS); -- } else { -- mctrl_gpio_set(stm32_port->gpios, -- stm32_port->port.mctrl & ~TIOCM_RTS); -- } --} -- --static void stm32_usart_rs485_rts_disable(struct uart_port *port) --{ -- struct stm32_port *stm32_port = to_stm32_port(port); -- struct serial_rs485 *rs485conf = &port->rs485; -- -- if (stm32_port->hw_flow_control || -- !(rs485conf->flags & SER_RS485_ENABLED)) -- return; -- -- if (rs485conf->flags & SER_RS485_RTS_ON_SEND) { -- mctrl_gpio_set(stm32_port->gpios, -- stm32_port->port.mctrl & ~TIOCM_RTS); -- } else { -- mctrl_gpio_set(stm32_port->gpios, -- stm32_port->port.mctrl | TIOCM_RTS); -- } --} -- - static void stm32_usart_transmit_chars_pio(struct uart_port *port) - { - struct stm32_port *stm32_port = to_stm32_port(port); -@@ -689,17 +706,6 @@ static irqreturn_t stm32_usart_threaded_interrupt(int irq, void *ptr) - return IRQ_HANDLED; - } - --static unsigned int stm32_usart_tx_empty(struct uart_port *port) --{ -- struct stm32_port *stm32_port = to_stm32_port(port); -- const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; -- -- if (readl_relaxed(port->membase + ofs->isr) & USART_SR_TC) -- return TIOCSER_TEMT; -- -- return 0; --} -- - static void stm32_usart_set_mctrl(struct uart_port *port, unsigned int mctrl) - { - struct stm32_port *stm32_port = to_stm32_port(port); --- -2.35.1 - diff --git a/queue-5.15/serial-stm32-factor-out-gpio-rts-toggling-into-separ.patch b/queue-5.15/serial-stm32-factor-out-gpio-rts-toggling-into-separ.patch deleted file mode 100644 index 5cafd8cd5f3..00000000000 --- a/queue-5.15/serial-stm32-factor-out-gpio-rts-toggling-into-separ.patch +++ /dev/null @@ -1,122 +0,0 @@ -From dd8c5cbb18aa72a3448ed2c02910460c8e789c43 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Sat, 30 Apr 2022 18:28:44 +0200 -Subject: serial: stm32: Factor out GPIO RTS toggling into separate function - -From: Marek Vasut - -[ Upstream commit 3bcea529b295a993b1b05db63f245ae8030c5acf ] - -Pull out the GPIO RTS enable and disable handling into separate function. -Limit the scope of GPIO RTS toggling only to GPIO emulated RS485 too. - -Signed-off-by: Marek Vasut -Cc: Alexandre Torgue -Cc: Erwan Le Ray -Cc: Greg Kroah-Hartman -Cc: Jean Philippe Romain -Cc: Valentin Caron -Cc: linux-arm-kernel@lists.infradead.org -Cc: linux-stm32@st-md-mailman.stormreply.com -To: linux-serial@vger.kernel.org -Link: https://lore.kernel.org/r/20220430162845.244655-1-marex@denx.de -Signed-off-by: Greg Kroah-Hartman -Stable-dep-of: adafbbf6895e ("serial: stm32: Deassert Transmit Enable on ->rs485_config()") -Signed-off-by: Sasha Levin ---- - drivers/tty/serial/stm32-usart.c | 59 ++++++++++++++++++++------------ - 1 file changed, 38 insertions(+), 21 deletions(-) - -diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c -index b4c512b138df..0e7bcbaf7268 100644 ---- a/drivers/tty/serial/stm32-usart.c -+++ b/drivers/tty/serial/stm32-usart.c -@@ -420,6 +420,42 @@ static void stm32_usart_tx_interrupt_disable(struct uart_port *port) - stm32_usart_clr_bits(port, ofs->cr1, USART_CR1_TXEIE); - } - -+static void stm32_usart_rs485_rts_enable(struct uart_port *port) -+{ -+ struct stm32_port *stm32_port = to_stm32_port(port); -+ struct serial_rs485 *rs485conf = &port->rs485; -+ -+ if (stm32_port->hw_flow_control || -+ !(rs485conf->flags & SER_RS485_ENABLED)) -+ return; -+ -+ if (rs485conf->flags & SER_RS485_RTS_ON_SEND) { -+ mctrl_gpio_set(stm32_port->gpios, -+ stm32_port->port.mctrl | TIOCM_RTS); -+ } else { -+ mctrl_gpio_set(stm32_port->gpios, -+ stm32_port->port.mctrl & ~TIOCM_RTS); -+ } -+} -+ -+static void stm32_usart_rs485_rts_disable(struct uart_port *port) -+{ -+ struct stm32_port *stm32_port = to_stm32_port(port); -+ struct serial_rs485 *rs485conf = &port->rs485; -+ -+ if (stm32_port->hw_flow_control || -+ !(rs485conf->flags & SER_RS485_ENABLED)) -+ return; -+ -+ if (rs485conf->flags & SER_RS485_RTS_ON_SEND) { -+ mctrl_gpio_set(stm32_port->gpios, -+ stm32_port->port.mctrl & ~TIOCM_RTS); -+ } else { -+ mctrl_gpio_set(stm32_port->gpios, -+ stm32_port->port.mctrl | TIOCM_RTS); -+ } -+} -+ - static void stm32_usart_transmit_chars_pio(struct uart_port *port) - { - struct stm32_port *stm32_port = to_stm32_port(port); -@@ -666,40 +702,21 @@ static void stm32_usart_disable_ms(struct uart_port *port) - static void stm32_usart_stop_tx(struct uart_port *port) - { - struct stm32_port *stm32_port = to_stm32_port(port); -- struct serial_rs485 *rs485conf = &port->rs485; - - stm32_usart_tx_interrupt_disable(port); - -- if (rs485conf->flags & SER_RS485_ENABLED) { -- if (rs485conf->flags & SER_RS485_RTS_ON_SEND) { -- mctrl_gpio_set(stm32_port->gpios, -- stm32_port->port.mctrl & ~TIOCM_RTS); -- } else { -- mctrl_gpio_set(stm32_port->gpios, -- stm32_port->port.mctrl | TIOCM_RTS); -- } -- } -+ stm32_usart_rs485_rts_disable(port); - } - - /* There are probably characters waiting to be transmitted. */ - static void stm32_usart_start_tx(struct uart_port *port) - { -- struct stm32_port *stm32_port = to_stm32_port(port); -- struct serial_rs485 *rs485conf = &port->rs485; - struct circ_buf *xmit = &port->state->xmit; - - if (uart_circ_empty(xmit) && !port->x_char) - return; - -- if (rs485conf->flags & SER_RS485_ENABLED) { -- if (rs485conf->flags & SER_RS485_RTS_ON_SEND) { -- mctrl_gpio_set(stm32_port->gpios, -- stm32_port->port.mctrl | TIOCM_RTS); -- } else { -- mctrl_gpio_set(stm32_port->gpios, -- stm32_port->port.mctrl & ~TIOCM_RTS); -- } -- } -+ stm32_usart_rs485_rts_enable(port); - - stm32_usart_transmit_chars(port); - } --- -2.35.1 - diff --git a/queue-5.15/serial-stm32-re-introduce-an-irq-flag-condition-in-u.patch b/queue-5.15/serial-stm32-re-introduce-an-irq-flag-condition-in-u.patch deleted file mode 100644 index a822535ac20..00000000000 --- a/queue-5.15/serial-stm32-re-introduce-an-irq-flag-condition-in-u.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 8661fb04fedaa722480ba4fb0410ea9801db0c65 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Wed, 20 Oct 2021 17:03:30 +0200 -Subject: serial: stm32: re-introduce an irq flag condition in - usart_receive_chars - -From: Erwan Le Ray - -[ Upstream commit cc58d0a3f0a4755b9c808e065d9227c6e984e7db ] - -Re-introduce an irq flag condition in usart_receive_chars. -This condition has been deleted by commit 75f4e830fa9c ("serial: do not -restore interrupt state in sysrq helper"). -This code was present to handle threaded case, and has been removed -because it is no more needed in this case. Nevertheless an irq safe lock -is still needed in some cases, when DMA should be stopped to receive errors -or breaks in PIO mode. -This patch is a precursor to the complete rework or stm32 serial driver -DMA implementation. - -Signed-off-by: Erwan Le Ray -Link: https://lore.kernel.org/r/20211020150332.10214-2-erwan.leray@foss.st.com -Signed-off-by: Greg Kroah-Hartman -Stable-dep-of: adafbbf6895e ("serial: stm32: Deassert Transmit Enable on ->rs485_config()") -Signed-off-by: Sasha Levin ---- - drivers/tty/serial/stm32-usart.c | 21 +++++++++++++-------- - 1 file changed, 13 insertions(+), 8 deletions(-) - -diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c -index fc166cc2c856..bba4facf7425 100644 ---- a/drivers/tty/serial/stm32-usart.c -+++ b/drivers/tty/serial/stm32-usart.c -@@ -211,19 +211,22 @@ static unsigned long stm32_usart_get_char(struct uart_port *port, u32 *sr, - return c; - } - --static void stm32_usart_receive_chars(struct uart_port *port, bool threaded) -+static void stm32_usart_receive_chars(struct uart_port *port, bool irqflag) - { - struct tty_port *tport = &port->state->port; - struct stm32_port *stm32_port = to_stm32_port(port); - const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; -- unsigned long c; -+ unsigned long c, flags; - u32 sr; - char flag; - -- spin_lock(&port->lock); -+ if (irqflag) -+ spin_lock_irqsave(&port->lock, flags); -+ else -+ spin_lock(&port->lock); - - while (stm32_usart_pending_rx(port, &sr, &stm32_port->last_res, -- threaded)) { -+ irqflag)) { - sr |= USART_SR_DUMMY_RX; - flag = TTY_NORMAL; - -@@ -277,7 +280,10 @@ static void stm32_usart_receive_chars(struct uart_port *port, bool threaded) - uart_insert_char(port, sr, USART_SR_ORE, c, flag); - } - -- uart_unlock_and_check_sysrq(port); -+ if (irqflag) -+ uart_unlock_and_check_sysrq_irqrestore(port, irqflag); -+ else -+ uart_unlock_and_check_sysrq(port); - - tty_flip_buffer_push(tport); - } -@@ -510,10 +516,9 @@ static irqreturn_t stm32_usart_interrupt(int irq, void *ptr) - static irqreturn_t stm32_usart_threaded_interrupt(int irq, void *ptr) - { - struct uart_port *port = ptr; -- struct stm32_port *stm32_port = to_stm32_port(port); - -- if (stm32_port->rx_ch) -- stm32_usart_receive_chars(port, true); -+ /* Receiver timeout irq for DMA RX */ -+ stm32_usart_receive_chars(port, false); - - return IRQ_HANDLED; - } --- -2.35.1 - diff --git a/queue-5.15/serial-stm32-rework-rx-over-dma.patch b/queue-5.15/serial-stm32-rework-rx-over-dma.patch deleted file mode 100644 index ef3814848cf..00000000000 --- a/queue-5.15/serial-stm32-rework-rx-over-dma.patch +++ /dev/null @@ -1,403 +0,0 @@ -From bf8b05df5e2e3aec519732bb58eab724f82aeff1 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Wed, 20 Oct 2021 17:03:31 +0200 -Subject: serial: stm32: rework RX over DMA - -From: Erwan Le Ray - -[ Upstream commit 33bb2f6ac3088936b7aad3cab6f439f91af0223c ] - -This patch reworks RX support over DMA to improve reliability: -- change dma buffer cyclic configuration by using 2 periods. DMA buffer -data are handled by a flip-flop between the 2 periods in order to avoid -risk of data loss/corruption -- change the size of dma buffer to 4096 to limit overruns -- add rx errors management (breaks, parity, framing and overrun). - When an error occurs on the uart line, the dma request line is masked at - HW level. The SW must 1st clear DMAR (dma request line enable), to - handle the error, then re-enable DMAR to recover. So, any correct data - is taken from the DMA buffer, before handling the error itself. Then - errors are handled from RDR/ISR/FIFO (e.g. in PIO mode). Last, DMA - reception is resumed. -- add a condition on DMA request line in DMA RX routines in order to -switch to PIO mode when no DMA request line is disabled, even if the DMA -channel is still enabled. - When the UART is wakeup source and is configured to use DMA for RX, any - incoming data that wakes up the system isn't correctly received. - At data reception, the irq_handler handles the WUF irq, and then the - data reception over DMA. - As the DMA transfer has been terminated at suspend, and will be restored - by resume callback (which has no yet been called by system), the data - can't be received. - The wake-up data has to be handled in PIO mode while suspend callback - has not been called. - -Signed-off-by: Valentin Caron -Signed-off-by: Erwan Le Ray -Link: https://lore.kernel.org/r/20211020150332.10214-3-erwan.leray@foss.st.com -Signed-off-by: Greg Kroah-Hartman -Stable-dep-of: adafbbf6895e ("serial: stm32: Deassert Transmit Enable on ->rs485_config()") -Signed-off-by: Sasha Levin ---- - drivers/tty/serial/stm32-usart.c | 206 ++++++++++++++++++++++++------- - drivers/tty/serial/stm32-usart.h | 12 +- - 2 files changed, 165 insertions(+), 53 deletions(-) - -diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c -index bba4facf7425..b4c512b138df 100644 ---- a/drivers/tty/serial/stm32-usart.c -+++ b/drivers/tty/serial/stm32-usart.c -@@ -167,66 +167,60 @@ static int stm32_usart_init_rs485(struct uart_port *port, - return uart_get_rs485_mode(port); - } - --static int stm32_usart_pending_rx(struct uart_port *port, u32 *sr, -- int *last_res, bool threaded) -+static bool stm32_usart_rx_dma_enabled(struct uart_port *port) - { - struct stm32_port *stm32_port = to_stm32_port(port); - const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; -- enum dma_status status; -- struct dma_tx_state state; - -- *sr = readl_relaxed(port->membase + ofs->isr); -+ if (!stm32_port->rx_ch) -+ return false; - -- if (threaded && stm32_port->rx_ch) { -- status = dmaengine_tx_status(stm32_port->rx_ch, -- stm32_port->rx_ch->cookie, -- &state); -- if (status == DMA_IN_PROGRESS && (*last_res != state.residue)) -- return 1; -- else -- return 0; -- } else if (*sr & USART_SR_RXNE) { -- return 1; -+ return !!(readl_relaxed(port->membase + ofs->cr3) & USART_CR3_DMAR); -+} -+ -+/* Return true when data is pending (in pio mode), and false when no data is pending. */ -+static bool stm32_usart_pending_rx_pio(struct uart_port *port, u32 *sr) -+{ -+ struct stm32_port *stm32_port = to_stm32_port(port); -+ const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; -+ -+ *sr = readl_relaxed(port->membase + ofs->isr); -+ /* Get pending characters in RDR or FIFO */ -+ if (*sr & USART_SR_RXNE) { -+ /* Get all pending characters from the RDR or the FIFO when using interrupts */ -+ if (!stm32_usart_rx_dma_enabled(port)) -+ return true; -+ -+ /* Handle only RX data errors when using DMA */ -+ if (*sr & USART_SR_ERR_MASK) -+ return true; - } -- return 0; -+ -+ return false; - } - --static unsigned long stm32_usart_get_char(struct uart_port *port, u32 *sr, -- int *last_res) -+static unsigned long stm32_usart_get_char_pio(struct uart_port *port) - { - struct stm32_port *stm32_port = to_stm32_port(port); - const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; - unsigned long c; - -- if (stm32_port->rx_ch) { -- c = stm32_port->rx_buf[RX_BUF_L - (*last_res)--]; -- if ((*last_res) == 0) -- *last_res = RX_BUF_L; -- } else { -- c = readl_relaxed(port->membase + ofs->rdr); -- /* apply RDR data mask */ -- c &= stm32_port->rdr_mask; -- } -+ c = readl_relaxed(port->membase + ofs->rdr); -+ /* Apply RDR data mask */ -+ c &= stm32_port->rdr_mask; - - return c; - } - --static void stm32_usart_receive_chars(struct uart_port *port, bool irqflag) -+static void stm32_usart_receive_chars_pio(struct uart_port *port) - { -- struct tty_port *tport = &port->state->port; - struct stm32_port *stm32_port = to_stm32_port(port); - const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; -- unsigned long c, flags; -+ unsigned long c; - u32 sr; - char flag; - -- if (irqflag) -- spin_lock_irqsave(&port->lock, flags); -- else -- spin_lock(&port->lock); -- -- while (stm32_usart_pending_rx(port, &sr, &stm32_port->last_res, -- irqflag)) { -+ while (stm32_usart_pending_rx_pio(port, &sr)) { - sr |= USART_SR_DUMMY_RX; - flag = TTY_NORMAL; - -@@ -245,7 +239,7 @@ static void stm32_usart_receive_chars(struct uart_port *port, bool irqflag) - writel_relaxed(sr & USART_SR_ERR_MASK, - port->membase + ofs->icr); - -- c = stm32_usart_get_char(port, &sr, &stm32_port->last_res); -+ c = stm32_usart_get_char_pio(port); - port->icount.rx++; - if (sr & USART_SR_ERR_MASK) { - if (sr & USART_SR_ORE) { -@@ -279,6 +273,94 @@ static void stm32_usart_receive_chars(struct uart_port *port, bool irqflag) - continue; - uart_insert_char(port, sr, USART_SR_ORE, c, flag); - } -+} -+ -+static void stm32_usart_push_buffer_dma(struct uart_port *port, unsigned int dma_size) -+{ -+ struct stm32_port *stm32_port = to_stm32_port(port); -+ struct tty_port *ttyport = &stm32_port->port.state->port; -+ unsigned char *dma_start; -+ int dma_count, i; -+ -+ dma_start = stm32_port->rx_buf + (RX_BUF_L - stm32_port->last_res); -+ -+ /* -+ * Apply rdr_mask on buffer in order to mask parity bit. -+ * This loop is useless in cs8 mode because DMA copies only -+ * 8 bits and already ignores parity bit. -+ */ -+ if (!(stm32_port->rdr_mask == (BIT(8) - 1))) -+ for (i = 0; i < dma_size; i++) -+ *(dma_start + i) &= stm32_port->rdr_mask; -+ -+ dma_count = tty_insert_flip_string(ttyport, dma_start, dma_size); -+ port->icount.rx += dma_count; -+ if (dma_count != dma_size) -+ port->icount.buf_overrun++; -+ stm32_port->last_res -= dma_count; -+ if (stm32_port->last_res == 0) -+ stm32_port->last_res = RX_BUF_L; -+} -+ -+static void stm32_usart_receive_chars_dma(struct uart_port *port) -+{ -+ struct stm32_port *stm32_port = to_stm32_port(port); -+ unsigned int dma_size; -+ -+ /* DMA buffer is configured in cyclic mode and handles the rollback of the buffer. */ -+ if (stm32_port->rx_dma_state.residue > stm32_port->last_res) { -+ /* Conditional first part: from last_res to end of DMA buffer */ -+ dma_size = stm32_port->last_res; -+ stm32_usart_push_buffer_dma(port, dma_size); -+ } -+ -+ dma_size = stm32_port->last_res - stm32_port->rx_dma_state.residue; -+ stm32_usart_push_buffer_dma(port, dma_size); -+} -+ -+static void stm32_usart_receive_chars(struct uart_port *port, bool irqflag) -+{ -+ struct tty_port *tport = &port->state->port; -+ struct stm32_port *stm32_port = to_stm32_port(port); -+ const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; -+ enum dma_status rx_dma_status; -+ unsigned long flags; -+ u32 sr; -+ -+ if (irqflag) -+ spin_lock_irqsave(&port->lock, flags); -+ else -+ spin_lock(&port->lock); -+ -+ if (stm32_usart_rx_dma_enabled(port)) { -+ rx_dma_status = dmaengine_tx_status(stm32_port->rx_ch, -+ stm32_port->rx_ch->cookie, -+ &stm32_port->rx_dma_state); -+ if (rx_dma_status == DMA_IN_PROGRESS) { -+ /* Empty DMA buffer */ -+ stm32_usart_receive_chars_dma(port); -+ sr = readl_relaxed(port->membase + ofs->isr); -+ if (sr & USART_SR_ERR_MASK) { -+ /* Disable DMA request line */ -+ stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAR); -+ -+ /* Switch to PIO mode to handle the errors */ -+ stm32_usart_receive_chars_pio(port); -+ -+ /* Switch back to DMA mode */ -+ stm32_usart_set_bits(port, ofs->cr3, USART_CR3_DMAR); -+ } -+ } else { -+ /* Disable RX DMA */ -+ dmaengine_terminate_async(stm32_port->rx_ch); -+ stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAR); -+ /* Fall back to interrupt mode */ -+ dev_dbg(port->dev, "DMA error, fallback to irq mode\n"); -+ stm32_usart_receive_chars_pio(port); -+ } -+ } else { -+ stm32_usart_receive_chars_pio(port); -+ } - - if (irqflag) - uart_unlock_and_check_sysrq_irqrestore(port, irqflag); -@@ -320,6 +402,13 @@ static void stm32_usart_tx_interrupt_enable(struct uart_port *port) - stm32_usart_set_bits(port, ofs->cr1, USART_CR1_TXEIE); - } - -+static void stm32_usart_rx_dma_complete(void *arg) -+{ -+ struct uart_port *port = arg; -+ -+ stm32_usart_receive_chars(port, true); -+} -+ - static void stm32_usart_tx_interrupt_disable(struct uart_port *port) - { - struct stm32_port *stm32_port = to_stm32_port(port); -@@ -498,7 +587,12 @@ static irqreturn_t stm32_usart_interrupt(int irq, void *ptr) - pm_wakeup_event(tport->tty->dev, 0); - } - -- if ((sr & USART_SR_RXNE) && !(stm32_port->rx_ch)) -+ /* -+ * rx errors in dma mode has to be handled ASAP to avoid overrun as the DMA request -+ * line has been masked by HW and rx data are stacking in FIFO. -+ */ -+ if (((sr & USART_SR_RXNE) && !stm32_usart_rx_dma_enabled(port)) || -+ ((sr & USART_SR_ERR_MASK) && stm32_usart_rx_dma_enabled(port))) - stm32_usart_receive_chars(port, false); - - if ((sr & USART_SR_TXE) && !(stm32_port->tx_ch)) { -@@ -507,7 +601,7 @@ static irqreturn_t stm32_usart_interrupt(int irq, void *ptr) - spin_unlock(&port->lock); - } - -- if (stm32_port->rx_ch) -+ if (stm32_usart_rx_dma_enabled(port)) - return IRQ_WAKE_THREAD; - else - return IRQ_HANDLED; -@@ -843,9 +937,11 @@ static void stm32_usart_set_termios(struct uart_port *port, - stm32_port->cr1_irq = USART_CR1_RTOIE; - writel_relaxed(bits, port->membase + ofs->rtor); - cr2 |= USART_CR2_RTOEN; -- /* Not using dma, enable fifo threshold irq */ -- if (!stm32_port->rx_ch) -- stm32_port->cr3_irq = USART_CR3_RXFTIE; -+ /* -+ * Enable fifo threshold irq in two cases, either when there is no DMA, or when -+ * wake up over usart, from low power until the DMA gets re-enabled by resume. -+ */ -+ stm32_port->cr3_irq = USART_CR3_RXFTIE; - } - - cr1 |= stm32_port->cr1_irq; -@@ -908,8 +1004,16 @@ static void stm32_usart_set_termios(struct uart_port *port, - if ((termios->c_cflag & CREAD) == 0) - port->ignore_status_mask |= USART_SR_DUMMY_RX; - -- if (stm32_port->rx_ch) -+ if (stm32_port->rx_ch) { -+ /* -+ * Setup DMA to collect only valid data and enable error irqs. -+ * This also enables break reception when using DMA. -+ */ -+ cr1 |= USART_CR1_PEIE; -+ cr3 |= USART_CR3_EIE; - cr3 |= USART_CR3_DMAR; -+ cr3 |= USART_CR3_DDRE; -+ } - - if (rs485conf->flags & SER_RS485_ENABLED) { - stm32_usart_config_reg_rs485(&cr1, &cr3, -@@ -1238,9 +1342,9 @@ static int stm32_usart_of_dma_rx_probe(struct stm32_port *stm32port, - return -ENODEV; - } - -- /* No callback as dma buffer is drained on usart interrupt */ -- desc->callback = NULL; -- desc->callback_param = NULL; -+ /* Set DMA callback */ -+ desc->callback = stm32_usart_rx_dma_complete; -+ desc->callback_param = port; - - /* Push current DMA transaction in the pending queue */ - ret = dma_submit_error(dmaengine_submit(desc)); -@@ -1405,6 +1509,7 @@ static int stm32_usart_serial_remove(struct platform_device *pdev) - struct stm32_port *stm32_port = to_stm32_port(port); - const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; - int err; -+ u32 cr3; - - pm_runtime_get_sync(&pdev->dev); - err = uart_remove_one_port(&stm32_usart_driver, port); -@@ -1415,7 +1520,12 @@ static int stm32_usart_serial_remove(struct platform_device *pdev) - pm_runtime_set_suspended(&pdev->dev); - pm_runtime_put_noidle(&pdev->dev); - -- stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAR); -+ stm32_usart_clr_bits(port, ofs->cr1, USART_CR1_PEIE); -+ cr3 = readl_relaxed(port->membase + ofs->cr3); -+ cr3 &= ~USART_CR3_EIE; -+ cr3 &= ~USART_CR3_DMAR; -+ cr3 &= ~USART_CR3_DDRE; -+ writel_relaxed(cr3, port->membase + ofs->cr3); - - if (stm32_port->tx_ch) { - stm32_usart_of_dma_tx_remove(stm32_port, pdev); -diff --git a/drivers/tty/serial/stm32-usart.h b/drivers/tty/serial/stm32-usart.h -index 07ac291328cd..53bcd032fce7 100644 ---- a/drivers/tty/serial/stm32-usart.h -+++ b/drivers/tty/serial/stm32-usart.h -@@ -109,7 +109,7 @@ struct stm32_usart_info stm32h7_info = { - /* USART_SR (F4) / USART_ISR (F7) */ - #define USART_SR_PE BIT(0) - #define USART_SR_FE BIT(1) --#define USART_SR_NF BIT(2) -+#define USART_SR_NE BIT(2) /* F7 (NF for F4) */ - #define USART_SR_ORE BIT(3) - #define USART_SR_IDLE BIT(4) - #define USART_SR_RXNE BIT(5) -@@ -126,7 +126,8 @@ struct stm32_usart_info stm32h7_info = { - #define USART_SR_SBKF BIT(18) /* F7 */ - #define USART_SR_WUF BIT(20) /* H7 */ - #define USART_SR_TEACK BIT(21) /* F7 */ --#define USART_SR_ERR_MASK (USART_SR_ORE | USART_SR_FE | USART_SR_PE) -+#define USART_SR_ERR_MASK (USART_SR_ORE | USART_SR_NE | USART_SR_FE |\ -+ USART_SR_PE) - /* Dummy bits */ - #define USART_SR_DUMMY_RX BIT(16) - -@@ -246,9 +247,9 @@ struct stm32_usart_info stm32h7_info = { - #define STM32_SERIAL_NAME "ttySTM" - #define STM32_MAX_PORTS 8 - --#define RX_BUF_L 200 /* dma rx buffer length */ --#define RX_BUF_P RX_BUF_L /* dma rx buffer period */ --#define TX_BUF_L 200 /* dma tx buffer length */ -+#define RX_BUF_L 4096 /* dma rx buffer length */ -+#define RX_BUF_P (RX_BUF_L / 2) /* dma rx buffer period */ -+#define TX_BUF_L RX_BUF_L /* dma tx buffer length */ - - struct stm32_port { - struct uart_port port; -@@ -272,6 +273,7 @@ struct stm32_port { - bool wakeup_src; - int rdr_mask; /* receive data register mask */ - struct mctrl_gpios *gpios; /* modem control gpios */ -+ struct dma_tx_state rx_dma_state; - }; - - static struct stm32_port stm32_ports[STM32_MAX_PORTS]; --- -2.35.1 - diff --git a/queue-5.15/serial-stm32-use-tc-interrupt-to-deassert-gpio-rts-i.patch b/queue-5.15/serial-stm32-use-tc-interrupt-to-deassert-gpio-rts-i.patch deleted file mode 100644 index c97ef4a7dff..00000000000 --- a/queue-5.15/serial-stm32-use-tc-interrupt-to-deassert-gpio-rts-i.patch +++ /dev/null @@ -1,136 +0,0 @@ -From 6fa778f8c0f1bc1bad754c6fca14cb758de84258 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Sat, 30 Apr 2022 18:28:45 +0200 -Subject: serial: stm32: Use TC interrupt to deassert GPIO RTS in RS485 mode - -From: Marek Vasut - -[ Upstream commit d7c76716169ddc37cf6316ff381d34ea807fbfd7 ] - -In case the RS485 mode is emulated using GPIO RTS, use the TC interrupt -to deassert the GPIO RTS, otherwise the GPIO RTS stays asserted after a -transmission ended and the RS485 cannot work. - -Signed-off-by: Marek Vasut -Cc: Alexandre Torgue -Cc: Erwan Le Ray -Cc: Greg Kroah-Hartman -Cc: Jean Philippe Romain -Cc: Valentin Caron -Cc: linux-arm-kernel@lists.infradead.org -Cc: linux-stm32@st-md-mailman.stormreply.com -To: linux-serial@vger.kernel.org -Link: https://lore.kernel.org/r/20220430162845.244655-2-marex@denx.de -Signed-off-by: Greg Kroah-Hartman -Stable-dep-of: adafbbf6895e ("serial: stm32: Deassert Transmit Enable on ->rs485_config()") -Signed-off-by: Sasha Levin ---- - drivers/tty/serial/stm32-usart.c | 42 ++++++++++++++++++++++++++++++-- - drivers/tty/serial/stm32-usart.h | 1 + - 2 files changed, 41 insertions(+), 2 deletions(-) - -diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c -index 0e7bcbaf7268..4a4108ef23e8 100644 ---- a/drivers/tty/serial/stm32-usart.c -+++ b/drivers/tty/serial/stm32-usart.c -@@ -402,6 +402,14 @@ static void stm32_usart_tx_interrupt_enable(struct uart_port *port) - stm32_usart_set_bits(port, ofs->cr1, USART_CR1_TXEIE); - } - -+static void stm32_usart_tc_interrupt_enable(struct uart_port *port) -+{ -+ struct stm32_port *stm32_port = to_stm32_port(port); -+ const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; -+ -+ stm32_usart_set_bits(port, ofs->cr1, USART_CR1_TCIE); -+} -+ - static void stm32_usart_rx_dma_complete(void *arg) - { - struct uart_port *port = arg; -@@ -420,6 +428,14 @@ static void stm32_usart_tx_interrupt_disable(struct uart_port *port) - stm32_usart_clr_bits(port, ofs->cr1, USART_CR1_TXEIE); - } - -+static void stm32_usart_tc_interrupt_disable(struct uart_port *port) -+{ -+ struct stm32_port *stm32_port = to_stm32_port(port); -+ const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; -+ -+ stm32_usart_clr_bits(port, ofs->cr1, USART_CR1_TCIE); -+} -+ - static void stm32_usart_rs485_rts_enable(struct uart_port *port) - { - struct stm32_port *stm32_port = to_stm32_port(port); -@@ -557,6 +573,13 @@ static void stm32_usart_transmit_chars(struct uart_port *port) - u32 isr; - int ret; - -+ if (!stm32_port->hw_flow_control && -+ port->rs485.flags & SER_RS485_ENABLED) { -+ stm32_port->txdone = false; -+ stm32_usart_tc_interrupt_disable(port); -+ stm32_usart_rs485_rts_enable(port); -+ } -+ - if (port->x_char) { - if (stm32_port->tx_dma_busy) - stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT); -@@ -596,8 +619,14 @@ static void stm32_usart_transmit_chars(struct uart_port *port) - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); - -- if (uart_circ_empty(xmit)) -+ if (uart_circ_empty(xmit)) { - stm32_usart_tx_interrupt_disable(port); -+ if (!stm32_port->hw_flow_control && -+ port->rs485.flags & SER_RS485_ENABLED) { -+ stm32_port->txdone = true; -+ stm32_usart_tc_interrupt_enable(port); -+ } -+ } - } - - static irqreturn_t stm32_usart_interrupt(int irq, void *ptr) -@@ -610,6 +639,13 @@ static irqreturn_t stm32_usart_interrupt(int irq, void *ptr) - - sr = readl_relaxed(port->membase + ofs->isr); - -+ if (!stm32_port->hw_flow_control && -+ port->rs485.flags & SER_RS485_ENABLED && -+ (sr & USART_SR_TC)) { -+ stm32_usart_tc_interrupt_disable(port); -+ stm32_usart_rs485_rts_disable(port); -+ } -+ - if ((sr & USART_SR_RTOF) && ofs->icr != UNDEF_REG) - writel_relaxed(USART_ICR_RTOCF, - port->membase + ofs->icr); -@@ -713,8 +749,10 @@ static void stm32_usart_start_tx(struct uart_port *port) - { - struct circ_buf *xmit = &port->state->xmit; - -- if (uart_circ_empty(xmit) && !port->x_char) -+ if (uart_circ_empty(xmit) && !port->x_char) { -+ stm32_usart_rs485_rts_disable(port); - return; -+ } - - stm32_usart_rs485_rts_enable(port); - -diff --git a/drivers/tty/serial/stm32-usart.h b/drivers/tty/serial/stm32-usart.h -index 53bcd032fce7..852573e1a690 100644 ---- a/drivers/tty/serial/stm32-usart.h -+++ b/drivers/tty/serial/stm32-usart.h -@@ -268,6 +268,7 @@ struct stm32_port { - bool hw_flow_control; - bool swap; /* swap RX & TX pins */ - bool fifoen; -+ bool txdone; - int rxftcfg; /* RX FIFO threshold CFG */ - int txftcfg; /* TX FIFO threshold CFG */ - bool wakeup_src; --- -2.35.1 - diff --git a/queue-5.15/series b/queue-5.15/series index 8c5d62f8cad..d3636d0e310 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -72,11 +72,6 @@ fs-dlm-fix-invalid-derefence-of-sb_lvbptr.patch scsi-lpfc-adjust-bytes-received-vales-during-cmf-tim.patch scsi-lpfc-adjust-cmf-total-bytes-and-rxmonitor.patch scsi-lpfc-rework-mib-rx-monitor-debug-info-logic.patch -serial-stm32-re-introduce-an-irq-flag-condition-in-u.patch -serial-stm32-rework-rx-over-dma.patch -serial-stm32-factor-out-gpio-rts-toggling-into-separ.patch -serial-stm32-use-tc-interrupt-to-deassert-gpio-rts-i.patch -serial-stm32-deassert-transmit-enable-on-rs485_confi.patch arm64-mte-move-register-initialization-to-c.patch btrfs-rename-root-fields-in-delayed-refs-structs.patch btrfs-pull-up-qgroup-checks-from-delayed-ref-core-to.patch -- 2.47.3