fsl_lpuart: Don't enable interrupts too early
authorIndan Zupancic <Indan.Zupancic@mep-info.com>
Thu, 5 May 2022 11:47:50 +0000 (13:47 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 18 May 2022 08:26:55 +0000 (10:26 +0200)
commit 401fb66a355eb0f22096cf26864324f8e63c7d78 upstream.

If an irq is pending when devm_request_irq() is called, the irq
handler will cause a NULL pointer access because initialisation
is not done yet.

Fixes: 9d7ee0e28da59 ("tty: serial: lpuart: avoid report NULL interrupt")
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Indan Zupancic <Indan.Zupancic@mep-info.com>
Link: https://lore.kernel.org/r/20220505114750.45423-1-Indan.Zupancic@mep-info.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/fsl_lpuart.c

index ac5112def40d1df35d93ef8eb453fe9d3884d95c..33e5eba6ff043edfb71b4b4e2825f00321873774 100644 (file)
@@ -2650,6 +2650,7 @@ static int lpuart_probe(struct platform_device *pdev)
        struct device_node *np = pdev->dev.of_node;
        struct lpuart_port *sport;
        struct resource *res;
+       irq_handler_t handler;
        int ret;
 
        sport = devm_kzalloc(&pdev->dev, sizeof(*sport), GFP_KERNEL);
@@ -2727,17 +2728,11 @@ static int lpuart_probe(struct platform_device *pdev)
 
        if (lpuart_is_32(sport)) {
                lpuart_reg.cons = LPUART32_CONSOLE;
-               ret = devm_request_irq(&pdev->dev, sport->port.irq, lpuart32_int, 0,
-                                       DRIVER_NAME, sport);
+               handler = lpuart32_int;
        } else {
                lpuart_reg.cons = LPUART_CONSOLE;
-               ret = devm_request_irq(&pdev->dev, sport->port.irq, lpuart_int, 0,
-                                       DRIVER_NAME, sport);
+               handler = lpuart_int;
        }
-
-       if (ret)
-               goto failed_irq_request;
-
        ret = uart_add_one_port(&lpuart_reg, &sport->port);
        if (ret)
                goto failed_attach_port;
@@ -2759,13 +2754,18 @@ static int lpuart_probe(struct platform_device *pdev)
 
        sport->port.rs485_config(&sport->port, &sport->port.rs485);
 
+       ret = devm_request_irq(&pdev->dev, sport->port.irq, handler, 0,
+                               DRIVER_NAME, sport);
+       if (ret)
+               goto failed_irq_request;
+
        return 0;
 
+failed_irq_request:
 failed_get_rs485:
 failed_reset:
        uart_remove_one_port(&lpuart_reg, &sport->port);
 failed_attach_port:
-failed_irq_request:
        lpuart_disable_clks(sport);
 failed_clock_enable:
 failed_out_of_range: