diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c index ab1667c20485..61017fea5cb3 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c @@ -3178,26 +3178,33 @@ void hdmi_frl_status_polling_work(struct work_struct *work) struct dc *dc = dm->dc; struct dc_link *dc_link; bool link_update = false; + bool link_detected; - for (int i = 0; i < MAX_LINKS; i++) { - dc_link = dc->links[i]; + /* Defer to the next cycle rather than block on a busy dc_lock. */ + if (mutex_trylock(&dm->dc_lock)) { + for (int i = 0; i < MAX_LINKS; i++) { + dc_link = dc->links[i]; + if (!dc_link || !dc_link->local_sink) + continue; - if (!dc_link || !dc_link->local_sink) - continue; + if (!dc_is_hdmi_signal(dc_link->connector_signal)) + continue; - if (!dc_is_hdmi_signal(dc_link->connector_signal)) - continue; + if (dc_link->frl_link_settings.frl_link_rate == 0) + continue; - if (dc_link->frl_link_settings.frl_link_rate == 0) - continue; - - link_update = dc_link_frl_poll_status_flag(dc_link); - if (link_update) { - mutex_lock(&dm->dc_lock); - dc_link_detect(dc_link, DETECT_REASON_RETRAIN); - mutex_unlock(&dm->dc_lock); + link_update = + dc_link_frl_poll_status_flag(dc_link); + if (link_update) { + link_detected = + dc_link_detect( + dc_link, DETECT_REASON_RETRAIN); + if (!link_detected) + DRM_ERROR("HDMI FRL retrain failed\n"); + } } + mutex_unlock(&dm->dc_lock); } queue_delayed_work(dm->hdmi_frl_status_polling_wq,