[PATCH 07/16] xen/char: implement suspend/resume calls for SCIF driver

Mykola Kvach posted 16 patches 11 months, 1 week ago
[PATCH 07/16] xen/char: implement suspend/resume calls for SCIF driver
Posted by Mykola Kvach 11 months, 1 week ago
From: Mykola Kvach <mykola_kvach@epam.com>

The changes have been tested only on the Renesas R-Car-H3 Starter Kit board.

Signed-off-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
Signed-off-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
Signed-off-by: Mykola Kvach <mykola_kvach@epam.com>
---
 xen/drivers/char/scif-uart.c | 31 ++++++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/xen/drivers/char/scif-uart.c b/xen/drivers/char/scif-uart.c
index 757793ca45..e166fb0f36 100644
--- a/xen/drivers/char/scif-uart.c
+++ b/xen/drivers/char/scif-uart.c
@@ -139,7 +139,7 @@ static void scif_uart_interrupt(int irq, void *data)
     }
 }
 
-static void __init scif_uart_init_preirq(struct serial_port *port)
+static void scif_uart_init_preirq(struct serial_port *port)
 {
     struct scif_uart *uart = port->uart;
     const struct port_params *params = uart->params;
@@ -271,6 +271,33 @@ static void scif_uart_stop_tx(struct serial_port *port)
     scif_writew(uart, SCIF_SCSCR, scif_readw(uart, SCIF_SCSCR) & ~SCSCR_TIE);
 }
 
+static void scif_uart_suspend(struct serial_port *port)
+{
+    struct scif_uart *uart = port->uart;
+
+    scif_uart_stop_tx(port);
+
+    /* Wait until last bit has been transmitted. */
+    while ( !(scif_readw(uart, SCIF_SCFSR) & SCFSR_TEND) );
+
+    /* Disable TX/RX parts and all interrupts */
+    scif_writew(uart, SCIF_SCSCR, 0);
+
+    /* Reset TX/RX FIFOs */
+    scif_writew(uart, SCIF_SCFCR, SCFCR_RFRST | SCFCR_TFRST);
+}
+
+static void scif_uart_resume(struct serial_port *port)
+{
+    struct scif_uart *uart = port->uart;
+
+    scif_uart_init_preirq(port);
+
+    /* Enable TX/RX and Error Interrupts  */
+    scif_writew(uart, SCIF_SCSCR, scif_readw(uart, SCIF_SCSCR) |
+                SCSCR_TIE | SCSCR_RIE | SCSCR_REIE);
+}
+
 static struct uart_driver __read_mostly scif_uart_driver = {
     .init_preirq  = scif_uart_init_preirq,
     .init_postirq = scif_uart_init_postirq,
@@ -281,6 +308,8 @@ static struct uart_driver __read_mostly scif_uart_driver = {
     .start_tx     = scif_uart_start_tx,
     .stop_tx      = scif_uart_stop_tx,
     .vuart_info   = scif_vuart_info,
+    .suspend      = scif_uart_suspend,
+    .resume       = scif_uart_resume,
 };
 
 static const struct dt_device_match scif_uart_dt_match[] __initconst =
-- 
2.43.0
Re: [PATCH 07/16] xen/char: implement suspend/resume calls for SCIF driver
Posted by Grygorii Strashko 10 months, 3 weeks ago

On 05.03.25 11:11, Mykola Kvach wrote:
> From: Mykola Kvach <mykola_kvach@epam.com>
> 
> The changes have been tested only on the Renesas R-Car-H3 Starter Kit board.
> 
> Signed-off-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
> Signed-off-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
> Signed-off-by: Mykola Kvach <mykola_kvach@epam.com>
> ---
>   xen/drivers/char/scif-uart.c | 31 ++++++++++++++++++++++++++++++-
>   1 file changed, 30 insertions(+), 1 deletion(-)
> 
> diff --git a/xen/drivers/char/scif-uart.c b/xen/drivers/char/scif-uart.c
> index 757793ca45..e166fb0f36 100644
> --- a/xen/drivers/char/scif-uart.c
> +++ b/xen/drivers/char/scif-uart.c
> @@ -139,7 +139,7 @@ static void scif_uart_interrupt(int irq, void *data)
>       }
>   }
>   
> -static void __init scif_uart_init_preirq(struct serial_port *port)
> +static void scif_uart_init_preirq(struct serial_port *port)
>   {
>       struct scif_uart *uart = port->uart;
>       const struct port_params *params = uart->params;
> @@ -271,6 +271,33 @@ static void scif_uart_stop_tx(struct serial_port *port)
>       scif_writew(uart, SCIF_SCSCR, scif_readw(uart, SCIF_SCSCR) & ~SCSCR_TIE);
>   }
>   

I assume you want ifdef CONFIG_SYSTEM_SUSPEND here also


