aboutsummaryrefslogtreecommitdiff
path: root/drivers/serial
diff options
context:
space:
mode:
authorRasmus Villemoes <rasmus.villemoes@prevas.dk>2023-10-16 10:35:22 +0200
committerTom Rini <trini@konsulko.com>2023-10-24 17:05:24 -0400
commit35dc728a3cd14338b5fa0b6f231aa555077c98a1 (patch)
tree59ad3b6c3df52508641f485591d5af5029b02d9a /drivers/serial
parent1000e2f96b582a69366f61a71d747c8ee9eb1cab (diff)
downloadu-boot-35dc728a3cd14338b5fa0b6f231aa555077c98a1.zip
u-boot-35dc728a3cd14338b5fa0b6f231aa555077c98a1.tar.gz
u-boot-35dc728a3cd14338b5fa0b6f231aa555077c98a1.tar.bz2
serial: introduce CONFIG_CONSOLE_FLUSH_ON_NEWLINE
When debugging, one sometimes only gets partial output lines or nothing at all from the last printf, because the uart has a largish buffer, and the code after the printf() may cause the CPU to hang before the uart IP has time to actually emit all the characters. That can be very confusing, because one doesn't then know exactly where the hang happens. Introduce a config knob allowing one to wait for the uart fifo to drain whenever a newline character is printed, roughly corresponding to the effect of setvbuf(..., _IOLBF, ...) in ordinary C programs. Since this uses IS_ENABLED() instead of cpp ifdef, we can remove the ifdef around the _serial_flush() definition - if neither CONSOLE_FLUSH_SUPPORT or CONSOLE_FLUSH_ON_NEWLINE are enabled, the compiler elides _serial_flush(), but it won't warn about it being unused. Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk> Reviewed-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/serial-uclass.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index 8bdcdd1..df6a387 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -182,7 +182,6 @@ int serial_initialize(void)
return serial_init();
}
-#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
static void _serial_flush(struct udevice *dev)
{
struct dm_serial_ops *ops = serial_get_ops(dev);
@@ -192,7 +191,6 @@ static void _serial_flush(struct udevice *dev)
while (ops->pending(dev, false) > 0)
;
}
-#endif
static void _serial_putc(struct udevice *dev, char ch)
{
@@ -205,6 +203,9 @@ static void _serial_putc(struct udevice *dev, char ch)
do {
err = ops->putc(dev, ch);
} while (err == -EAGAIN);
+
+ if (IS_ENABLED(CONFIG_CONSOLE_FLUSH_ON_NEWLINE) && ch == '\n')
+ _serial_flush(dev);
}
static int __serial_puts(struct udevice *dev, const char *str, size_t len)
@@ -243,6 +244,9 @@ static void _serial_puts(struct udevice *dev, const char *str)
if (*newline && __serial_puts(dev, "\r\n", 2))
return;
+ if (IS_ENABLED(CONFIG_CONSOLE_FLUSH_ON_NEWLINE) && *newline)
+ _serial_flush(dev);
+
str += len + !!*newline;
} while (*str);
}