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

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

 



The patch adds a barrier between two sequential read/write cycles
to provide the required minimum High-CS time.

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 }
 };
 
+static inline void sccnxp_barrier(void)
+{
+	/* Barrier between read and/or write cycles */
+	cpu_relax();
+}
+
 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);
+	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;
 		}
-- 
2.4.9

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