diff mbox series

[v2] x86: serial: ns16550: Allow the UART to be silently disabled

Message ID 20231101180447.99361-1-sjg@chromium.org
State New
Delegated to: Bin Meng
Headers show
Series [v2] x86: serial: ns16550: Allow the UART to be silently disabled | expand

Commit Message

Simon Glass Nov. 1, 2023, 6:04 p.m. UTC
U-Boot normally requires a UART. When booting from coreboot it is
sometimes just not available, e.g. when no sysinfo or DBG2 information
is provided.

In this case we need to continue running, since the display can be used.
Add a flag to disable serial for this case.

This allows U-Boot to start up and operation from the display, instead
of hanging on start-up.

This could perhaps be hidden behind a Kconfig option to reduce code
size.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2:
- Drop RFC tag since there were no comments

 drivers/serial/ns16550.c         | 17 +++++++++++++++--
 drivers/serial/serial_coreboot.c |  1 +
 include/ns16550.h                |  1 +
 3 files changed, 17 insertions(+), 2 deletions(-)

Comments

Bin Meng Nov. 5, 2023, 2:11 p.m. UTC | #1
Hi Simon,

On Thu, Nov 2, 2023 at 2:04 AM Simon Glass <sjg@chromium.org> wrote:
>
> U-Boot normally requires a UART. When booting from coreboot it is
> sometimes just not available, e.g. when no sysinfo or DBG2 information
> is provided.
>
> In this case we need to continue running, since the display can be used.
> Add a flag to disable serial for this case.
>
> This allows U-Boot to start up and operation from the display, instead
> of hanging on start-up.
>
> This could perhaps be hidden behind a Kconfig option to reduce code
> size.

I think using a generic Kconfig option and filtering this out in the
generic serial probe code is better than what is proposed in this
patch.

>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2:
> - Drop RFC tag since there were no comments
>
>  drivers/serial/ns16550.c         | 17 +++++++++++++++--
>  drivers/serial/serial_coreboot.c |  1 +
>  include/ns16550.h                |  1 +
>  3 files changed, 17 insertions(+), 2 deletions(-)
>

Regards,
Bin
diff mbox series

Patch

diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index 6deb1d8ddc5..a0545f37cb6 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -385,6 +385,8 @@  static int ns16550_serial_putc(struct udevice *dev, const char ch)
 {
 	struct ns16550 *const com_port = dev_get_priv(dev);
 
+	if (com_port->plat->flags & NS16550_FLAG_DISABLE)
+		return 0;
 	if (!(serial_in(&com_port->lsr) & UART_LSR_THRE))
 		return -EAGAIN;
 	serial_out(ch, &com_port->thr);
@@ -405,6 +407,9 @@  static int ns16550_serial_pending(struct udevice *dev, bool input)
 {
 	struct ns16550 *const com_port = dev_get_priv(dev);
 
+	if (com_port->plat->flags & NS16550_FLAG_DISABLE)
+		return 0;
+
 	if (input)
 		return (serial_in(&com_port->lsr) & UART_LSR_DR) ? 1 : 0;
 	else
@@ -415,6 +420,9 @@  static int ns16550_serial_getc(struct udevice *dev)
 {
 	struct ns16550 *const com_port = dev_get_priv(dev);
 
+	if (com_port->plat->flags & NS16550_FLAG_DISABLE)
+		return 0;
+
 	if (!(serial_in(&com_port->lsr) & UART_LSR_DR))
 		return -EAGAIN;
 
@@ -429,7 +437,8 @@  static int ns16550_serial_setbrg(struct udevice *dev, int baudrate)
 
 	clock_divisor = ns16550_calc_divisor(com_port, plat->clock, baudrate);
 
-	ns16550_setbrg(com_port, clock_divisor);
+	if (!(plat->flags & NS16550_FLAG_DISABLE))
+		ns16550_setbrg(com_port, clock_divisor);
 
 	return 0;
 }
@@ -442,6 +451,9 @@  static int ns16550_serial_setconfig(struct udevice *dev, uint serial_config)
 	uint bits = SERIAL_GET_BITS(serial_config);
 	uint stop = SERIAL_GET_STOP(serial_config);
 
+	if (com_port->plat->flags & NS16550_FLAG_DISABLE)
+		return 0;
+
 	/*
 	 * only parity config is implemented, check if other serial settings
 	 * are the default one.
@@ -534,7 +546,8 @@  int ns16550_serial_probe(struct udevice *dev)
 		reset_deassert_bulk(&reset_bulk);
 
 	com_port->plat = dev_get_plat(dev);
-	ns16550_init(com_port, -1);
+	if (!(plat->flags & NS16550_FLAG_DISABLE))
+		ns16550_init(com_port, -1);
 
 	return 0;
 }
diff --git a/drivers/serial/serial_coreboot.c b/drivers/serial/serial_coreboot.c
index 23066e4d054..cdf9afc1739 100644
--- a/drivers/serial/serial_coreboot.c
+++ b/drivers/serial/serial_coreboot.c
@@ -120,6 +120,7 @@  static int coreboot_of_to_plat(struct udevice *dev)
 		 * there is no UART, which may panic. So stay silent and
 		 * pray that the video console will work.
 		 */
+		plat->flags |= NS16550_FLAG_DISABLE;
 		log_debug("Cannot detect UART\n");
 	}
 
diff --git a/include/ns16550.h b/include/ns16550.h
index 7f481300083..3c4f3e7539a 100644
--- a/include/ns16550.h
+++ b/include/ns16550.h
@@ -52,6 +52,7 @@  enum ns16550_flags {
 	NS16550_FLAG_IO		= 1 << 0, /* Use I/O access (else mem-mapped) */
 	NS16550_FLAG_ENDIAN	= 1 << 1, /* Use out_le/be_32() */
 	NS16550_FLAG_BE		= 1 << 2, /* Big-endian access (else little) */
+	NS16550_FLAG_DISABLE	= BIT(3), /* No output or input */
 };
 
 /**