diff mbox series

[v2,3/3] tty: serial: sh-sci: Add RZ/G2L SCIF DMA rx support

Message ID 20230324100222.116666-4-biju.das.jz@bp.renesas.com (mailing list archive)
State Superseded
Delegated to: Geert Uytterhoeven
Headers show
Series Add RZ/G2L SCIFA DMAC support | expand

Commit Message

Biju Das March 24, 2023, 10:02 a.m. UTC
Add SCIF DMA rx support for RZ/G2L alike SoCs.

RZ/G2L alike SoCs use the same signal for both interrupt and DMA transfer
requests, so we must disable line interrupt while transferring DMA.

We must set FIFO trigger to 1 so that SCIF will request DMA when there is
a character as SCIF DMA request is based on FIFO data full RDF.

Based on a patch in the BSP by Long Luu
<long.luu.ur@renesas.com>

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
v1->v2:
 * No change
---
 drivers/tty/serial/sh-sci.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

Comments

Geert Uytterhoeven March 27, 2023, 10:10 a.m. UTC | #1
Hi Biju,

On Fri, Mar 24, 2023 at 11:02 AM Biju Das <biju.das.jz@bp.renesas.com> wrote:
> Add SCIF DMA rx support for RZ/G2L alike SoCs.
>
> RZ/G2L alike SoCs use the same signal for both interrupt and DMA transfer
> requests, so we must disable line interrupt while transferring DMA.
>
> We must set FIFO trigger to 1 so that SCIF will request DMA when there is
> a character as SCIF DMA request is based on FIFO data full RDF.
>
> Based on a patch in the BSP by Long Luu
> <long.luu.ur@renesas.com>
>
> Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>

Thanks for your patch!

> --- a/drivers/tty/serial/sh-sci.c
> +++ b/drivers/tty/serial/sh-sci.c
> @@ -1312,9 +1312,13 @@ static void sci_dma_rx_reenable_irq(struct sci_port *s)
>
>         /* Direct new serial port interrupts back to CPU */
>         scr = serial_port_in(port, SCSCR);
> -       if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
> -               scr &= ~SCSCR_RDRQE;
> +       if (port->type == PORT_SCIFA || port->type == PORT_SCIFB ||
> +           is_rz_scif_port(port, s)) {
>                 enable_irq(s->irqs[SCIx_RXI_IRQ]);
> +               if (port->type == PORT_SCIF)
> +                       scif_set_rtrg(port, s->rx_trigger);
> +               else
> +                       scr &= ~SCSCR_RDRQE;
>         }
>         serial_port_out(port, SCSCR, scr | SCSCR_RIE);
>  }
> @@ -1735,7 +1739,15 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
>                         if (sci_dma_rx_submit(s, false) < 0)
>                                 goto handle_pio;
>
> -                       scr &= ~SCSCR_RIE;
> +                       if (is_rz_scif_port(port, s)) {
> +                               /* Switch irq from SCIF to DMA */
> +                               disable_irq_nosync(s->irqs[SCIx_RXI_IRQ]);

Perhaps this can be combined with the disable_irq_nosync() above?

> +                               scif_set_rtrg(port, 1);
> +                               /* DMA need RIE enable */
> +                               scr |= SCSCR_RIE;
> +                       } else {
> +                               scr &= ~SCSCR_RIE;
> +                       }

... and this with some other SCIFA code path?

Looks like RZ/A2 and RZ/G2L "SCIFA" does have some resemblance with
SCIFA, contrary to earlier statements?
Perhaps the code can be simplified by treating it even more like
a SCIFA?

>                 }
>                 serial_port_out(port, SCSCR, scr);
>                 /* Clear current interrupt */

Gr{oetje,eeting}s,

                        Geert
Biju Das March 28, 2023, 3:36 p.m. UTC | #2
Hi Geert,

Thanks for the feedback.


