mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 20:54:03 +02:00
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:
parent
6e5bd7cc3a
commit
dbe2afb952
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user