]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
serial: stm32: fix clearing interrupt error flags
authorFabrice Gasnier <fabrice.gasnier@st.com>
Thu, 21 Nov 2019 08:10:49 +0000 (09:10 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 27 Jan 2020 13:51:22 +0000 (14:51 +0100)
[ Upstream commit 1250ed7114a977cdc2a67a0c09d6cdda63970eb9 ]

The interrupt clear flag register is a "write 1 to clear" register.
So, only writing ones allows to clear flags:
- Replace buggy stm32_clr_bits() by a simple write to clear error flags
- Replace useless read/modify/write stm32_set_bits() routine by a
  simple write to clear TC (transfer complete) flag.

Fixes: 4f01d833fdcd ("serial: stm32: fix rx error handling")
Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
Cc: stable <stable@vger.kernel.org>
Link: https://lore.kernel.org/r/1574323849-1909-1-git-send-email-fabrice.gasnier@st.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/tty/serial/stm32-usart.c

index d096e552176cc38c4fbc16ca14d55e36e77d04e1..bce4ac1787add94c6e0ff7c1605f04c6f0ec9b8f 100644 (file)
@@ -239,8 +239,8 @@ static void stm32_receive_chars(struct uart_port *port, bool threaded)
                 * cleared by the sequence [read SR - read DR].
                 */
                if ((sr & USART_SR_ERR_MASK) && ofs->icr != UNDEF_REG)
-                       stm32_clr_bits(port, ofs->icr, USART_ICR_ORECF |
-                                      USART_ICR_PECF | USART_ICR_FECF);
+                       writel_relaxed(sr & USART_SR_ERR_MASK,
+                                      port->membase + ofs->icr);
 
                c = stm32_get_char(port, &sr, &stm32_port->last_res);
                port->icount.rx++;
@@ -409,7 +409,7 @@ static void stm32_transmit_chars(struct uart_port *port)
        if (ofs->icr == UNDEF_REG)
                stm32_clr_bits(port, ofs->isr, USART_SR_TC);
        else
-               stm32_set_bits(port, ofs->icr, USART_ICR_TCCF);
+               writel_relaxed(USART_ICR_TCCF, port->membase + ofs->icr);
 
        if (stm32_port->tx_ch)
                stm32_transmit_chars_dma(port);