> Subject: Re: [PATCH v2 3/3] tty: serial: sh-sci: Add RZ/G2L SCIF DMA rx
> support
> 
> Hi Biju,
> 
> On Fri, Mar 24, 2023 at 11:02 AM Biju Das <biju.das.jz@bp.renesas.com>
> wrote:
> > Add SCIF DMA rx support for RZ/G2L alike SoCs.
> >
> > RZ/G2L alike SoCs use the same signal for both interrupt and DMA
> > transfer requests, so we must disable line interrupt while transferring
> DMA.
> >
> > We must set FIFO trigger to 1 so that SCIF will request DMA when there
> > is a character as SCIF DMA request is based on FIFO data full RDF.
> >
> > Based on a patch in the BSP by Long Luu <long.luu.ur@renesas.com>
> >
> > Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
> 
> Thanks for your patch!
> 
> > --- a/drivers/tty/serial/sh-sci.c
> > +++ b/drivers/tty/serial/sh-sci.c
> > @@ -1312,9 +1312,13 @@ static void sci_dma_rx_reenable_irq(struct
> > sci_port *s)
> >
> >         /* Direct new serial port interrupts back to CPU */
> >         scr = serial_port_in(port, SCSCR);
> > -       if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
> > -               scr &= ~SCSCR_RDRQE;
> > +       if (port->type == PORT_SCIFA || port->type == PORT_SCIFB ||
> > +           is_rz_scif_port(port, s)) {
> >                 enable_irq(s->irqs[SCIx_RXI_IRQ]);
> > +               if (port->type == PORT_SCIF)
> > +                       scif_set_rtrg(port, s->rx_trigger);
> > +               else
> > +                       scr &= ~SCSCR_RDRQE;
> >         }
> >         serial_port_out(port, SCSCR, scr | SCSCR_RIE);  } @@ -1735,7
> > +1739,15 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
> >                         if (sci_dma_rx_submit(s, false) < 0)
> >                                 goto handle_pio;
> >
> > -                       scr &= ~SCSCR_RIE;
> > +                       if (is_rz_scif_port(port, s)) {
> > +                               /* Switch irq from SCIF to DMA */
> > +
> > + disable_irq_nosync(s->irqs[SCIx_RXI_IRQ]);
> 
> Perhaps this can be combined with the disable_irq_nosync() above?

OK, will do, As per Table 22.19 SCIFA Interrupt Sources, DMAC activation
Only possible with RXI interrupt.

So we need to use "s->irqs[SCIx_RXI_IRQ]" instead of "irq" for RZ/G2L SCIFA.


> 
> > +                               scif_set_rtrg(port, 1);
> > +                               /* DMA need RIE enable */
> > +                               scr |= SCSCR_RIE;
> > +                       } else {
> > +                               scr &= ~SCSCR_RIE;
> > +                       }
> 
> ... and this with some other SCIFA code path?

OK.

> 
> Looks like RZ/A2 and RZ/G2L "SCIFA" does have some resemblance with SCIFA,
> contrary to earlier statements?
> Perhaps the code can be simplified by treating it even more like a SCIFA?

Yes, new patch looks like

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 367bdb913d4a..146409e44556 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1299,9 +1299,13 @@ static void sci_dma_rx_reenable_irq(struct sci_port *s)
 
 	/* Direct new serial port interrupts back to CPU */
 	scr = serial_port_in(port, SCSCR);
-	if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
-		scr &= ~SCSCR_RDRQE;
+	if (port->type == PORT_SCIFA || port->type == PORT_SCIFB ||
+	    s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE) {
 		enable_irq(s->irqs[SCIx_RXI_IRQ]);
+		if (s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE)
+			scif_set_rtrg(port, s->rx_trigger);
+		else
+			scr &= ~SCSCR_RDRQE;
 	}
 	serial_port_out(port, SCSCR, scr | SCSCR_RIE);
 }
@@ -1538,7 +1542,8 @@ static enum hrtimer_restart sci_dma_rx_timer_fn(struct hrtimer *t)
 			tty_flip_buffer_push(&port->state->port);
 	}
 
-	if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
+	if (port->type == PORT_SCIFA || port->type == PORT_SCIFB ||
+	    s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE)
 		sci_dma_rx_submit(s, true);
 
 	sci_dma_rx_reenable_irq(s);
@@ -1662,7 +1667,8 @@ static void sci_request_dma(struct uart_port *port)
 
 		s->chan_rx_saved = s->chan_rx = chan;
 
