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
