由于提前返回引起的待机状态下唤醒 HDMI 无输出 概述 为解决 RTC 定时唤醒(ALARM_EVENT)时 HDMI PHY 异常上电,在 rtk_drm_resume() 和 rtk_hdmi_resume() 中加入 ALARM_EVENT 判断后提前 return 0。这把 RTC 静默唤醒本身的 HDMI 上电问题解决了,但提前返回跳过了 resume 路径中的关键配对操作,导致跨 suspend/resume 周期的状态污染——下次手动唤醒时 HDMI 概率无输出。
经日志验证(等待一次RTC唤醒,然后重新进入待机后,手动退出待机后HDMI无输出.txt),问题稳定复现。
drm_mode_config_helper_resume() 源码 rtk_drm_resume() 通过调用此函数完成 DRM 层 resume。以下为内核源码(drm_modeset_helper.c),ALARM 路径的裸 return 0 跳过了这个函数的全部三步操作。同时贴上对应的 suspend 函数作为配对参考。
/* drm_modeset_helper.c L195-223 */ int drm_mode_config_helper_suspend(struct drm_device *dev) { struct drm_atomic_state *state; if (!dev) return 0; if (dev->mode_config.poll_enabled) drm_kms_helper_poll_disable(dev); // ③ 配对: poll_disable drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 1); // ② 配对: fb→SUSPENDED state = drm_atomic_helper_suspend(dev); // ① 配对: 分配 state if (IS_ERR(state)) { drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 0); if (dev->mode_config.poll_enabled) drm_kms_helper_poll_enable(dev); return PTR_ERR(state); } dev->mode_config.suspend_state = state; return 0; } /* drm_modeset_helper.c L240-263 */ int drm_mode_config_helper_resume(struct drm_device *dev) { int ret; if (!dev) return 0; if (WARN_ON(!dev->mode_config.suspend_state)) return -EINVAL; // 步骤 ①: 恢复原子状态 + 释放内存 ret = drm_atomic_helper_resume(dev, dev->mode_config.suspend_state); if (ret) DRM_ERROR("Failed to resume (%d)\n", ret); dev->mode_config.suspend_state = NULL; // 步骤 ②: 恢复 fbdev drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 0); // 步骤 ③: 恢复输出轮询 if (dev->mode_config.poll_enabled) drm_kms_helper_poll_enable(dev); return ret; } suspend 和 resume 的配对关系:
...