-		if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
+		if (port->type == PORT_SCIFA || port->type == PORT_SCIFB ||
+		    s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE)
 			sci_dma_rx_submit(s, false);
 	}
 }
@@ -1715,9 +1721,16 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
 		u16 ssr = serial_port_in(port, SCxSR);
 
 		/* Disable future Rx interrupts */
-		if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
-			disable_irq_nosync(irq);
-			scr |= SCSCR_RDRQE;
+		if (port->type == PORT_SCIFA || port->type == PORT_SCIFB ||
+		    s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE) {
+			if (s->cfg->regtype != SCIx_RZ_SCIFA_REGTYPE) {
+				disable_irq_nosync(irq);
+				scr |= SCSCR_RDRQE;
+			} else {
+				disable_irq_nosync(s->irqs[SCIx_RXI_IRQ]);
+				scif_set_rtrg(port, 1);
+				scr |= SCSCR_RIE;
+			}
		} else {
 			if (sci_dma_rx_submit(s, false) < 0)
 				goto handle_pio;

Cheers,
Biju
> 
> >                 }
> >                 serial_port_out(port, SCSCR, scr);
> >                 /* Clear current interrupt */
> 
> Gr{oetje,eeting}s,
> 
>                         Geert
> 
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-
> m68k.org
> 
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like
> that.
>                                 -- Linus Torvalds
Geert Uytterhoeven March 28, 2023, 4:08 p.m. UTC | #3
Hi Biju,

