[RFT PATCH v3 21/27] tty: serial: samsung_tty: IRQ rework

Andy Shevchenko andy.shevchenko at gmail.com
Fri Mar 5 15:17:54 GMT 2021


On Thu, Mar 4, 2021 at 11:41 PM Hector Martin <marcan at marcan.st> wrote:
>
> * Split out s3c24xx_serial_tx_chars from s3c24xx_serial_tx_irq,
>   where only the latter acquires the port lock. This will be necessary
>   on platforms which have edge-triggered IRQs, as we need to call
>   s3c24xx_serial_tx_chars to kick off transmission from outside IRQ
>   context, with the port lock held.
>
> * Rename s3c24xx_serial_rx_chars to s3c24xx_serial_rx_irq for
>   consistency with the above. All it does now is call two other
>   functions anyway.
>
> Signed-off-by: Hector Martin <marcan at marcan.st>
> ---
>  drivers/tty/serial/samsung_tty.c | 34 +++++++++++++++++++-------------
>  1 file changed, 20 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
> index 39b2eb165bdc..7106eb238d8c 100644
> --- a/drivers/tty/serial/samsung_tty.c
> +++ b/drivers/tty/serial/samsung_tty.c
> @@ -827,7 +827,7 @@ static irqreturn_t s3c24xx_serial_rx_chars_pio(void *dev_id)
>         return IRQ_HANDLED;
>  }
>
> -static irqreturn_t s3c24xx_serial_rx_chars(int irq, void *dev_id)
> +static irqreturn_t s3c24xx_serial_rx_irq(int irq, void *dev_id)
>  {
>         struct s3c24xx_uart_port *ourport = dev_id;
>
> @@ -836,16 +836,12 @@ static irqreturn_t s3c24xx_serial_rx_chars(int irq, void *dev_id)
>         return s3c24xx_serial_rx_chars_pio(dev_id);
>  }
>
> -static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
> +static void s3c24xx_serial_tx_chars(struct s3c24xx_uart_port *ourport)
>  {
> -       struct s3c24xx_uart_port *ourport = id;
>         struct uart_port *port = &ourport->port;
>         struct circ_buf *xmit = &port->state->xmit;
> -       unsigned long flags;
>         int count, dma_count = 0;
>
> -       spin_lock_irqsave(&port->lock, flags);
> -
>         count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
>
>         if (ourport->dma && ourport->dma->tx_chan &&
> @@ -862,7 +858,7 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
>                 wr_reg(port, S3C2410_UTXH, port->x_char);
>                 port->icount.tx++;
>                 port->x_char = 0;
> -               goto out;
> +               return;
>         }
>
>         /* if there isn't anything more to transmit, or the uart is now
> @@ -871,7 +867,7 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
>
>         if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
>                 s3c24xx_serial_stop_tx(port);
> -               goto out;
> +               return;
>         }
>
>         /* try and drain the buffer... */
> @@ -893,7 +889,7 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
>
>         if (!count && dma_count) {
>                 s3c24xx_serial_start_tx_dma(ourport, dma_count);
> -               goto out;
> +               return;
>         }
>
>         if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) {
> @@ -904,8 +900,18 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
>
>         if (uart_circ_empty(xmit))
>                 s3c24xx_serial_stop_tx(port);
> +}
> +
> +static irqreturn_t s3c24xx_serial_tx_irq(int irq, void *id)
> +{
> +       struct s3c24xx_uart_port *ourport = id;
> +       struct uart_port *port = &ourport->port;
> +       unsigned long flags;
> +


> +       spin_lock_irqsave(&port->lock, flags);
> +
> +       s3c24xx_serial_tx_chars(ourport);
>
> -out:
>         spin_unlock_irqrestore(&port->lock, flags);

Add a separate change that removes flags from the spin lock in the IRQ handler.

>         return IRQ_HANDLED;
>  }
> @@ -919,11 +925,11 @@ static irqreturn_t s3c64xx_serial_handle_irq(int irq, void *id)
>         irqreturn_t ret = IRQ_HANDLED;
>
>         if (pend & S3C64XX_UINTM_RXD_MSK) {
> -               ret = s3c24xx_serial_rx_chars(irq, id);
> +               ret = s3c24xx_serial_rx_irq(irq, id);
>                 wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_RXD_MSK);
>         }
>         if (pend & S3C64XX_UINTM_TXD_MSK) {
> -               ret = s3c24xx_serial_tx_chars(irq, id);
> +               ret = s3c24xx_serial_tx_irq(irq, id);
>                 wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_TXD_MSK);
>         }
>         return ret;
> @@ -1155,7 +1161,7 @@ static int s3c24xx_serial_startup(struct uart_port *port)
>
>         ourport->rx_enabled = 1;
>
> -       ret = request_irq(ourport->rx_irq, s3c24xx_serial_rx_chars, 0,
> +       ret = request_irq(ourport->rx_irq, s3c24xx_serial_rx_irq, 0,
>                           s3c24xx_serial_portname(port), ourport);
>
>         if (ret != 0) {
> @@ -1169,7 +1175,7 @@ static int s3c24xx_serial_startup(struct uart_port *port)
>
>         ourport->tx_enabled = 1;
>
> -       ret = request_irq(ourport->tx_irq, s3c24xx_serial_tx_chars, 0,
> +       ret = request_irq(ourport->tx_irq, s3c24xx_serial_tx_irq, 0,
>                           s3c24xx_serial_portname(port), ourport);
>
>         if (ret) {
> --
> 2.30.0
>


-- 
With Best Regards,
Andy Shevchenko



More information about the linux-arm-kernel mailing list