diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/include/asm/udbg.h | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/udbg.c | 7 | ||||
-rw-r--r-- | arch/powerpc/kernel/udbg_16550.c | 60 |
3 files changed, 58 insertions, 10 deletions
diff --git a/arch/powerpc/include/asm/udbg.h b/arch/powerpc/include/asm/udbg.h index 6418ceea44b..cd21e5e6b04 100644 --- a/arch/powerpc/include/asm/udbg.h +++ b/arch/powerpc/include/asm/udbg.h @@ -15,6 +15,7 @@ #include <linux/init.h> extern void (*udbg_putc)(char c); +extern void (*udbg_flush)(void); extern int (*udbg_getc)(void); extern int (*udbg_getc_poll)(void); diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c index 7d6c9bb8c77..fc9af47e212 100644 --- a/arch/powerpc/kernel/udbg.c +++ b/arch/powerpc/kernel/udbg.c @@ -18,6 +18,7 @@ #include <asm/udbg.h> void (*udbg_putc)(char c); +void (*udbg_flush)(void); int (*udbg_getc)(void); int (*udbg_getc_poll)(void); @@ -76,6 +77,9 @@ void udbg_puts(const char *s) while ((c = *s++) != '\0') udbg_putc(c); } + + if (udbg_flush) + udbg_flush(); } #if 0 else { @@ -98,6 +102,9 @@ int udbg_write(const char *s, int n) } } + if (udbg_flush) + udbg_flush(); + return n - remain; } diff --git a/arch/powerpc/kernel/udbg_16550.c b/arch/powerpc/kernel/udbg_16550.c index 7b7da8cfd5e..0362a891e54 100644 --- a/arch/powerpc/kernel/udbg_16550.c +++ b/arch/powerpc/kernel/udbg_16550.c @@ -48,14 +48,21 @@ struct NS16550 { static struct NS16550 __iomem *udbg_comport; -static void udbg_550_putc(char c) +static void udbg_550_flush(void) { if (udbg_comport) { while ((in_8(&udbg_comport->lsr) & LSR_THRE) == 0) /* wait for idle */; - out_8(&udbg_comport->thr, c); + } +} + +static void udbg_550_putc(char c) +{ + if (udbg_comport) { if (c == '\n') udbg_550_putc('\r'); + udbg_550_flush(); + out_8(&udbg_comport->thr, c); } } @@ -108,6 +115,7 @@ void udbg_init_uart(void __iomem *comport, unsigned int speed, /* Clear & enable FIFOs */ out_8(&udbg_comport->fcr ,0x07); udbg_putc = udbg_550_putc; + udbg_flush = udbg_550_flush; udbg_getc = udbg_550_getc; udbg_getc_poll = udbg_550_getc_poll; } @@ -149,14 +157,21 @@ unsigned int udbg_probe_uart_speed(void __iomem *comport, unsigned int clock) } #ifdef CONFIG_PPC_MAPLE -void udbg_maple_real_putc(char c) +void udbg_maple_real_flush(void) { if (udbg_comport) { while ((real_readb(&udbg_comport->lsr) & LSR_THRE) == 0) /* wait for idle */; - real_writeb(c, &udbg_comport->thr); eieio(); + } +} + +void udbg_maple_real_putc(char c) +{ + if (udbg_comport) { if (c == '\n') udbg_maple_real_putc('\r'); + udbg_maple_real_flush(); + real_writeb(c, &udbg_comport->thr); eieio(); } } @@ -165,20 +180,28 @@ void __init udbg_init_maple_realmode(void) udbg_comport = (struct NS16550 __iomem *)0xf40003f8; udbg_putc = udbg_maple_real_putc; + udbg_flush = udbg_maple_real_flush; udbg_getc = NULL; udbg_getc_poll = NULL; } #endif /* CONFIG_PPC_MAPLE */ #ifdef CONFIG_PPC_PASEMI -void udbg_pas_real_putc(char c) +void udbg_pas_real_flush(void) { if (udbg_comport) { while ((real_205_readb(&udbg_comport->lsr) & LSR_THRE) == 0) /* wait for idle */; - real_205_writeb(c, &udbg_comport->thr); eieio(); + } +} + +void udbg_pas_real_putc(char c) +{ + if (udbg_comport) { if (c == '\n') udbg_pas_real_putc('\r'); + udbg_pas_real_flush(); + real_205_writeb(c, &udbg_comport->thr); eieio(); } } @@ -187,6 +210,7 @@ void udbg_init_pas_realmode(void) udbg_comport = (struct NS16550 __iomem *)0xfcff03f8UL; udbg_putc = udbg_pas_real_putc; + udbg_flush = udbg_pas_real_flush; udbg_getc = NULL; udbg_getc_poll = NULL; } @@ -195,14 +219,21 @@ void udbg_init_pas_realmode(void) #ifdef CONFIG_PPC_EARLY_DEBUG_44x #include <platforms/44x/44x.h> -static void udbg_44x_as1_putc(char c) +static int udbg_44x_as1_flush(void) { if (udbg_comport) { while ((as1_readb(&udbg_comport->lsr) & LSR_THRE) == 0) /* wait for idle */; - as1_writeb(c, &udbg_comport->thr); eieio(); + } +} + +static void udbg_44x_as1_putc(char c) +{ + if (udbg_comport) { if (c == '\n') udbg_44x_as1_putc('\r'); + udbg_44x_as1_flush(); + as1_writeb(c, &udbg_comport->thr); eieio(); } } @@ -222,19 +253,27 @@ void __init udbg_init_44x_as1(void) (struct NS16550 __iomem *)PPC44x_EARLY_DEBUG_VIRTADDR; udbg_putc = udbg_44x_as1_putc; + udbg_flush = udbg_44x_as1_flush; udbg_getc = udbg_44x_as1_getc; } #endif /* CONFIG_PPC_EARLY_DEBUG_44x */ #ifdef CONFIG_PPC_EARLY_DEBUG_40x -static void udbg_40x_real_putc(char c) +static void udbg_40x_real_flush(void) { if (udbg_comport) { while ((real_readb(&udbg_comport->lsr) & LSR_THRE) == 0) /* wait for idle */; - real_writeb(c, &udbg_comport->thr); eieio(); + } +} + +static void udbg_40x_real_putc(char c) +{ + if (udbg_comport) { if (c == '\n') udbg_40x_real_putc('\r'); + udbg_40x_real_flush(); + real_writeb(c, &udbg_comport->thr); eieio(); } } @@ -254,6 +293,7 @@ void __init udbg_init_40x_realmode(void) CONFIG_PPC_EARLY_DEBUG_40x_PHYSADDR; udbg_putc = udbg_40x_real_putc; + udbg_flush = udbg_40x_real_flush; udbg_getc = udbg_40x_real_getc; udbg_getc_poll = NULL; } |