> +static void scif_uart_suspend(struct serial_port *port)
> +{
> +    struct scif_uart *uart = port->uart;
> +
> +    scif_uart_stop_tx(port);
> +
> +    /* Wait until last bit has been transmitted. */
> +    while ( !(scif_readw(uart, SCIF_SCFSR) & SCFSR_TEND) );
> +
> +    /* Disable TX/RX parts and all interrupts */
> +    scif_writew(uart, SCIF_SCSCR, 0);
> +
> +    /* Reset TX/RX FIFOs */
> +    scif_writew(uart, SCIF_SCFCR, SCFCR_RFRST | SCFCR_TFRST);
> +}
> +
> +static void scif_uart_resume(struct serial_port *port)
> +{
> +    struct scif_uart *uart = port->uart;
> +
> +    scif_uart_init_preirq(port);
> +
> +    /* Enable TX/RX and Error Interrupts  */
> +    scif_writew(uart, SCIF_SCSCR, scif_readw(uart, SCIF_SCSCR) |
> +                SCSCR_TIE | SCSCR_RIE | SCSCR_REIE);
> +}
> +
>   static struct uart_driver __read_mostly scif_uart_driver = {
>       .init_preirq  = scif_uart_init_preirq,
>       .init_postirq = scif_uart_init_postirq,
> @@ -281,6 +308,8 @@ static struct uart_driver __read_mostly scif_uart_driver = {
>       .start_tx     = scif_uart_start_tx,
>       .stop_tx      = scif_uart_stop_tx,
>       .vuart_info   = scif_vuart_info,
> +    .suspend      = scif_uart_suspend,
> +    .resume       = scif_uart_resume,
>   };
>   
>   static const struct dt_device_match scif_uart_dt_match[] __initconst =

-- 
Best regards,
-grygorii
Re: [PATCH 07/16] xen/char: implement suspend/resume calls for SCIF driver
Posted by Mykola Kvach 10 months, 3 weeks ago
Hi,

On Wed, Mar 19, 2025 at 7:21 PM Grygorii Strashko
<grygorii_strashko@epam.com> wrote:
>
>
>
> On 05.03.25 11:11, Mykola Kvach wrote:
> > From: Mykola Kvach <mykola_kvach@epam.com>
> >
> > The changes have been tested only on the Renesas R-Car-H3 Starter Kit board.
> >
> > Signed-off-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
> > Signed-off-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
> > Signed-off-by: Mykola Kvach <mykola_kvach@epam.com>
> > ---
> >   xen/drivers/char/scif-uart.c | 31 ++++++++++++++++++++++++++++++-
> >   1 file changed, 30 insertions(+), 1 deletion(-)
> >
> > diff --git a/xen/drivers/char/scif-uart.c b/xen/drivers/char/scif-uart.c
> > index 757793ca45..e166fb0f36 100644
> > --- a/xen/drivers/char/scif-uart.c
> > +++ b/xen/drivers/char/scif-uart.c
> > @@ -139,7 +139,7 @@ static void scif_uart_interrupt(int irq, void *data)
> >       }
> >   }
> >
> > -static void __init scif_uart_init_preirq(struct serial_port *port)
> > +static void scif_uart_init_preirq(struct serial_port *port)
> >   {
> >       struct scif_uart *uart = port->uart;
> >       const struct port_params *params = uart->params;
> > @@ -271,6 +271,33 @@ static void scif_uart_stop_tx(struct serial_port *port)
> >       scif_writew(uart, SCIF_SCSCR, scif_readw(uart, SCIF_SCSCR) & ~SCSCR_TIE);
> >   }
> >
>
> I assume you want ifdef CONFIG_SYSTEM_SUSPEND here also

I was thinking about it and decided that since we have the
suspend/resume fields uncovered for uart_driver,
I'll leave the functions uncovered as well.

I'll add coverage in the next patch series.
It’s probably needed to cover the suspend/resume fields too, but that
will require additional changes for other UART drivers.
Thank you for pointing that out.

>
>
> > +static void scif_uart_suspend(struct serial_port *port)
> > +{
> > +    struct scif_uart *uart = port->uart;
> > +
> > +    scif_uart_stop_tx(port);
> > +
> > +    /* Wait until last bit has been transmitted. */
> > +    while ( !(scif_readw(uart, SCIF_SCFSR) & SCFSR_TEND) );
> > +
> > +    /* Disable TX/RX parts and all interrupts */
> > +    scif_writew(uart, SCIF_SCSCR, 0);
> > +
> > +    /* Reset TX/RX FIFOs */
> > +    scif_writew(uart, SCIF_SCFCR, SCFCR_RFRST | SCFCR_TFRST);
> > +}
> > +
> > +static void scif_uart_resume(struct serial_port *port)
> > +{
> > +    struct scif_uart *uart = port->uart;
> > +
> > +    scif_uart_init_preirq(port);
> > +
> > +    /* Enable TX/RX and Error Interrupts  */
> > +    scif_writew(uart, SCIF_SCSCR, scif_readw(uart, SCIF_SCSCR) |
> > +                SCSCR_TIE | SCSCR_RIE | SCSCR_REIE);
> > +}
> > +
> >   static struct uart_driver __read_mostly scif_uart_driver = {
> >       .init_preirq  = scif_uart_init_preirq,
> >       .init_postirq = scif_uart_init_postirq,
> > @@ -281,6 +308,8 @@ static struct uart_driver __read_mostly scif_uart_driver = {
> >       .start_tx     = scif_uart_start_tx,
> >       .stop_tx      = scif_uart_stop_tx,
> >       .vuart_info   = scif_vuart_info,
> > +    .suspend      = scif_uart_suspend,
> > +    .resume       = scif_uart_resume,
> >   };
> >
> >   static const struct dt_device_match scif_uart_dt_match[] __initconst =
>
> --
> Best regards,
> -grygorii

Best regards,
Mykola