[PATCH v7 25/35] drm/bridge_connector: suppress hotplug for IRQ_HPD without status changes
From: Yongxing Mou
Date: Tue Sep 29 2026 - 00:33:55 EST
DP IRQ_HPD does not necessarily indicate a display connection change.
It can also signal link status changes or pending MST messages, which
need bridge-side handling but do not necessarily require userspace to
reprobe the connector.
Currently, the HPD handler sends a hotplug event for every notification,
without distinguishing ordinary HPD from IRQ_HPD. This causes IRQ_HPD
notifications with no connection change to trigger unnecessary connector
reprobes.
However, filtering out all IRQ_HPD notifications would also discard
hotplug events for downstream display connection changes on a DP branch,
where upstream HPD can remain asserted. The decision therefore needs to
use the actual connector status after handling the notification, rather
than the raw HPD status reported by the event.
Pass the event to the bridge chain first, then call the bridge .detect()
callback to update connector->status. Fall back to the reported status
when no .detect() callback is available. For IRQ_HPD, send a hotplug event
only when the connector status changes, suppressing IRQ-only notifications
while preserving notifications for downstream connection changes.
Keep hotplug events unconditional for ordinary HPD notifications. An
earlier detect may already have updated the connection status before
subsequent plug handling reads the EDID, so a reprobe is still needed.
Signed-off-by: Yongxing Mou <yongxing.mou@xxxxxxxxxxxxxxxx>
---
drivers/gpu/drm/display/drm_bridge_connector.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c
index 083d70017f02..d27ce59ca32b 100644
--- a/drivers/gpu/drm/display/drm_bridge_connector.c
+++ b/drivers/gpu/drm/display/drm_bridge_connector.c
@@ -159,15 +159,28 @@ static void drm_bridge_connector_handle_hpd(struct drm_bridge_connector *drm_bri
enum drm_connector_dp_event event)
{
struct drm_connector *connector = &drm_bridge_connector->base;
+ struct drm_bridge *detect = drm_bridge_connector->bridge_detect;
struct drm_device *dev = connector->dev;
+ enum drm_connector_status old_status, new_status;
+ bool level_hpd;
+ bool changed;
+
+ level_hpd = event == DRM_CONNECTOR_NO_EXTRA_STATUS;
mutex_lock(&dev->mode_config.mutex);
- connector->status = status;
+ old_status = connector->status;
mutex_unlock(&dev->mode_config.mutex);
drm_bridge_connector_hpd_notify(connector, status, event);
- drm_kms_helper_connector_hotplug_event(connector);
+ mutex_lock(&dev->mode_config.mutex);
+ new_status = detect ? detect->funcs->detect(detect, connector) : status;
+ connector->status = new_status;
+ changed = new_status != old_status;
+ mutex_unlock(&dev->mode_config.mutex);
+
+ if (changed || level_hpd)
+ drm_kms_helper_connector_hotplug_event(connector);
}
static void drm_bridge_connector_hpd_cb(void *cb_data,
--
2.43.0