From: "Pali Rohár" <pali@kernel.org>
To: Simon Glass <sjg@chromium.org>
Cc: u-boot@lists.denx.de
Subject: [PATCH v3 2/6] console: Implement flush() function
Date: Mon, 5 Sep 2022 11:31:17 +0200 [thread overview]
Message-ID: <20220905093121.11630-3-pali@kernel.org> (raw)
In-Reply-To: <20220905093121.11630-1-pali@kernel.org>
On certain places it is required to flush output print buffers to ensure
that text strings were sent to console or serial devices. For example when
printing message that U-Boot is going to boot kernel or when U-Boot is
going to change baudrate of terminal device.
Therefore introduce a new flush() and fflush() functions into console code.
These functions will call .flush callback of associated stdio_dev device.
As this function may increase U-Boot side, allow to compile U-Boot without
this function. For this purpose there is a new config CONSOLE_FLUSH_SUPPORT
which is enabled by default and can be disabled. It is a good idea to have
this option enabled for all boards which have enough space for it.
When option is disabled when U-Boot defines just empty static inline
function fflush() to avoid ifdefs in other code.
Signed-off-by: Pali Rohár <pali@kernel.org>
---
Changes in v3:
* Added macro STDIO_DEV_ASSIGN_FLUSH()
---
common/Kconfig | 6 +++++
common/console.c | 61 +++++++++++++++++++++++++++++++++++++++++++++
include/_exports.h | 3 +++
include/stdio.h | 15 +++++++++++
include/stdio_dev.h | 7 ++++++
5 files changed, 92 insertions(+)
diff --git a/common/Kconfig b/common/Kconfig
index e7914ca750a3..109741cc6c44 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -186,6 +186,12 @@ config PRE_CON_BUF_ADDR
We should consider removing this option and allocating the memory
in board_init_f_init_reserve() instead.
+config CONSOLE_FLUSH_SUPPORT
+ bool "Enable console flush support"
+ default y
+ help
+ This enables compilation of flush() function for console flush support.
+
config CONSOLE_MUX
bool "Enable console multiplexing"
default y if DM_VIDEO || VIDEO || LCD
diff --git a/common/console.c b/common/console.c
index e783f309bf06..0abfc224b53b 100644
--- a/common/console.c
+++ b/common/console.c
@@ -199,6 +199,7 @@ static int console_setfile(int file, struct stdio_dev * dev)
case stdout:
gd->jt->putc = putc;
gd->jt->puts = puts;
+ STDIO_DEV_ASSIGN_FLUSH(gd->jt, flush);
gd->jt->printf = printf;
break;
}
@@ -364,6 +365,19 @@ static void console_puts(int file, const char *s)
}
}
+#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
+static void console_flush(int file)
+{
+ int i;
+ struct stdio_dev *dev;
+
+ for_each_console_dev(i, file, dev) {
+ if (dev->flush != NULL)
+ dev->flush(dev);
+ }
+}
+#endif
+
#if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
static inline void console_doenv(int file, struct stdio_dev *dev)
{
@@ -413,6 +427,14 @@ static inline void console_puts(int file, const char *s)
stdio_devices[file]->puts(stdio_devices[file], s);
}
+#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
+static inline void console_flush(int file)
+{
+ if (stdio_devices[file]->flush)
+ stdio_devices[file]->flush(stdio_devices[file]);
+}
+#endif
+
#if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV)
static inline void console_doenv(int file, struct stdio_dev *dev)
{
@@ -526,6 +548,14 @@ void fputs(int file, const char *s)
console_puts(file, s);
}
+#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
+void fflush(int file)
+{
+ if (file < MAX_FILES)
+ console_flush(file);
+}
+#endif
+
int fprintf(int file, const char *fmt, ...)
{
va_list args;
@@ -740,6 +770,37 @@ void puts(const char *s)
}
}
+#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
+void flush(void)
+{
+ if (!gd)
+ return;
+
+ /* sandbox can send characters to stdout before it has a console */
+ if (IS_ENABLED(CONFIG_SANDBOX) && !(gd->flags & GD_FLG_SERIAL_READY)) {
+ os_flush();
+ return;
+ }
+
+ if (IS_ENABLED(CONFIG_DEBUG_UART) && !(gd->flags & GD_FLG_SERIAL_READY))
+ return;
+
+ if (IS_ENABLED(CONFIG_SILENT_CONSOLE) && (gd->flags & GD_FLG_SILENT))
+ return;
+
+ if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE))
+ return;
+
+ if (!gd->have_console)
+ return;
+
+ if (gd->flags & GD_FLG_DEVINIT) {
+ /* Send to the standard output */
+ fflush(stdout);
+ }
+}
+#endif
+
#ifdef CONFIG_CONSOLE_RECORD
int console_record_init(void)
{
diff --git a/include/_exports.h b/include/_exports.h
index f6df8b610734..1af946fac327 100644
--- a/include/_exports.h
+++ b/include/_exports.h
@@ -12,6 +12,9 @@
EXPORT_FUNC(tstc, int, tstc, void)
EXPORT_FUNC(putc, void, putc, const char)
EXPORT_FUNC(puts, void, puts, const char *)
+#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
+ EXPORT_FUNC(flush, void, flush, void)
+#endif
EXPORT_FUNC(printf, int, printf, const char*, ...)
#if (defined(CONFIG_X86) && !defined(CONFIG_X86_64)) || defined(CONFIG_PPC)
EXPORT_FUNC(irq_install_handler, void, install_hdlr,
diff --git a/include/stdio.h b/include/stdio.h
index 1939a48f0fb6..3241e2d493fa 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -15,6 +15,11 @@ int tstc(void);
defined(CONFIG_SPL_SERIAL))
void putc(const char c);
void puts(const char *s);
+#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
+void flush(void);
+#else
+static inline void flush(void) {}
+#endif
int __printf(1, 2) printf(const char *fmt, ...);
int vprintf(const char *fmt, va_list args);
#else
@@ -26,6 +31,10 @@ static inline void puts(const char *s)
{
}
+static inline void flush(void)
+{
+}
+
static inline int __printf(1, 2) printf(const char *fmt, ...)
{
return 0;
@@ -48,11 +57,17 @@ static inline int vprintf(const char *fmt, va_list args)
/* stderr */
#define eputc(c) fputc(stderr, c)
#define eputs(s) fputs(stderr, s)
+#define eflush() fflush(stderr)
#define eprintf(fmt, args...) fprintf(stderr, fmt, ##args)
int __printf(2, 3) fprintf(int file, const char *fmt, ...);
void fputs(int file, const char *s);
void fputc(int file, const char c);
+#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
+void fflush(int file);
+#else
+static inline void fflush(int file) {}
+#endif
int ftstc(int file);
int fgetc(int file);
diff --git a/include/stdio_dev.h b/include/stdio_dev.h
index 270fa2729fb2..3105928970db 100644
--- a/include/stdio_dev.h
+++ b/include/stdio_dev.h
@@ -37,6 +37,13 @@ struct stdio_dev {
void (*putc)(struct stdio_dev *dev, const char c);
/* To put a string (accelerator) */
void (*puts)(struct stdio_dev *dev, const char *s);
+#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
+ /* To flush output queue */
+ void (*flush)(struct stdio_dev *dev);
+#define STDIO_DEV_ASSIGN_FLUSH(dev, flush_func) ((dev)->flush = (flush_func))
+#else
+#define STDIO_DEV_ASSIGN_FLUSH(dev, flush_func)
+#endif
/* INPUT functions */
--
2.20.1
next prev parent reply other threads:[~2022-09-05 9:32 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-09-05 9:31 [PATCH v3 0/6] console: Implement flush() function Pali Rohár
2022-09-05 9:31 ` [PATCH v3 1/6] sandbox: Add function os_flush() Pali Rohár
2022-09-07 21:10 ` Simon Glass
2022-09-24 18:00 ` Tom Rini
2022-09-05 9:31 ` Pali Rohár [this message]
2022-09-07 21:11 ` [PATCH v3 2/6] console: Implement flush() function Simon Glass
2022-09-05 9:31 ` [PATCH v3 3/6] serial: Implement flush callback Pali Rohár
2022-09-05 17:24 ` Michael Nazzareno Trimarchi
2022-09-05 17:28 ` Pali Rohár
2022-09-07 21:11 ` Simon Glass
2022-09-05 9:31 ` [PATCH v3 4/6] serial: Implement serial_flush() function for console flush() fallback Pali Rohár
2022-09-07 21:10 ` Simon Glass
2022-09-20 21:40 ` Tom Rini
2022-09-20 22:18 ` Pali Rohár
2022-09-20 22:29 ` Tom Rini
2022-09-20 22:32 ` Pali Rohár
2022-09-20 22:46 ` Tom Rini
2022-09-05 9:31 ` [PATCH v3 5/6] serial: Call flush() before changing baudrate Pali Rohár
2022-09-07 21:10 ` Simon Glass
2022-09-05 9:31 ` [PATCH v3 6/6] boot: Call flush() before booting Pali Rohár
2022-09-07 21:10 ` Simon Glass
2022-09-07 21:14 ` Pali Rohár
2022-09-21 13:49 ` [PATCH v3 0/6] console: Implement flush() function Tom Rini
2022-09-21 13:54 ` Pali Rohár
2022-09-21 13:56 ` Tom Rini
2022-09-22 11:27 ` Simon Glass
2022-09-22 13:13 ` Heinrich Schuchardt
2022-09-22 13:14 ` Pali Rohár
2022-09-22 15:06 ` Heinrich Schuchardt
2022-09-23 15:45 ` Pali Rohár
2022-09-23 15:57 ` Tom Rini
2022-09-23 16:07 ` Pali Rohár
2022-09-23 16:19 ` Tom Rini
2022-09-24 14:01 ` Simon Glass
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220905093121.11630-3-pali@kernel.org \
--to=pali@kernel.org \
--cc=sjg@chromium.org \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox