Replace the .detect() connector_funcs callback with the atomic-aware
.detect_ctx() connector_helper_funcs hook.

This propagates the modeset acquire context through
drm_atomic_helper_connector_hdmi_hotplug_ctx() to the HDMI connector
framework, enabling SCDC state recovery via CRTC reset when the sink
reconnects during an active display pipeline.

Tested-by: Diederik de Haas <[email protected]>
Tested-by: Maud Spierings <[email protected]>
Reviewed-by: Dmitry Baryshkov <[email protected]>
Signed-off-by: Cristian Ciocaltea <[email protected]>
---
 drivers/gpu/drm/display/drm_bridge_connector.c | 74 ++++++++++++++------------
 1 file changed, 40 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c 
b/drivers/gpu/drm/display/drm_bridge_connector.c
index b69785eb49e2..47bb0dcf509f 100644
--- a/drivers/gpu/drm/display/drm_bridge_connector.c
+++ b/drivers/gpu/drm/display/drm_bridge_connector.c
@@ -208,39 +208,6 @@ static void drm_bridge_connector_disable_hpd(struct 
drm_connector *connector)
  * Bridge Connector Functions
  */
 
-static enum drm_connector_status
-drm_bridge_connector_detect(struct drm_connector *connector, bool force)
-{
-       struct drm_bridge_connector *bridge_connector =
-               to_drm_bridge_connector(connector);
-       struct drm_bridge *detect = bridge_connector->bridge_detect;
-       struct drm_bridge *hdmi = bridge_connector->bridge_hdmi;
-       enum drm_connector_status status;
-
-       if (detect) {
-               status = detect->funcs->detect(detect, connector);
-
-               if (hdmi)
-                       drm_atomic_helper_connector_hdmi_hotplug(connector, 
status);
-
-               drm_bridge_connector_hpd_notify(connector, status);
-       } else {
-               switch (connector->connector_type) {
-               case DRM_MODE_CONNECTOR_DPI:
-               case DRM_MODE_CONNECTOR_LVDS:
-               case DRM_MODE_CONNECTOR_DSI:
-               case DRM_MODE_CONNECTOR_eDP:
-                       status = connector_status_connected;
-                       break;
-               default:
-                       status = connector_status_unknown;
-                       break;
-               }
-       }
-
-       return status;
-}
-
 static void drm_bridge_connector_force(struct drm_connector *connector)
 {
        struct drm_bridge_connector *bridge_connector =
@@ -278,7 +245,6 @@ static void drm_bridge_connector_reset(struct drm_connector 
*connector)
 
 static const struct drm_connector_funcs drm_bridge_connector_funcs = {
        .reset = drm_bridge_connector_reset,
-       .detect = drm_bridge_connector_detect,
        .force = drm_bridge_connector_force,
        .fill_modes = drm_helper_probe_single_connector_modes,
        .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
@@ -291,6 +257,45 @@ static const struct drm_connector_funcs 
drm_bridge_connector_funcs = {
  * Bridge Connector Helper Functions
  */
 
+static int drm_bridge_connector_detect_ctx(struct drm_connector *connector,
+                                          struct drm_modeset_acquire_ctx *ctx,
+                                          bool force)
+{
+       struct drm_bridge_connector *bridge_connector =
+               to_drm_bridge_connector(connector);
+       struct drm_bridge *detect = bridge_connector->bridge_detect;
+       struct drm_bridge *hdmi = bridge_connector->bridge_hdmi;
+       enum drm_connector_status status;
+       int ret;
+
+       if (detect) {
+               status = detect->funcs->detect(detect, connector);
+
+               if (hdmi) {
+                       ret = 
drm_atomic_helper_connector_hdmi_hotplug_ctx(connector,
+                                                                          
status, ctx);
+                       if (ret == -EDEADLOCK)
+                               return ret;
+               }
+
+               drm_bridge_connector_hpd_notify(connector, status);
+       } else {
+               switch (connector->connector_type) {
+               case DRM_MODE_CONNECTOR_DPI:
+               case DRM_MODE_CONNECTOR_LVDS:
+               case DRM_MODE_CONNECTOR_DSI:
+               case DRM_MODE_CONNECTOR_eDP:
+                       status = connector_status_connected;
+                       break;
+               default:
+                       status = connector_status_unknown;
+                       break;
+               }
+       }
+
+       return status;
+}
+
 static int drm_bridge_connector_get_modes_edid(struct drm_connector *connector,
                                               struct drm_bridge *bridge)
 {
@@ -382,6 +387,7 @@ static int drm_bridge_connector_atomic_check(struct 
drm_connector *connector,
 
 static const struct drm_connector_helper_funcs 
drm_bridge_connector_helper_funcs = {
        .get_modes = drm_bridge_connector_get_modes,
+       .detect_ctx = drm_bridge_connector_detect_ctx,
        .mode_valid = drm_bridge_connector_mode_valid,
        .enable_hpd = drm_bridge_connector_enable_hpd,
        .disable_hpd = drm_bridge_connector_disable_hpd,

-- 
2.53.0

Reply via email to