tty: serial: samsung_tty: Separate S3C64XX ops structure
authorHector Martin <marcan@marcan.st>
Thu, 4 Mar 2021 21:38:53 +0000 (06:38 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 10 Mar 2021 08:34:10 +0000 (09:34 +0100)
Instead of patching a single global ops structure depending on the port
type, use a separate s3c64xx_serial_ops for the S3C64XX type. This
allows us to mark the structures as const.

Also split out s3c64xx_serial_shutdown into a separate function now that
we have a separate ops structure; this avoids excessive branching
control flow and mirrors s3c64xx_serial_startup. tx_claimed and
rx_claimed are only used in the S3C24XX functions.

Signed-off-by: Hector Martin <marcan@marcan.st>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
Tested-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
Link: https://lore.kernel.org/r/20210304213902.83903-19-marcan@marcan.st
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/samsung_tty.c

index 30adb15..33b421d 100644 (file)
@@ -1099,27 +1099,36 @@ static void s3c24xx_serial_shutdown(struct uart_port *port)
        struct s3c24xx_uart_port *ourport = to_ourport(port);
 
        if (ourport->tx_claimed) {
-               if (!s3c24xx_serial_has_interrupt_mask(port))
-                       free_irq(ourport->tx_irq, ourport);
+               free_irq(ourport->tx_irq, ourport);
                ourport->tx_enabled = 0;
                ourport->tx_claimed = 0;
                ourport->tx_mode = 0;
        }
 
        if (ourport->rx_claimed) {
-               if (!s3c24xx_serial_has_interrupt_mask(port))
-                       free_irq(ourport->rx_irq, ourport);
+               free_irq(ourport->rx_irq, ourport);
                ourport->rx_claimed = 0;
                ourport->rx_enabled = 0;
        }
 
-       /* Clear pending interrupts and mask all interrupts */
-       if (s3c24xx_serial_has_interrupt_mask(port)) {
-               free_irq(port->irq, ourport);
+       if (ourport->dma)
+               s3c24xx_serial_release_dma(ourport);
 
-               wr_regl(port, S3C64XX_UINTP, 0xf);
-               wr_regl(port, S3C64XX_UINTM, 0xf);
-       }
+       ourport->tx_in_progress = 0;
+}
+
+static void s3c64xx_serial_shutdown(struct uart_port *port)
+{
+       struct s3c24xx_uart_port *ourport = to_ourport(port);
+
+       ourport->tx_enabled = 0;
+       ourport->tx_mode = 0;
+       ourport->rx_enabled = 0;
+
+       free_irq(port->irq, ourport);
+
+       wr_regl(port, S3C64XX_UINTP, 0xf);
+       wr_regl(port, S3C64XX_UINTM, 0xf);
 
        if (ourport->dma)
                s3c24xx_serial_release_dma(ourport);
@@ -1194,9 +1203,7 @@ static int s3c64xx_serial_startup(struct uart_port *port)
 
        /* For compatibility with s3c24xx Soc's */
        ourport->rx_enabled = 1;
-       ourport->rx_claimed = 1;
        ourport->tx_enabled = 0;
-       ourport->tx_claimed = 1;
 
        spin_lock_irqsave(&port->lock, flags);
 
@@ -1609,7 +1616,7 @@ static void s3c24xx_serial_put_poll_char(struct uart_port *port,
                         unsigned char c);
 #endif
 
-static struct uart_ops s3c24xx_serial_ops = {
+static const struct uart_ops s3c24xx_serial_ops = {
        .pm             = s3c24xx_serial_pm,
        .tx_empty       = s3c24xx_serial_tx_empty,
        .get_mctrl      = s3c24xx_serial_get_mctrl,
@@ -1632,6 +1639,29 @@ static struct uart_ops s3c24xx_serial_ops = {
 #endif
 };
 
+static const struct uart_ops s3c64xx_serial_ops = {
+       .pm             = s3c24xx_serial_pm,
+       .tx_empty       = s3c24xx_serial_tx_empty,
+       .get_mctrl      = s3c24xx_serial_get_mctrl,
+       .set_mctrl      = s3c24xx_serial_set_mctrl,
+       .stop_tx        = s3c24xx_serial_stop_tx,
+       .start_tx       = s3c24xx_serial_start_tx,
+       .stop_rx        = s3c24xx_serial_stop_rx,
+       .break_ctl      = s3c24xx_serial_break_ctl,
+       .startup        = s3c64xx_serial_startup,
+       .shutdown       = s3c64xx_serial_shutdown,
+       .set_termios    = s3c24xx_serial_set_termios,
+       .type           = s3c24xx_serial_type,
+       .release_port   = s3c24xx_serial_release_port,
+       .request_port   = s3c24xx_serial_request_port,
+       .config_port    = s3c24xx_serial_config_port,
+       .verify_port    = s3c24xx_serial_verify_port,
+#if defined(CONFIG_SERIAL_SAMSUNG_CONSOLE) && defined(CONFIG_CONSOLE_POLL)
+       .poll_get_char = s3c24xx_serial_get_poll_char,
+       .poll_put_char = s3c24xx_serial_put_poll_char,
+#endif
+};
+
 static struct uart_driver s3c24xx_uart_drv = {
        .owner          = THIS_MODULE,
        .driver_name    = "s3c2410_serial",
@@ -1864,10 +1894,6 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
        /* setup info for port */
        port->dev       = &platdev->dev;
 
-       /* Startup sequence is different for s3c64xx and higher SoC's */
-       if (s3c24xx_serial_has_interrupt_mask(port))
-               s3c24xx_serial_ops.startup = s3c64xx_serial_startup;
-
        port->uartclk = 1;
 
        if (cfg->uart_flags & UPF_CONS_FLOW) {
@@ -2015,6 +2041,17 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
                        dev_get_platdata(&pdev->dev) :
                        ourport->drv_data->def_cfg;
 
+       switch (ourport->info->type) {
+       case PORT_S3C2410:
+       case PORT_S3C2412:
+       case PORT_S3C2440:
+               ourport->port.ops = &s3c24xx_serial_ops;
+               break;
+       case PORT_S3C6400:
+               ourport->port.ops = &s3c64xx_serial_ops;
+               break;
+       }
+
        if (np) {
                of_property_read_u32(np,
                        "samsung,uart-fifosize", &ourport->port.fifosize);