diff mbox series

[v3,3/6] serial: Implement flush callback

Message ID 20220905093121.11630-4-pali@kernel.org
State Accepted
Commit 016e2be96d4247ceacca05932f2e94d31607cc57
Delegated to: Tom Rini
Headers show
Series console: Implement flush() function | expand

Commit Message

Pali Rohár Sept. 5, 2022, 9:31 a.m. UTC
UART drivers have putc/puts functions which just put characters into HW
transmit queue and do not wait until all data are transmitted.

Implement flush callback via serial driver's pending(false) callback which
waits until HW transmit all characters from the queue.

Signed-off-by: Pali Rohár <pali@kernel.org>
---
 drivers/serial/serial-uclass.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

Comments

Michael Nazzareno Trimarchi Sept. 5, 2022, 5:24 p.m. UTC | #1
Hi

Il lun 5 set 2022, 11:32 Pali Rohár <pali@kernel.org> ha scritto:

> UART drivers have putc/puts functions which just put characters into HW
> transmit queue and do not wait until all data are transmitted.
>
> Implement flush callback via serial driver's pending(false) callback which
> waits until HW transmit all characters from the queue.
>

This is a drain if you want to wait. Is not the right terminology?

Michael


> Signed-off-by: Pali Rohár <pali@kernel.org>
> ---
>  drivers/serial/serial-uclass.c | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
>
> diff --git a/drivers/serial/serial-uclass.c
> b/drivers/serial/serial-uclass.c
> index 30650e37b0d7..be6502f3d24c 100644
> --- a/drivers/serial/serial-uclass.c
> +++ b/drivers/serial/serial-uclass.c
> @@ -238,6 +238,18 @@ static void _serial_puts(struct udevice *dev, const
> char *str)
>         } while (*str);
>  }
>
> +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
> +static void _serial_flush(struct udevice *dev)
> +{
> +       struct dm_serial_ops *ops = serial_get_ops(dev);
> +
> +       if (!ops->pending)
> +               return;
> +       while (ops->pending(dev, false) > 0)
> +               ;
> +}
> +#endif
> +
>  static int __serial_getc(struct udevice *dev)
>  {
>         struct dm_serial_ops *ops = serial_get_ops(dev);
> @@ -398,6 +410,13 @@ static void serial_stub_puts(struct stdio_dev *sdev,
> const char *str)
>         _serial_puts(sdev->priv, str);
>  }
>
> +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
> +static void serial_stub_flush(struct stdio_dev *sdev)
> +{
> +       _serial_flush(sdev->priv);
> +}
> +#endif
> +
>  static int serial_stub_getc(struct stdio_dev *sdev)
>  {
>         return _serial_getc(sdev->priv);
> @@ -520,6 +539,7 @@ static int serial_post_probe(struct udevice *dev)
>         sdev.priv = dev;
>         sdev.putc = serial_stub_putc;
>         sdev.puts = serial_stub_puts;
> +       STDIO_DEV_ASSIGN_FLUSH(&sdev, serial_stub_flush);
>         sdev.getc = serial_stub_getc;
>         sdev.tstc = serial_stub_tstc;
>
> --
> 2.20.1
>
>
Pali Rohár Sept. 5, 2022, 5:28 p.m. UTC | #2
On Monday 05 September 2022 19:24:17 Michael Nazzareno Trimarchi wrote:
> Hi
> 
> Il lun 5 set 2022, 11:32 Pali Rohár <pali@kernel.org> ha scritto:
> 
> > UART drivers have putc/puts functions which just put characters into HW
> > transmit queue and do not wait until all data are transmitted.
> >
> > Implement flush callback via serial driver's pending(false) callback which
> > waits until HW transmit all characters from the queue.
> >
> 
> This is a drain if you want to wait. Is not the right terminology?

Yes, for tty devices it is drain. But for C stdio.h it is (f)flush.
Hence I used more generic name flush() as it is not only for serial
devices, but for any U-Boot stdio device. E.g. sandbox os use real
fflush function.

But feel free to choose any other name of function. I do not care a much
about it.

> Michael
> 
> 
> > Signed-off-by: Pali Rohár <pali@kernel.org>
> > ---
> >  drivers/serial/serial-uclass.c | 20 ++++++++++++++++++++
> >  1 file changed, 20 insertions(+)
> >
> > diff --git a/drivers/serial/serial-uclass.c
> > b/drivers/serial/serial-uclass.c
> > index 30650e37b0d7..be6502f3d24c 100644
> > --- a/drivers/serial/serial-uclass.c
> > +++ b/drivers/serial/serial-uclass.c
> > @@ -238,6 +238,18 @@ static void _serial_puts(struct udevice *dev, const
> > char *str)
> >         } while (*str);
> >  }
> >
> > +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
> > +static void _serial_flush(struct udevice *dev)
> > +{
> > +       struct dm_serial_ops *ops = serial_get_ops(dev);
> > +
> > +       if (!ops->pending)
> > +               return;
> > +       while (ops->pending(dev, false) > 0)
> > +               ;
> > +}
> > +#endif
> > +
> >  static int __serial_getc(struct udevice *dev)
> >  {
> >         struct dm_serial_ops *ops = serial_get_ops(dev);
> > @@ -398,6 +410,13 @@ static void serial_stub_puts(struct stdio_dev *sdev,
> > const char *str)
> >         _serial_puts(sdev->priv, str);
> >  }
> >
> > +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
> > +static void serial_stub_flush(struct stdio_dev *sdev)
> > +{
> > +       _serial_flush(sdev->priv);
> > +}
> > +#endif
> > +
> >  static int serial_stub_getc(struct stdio_dev *sdev)
> >  {
> >         return _serial_getc(sdev->priv);
> > @@ -520,6 +539,7 @@ static int serial_post_probe(struct udevice *dev)
> >         sdev.priv = dev;
> >         sdev.putc = serial_stub_putc;
> >         sdev.puts = serial_stub_puts;
> > +       STDIO_DEV_ASSIGN_FLUSH(&sdev, serial_stub_flush);
> >         sdev.getc = serial_stub_getc;
> >         sdev.tstc = serial_stub_tstc;
> >
> > --
> > 2.20.1
> >
> >
Simon Glass Sept. 7, 2022, 9:11 p.m. UTC | #3
On Mon, 5 Sept 2022 at 03:31, Pali Rohár <pali@kernel.org> wrote:
>
> UART drivers have putc/puts functions which just put characters into HW
> transmit queue and do not wait until all data are transmitted.
>
> Implement flush callback via serial driver's pending(false) callback which
> waits until HW transmit all characters from the queue.
>
> Signed-off-by: Pali Rohár <pali@kernel.org>
> ---
>  drivers/serial/serial-uclass.c | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)

