Re: [PATCH RESEND] serial: sccnxp: Add barrier between two sequential read/write cycles

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

 



Hi Alexander,

On 06/07/2016 08:59 AM, Alexander Shiyan wrote:
> The patch adds a barrier between two sequential read/write cycles
> to provide the required minimum High-CS time.

Which is how long? 100ns?
The commit log should include this information.


> Signed-off-by: Alexander Shiyan <shc_work@xxxxxxx>
> ---
>  drivers/tty/serial/sccnxp.c | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 
> diff --git a/drivers/tty/serial/sccnxp.c b/drivers/tty/serial/sccnxp.c
> index fcf803f..b3c060d 100644
> --- a/drivers/tty/serial/sccnxp.c
> +++ b/drivers/tty/serial/sccnxp.c
> @@ -281,6 +281,12 @@ static const struct {
>  	{ 0, 0, 0, 0 }
>  };

I'm wondering if this delay should be implemented in the
i/o accessors instead. Otherwise, the delay may be skipped; eg.,
sccnxp_start_tx(), sccnxp_handle_rx(), sccnxp_handle_events(), ...


> +static inline void sccnxp_barrier(void)
> +{
> +	/* Barrier between read and/or write cycles */
> +	cpu_relax();

ndelay(100 /* ns */);


> +}
> +
>  static int sccnxp_set_baud(struct uart_port *port, int baud)
>  {
>  	struct sccnxp_port *s = dev_get_drvdata(port->dev);
> @@ -307,10 +313,13 @@ static int sccnxp_set_baud(struct uart_port *port, int baud)
>  		mr0 |= MR0_FIFO | MR0_TXLVL;
>  		/* Update MR0 */
>  		sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_MRPTR0);
> +		sccnxp_barrier();
>  		sccnxp_port_write(port, SCCNXP_MR_REG, mr0);
> +		sccnxp_barrier();
>  	}
>  
>  	sccnxp_port_write(port, SCCNXP_ACR_REG, acr | ACR_TIMER_MODE);
> +	sccnxp_barrier();
>  	sccnxp_port_write(port, SCCNXP_CSR_REG, (csr << 4) | csr);
>  
>  	if (baud != bestbaud)
> @@ -620,8 +629,11 @@ static void sccnxp_set_termios(struct uart_port *port,
>  	/* Disable RX & TX, reset break condition, status and FIFOs */
>  	sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_RX_RESET |
>  					       CR_RX_DISABLE | CR_TX_DISABLE);
> +	sccnxp_barrier();
>  	sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_TX_RESET);

Note 7 on pg 19 of the 2698 datasheet [1] says:

"Consecutive write operations to the command register require at least three
edges of the X1 clock between writes"

By my math, that should be 360ns. Agree?

Regards,
Peter Hurley

[1] http://www.nxp.com/documents/data_sheet/SCC2698B.pdf



> +	sccnxp_barrier();
>  	sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_STATUS_RESET);
> +	sccnxp_barrier();
>  	sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_BREAK_RESET);
>  
>  	/* Word size */
> @@ -653,7 +665,9 @@ static void sccnxp_set_termios(struct uart_port *port,
>  
>  	/* Update desired format */
>  	sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_MRPTR1);
> +	sccnxp_barrier();
>  	sccnxp_port_write(port, SCCNXP_MR_REG, mr1);
> +	sccnxp_barrier();
>  	sccnxp_port_write(port, SCCNXP_MR_REG, mr2);
>  
>  	/* Set read status mask */
> @@ -705,9 +719,13 @@ static int sccnxp_startup(struct uart_port *port)
>  
>  	/* Reset break condition, status and FIFOs */
>  	sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_RX_RESET);
> +	sccnxp_barrier();
>  	sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_TX_RESET);
> +	sccnxp_barrier();
>  	sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_STATUS_RESET);
> +	sccnxp_barrier();
>  	sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_BREAK_RESET);
> +	sccnxp_barrier();
>  
>  	/* Enable RX & TX */
>  	sccnxp_port_write(port, SCCNXP_CR_REG, CR_RX_ENABLE | CR_TX_ENABLE);
> @@ -803,6 +821,7 @@ static void sccnxp_console_putchar(struct uart_port *port, int c)
>  
>  	while (tryes--) {
>  		if (sccnxp_port_read(port, SCCNXP_SR_REG) & SR_TXRDY) {
> +			sccnxp_barrier();
>  			sccnxp_port_write(port, SCCNXP_THR_REG, c);
>  			break;
>  		}
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[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