drm/amd/display: Fix refcount over dc_sink.
authorAndrey Grodzovsky <Andrey.Grodzovsky@amd.com>
Wed, 7 Dec 2016 19:10:05 +0000 (14:10 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 26 Sep 2017 21:04:38 +0000 (17:04 -0400)
Retain a dc_sink pointer until a new physical pointer
arrives in case of new display connected.

Signed-off-by: Andrey Grodzovsky <Andrey.Grodzovsky@amd.com>
Reviewed-by: Andrey Grodzovsky <Andrey.Grodzovsky@amd.com>
Acked-by: Harry Wentland <Harry.Wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c

index 396dbd6611831c5385d01b89024e1e62a961a65e..e5ba23253814ea649336b3be2f653652ba2d263c 100644 (file)
@@ -737,9 +737,17 @@ void amdgpu_dm_update_connector_after_detect(
                mutex_lock(&dev->mode_config.mutex);
 
                if (sink) {
-                       if (aconnector->dc_sink)
+                       if (aconnector->dc_sink) {
                                amdgpu_dm_remove_sink_from_freesync_module(
                                                                connector);
+                               /* retain and release bellow are used for
+                                * bump up refcount for sink because the link don't point
+                                * to it anymore after disconnect so on next crtc to connector
+                                * reshuffle by UMD we will get into unwanted dc_sink release
+                                */
+                               if (aconnector->dc_sink != aconnector->dc_em_sink)
+                                       dc_sink_release(aconnector->dc_sink);
+                       }
                        aconnector->dc_sink = sink;
                        amdgpu_dm_add_sink_to_freesync_module(
                                                connector, aconnector->edid);
@@ -747,6 +755,8 @@ void amdgpu_dm_update_connector_after_detect(
                        amdgpu_dm_remove_sink_from_freesync_module(connector);
                        if (!aconnector->dc_sink)
                                aconnector->dc_sink = aconnector->dc_em_sink;
+                       else if (aconnector->dc_sink != aconnector->dc_em_sink)
+                               dc_sink_retain(aconnector->dc_sink);
                }
 
                mutex_unlock(&dev->mode_config.mutex);