aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/udbg.c
diff options
context:
space:
mode:
authorAndrew Klossner <andrew@cesa.opbu.xerox.com>2009-03-09 03:52:41 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-03-11 02:11:34 -0400
commitaf9c7249071bf862781df06eb24456cab763dc7d (patch)
tree8ec042b89029db61ccdb493f46ab7f4cdd9306cb /arch/powerpc/kernel/udbg.c
parenta77acda0b7f2e54009955512e577812433d7abc5 (diff)
powerpc/udbg: Fix lost byte during console handover; change LFCR to CRLF
When the console is on a serial port to be driven by serial8250, a character can be lost from the end of the first line in the two-line sequence serial8250.0: ttyS0 at MMIO 0xe0004500 (irq = 42) is a 16550A console handover: boot [udbg0] -> real [ttyS0] This happens because udbg_puts or udbg_write stuff the last byte of the line into the Tx FIFO and return, whereupon the serial8250 initialization code immediately empties that FIFO. The fix: udbg_puts and udbg_write now wait for the Tx FIFO to clear before returning. This delays the system by one additional serial frame time for each line written by udbg, but the effect is not noticeable, a cumulative 17 milliseconds for 200 lines of early printk output at 115200 baud. Also, the routines in udbg_16550.c now emit CRLF instead of LFCR. Linux makes a point of emitting CRLF because, when serial output is captured to a file, LFCR sequences can confuse text editors. See http://lkml.org/lkml/2006/2/4/50 for some history. Signed-off-by: Andrew Klossner <andrew@cesa.opbu.xerox.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel/udbg.c')
-rw-r--r--arch/powerpc/kernel/udbg.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c
index 7d6c9bb8c77f..fc9af47e2128 100644
--- a/arch/powerpc/kernel/udbg.c
+++ b/arch/powerpc/kernel/udbg.c
@@ -18,6 +18,7 @@
18#include <asm/udbg.h> 18#include <asm/udbg.h>
19 19
20void (*udbg_putc)(char c); 20void (*udbg_putc)(char c);
21void (*udbg_flush)(void);
21int (*udbg_getc)(void); 22int (*udbg_getc)(void);
22int (*udbg_getc_poll)(void); 23int (*udbg_getc_poll)(void);
23 24
@@ -76,6 +77,9 @@ void udbg_puts(const char *s)
76 while ((c = *s++) != '\0') 77 while ((c = *s++) != '\0')
77 udbg_putc(c); 78 udbg_putc(c);
78 } 79 }
80
81 if (udbg_flush)
82 udbg_flush();
79 } 83 }
80#if 0 84#if 0
81 else { 85 else {
@@ -98,6 +102,9 @@ int udbg_write(const char *s, int n)
98 } 102 }
99 } 103 }
100 104
105 if (udbg_flush)
106 udbg_flush();
107
101 return n - remain; 108 return n - remain;
102} 109}
103 110