The connector created by drm_bridge_connector_init() only gets
DRM_CONNECTOR_POLL_HPD when a bridge in the chain declares
DRM_BRIDGE_OP_HPD.  Without it, the HPD events reported from the IRQ
thread were silently dropped and the connection state was only
refreshed by the periodic poll worker.

Declare DRM_BRIDGE_OP_HPD on the Analogix DP bridge, implement the
no-op .hpd_enable/.hpd_disable callbacks, and report the hotplug
events via drm_bridge_hpd_notify() with the status read from the
hardware.

Signed-off-by: Damon Ding <[email protected]>
---
 .../drm/bridge/analogix/analogix_dp_core.c    | 22 +++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 009567da5f17..938c70dc8e15 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -31,7 +31,6 @@
 #include <drm/drm_edid.h>
 #include <drm/drm_of.h>
 #include <drm/drm_print.h>
-#include <drm/drm_probe_helper.h>
 
 #include <video/of_display_timing.h>
 
@@ -741,9 +740,13 @@ static irqreturn_t analogix_dp_irq_thread(int irq, void 
*arg)
                hpd_detected = (irq_type & DP_IRQ_TYPE_HP_CABLE_IN) ||
                               (irq_type & DP_IRQ_TYPE_HP_CABLE_OUT);
        if (hpd_detected) {
+               enum drm_connector_status status;
+
                dev_dbg(dp->dev, "Detected cable status changed!\n");
-               if (dp->drm_dev)
-                       drm_helper_hpd_irq_event(dp->drm_dev);
+
+               status = analogix_dp_get_plug_in_status(dp) == 0 ? 
connector_status_connected :
+                                                                  
connector_status_disconnected;
+               drm_bridge_hpd_notify(&dp->bridge, status);
        }
 
        pm_runtime_mark_last_busy(dp->dev);
@@ -1280,6 +1283,14 @@ static void 
analogix_dp_bridge_atomic_post_disable(struct drm_bridge *bridge,
                DRM_ERROR("Failed to enable psr (%d)\n", ret);
 }
 
+static void analogix_dp_bridge_hpd_enable(struct drm_bridge *bridge)
+{
+}
+
+static void analogix_dp_bridge_hpd_disable(struct drm_bridge *bridge)
+{
+}
+
 static const struct drm_bridge_funcs analogix_dp_bridge_funcs = {
        .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
        .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
@@ -1292,6 +1303,8 @@ static const struct drm_bridge_funcs 
analogix_dp_bridge_funcs = {
        .attach = analogix_dp_bridge_attach,
        .edid_read = analogix_dp_bridge_edid_read,
        .detect = analogix_dp_bridge_detect,
+       .hpd_enable = analogix_dp_bridge_hpd_enable,
+       .hpd_disable = analogix_dp_bridge_hpd_disable,
 };
 
 static int analogix_dp_dt_parse_lanes_map(struct analogix_dp_device *dp)
@@ -1612,7 +1625,8 @@ int analogix_dp_bind(struct analogix_dp_device *dp, 
struct drm_device *drm_dev)
                return ret;
        }
 
-       bridge->ops = DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_DETECT;
+       bridge->ops = DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_DETECT |
+                     DRM_BRIDGE_OP_HPD;
        bridge->of_node = dp->dev->of_node;
        bridge->type = DRM_MODE_CONNECTOR_eDP;
        ret = devm_drm_bridge_add(dp->dev, &dp->bridge);
-- 
2.34.1

Reply via email to