RE: [EXT] Re: [PATCH V2 1/1] serial: fsl_lpuart: zero out parity bit in CS7 mode

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




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




[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux