aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/st-asc.c
diff options
context:
space:
mode:
authorDaniel Thompson <daniel.thompson@linaro.org>2014-05-13 12:08:57 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-05-28 15:24:31 -0400
commit1ffcd67dbcde910c2fd2d1c427c5f62f385fff12 (patch)
tree911a73cd45a6f8ff494c71015ccc32dba086cff3 /drivers/tty/serial/st-asc.c
parentd3352154041e28cf8c1c260cca41d8e83d5377d8 (diff)
serial: st-asc: Fix data corruption during long console bursts
On my test platform (B2020/STiH416) the serial port issues bad characters during the initial message avalanche as the console comes up. The problem also occurs when dense(ish) I/O is done using the polled I/O interface. The problem is fixed for me by using the FIFO half-empty bit rather than FIFO full bit. Note that using the half-empty bit causes the FIFO to be managed in a similar way to interrupt based I/O (i.e. where the hardware gets best test coverage). Running the FIFO half full will have no impact (good or bad) on console performance. The UART will still remain fully saturated and the busy-wait until the FIFO is empty in asc_console_write() will complete at the same time. Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org> Acked-by: Maxime Coquelin <maxime.coquelin@st.com> Acked-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial/st-asc.c')
-rw-r--r--drivers/tty/serial/st-asc.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c
index dd3a96e07026..c7f61ac27132 100644
--- a/drivers/tty/serial/st-asc.c
+++ b/drivers/tty/serial/st-asc.c
@@ -194,9 +194,9 @@ static inline u32 asc_txfifo_is_empty(struct uart_port *port)
194 return asc_in(port, ASC_STA) & ASC_STA_TE; 194 return asc_in(port, ASC_STA) & ASC_STA_TE;
195} 195}
196 196
197static inline int asc_txfifo_is_full(struct uart_port *port) 197static inline u32 asc_txfifo_is_half_empty(struct uart_port *port)
198{ 198{
199 return asc_in(port, ASC_STA) & ASC_STA_TF; 199 return asc_in(port, ASC_STA) & ASC_STA_THE;
200} 200}
201 201
202static inline const char *asc_port_name(struct uart_port *port) 202static inline const char *asc_port_name(struct uart_port *port)
@@ -628,7 +628,7 @@ static int asc_get_poll_char(struct uart_port *port)
628 628
629static void asc_put_poll_char(struct uart_port *port, unsigned char c) 629static void asc_put_poll_char(struct uart_port *port, unsigned char c)
630{ 630{
631 while (asc_txfifo_is_full(port)) 631 while (!asc_txfifo_is_half_empty(port))
632 cpu_relax(); 632 cpu_relax();
633 asc_out(port, ASC_TXBUF, c); 633 asc_out(port, ASC_TXBUF, c);
634} 634}
@@ -783,7 +783,7 @@ static void asc_console_putchar(struct uart_port *port, int ch)
783 unsigned int timeout = 1000000; 783 unsigned int timeout = 1000000;
784 784
785 /* Wait for upto 1 second in case flow control is stopping us. */ 785 /* Wait for upto 1 second in case flow control is stopping us. */
786 while (--timeout && asc_txfifo_is_full(port)) 786 while (--timeout && !asc_txfifo_is_half_empty(port))
787 udelay(1); 787 udelay(1);
788 788
789 asc_out(port, ASC_TXBUF, ch); 789 asc_out(port, ASC_TXBUF, ch);