serial: tegra-tcu: Reorder channel initialization

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: 2d908b38d4 ("serial: Add Tegra Combined UART driver")
Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
Link: https://lore.kernel.org/r/20210609155655.3567545-1-mperttunen@nvidia.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Mikko Perttunen 2021-06-09 18:56:55 +03:00 committed by Greg Kroah-Hartman
parent 08a84410a0
commit af9a1f61ac

View File

@ -195,13 +195,6 @@ static int tegra_tcu_probe(struct platform_device *pdev)
return err; 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) #if IS_ENABLED(CONFIG_SERIAL_TEGRA_TCU_CONSOLE)
/* setup the console */ /* setup the console */
strcpy(tcu->console.name, "ttyTCU"); strcpy(tcu->console.name, "ttyTCU");
@ -226,7 +219,7 @@ static int tegra_tcu_probe(struct platform_device *pdev)
if (err) { if (err) {
dev_err(&pdev->dev, "failed to register UART driver: %d\n", dev_err(&pdev->dev, "failed to register UART driver: %d\n",
err); err);
goto free_rx; goto free_tx;
} }
/* setup the port */ /* setup the port */
@ -246,6 +239,17 @@ static int tegra_tcu_probe(struct platform_device *pdev)
goto unregister_uart; 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); platform_set_drvdata(pdev, tcu);
#if IS_ENABLED(CONFIG_SERIAL_TEGRA_TCU_CONSOLE) #if IS_ENABLED(CONFIG_SERIAL_TEGRA_TCU_CONSOLE)
register_console(&tcu->console); register_console(&tcu->console);
@ -253,10 +257,10 @@ static int tegra_tcu_probe(struct platform_device *pdev)
return 0; return 0;
remove_uart_port:
uart_remove_one_port(&tcu->driver, &tcu->port);
unregister_uart: unregister_uart:
uart_unregister_driver(&tcu->driver); uart_unregister_driver(&tcu->driver);
free_rx:
mbox_free_channel(tcu->rx);
free_tx: free_tx:
mbox_free_channel(tcu->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) #if IS_ENABLED(CONFIG_SERIAL_TEGRA_TCU_CONSOLE)
unregister_console(&tcu->console); unregister_console(&tcu->console);
#endif #endif
mbox_free_channel(tcu->rx);
uart_remove_one_port(&tcu->driver, &tcu->port); uart_remove_one_port(&tcu->driver, &tcu->port);
uart_unregister_driver(&tcu->driver); uart_unregister_driver(&tcu->driver);
mbox_free_channel(tcu->rx);
mbox_free_channel(tcu->tx); mbox_free_channel(tcu->tx);
return 0; return 0;