serial: qcom_geni: Add shutdown callback to quiesce hardware on reboot

During system reboot, an active UART DMA transfer can leave the GENI
Serial Engine in an indeterminate state. On VM-based platforms, if a
DMA transfer is in progress when the VM is shut down, the SMMU can
raise context faults as the DMA engine continues to access IOVAs that
have already been invalidated during VM teardown.

Add a shutdown callback to stop TX and RX and bring the hardware to
idle before the system resets, preventing both hardware state corruption
on reboot and SMMU faults during VM shutdown. The port lock is not taken
here since shutdown runs from process context with the device already
quiesced from the UART core's perspective; instead, the runtime PM status
is checked so that TX/RX are only stopped while clocks and resources are
still active, avoiding any register access once the device is runtime
suspended.

Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
Link: https://patch.msgid.link/20260715-add_shutdown_and_panic_notifier_serial-v1-1-23e3787c7109@oss.qualcomm.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Praveen Talari 2026-07-15 09:55:14 +05:30 committed by Greg Kroah-Hartman
parent 6e5bd7cc3a
commit dbe2afb952

View File

@ -2112,6 +2112,18 @@ static const struct dev_pm_ops qcom_geni_serial_pm_ops = {
SYSTEM_SLEEP_PM_OPS(qcom_geni_serial_suspend, qcom_geni_serial_resume)
};
static void qcom_geni_serial_sys_shutdown(struct platform_device *pdev)
{
struct qcom_geni_serial_port *port = platform_get_drvdata(pdev);
struct uart_port *uport = &port->uport;
if (pm_runtime_status_suspended(uport->dev))
return;
qcom_geni_serial_stop_tx(uport);
qcom_geni_serial_stop_rx(uport);
}
static const struct of_device_id qcom_geni_serial_match_table[] = {
#if IS_ENABLED(CONFIG_SERIAL_QCOM_GENI_CONSOLE)
{
@ -2138,6 +2150,7 @@ MODULE_DEVICE_TABLE(of, qcom_geni_serial_match_table);
static struct platform_driver qcom_geni_serial_platform_driver = {
.remove = qcom_geni_serial_remove,
.probe = qcom_geni_serial_probe,
.shutdown = qcom_geni_serial_sys_shutdown,
.driver = {
.name = "qcom_geni_serial",
.of_match_table = qcom_geni_serial_match_table,