On Tue, Mar 28, 2023 at 5:36 PM Biju Das <biju.das.jz@bp.renesas.com> wrote:
> > Subject: Re: [PATCH v2 3/3] tty: serial: sh-sci: Add RZ/G2L SCIF DMA rx
> > support
> > On Fri, Mar 24, 2023 at 11:02 AM Biju Das <biju.das.jz@bp.renesas.com>
> > wrote:
> > > Add SCIF DMA rx support for RZ/G2L alike SoCs.
> > >
> > > RZ/G2L alike SoCs use the same signal for both interrupt and DMA
> > > transfer requests, so we must disable line interrupt while transferring
> > DMA.
> > >
> > > We must set FIFO trigger to 1 so that SCIF will request DMA when there
> > > is a character as SCIF DMA request is based on FIFO data full RDF.
> > >
> > > Based on a patch in the BSP by Long Luu <long.luu.ur@renesas.com>
> > >
> > > Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
> >
> > Thanks for your patch!
> >
> > > --- a/drivers/tty/serial/sh-sci.c
> > > +++ b/drivers/tty/serial/sh-sci.c
> > > @@ -1312,9 +1312,13 @@ static void sci_dma_rx_reenable_irq(struct
> > > sci_port *s)
> > >
> > >         /* Direct new serial port interrupts back to CPU */
> > >         scr = serial_port_in(port, SCSCR);
> > > -       if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
> > > -               scr &= ~SCSCR_RDRQE;
> > > +       if (port->type == PORT_SCIFA || port->type == PORT_SCIFB ||
> > > +           is_rz_scif_port(port, s)) {
> > >                 enable_irq(s->irqs[SCIx_RXI_IRQ]);
> > > +               if (port->type == PORT_SCIF)
> > > +                       scif_set_rtrg(port, s->rx_trigger);
> > > +               else
> > > +                       scr &= ~SCSCR_RDRQE;
> > >         }
> > >         serial_port_out(port, SCSCR, scr | SCSCR_RIE);  } @@ -1735,7
> > > +1739,15 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
> > >                         if (sci_dma_rx_submit(s, false) < 0)
> > >                                 goto handle_pio;
> > >
> > > -                       scr &= ~SCSCR_RIE;
> > > +                       if (is_rz_scif_port(port, s)) {
> > > +                               /* Switch irq from SCIF to DMA */
> > > +
> > > + disable_irq_nosync(s->irqs[SCIx_RXI_IRQ]);
> >
> > Perhaps this can be combined with the disable_irq_nosync() above?
>
> OK, will do, As per Table 22.19 SCIFA Interrupt Sources, DMAC activation
> Only possible with RXI interrupt.
>
> So we need to use "s->irqs[SCIx_RXI_IRQ]" instead of "irq" for RZ/G2L SCIFA.
>
>
> >
> > > +                               scif_set_rtrg(port, 1);
> > > +                               /* DMA need RIE enable */
> > > +                               scr |= SCSCR_RIE;
> > > +                       } else {
> > > +                               scr &= ~SCSCR_RIE;
> > > +                       }
> >
> > ... and this with some other SCIFA code path?
>
> OK.
>
> >
> > Looks like RZ/A2 and RZ/G2L "SCIFA" does have some resemblance with SCIFA,
> > contrary to earlier statements?
> > Perhaps the code can be simplified by treating it even more like a SCIFA?
>
> Yes, new patch looks like
>
> diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
> index 367bdb913d4a..146409e44556 100644
> --- a/drivers/tty/serial/sh-sci.c
> +++ b/drivers/tty/serial/sh-sci.c
> @@ -1299,9 +1299,13 @@ static void sci_dma_rx_reenable_irq(struct sci_port *s)
>
>         /* Direct new serial port interrupts back to CPU */
>         scr = serial_port_in(port, SCSCR);
> -       if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
> -               scr &= ~SCSCR_RDRQE;
> +       if (port->type == PORT_SCIFA || port->type == PORT_SCIFB ||
> +           s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE) {
>                 enable_irq(s->irqs[SCIx_RXI_IRQ]);
> +               if (s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE)
> +                       scif_set_rtrg(port, s->rx_trigger);
> +               else
> +                       scr &= ~SCSCR_RDRQE;
>         }
>         serial_port_out(port, SCSCR, scr | SCSCR_RIE);
>  }
> @@ -1538,7 +1542,8 @@ static enum hrtimer_restart sci_dma_rx_timer_fn(struct hrtimer *t)
>                         tty_flip_buffer_push(&port->state->port);
>         }
>
> -       if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
> +       if (port->type == PORT_SCIFA || port->type == PORT_SCIFB ||
> +           s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE)
>                 sci_dma_rx_submit(s, true);
>
>         sci_dma_rx_reenable_irq(s);
> @@ -1662,7 +1667,8 @@ static void sci_request_dma(struct uart_port *port)
>
>                 s->chan_rx_saved = s->chan_rx = chan;
>
> -               if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
> +               if (port->type == PORT_SCIFA || port->type == PORT_SCIFB ||
> +                   s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE)
>                         sci_dma_rx_submit(s, false);
>         }
>  }
> @@ -1715,9 +1721,16 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
>                 u16 ssr = serial_port_in(port, SCxSR);
>
>                 /* Disable future Rx interrupts */
> -               if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
> -                       disable_irq_nosync(irq);
> -                       scr |= SCSCR_RDRQE;
> +               if (port->type == PORT_SCIFA || port->type == PORT_SCIFB ||
> +                   s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE) {
> +                       if (s->cfg->regtype != SCIx_RZ_SCIFA_REGTYPE) {

Please reverse order, and use "==", to match the flow in
sci_dma_rx_reenable_irq() above.

> +                               disable_irq_nosync(irq);

I think that can be s->irqs[SCIx_RXI_IRQ] unconditionally, i.e. outside
the if/else?

> +                               scr |= SCSCR_RDRQE;
> +                       } else {
> +                               disable_irq_nosync(s->irqs[SCIx_RXI_IRQ]);
> +                               scif_set_rtrg(port, 1);
> +                               scr |= SCSCR_RIE;
> +                       }
>                 } else {
>                         if (sci_dma_rx_submit(s, false) < 0)
>                                 goto handle_pio;

Gr{oetje,eeting}s,

                        Geert
Biju Das March 28, 2023, 4:21 p.m. UTC | #4
Hi Geert,

Thanks for the feedback.

> Subject: Re: [PATCH v2 3/3] tty: serial: sh-sci: Add RZ/G2L SCIF DMA rx
> support
> 
> Hi Biju,
> 
> On Tue, Mar 28, 2023 at 5:36 PM Biju Das <biju.das.jz@bp.renesas.com> wrote:
> > > Subject: Re: [PATCH v2 3/3] tty: serial: sh-sci: Add RZ/G2L SCIF DMA
> > > rx support On Fri, Mar 24, 2023 at 11:02 AM Biju Das
> > > <biju.das.jz@bp.renesas.com>
> > > wrote:
> > > > Add SCIF DMA rx support for RZ/G2L alike SoCs.
> > > >
> > > > RZ/G2L alike SoCs use the same signal for both interrupt and DMA
> > > > transfer requests, so we must disable line interrupt while
> > > > transferring
> > > DMA.
> > > >
> > > > We must set FIFO trigger to 1 so that SCIF will request DMA when
> > > > there is a character as SCIF DMA request is based on FIFO data full
> RDF.
> > > >
> > > > Based on a patch in the BSP by Long Luu <long.luu.ur@renesas.com>
> > > >
> > > > Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
> > >
> > > Thanks for your patch!
> > >
> > > > --- a/drivers/tty/serial/sh-sci.c
> > > > +++ b/drivers/tty/serial/sh-sci.c
> > > > @@ -1312,9 +1312,13 @@ static void sci_dma_rx_reenable_irq(struct
> > > > sci_port *s)
> > > >
> > > >         /* Direct new serial port interrupts back to CPU */
> > > >         scr = serial_port_in(port, SCSCR);
> > > > -       if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
> > > > -               scr &= ~SCSCR_RDRQE;
> > > > +       if (port->type == PORT_SCIFA || port->type == PORT_SCIFB ||
> > > > +           is_rz_scif_port(port, s)) {
> > > >                 enable_irq(s->irqs[SCIx_RXI_IRQ]);
> > > > +               if (port->type == PORT_SCIF)
> > > > +                       scif_set_rtrg(port, s->rx_trigger);
> > > > +               else
> > > > +                       scr &= ~SCSCR_RDRQE;
> > > >         }
> > > >         serial_port_out(port, SCSCR, scr | SCSCR_RIE);  } @@
> > > > -1735,7
> > > > +1739,15 @@ static irqreturn_t sci_rx_interrupt(int irq, void
> > > > +*ptr)
> > > >                         if (sci_dma_rx_submit(s, false) < 0)
> > > >                                 goto handle_pio;
> > > >
> > > > -                       scr &= ~SCSCR_RIE;
> > > > +                       if (is_rz_scif_port(port, s)) {
> > > > +                               /* Switch irq from SCIF to DMA */
> > > > +
> > > > + disable_irq_nosync(s->irqs[SCIx_RXI_IRQ]);
> > >
> > > Perhaps this can be combined with the disable_irq_nosync() above?
> >
> > OK, will do, As per Table 22.19 SCIFA Interrupt Sources, DMAC
> > activation Only possible with RXI interrupt.
> >
> > So we need to use "s->irqs[SCIx_RXI_IRQ]" instead of "irq" for RZ/G2L
> SCIFA.
> >
> >
> > >
> > > > +                               scif_set_rtrg(port, 1);
> > > > +                               /* DMA need RIE enable */
> > > > +                               scr |= SCSCR_RIE;
> > > > +                       } else {
> > > > +                               scr &= ~SCSCR_RIE;
> > > > +                       }
> > >
> > > ... and this with some other SCIFA code path?
> >
> > OK.
> >
> > >
> > > Looks like RZ/A2 and RZ/G2L "SCIFA" does have some resemblance with
> > > SCIFA, contrary to earlier statements?
> > > Perhaps the code can be simplified by treating it even more like a
> SCIFA?
> >
> > Yes, new patch looks like
> >
> > diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
> > index 367bdb913d4a..146409e44556 100644
> > --- a/drivers/tty/serial/sh-sci.c
> > +++ b/drivers/tty/serial/sh-sci.c
> > @@ -1299,9 +1299,13 @@ static void sci_dma_rx_reenable_irq(struct
> > sci_port *s)
> >
> >         /* Direct new serial port interrupts back to CPU */
> >         scr = serial_port_in(port, SCSCR);
> > -       if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
> > -               scr &= ~SCSCR_RDRQE;
> > +       if (port->type == PORT_SCIFA || port->type == PORT_SCIFB ||
> > +           s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE) {
> >                 enable_irq(s->irqs[SCIx_RXI_IRQ]);
> > +               if (s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE)
> > +                       scif_set_rtrg(port, s->rx_trigger);
> > +               else
> > +                       scr &= ~SCSCR_RDRQE;
> >         }
> >         serial_port_out(port, SCSCR, scr | SCSCR_RIE);  } @@ -1538,7
> > +1542,8 @@ static enum hrtimer_restart sci_dma_rx_timer_fn(struct hrtimer
> *t)
> >                         tty_flip_buffer_push(&port->state->port);
> >         }
> >
> > -       if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
> > +       if (port->type == PORT_SCIFA || port->type == PORT_SCIFB ||
> > +           s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE)
> >                 sci_dma_rx_submit(s, true);
> >
> >         sci_dma_rx_reenable_irq(s);
> > @@ -1662,7 +1667,8 @@ static void sci_request_dma(struct uart_port
> > *port)
> >
> >                 s->chan_rx_saved = s->chan_rx = chan;
> >
> > -               if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
> > +               if (port->type == PORT_SCIFA || port->type == PORT_SCIFB
> ||
> > +                   s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE)
> >                         sci_dma_rx_submit(s, false);
> >         }
> >  }
> > @@ -1715,9 +1721,16 @@ static irqreturn_t sci_rx_interrupt(int irq, void
> *ptr)
> >                 u16 ssr = serial_port_in(port, SCxSR);
> >
> >                 /* Disable future Rx interrupts */
> > -               if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
> {
> > -                       disable_irq_nosync(irq);
> > -                       scr |= SCSCR_RDRQE;
> > +               if (port->type == PORT_SCIFA || port->type == PORT_SCIFB
> ||
> > +                   s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE) {
> > +                       if (s->cfg->regtype != SCIx_RZ_SCIFA_REGTYPE)
> > + {
> 
> Please reverse order, and use "==", to match the flow in
> sci_dma_rx_reenable_irq() above.

OK.

> 
> > +                               disable_irq_nosync(irq);
> 
> I think that can be s->irqs[SCIx_RXI_IRQ] unconditionally, i.e. outside the
> if/else?

Ok. Will do.

Thanks and regards,
Biju

> 
> > +                               scr |= SCSCR_RDRQE;
> > +                       } else {
> > +                               disable_irq_nosync(s->irqs[SCIx_RXI_IRQ]);
> > +                               scif_set_rtrg(port, 1);
> > +                               scr |= SCSCR_RIE;
> > +                       }
> >                 } else {
> >                         if (sci_dma_rx_submit(s, false) < 0)
> >                                 goto handle_pio;
> 
> Gr{oetje,eeting}s,
> 
>                         Geert
> 
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-
> m68k.org
> 
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like
> that.
>                                 -- Linus Torvalds
diff mbox series

Patch

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 81797eb722cb..ce3d6af47759 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1312,9 +1312,13 @@  static void sci_dma_rx_reenable_irq(struct sci_port *s)
 
 	/* Direct new serial port interrupts back to CPU */
 	scr = serial_port_in(port, SCSCR);
-	if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
-		scr &= ~SCSCR_RDRQE;
+	if (port->type == PORT_SCIFA || port->type == PORT_SCIFB ||
+	    is_rz_scif_port(port, s)) {
 		enable_irq(s->irqs[SCIx_RXI_IRQ]);
+		if (port->type == PORT_SCIF)
+			scif_set_rtrg(port, s->rx_trigger);
+		else
+			scr &= ~SCSCR_RDRQE;
 	}
 	serial_port_out(port, SCSCR, scr | SCSCR_RIE);
 }
@@ -1735,7 +1739,15 @@  static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
 			if (sci_dma_rx_submit(s, false) < 0)
 				goto handle_pio;
 
-			scr &= ~SCSCR_RIE;
+			if (is_rz_scif_port(port, s)) {
+				/* Switch irq from SCIF to DMA */
+				disable_irq_nosync(s->irqs[SCIx_RXI_IRQ]);
+				scif_set_rtrg(port, 1);
+				/* DMA need RIE enable */
+				scr |= SCSCR_RIE;
+			} else {
+				scr &= ~SCSCR_RIE;
+			}
 		}
 		serial_port_out(port, SCSCR, scr);
 		/* Clear current interrupt */