Request the RX mailbox only after initializing the UART data structures. Otherwise it can rarely happen that the receive callback is called before the UART is ready. Fixes: 2d908b38d409 ("serial: Add Tegra Combined UART driver") Signed-off-by: Mikko Perttunen <mperttunen@xxxxxxxxxx> --- drivers/tty/serial/tegra-tcu.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/drivers/tty/serial/tegra-tcu.c b/drivers/tty/serial/tegra-tcu.c index 52687c65ad74..4877c54c613d 100644 --- a/drivers/tty/serial/tegra-tcu.c +++ b/drivers/tty/serial/tegra-tcu.c @@ -195,13 +195,6 @@ static int tegra_tcu_probe(struct platform_device *pdev) return err; } - tcu->rx = mbox_request_channel_byname(&tcu->rx_client, "rx"); - if (IS_ERR(tcu->rx)) { - err = PTR_ERR(tcu->rx); - dev_err(&pdev->dev, "failed to get rx mailbox: %d\n", err); - goto free_tx; - } - #if IS_ENABLED(CONFIG_SERIAL_TEGRA_TCU_CONSOLE) /* setup the console */ strcpy(tcu->console.name, "ttyTCU"); @@ -226,7 +219,7 @@ static int tegra_tcu_probe(struct platform_device *pdev) if (err) { dev_err(&pdev->dev, "failed to register UART driver: %d\n", err); - goto free_rx; + goto free_tx; } /* setup the port */ @@ -246,6 +239,17 @@ static int tegra_tcu_probe(struct platform_device *pdev) goto unregister_uart; } + /* + * Request RX channel after creating port to ensure tcu->port + * is ready for any immediate incoming bytes. + */ + tcu->rx = mbox_request_channel_byname(&tcu->rx_client, "rx"); + if (IS_ERR(tcu->rx)) { + err = PTR_ERR(tcu->rx); + dev_err(&pdev->dev, "failed to get rx mailbox: %d\n", err); + goto remove_uart_port; + } + platform_set_drvdata(pdev, tcu); #if IS_ENABLED(CONFIG_SERIAL_TEGRA_TCU_CONSOLE) register_console(&tcu->console); @@ -253,10 +257,10 @@ static int tegra_tcu_probe(struct platform_device *pdev) return 0; +remove_uart_port: + uart_remove_one_port(&tcu->driver, &tcu->port); unregister_uart: uart_unregister_driver(&tcu->driver); -free_rx: - mbox_free_channel(tcu->rx); free_tx: mbox_free_channel(tcu->tx); @@ -270,9 +274,9 @@ static int tegra_tcu_remove(struct platform_device *pdev) #if IS_ENABLED(CONFIG_SERIAL_TEGRA_TCU_CONSOLE) unregister_console(&tcu->console); #endif + mbox_free_channel(tcu->rx); uart_remove_one_port(&tcu->driver, &tcu->port); uart_unregister_driver(&tcu->driver); - mbox_free_channel(tcu->rx); mbox_free_channel(tcu->tx); return 0; -- 2.30.1