summaryrefslogtreecommitdiff
path: root/drivers/tty/serial
diff options
context:
space:
mode:
authorPraveen Talari <praveen.talari@oss.qualcomm.com>2026-07-15 09:55:14 +0530
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-07-17 13:02:19 +0200
commitdbe2afb952bdb782450d8f678adeb502791e7edd (patch)
tree4eec3bb8c6f059c3dd195bb6448e652a7f3c9f6d /drivers/tty/serial
parent6e5bd7cc3a2f304a66d294011647d82074421979 (diff)
downloadlinux-next-dbe2afb952bdb782450d8f678adeb502791e7edd.tar.gz
linux-next-dbe2afb952bdb782450d8f678adeb502791e7edd.zip
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>
Diffstat (limited to 'drivers/tty/serial')
-rw-r--r--drivers/tty/serial/qcom_geni_serial.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index 751738f848ad..04e1227390dd 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -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,