Reviewed-by: Simon Glass <sjg@chromium.org>
diff mbox series

Patch

diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index 30650e37b0d7..be6502f3d24c 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -238,6 +238,18 @@  static void _serial_puts(struct udevice *dev, const char *str)
 	} while (*str);
 }
 
+#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
+static void _serial_flush(struct udevice *dev)
+{
+	struct dm_serial_ops *ops = serial_get_ops(dev);
+
+	if (!ops->pending)
+		return;
+	while (ops->pending(dev, false) > 0)
+		;
+}
+#endif
+
 static int __serial_getc(struct udevice *dev)
 {
 	struct dm_serial_ops *ops = serial_get_ops(dev);
@@ -398,6 +410,13 @@  static void serial_stub_puts(struct stdio_dev *sdev, const char *str)
 	_serial_puts(sdev->priv, str);
 }
 
+#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
+static void serial_stub_flush(struct stdio_dev *sdev)
+{
+	_serial_flush(sdev->priv);
+}
+#endif
+
 static int serial_stub_getc(struct stdio_dev *sdev)
 {
 	return _serial_getc(sdev->priv);
@@ -520,6 +539,7 @@  static int serial_post_probe(struct udevice *dev)
 	sdev.priv = dev;
 	sdev.putc = serial_stub_putc;
 	sdev.puts = serial_stub_puts;
+	STDIO_DEV_ASSIGN_FLUSH(&sdev, serial_stub_flush);
 	sdev.getc = serial_stub_getc;
 	sdev.tstc = serial_stub_tstc;