> -----Original Message----- > From: Ilpo Järvinen <ilpo.jarvinen@xxxxxxxxxxxxxxx> > Sent: Tuesday, July 19, 2022 5:26 AM > To: Shenwei Wang <shenwei.wang@xxxxxxx> > Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>; linux-serial <linux- > serial@xxxxxxxxxxxxxxx>; stable@xxxxxxxxxxxxxxx > Subject: [EXT] Re: [PATCH V2 1/1] serial: fsl_lpuart: zero out parity bit in CS7 > mode > > Caution: EXT Email > > On Thu, 14 Jul 2022, Shenwei Wang wrote: > > > The LPUART hardware doesn't zero out the parity bit on the received > > characters. This behavior won't impact the use cases of CS8 because > > the parity bit is the 9th bit which is not currently used by software. > > But the parity bit for CS7 must be zeroed out by software in order to > > get the correct raw data. > > This problem only occurs with the lpuart32 variant? Or should the other > functions be changed as well? In theory this problem should occur with the non lpuart32 variant too, because LPUART32 was derived from the non lpuart32 IP module. However, I don't have a platform to confirm it. Thanks, Shenwei > > -- > i. > > > > Signed-off-by: Shenwei Wang <shenwei.wang@xxxxxxx> > > --- > > changes in v2 > > - remove the "inline" keyword from the function of > > lpuart_tty_insert_flip_string; > > > > changes in v1 > > - fix the code indent and whitespace issue; > > > > drivers/tty/serial/fsl_lpuart.c | 26 ++++++++++++++++++++++++-- > > 1 file changed, 24 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/tty/serial/fsl_lpuart.c > > b/drivers/tty/serial/fsl_lpuart.c index fc7d235a1e270..afa0f941c862f > > 100644 > > --- a/drivers/tty/serial/fsl_lpuart.c > > +++ b/drivers/tty/serial/fsl_lpuart.c > > @@ -274,6 +274,8 @@ struct lpuart_port { > > int rx_dma_rng_buf_len; > > unsigned int dma_tx_nents; > > wait_queue_head_t dma_wait; > > + bool is_cs7; /* Set to true when character size is 7 */ > > + /* and the parity is enabled */ > > }; > > > > struct lpuart_soc_data { > > @@ -1022,6 +1024,9 @@ static void lpuart32_rxint(struct lpuart_port *sport) > > flg = TTY_OVERRUN; > > } > > > > + if (sport->is_cs7) > > + rx &= 0x7F; > > + > > if (tty_insert_flip_char(port, rx, flg) == 0) > > sport->port.icount.buf_overrun++; > > } > > @@ -1107,6 +1112,17 @@ static void lpuart_handle_sysrq(struct lpuart_port > *sport) > > } > > } > > > > +static int lpuart_tty_insert_flip_string(struct tty_port *port, > > + unsigned char *chars, size_t size, bool is_cs7) { > > + int i; > > + > > + if (is_cs7) > > + for (i = 0; i < size; i++) > > + chars[i] &= 0x7F; > > + return tty_insert_flip_string(port, chars, size); } > > + > > static void lpuart_copy_rx_to_tty(struct lpuart_port *sport) { > > struct tty_port *port = &sport->port.state->port; @@ -1217,7 > > +1233,8 @@ static void lpuart_copy_rx_to_tty(struct lpuart_port *sport) > > if (ring->head < ring->tail) { > > count = sport->rx_sgl.length - ring->tail; > > > > - copied = tty_insert_flip_string(port, ring->buf + ring->tail, count); > > + copied = lpuart_tty_insert_flip_string(port, ring->buf + ring->tail, > > + count, sport->is_cs7); > > if (copied != count) > > sport->port.icount.buf_overrun++; > > ring->tail = 0; > > @@ -1227,7 +1244,8 @@ static void lpuart_copy_rx_to_tty(struct lpuart_port > *sport) > > /* Finally we read data from tail to head */ > > if (ring->tail < ring->head) { > > count = ring->head - ring->tail; > > - copied = tty_insert_flip_string(port, ring->buf + ring->tail, count); > > + copied = lpuart_tty_insert_flip_string(port, ring->buf + ring->tail, > > + count, sport->is_cs7); > > if (copied != count) > > sport->port.icount.buf_overrun++; > > /* Wrap ring->head if needed */ @@ -2066,6 +2084,7 @@ > > lpuart32_set_termios(struct uart_port *port, struct ktermios *termios, > > ctrl = old_ctrl = lpuart32_read(&sport->port, UARTCTRL); > > bd = lpuart32_read(&sport->port, UARTBAUD); > > modem = lpuart32_read(&sport->port, UARTMODIR); > > + sport->is_cs7 = false; > > /* > > * only support CS8 and CS7, and for CS7 must enable PE. > > * supported mode: > > @@ -2184,6 +2203,9 @@ lpuart32_set_termios(struct uart_port *port, struct > ktermios *termios, > > lpuart32_write(&sport->port, ctrl, UARTCTRL); > > /* restore control register */ > > > > + if ((ctrl & (UARTCTRL_PE | UARTCTRL_M)) == UARTCTRL_PE) > > + sport->is_cs7 = true; > > + > > if (old && sport->lpuart_dma_rx_use) { > > if (!lpuart_start_rx_dma(sport)) > > rx_dma_timer_init(sport); > > -- > > 2.25.1 > >