MLK-16357 tty: serial: lpuart: avoid report NULL interrupt
authorFugang Duan <fugang.duan@nxp.com>
Fri, 15 Sep 2017 10:50:43 +0000 (18:50 +0800)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 20:38:35 +0000 (15:38 -0500)
The current driver register irq in .startup() and free the irq in
.shutdown(), then user will see the NULL interrupt output from
'cat /proc/interrupts' after the uart port test completed:
...
 41:        515          0          0          0     GICv3 257 Level     fsl-lpuart
 42:          2          0          0          0     GICv3 258 Level
...

It is better to register all the irqs during probe function via devm_request_irq()
to avoid to call free_irq().

(BuildInfo: SCFW 3e70523d, IMX-MKIMAGE 0, ATF 0)

Signed-off-by: Fugang Duan <fugang.duan@nxp.com>
Reviewed-by: Richard Zhu <hongxing.zhu@nxp.com>
drivers/tty/serial/fsl_lpuart.c

index 40569a7..3b6cbc4 100644 (file)
@@ -1307,11 +1307,6 @@ static int lpuart_startup(struct uart_port *port)
        } else
                sport->lpuart_dma_tx_use = false;
 
-       ret = devm_request_irq(port->dev, port->irq, lpuart_int, 0,
-                               DRIVER_NAME, sport);
-       if (ret)
-               return ret;
-
        spin_lock_irqsave(&sport->port.lock, flags);
 
        lpuart_setup_watermark(sport);
@@ -1383,11 +1378,6 @@ static int lpuart32_startup(struct uart_port *port)
        } else
                sport->lpuart_dma_tx_use = false;
 
-       ret = devm_request_irq(port->dev, port->irq, lpuart32_int, 0,
-                               DRIVER_NAME, sport);
-       if (ret)
-               return ret;
-
        spin_lock_irqsave(&sport->port.lock, flags);
 
        lpuart32_setup_watermark(sport);
@@ -1419,8 +1409,6 @@ static void lpuart_shutdown(struct uart_port *port)
 
        spin_unlock_irqrestore(&port->lock, flags);
 
-       devm_free_irq(port->dev, port->irq, sport);
-
        if (sport->lpuart_dma_rx_use) {
                ret = wait_event_interruptible_timeout(sport->dma_wait,
                        !sport->dma_rx_in_progress, msecs_to_jiffies(1));
@@ -1472,8 +1460,6 @@ static void lpuart32_shutdown(struct uart_port *port)
 
        spin_unlock_irqrestore(&port->lock, flags);
 
-       devm_free_irq(port->dev, port->irq, sport);
-
        if (sport->lpuart_dma_rx_use) {
                ret = wait_event_interruptible_timeout(sport->dma_wait,
                        !sport->dma_rx_in_progress, msecs_to_jiffies(1));
@@ -2275,17 +2261,22 @@ static int lpuart_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, &sport->port);
 
-       if (sport->lpuart32)
+       if (sport->lpuart32) {
                lpuart_reg.cons = LPUART32_CONSOLE;
-       else
+               ret = devm_request_irq(&pdev->dev, sport->port.irq, lpuart32_int, 0,
+                                       DRIVER_NAME, sport);
+       } else {
                lpuart_reg.cons = LPUART_CONSOLE;
+               ret = devm_request_irq(&pdev->dev, sport->port.irq, lpuart_int, 0,
+                                       DRIVER_NAME, sport);
+       }
+
+       if (ret)
+               goto failed_irq_request;
 
        ret = uart_add_one_port(&lpuart_reg, &sport->port);
-       if (ret) {
-               clk_disable_unprepare(sport->per_clk);
-               clk_disable_unprepare(sport->ipg_clk);
-               return ret;
-       }
+       if (ret)
+               goto failed_attach_port;
 
        sport->dma_tx_chan = dma_request_slave_channel(sport->port.dev, "tx");
        if (!sport->dma_tx_chan)
@@ -2302,9 +2293,11 @@ static int lpuart_probe(struct platform_device *pdev)
                writeb(UARTMODEM_TXRTSE, sport->port.membase + UARTMODEM);
        }
 
+failed_attach_port:
+failed_irq_request:
        clk_disable_unprepare(sport->per_clk);
        clk_disable_unprepare(sport->ipg_clk);
-       return 0;
+       return ret;
 }
 
 static int lpuart_remove(struct platform_device *pdev)