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]

 



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?

-- 
 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]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux