drm_atomic_helper_shutdown() disables all CRTCs but leaves output polling and IRQ-driven hot-plug detection running. On reboot, a late DP hot-plug-detect (HPD) IRQ can fire after apps_smmu has already disabled translation for the display subsystem, causing the HPD thread to kick off a new modeset that drives DPU/DP hardware and DMA through a stale IOMMU mapping.
drm_atomic_helper_shutdown() disables all CRTCs first, but a pending HPD IRQ thread wakes up afterwards, reads the DPCD, and fires an unsolicited hotplug event that triggers a second atomic commit turning the display back on -- right as the IOMMU is disabling translation: systemd-shutdown[1]: Rebooting. msm_dpu: drm_atomic_commit: committing (shutdown disabling CRTCs) arm-smmu 3da0000.iommu: disabling translation msm_dpu: drm_dp_read_dpcd_caps (late HPD IRQ thread wakes up) msm_dpu: drm_sysfs_connector_hotplug_event: DP-1 hotplug event msm_dpu: drm_client_modeset_probe: DP-1 found preferred mode msm_dpu: drm_atomic_commit: committing (unsolicited, re-enables display) dpu_crtc_commit_kickoff: crtc94 first commit arm-smmu 15200000.iommu: disabling translation drm_kms_helper_poll_fini() tears down this: it stops the output poll worker and calls each connector's &drm_connector_helper_funcs.disable_hpd, which for HPD-capable bridges masks the interrupt in hardware. Reported on Qualcomm platforms such as lemans-evk and monaco-evk during reboot stress testing. Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Mahadevan P <[email protected]> --- Changes in v2: - Dropped the drm/msm/dp local .shutdown patch (disable_irq()/ synchronize_irq() in dp_display.c)., fixed this at the DRM core level instead so every driver benefits, not just msm_dp.(Dmitry). - Link to v1: https://lore.kernel.org/r/[email protected] --- drivers/gpu/drm/drm_atomic_helper.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 285aac3554df..80c67623180a 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -43,6 +43,7 @@ #include <drm/drm_gem_atomic_helper.h> #include <drm/drm_panic.h> #include <drm/drm_print.h> +#include <drm/drm_probe_helper.h> #include <drm/drm_self_refresh_helper.h> #include <drm/drm_vblank.h> #include <drm/drm_writeback.h> @@ -3676,6 +3677,8 @@ EXPORT_SYMBOL(drm_atomic_helper_reset_crtc); * * This is just a convenience wrapper around drm_atomic_helper_disable_all(), * and it is the atomic version of drm_helper_force_disable_all(). + * + * This also tears down output polling and HPD via drm_kms_helper_poll_fini(). */ void drm_atomic_helper_shutdown(struct drm_device *dev) { @@ -3685,6 +3688,8 @@ void drm_atomic_helper_shutdown(struct drm_device *dev) if (dev == NULL) return; + drm_kms_helper_poll_fini(dev); + DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret); ret = drm_atomic_helper_disable_all(dev, &ctx); --- base-commit: 1a1757b76427f6201bfe0bf1bea9f7574f332a93 change-id: 20260717-dpshutdown-047912fcf60b Best regards, -- Mahadevan P <[email protected]>
