mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v3 0/3] drm/bridge: display-connector: detect DP state if cable is plugged on boot
@ 2026-05-28  7:10 Dmitry Baryshkov
  2026-05-28  7:10 ` [PATCH v3 1/3] drm/bridge: split hpd_mutex into two mutexes Dmitry Baryshkov
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Dmitry Baryshkov @ 2026-05-28  7:10 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Tomi Valkeinen,
	Boris Brezillon, Sam Ravnborg, Sebastian Reichel, Yongxing Mou,
	Jonas Karlman
  Cc: dri-devel, linux-kernel

Unlike the USB-C AltMode handling and unlike the DP controller handling
the HPD on its own, if the display-connector is being used to handle the
HPD pin, DP controller might not be able to get either the HPD
notification nor detect the cable state if the cable is plugged in
before the system has booted.

Make the display-connector send the HPD notifications during system
startup for DisplayPort connectors.

It's typically not a problem for other types of display connectors since
there is no special procedure to detect if the monitor is actually
plugged in or not.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
Changes in v3:
- Corrected typos in the commit message (Sashiko)
- Reworked HPD-related bridge locking to remove AB-BA deadlock (Jonas,
  Sashiko)
- Link to v2: https://patch.msgid.link/20260513-dp-connector-hpd-v2-0-42f757bfcbf9@oss.qualcomm.com

Changes in v2:
- Expanded commit message, explaining difference from HDMI (Laurent)
- Link to v1: https://lore.kernel.org/r/20260314-dp-connector-hpd-v1-0-786044cedc17@oss.qualcomm.com

---
Dmitry Baryshkov (3):
      drm/bridge: split hpd_mutex into two mutexes
      drm/bridge: display-connector: don't autoenable HPD IRQ
      drm/bridge: display-connector: trigger initial HPD event for DP

 drivers/gpu/drm/bridge/display-connector.c | 36 ++++++++++++++++++++++++++++++
 drivers/gpu/drm/drm_bridge.c               | 16 ++++++++++---
 include/drm/drm_bridge.h                   |  4 ++++
 3 files changed, 53 insertions(+), 3 deletions(-)
---
base-commit: 687da68900cd1a46549f7d9430c7d40346cb86a0
change-id: 20260314-dp-connector-hpd-f069e66bc6af

Best regards,
--  
With best wishes
Dmitry


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v3 1/3] drm/bridge: split hpd_mutex into two mutexes
  2026-05-28  7:10 [PATCH v3 0/3] drm/bridge: display-connector: detect DP state if cable is plugged on boot Dmitry Baryshkov
@ 2026-05-28  7:10 ` Dmitry Baryshkov
  2026-06-01 16:01   ` Sebastian Reichel
  2026-05-28  7:10 ` [PATCH v3 2/3] drm/bridge: display-connector: don't autoenable HPD IRQ Dmitry Baryshkov
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: Dmitry Baryshkov @ 2026-05-28  7:10 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Tomi Valkeinen,
	Boris Brezillon, Sam Ravnborg, Sebastian Reichel, Yongxing Mou,
	Jonas Karlman
  Cc: dri-devel, linux-kernel

Currently almost all bridge drivers which implement hpd_enable /
hpd_disable callbacks simply toggle the hardware registers generating
the interrupt. However, as pointed out by Jonas Karlman and Sashiko bot,
using those callbacks for enable_irq() / disable_irq() calls or
scheduling and cancelling the work can cause a AB-BA deadlock (between
hpd_mutex lock and the corresponding lock).

Split the hpd_mutex into two locks: one simply making sure that hpd_cb /
hpd_data are consistent and another one, hpd_state_mutex, making sure
that concurrent drm_bridge_hpd_enable() / drm_bridge_hpd_disable() calls
can't end up with inconsistency between hpd_cb/_data and bridge's
internal state.

Link: https://lore.kernel.org/dri-devel/9aa4bd35-bff6-4009-a959-ce31010c7b35@kwiboo.se
Link: https://sashiko.dev/#/patchset/20260513-dp-connector-hpd-v2-0-42f757bfcbf9%40oss.qualcomm.com
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
 drivers/gpu/drm/drm_bridge.c | 16 +++++++++++++---
 include/drm/drm_bridge.h     |  4 ++++
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index 687b36eea0c7..9a185032a3bd 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -417,6 +417,7 @@ void drm_bridge_add(struct drm_bridge *bridge)
 	if (!list_empty(&bridge->list))
 		list_del_init(&bridge->list);
 
+	mutex_init(&bridge->hpd_state_mutex);
 	mutex_init(&bridge->hpd_mutex);
 
 	if (bridge->ops & DRM_BRIDGE_OP_HDMI)
@@ -469,6 +470,7 @@ void drm_bridge_remove(struct drm_bridge *bridge)
 	mutex_unlock(&bridge_lock);
 
 	mutex_destroy(&bridge->hpd_mutex);
+	mutex_destroy(&bridge->hpd_state_mutex);
 
 	drm_bridge_put(bridge);
 }
@@ -1451,19 +1453,25 @@ void drm_bridge_hpd_enable(struct drm_bridge *bridge,
 	if (!(bridge->ops & DRM_BRIDGE_OP_HPD))
 		return;
 
+	mutex_lock(&bridge->hpd_state_mutex);
+
 	mutex_lock(&bridge->hpd_mutex);
 
-	if (WARN(bridge->hpd_cb, "Hot plug detection already enabled\n"))
+	if (WARN(bridge->hpd_cb, "Hot plug detection already enabled\n")) {
+		mutex_unlock(&bridge->hpd_mutex);
 		goto unlock;
+	}
 
 	bridge->hpd_cb = cb;
 	bridge->hpd_data = data;
 
+	mutex_unlock(&bridge->hpd_mutex);
+
 	if (bridge->funcs->hpd_enable)
 		bridge->funcs->hpd_enable(bridge);
 
 unlock:
-	mutex_unlock(&bridge->hpd_mutex);
+	mutex_unlock(&bridge->hpd_state_mutex);
 }
 EXPORT_SYMBOL_GPL(drm_bridge_hpd_enable);
 
@@ -1484,13 +1492,15 @@ void drm_bridge_hpd_disable(struct drm_bridge *bridge)
 	if (!(bridge->ops & DRM_BRIDGE_OP_HPD))
 		return;
 
-	mutex_lock(&bridge->hpd_mutex);
+	mutex_lock(&bridge->hpd_state_mutex);
 	if (bridge->funcs->hpd_disable)
 		bridge->funcs->hpd_disable(bridge);
 
+	mutex_lock(&bridge->hpd_mutex);
 	bridge->hpd_cb = NULL;
 	bridge->hpd_data = NULL;
 	mutex_unlock(&bridge->hpd_mutex);
+	mutex_unlock(&bridge->hpd_state_mutex);
 }
 EXPORT_SYMBOL_GPL(drm_bridge_hpd_disable);
 
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 4ba3a5deef9a..00a95f927e34 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -1256,6 +1256,10 @@ struct drm_bridge {
 	 * @hpd_mutex: Protects the @hpd_cb and @hpd_data fields.
 	 */
 	struct mutex hpd_mutex;
+	/**
+	 * @hpd_state_mutex: Protects the HPD en/disablement state for the bridge.
+	 */
+	struct mutex hpd_state_mutex;
 	/**
 	 * @hpd_cb: Hot plug detection callback, registered with
 	 * drm_bridge_hpd_enable().

-- 
2.47.3


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v3 2/3] drm/bridge: display-connector: don't autoenable HPD IRQ
  2026-05-28  7:10 [PATCH v3 0/3] drm/bridge: display-connector: detect DP state if cable is plugged on boot Dmitry Baryshkov
  2026-05-28  7:10 ` [PATCH v3 1/3] drm/bridge: split hpd_mutex into two mutexes Dmitry Baryshkov
@ 2026-05-28  7:10 ` Dmitry Baryshkov
  2026-05-28 11:07   ` Neil Armstrong
  2026-06-01 16:01   ` Sebastian Reichel
  2026-05-28  7:10 ` [PATCH v3 3/3] drm/bridge: display-connector: trigger initial HPD event for DP Dmitry Baryshkov
  2026-06-08  6:49 ` [PATCH v3 0/3] drm/bridge: display-connector: detect DP state if cable is plugged on boot Dmitry Baryshkov
  3 siblings, 2 replies; 9+ messages in thread
From: Dmitry Baryshkov @ 2026-05-28  7:10 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Tomi Valkeinen,
	Boris Brezillon, Sam Ravnborg, Sebastian Reichel, Yongxing Mou,
	Jonas Karlman
  Cc: dri-devel, linux-kernel

If HPD IRQ is enabled in the display_connector's probe, it can be
triggered too early, before the DRM connector is completely setup. Use
the enable_hpd / disable_hpd callbacks to control enablement of the HPD
IRQ.

Fixes: 0c275c30176b ("drm/bridge: Add bridge driver for display connectors")
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
 drivers/gpu/drm/bridge/display-connector.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/gpu/drm/bridge/display-connector.c b/drivers/gpu/drm/bridge/display-connector.c
index 16c0631adeb1..6bb1134f75c3 100644
--- a/drivers/gpu/drm/bridge/display-connector.c
+++ b/drivers/gpu/drm/bridge/display-connector.c
@@ -87,6 +87,20 @@ display_connector_bridge_detect(struct drm_bridge *bridge, struct drm_connector
 	return display_connector_detect(bridge);
 }
 
+static void display_connector_hpd_enable(struct drm_bridge *bridge)
+{
+	struct display_connector *conn = to_display_connector(bridge);
+
+	enable_irq(conn->hpd_irq);
+}
+
+static void display_connector_hpd_disable(struct drm_bridge *bridge)
+{
+	struct display_connector *conn = to_display_connector(bridge);
+
+	disable_irq(conn->hpd_irq);
+}
+
 static const struct drm_edid *display_connector_edid_read(struct drm_bridge *bridge,
 							  struct drm_connector *connector)
 {
@@ -178,6 +192,8 @@ static u32 *display_connector_get_input_bus_fmts(struct drm_bridge *bridge,
 static const struct drm_bridge_funcs display_connector_bridge_funcs = {
 	.attach = display_connector_attach,
 	.detect = display_connector_bridge_detect,
+	.hpd_enable = display_connector_hpd_enable,
+	.hpd_disable = display_connector_hpd_disable,
 	.edid_read = display_connector_edid_read,
 	.atomic_get_output_bus_fmts = display_connector_get_output_bus_fmts,
 	.atomic_get_input_bus_fmts = display_connector_get_input_bus_fmts,
@@ -307,6 +323,7 @@ static int display_connector_probe(struct platform_device *pdev)
 						NULL, display_connector_hpd_irq,
 						IRQF_TRIGGER_RISING |
 						IRQF_TRIGGER_FALLING |
+						IRQF_NO_AUTOEN |
 						IRQF_ONESHOT,
 						"HPD", conn);
 		if (ret) {

-- 
2.47.3


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v3 3/3] drm/bridge: display-connector: trigger initial HPD event for DP
  2026-05-28  7:10 [PATCH v3 0/3] drm/bridge: display-connector: detect DP state if cable is plugged on boot Dmitry Baryshkov
  2026-05-28  7:10 ` [PATCH v3 1/3] drm/bridge: split hpd_mutex into two mutexes Dmitry Baryshkov
  2026-05-28  7:10 ` [PATCH v3 2/3] drm/bridge: display-connector: don't autoenable HPD IRQ Dmitry Baryshkov
@ 2026-05-28  7:10 ` Dmitry Baryshkov
  2026-06-01 16:02   ` Sebastian Reichel
  2026-06-08  6:49 ` [PATCH v3 0/3] drm/bridge: display-connector: detect DP state if cable is plugged on boot Dmitry Baryshkov
  3 siblings, 1 reply; 9+ messages in thread
From: Dmitry Baryshkov @ 2026-05-28  7:10 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Tomi Valkeinen,
	Boris Brezillon, Sam Ravnborg, Sebastian Reichel, Yongxing Mou,
	Jonas Karlman
  Cc: dri-devel, linux-kernel

If the DisplayPort drivers use display-connector for the HPD detection,
the internal HPD state machine might be not active and thus the hardware
might be not able to handle cable detection correctly. Instead it will
depend on the external HPD notifications to set the cable state,
bypassing the internal HPD state machine (for example this is the case
for the msm DP driver).

However if the cable has been plugged before the HPD IRQ has been
enabled, there will be no HPD event coming. The drivers might fail
detection in such a case. Trigger the HPD notification after enabling
the HPD IRQ, propagating the cable insertion state.

Note, this issue only affects drivers which set OP_HPD but not OP_DETECT
(like dp-connector). Here DP differs from HDMI. For HDMI there is no
additional state or extra "bridge with no sinks plugged" cases. The HPD
pin state is equal to the display plugged state. Nor do we have an AUX
bus with timeouts, etc.

Fixes: 2e2bf3a5584d ("drm/bridge: display-connector: add DP support")
Reported-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
 drivers/gpu/drm/bridge/display-connector.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/gpu/drm/bridge/display-connector.c b/drivers/gpu/drm/bridge/display-connector.c
index 6bb1134f75c3..f7a5bfd9c075 100644
--- a/drivers/gpu/drm/bridge/display-connector.c
+++ b/drivers/gpu/drm/bridge/display-connector.c
@@ -12,6 +12,7 @@
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
+#include <linux/workqueue.h>
 
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_bridge.h>
@@ -25,6 +26,8 @@ struct display_connector {
 
 	struct regulator	*supply;
 	struct gpio_desc	*ddc_en;
+
+	struct work_struct	hpd_work;
 };
 
 static inline struct display_connector *
@@ -92,15 +95,29 @@ static void display_connector_hpd_enable(struct drm_bridge *bridge)
 	struct display_connector *conn = to_display_connector(bridge);
 
 	enable_irq(conn->hpd_irq);
+
+	if (conn->bridge.type == DRM_MODE_CONNECTOR_DisplayPort)
+		schedule_work(&conn->hpd_work);
 }
 
 static void display_connector_hpd_disable(struct drm_bridge *bridge)
 {
 	struct display_connector *conn = to_display_connector(bridge);
 
+	if (conn->bridge.type == DRM_MODE_CONNECTOR_DisplayPort)
+		cancel_work_sync(&conn->hpd_work);
+
 	disable_irq(conn->hpd_irq);
 }
 
+static void display_connector_hpd_work(struct work_struct *work)
+{
+	struct display_connector *conn = container_of(work, struct display_connector, hpd_work);
+	struct drm_bridge *bridge = &conn->bridge;
+
+	drm_bridge_hpd_notify(bridge, display_connector_detect(bridge));
+}
+
 static const struct drm_edid *display_connector_edid_read(struct drm_bridge *bridge,
 							  struct drm_connector *connector)
 {
@@ -395,6 +412,8 @@ static int display_connector_probe(struct platform_device *pdev)
 		conn->bridge.ops |= DRM_BRIDGE_OP_DETECT;
 	if (conn->hpd_irq >= 0)
 		conn->bridge.ops |= DRM_BRIDGE_OP_HPD;
+	if (conn->hpd_irq >= 0 && type == DRM_MODE_CONNECTOR_DisplayPort)
+		INIT_WORK(&conn->hpd_work, display_connector_hpd_work);
 
 	dev_dbg(&pdev->dev,
 		"Found %s display connector '%s' %s DDC bus and %s HPD GPIO (ops 0x%x)\n",

-- 
2.47.3


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 2/3] drm/bridge: display-connector: don't autoenable HPD IRQ
  2026-05-28  7:10 ` [PATCH v3 2/3] drm/bridge: display-connector: don't autoenable HPD IRQ Dmitry Baryshkov
@ 2026-05-28 11:07   ` Neil Armstrong
  2026-06-01 16:01   ` Sebastian Reichel
  1 sibling, 0 replies; 9+ messages in thread
From: Neil Armstrong @ 2026-05-28 11:07 UTC (permalink / raw)
  To: Dmitry Baryshkov, Andrzej Hajda, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Tomi Valkeinen,
	Boris Brezillon, Sam Ravnborg, Sebastian Reichel, Yongxing Mou
  Cc: dri-devel, linux-kernel

On 5/28/26 09:10, Dmitry Baryshkov wrote:
> If HPD IRQ is enabled in the display_connector's probe, it can be
> triggered too early, before the DRM connector is completely setup. Use
> the enable_hpd / disable_hpd callbacks to control enablement of the HPD
> IRQ.
> 
> Fixes: 0c275c30176b ("drm/bridge: Add bridge driver for display connectors")
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> ---
>   drivers/gpu/drm/bridge/display-connector.c | 17 +++++++++++++++++
>   1 file changed, 17 insertions(+)
> 
> diff --git a/drivers/gpu/drm/bridge/display-connector.c b/drivers/gpu/drm/bridge/display-connector.c
> index 16c0631adeb1..6bb1134f75c3 100644
> --- a/drivers/gpu/drm/bridge/display-connector.c
> +++ b/drivers/gpu/drm/bridge/display-connector.c
> @@ -87,6 +87,20 @@ display_connector_bridge_detect(struct drm_bridge *bridge, struct drm_connector
>   	return display_connector_detect(bridge);
>   }
>   
> +static void display_connector_hpd_enable(struct drm_bridge *bridge)
> +{
> +	struct display_connector *conn = to_display_connector(bridge);
> +
> +	enable_irq(conn->hpd_irq);
> +}
> +
> +static void display_connector_hpd_disable(struct drm_bridge *bridge)
> +{
> +	struct display_connector *conn = to_display_connector(bridge);
> +
> +	disable_irq(conn->hpd_irq);
> +}
> +
>   static const struct drm_edid *display_connector_edid_read(struct drm_bridge *bridge,
>   							  struct drm_connector *connector)
>   {
> @@ -178,6 +192,8 @@ static u32 *display_connector_get_input_bus_fmts(struct drm_bridge *bridge,
>   static const struct drm_bridge_funcs display_connector_bridge_funcs = {
>   	.attach = display_connector_attach,
>   	.detect = display_connector_bridge_detect,
> +	.hpd_enable = display_connector_hpd_enable,
> +	.hpd_disable = display_connector_hpd_disable,
>   	.edid_read = display_connector_edid_read,
>   	.atomic_get_output_bus_fmts = display_connector_get_output_bus_fmts,
>   	.atomic_get_input_bus_fmts = display_connector_get_input_bus_fmts,
> @@ -307,6 +323,7 @@ static int display_connector_probe(struct platform_device *pdev)
>   						NULL, display_connector_hpd_irq,
>   						IRQF_TRIGGER_RISING |
>   						IRQF_TRIGGER_FALLING |
> +						IRQF_NO_AUTOEN |
>   						IRQF_ONESHOT,
>   						"HPD", conn);
>   		if (ret) {
> 

Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>

Thanks,
Neil

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 1/3] drm/bridge: split hpd_mutex into two mutexes
  2026-05-28  7:10 ` [PATCH v3 1/3] drm/bridge: split hpd_mutex into two mutexes Dmitry Baryshkov
@ 2026-06-01 16:01   ` Sebastian Reichel
  0 siblings, 0 replies; 9+ messages in thread
From: Sebastian Reichel @ 2026-06-01 16:01 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Tomi Valkeinen,
	Boris Brezillon, Sam Ravnborg, Yongxing Mou, dri-devel,
	linux-kernel

[-- Attachment #1: Type: text/plain, Size: 3946 bytes --]

Hi,

On Thu, May 28, 2026 at 10:10:48AM +0300, Dmitry Baryshkov wrote:
> Currently almost all bridge drivers which implement hpd_enable /
> hpd_disable callbacks simply toggle the hardware registers generating
> the interrupt. However, as pointed out by Jonas Karlman and Sashiko bot,
> using those callbacks for enable_irq() / disable_irq() calls or
> scheduling and cancelling the work can cause a AB-BA deadlock (between
> hpd_mutex lock and the corresponding lock).
> 
> Split the hpd_mutex into two locks: one simply making sure that hpd_cb /
> hpd_data are consistent and another one, hpd_state_mutex, making sure
> that concurrent drm_bridge_hpd_enable() / drm_bridge_hpd_disable() calls
> can't end up with inconsistency between hpd_cb/_data and bridge's
> internal state.
> 
> Link: https://lore.kernel.org/dri-devel/9aa4bd35-bff6-4009-a959-ce31010c7b35@kwiboo.se
> Link: https://sashiko.dev/#/patchset/20260513-dp-connector-hpd-v2-0-42f757bfcbf9%40oss.qualcomm.com
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

-- Sebastian

>  drivers/gpu/drm/drm_bridge.c | 16 +++++++++++++---
>  include/drm/drm_bridge.h     |  4 ++++
>  2 files changed, 17 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
> index 687b36eea0c7..9a185032a3bd 100644
> --- a/drivers/gpu/drm/drm_bridge.c
> +++ b/drivers/gpu/drm/drm_bridge.c
> @@ -417,6 +417,7 @@ void drm_bridge_add(struct drm_bridge *bridge)
>  	if (!list_empty(&bridge->list))
>  		list_del_init(&bridge->list);
>  
> +	mutex_init(&bridge->hpd_state_mutex);
>  	mutex_init(&bridge->hpd_mutex);
>  
>  	if (bridge->ops & DRM_BRIDGE_OP_HDMI)
> @@ -469,6 +470,7 @@ void drm_bridge_remove(struct drm_bridge *bridge)
>  	mutex_unlock(&bridge_lock);
>  
>  	mutex_destroy(&bridge->hpd_mutex);
> +	mutex_destroy(&bridge->hpd_state_mutex);
>  
>  	drm_bridge_put(bridge);
>  }
> @@ -1451,19 +1453,25 @@ void drm_bridge_hpd_enable(struct drm_bridge *bridge,
>  	if (!(bridge->ops & DRM_BRIDGE_OP_HPD))
>  		return;
>  
> +	mutex_lock(&bridge->hpd_state_mutex);
> +
>  	mutex_lock(&bridge->hpd_mutex);
>  
> -	if (WARN(bridge->hpd_cb, "Hot plug detection already enabled\n"))
> +	if (WARN(bridge->hpd_cb, "Hot plug detection already enabled\n")) {
> +		mutex_unlock(&bridge->hpd_mutex);
>  		goto unlock;
> +	}
>  
>  	bridge->hpd_cb = cb;
>  	bridge->hpd_data = data;
>  
> +	mutex_unlock(&bridge->hpd_mutex);
> +
>  	if (bridge->funcs->hpd_enable)
>  		bridge->funcs->hpd_enable(bridge);
>  
>  unlock:
> -	mutex_unlock(&bridge->hpd_mutex);
> +	mutex_unlock(&bridge->hpd_state_mutex);
>  }
>  EXPORT_SYMBOL_GPL(drm_bridge_hpd_enable);
>  
> @@ -1484,13 +1492,15 @@ void drm_bridge_hpd_disable(struct drm_bridge *bridge)
>  	if (!(bridge->ops & DRM_BRIDGE_OP_HPD))
>  		return;
>  
> -	mutex_lock(&bridge->hpd_mutex);
> +	mutex_lock(&bridge->hpd_state_mutex);
>  	if (bridge->funcs->hpd_disable)
>  		bridge->funcs->hpd_disable(bridge);
>  
> +	mutex_lock(&bridge->hpd_mutex);
>  	bridge->hpd_cb = NULL;
>  	bridge->hpd_data = NULL;
>  	mutex_unlock(&bridge->hpd_mutex);
> +	mutex_unlock(&bridge->hpd_state_mutex);
>  }
>  EXPORT_SYMBOL_GPL(drm_bridge_hpd_disable);
>  
> diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
> index 4ba3a5deef9a..00a95f927e34 100644
> --- a/include/drm/drm_bridge.h
> +++ b/include/drm/drm_bridge.h
> @@ -1256,6 +1256,10 @@ struct drm_bridge {
>  	 * @hpd_mutex: Protects the @hpd_cb and @hpd_data fields.
>  	 */
>  	struct mutex hpd_mutex;
> +	/**
> +	 * @hpd_state_mutex: Protects the HPD en/disablement state for the bridge.
> +	 */
> +	struct mutex hpd_state_mutex;
>  	/**
>  	 * @hpd_cb: Hot plug detection callback, registered with
>  	 * drm_bridge_hpd_enable().
> 
> -- 
> 2.47.3
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 2/3] drm/bridge: display-connector: don't autoenable HPD IRQ
  2026-05-28  7:10 ` [PATCH v3 2/3] drm/bridge: display-connector: don't autoenable HPD IRQ Dmitry Baryshkov
  2026-05-28 11:07   ` Neil Armstrong
@ 2026-06-01 16:01   ` Sebastian Reichel
  1 sibling, 0 replies; 9+ messages in thread
From: Sebastian Reichel @ 2026-06-01 16:01 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Tomi Valkeinen,
	Boris Brezillon, Sam Ravnborg, Yongxing Mou, dri-devel,
	linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2470 bytes --]

Hi,

On Thu, May 28, 2026 at 10:10:49AM +0300, Dmitry Baryshkov wrote:
> If HPD IRQ is enabled in the display_connector's probe, it can be
> triggered too early, before the DRM connector is completely setup. Use
> the enable_hpd / disable_hpd callbacks to control enablement of the HPD
> IRQ.
> 
> Fixes: 0c275c30176b ("drm/bridge: Add bridge driver for display connectors")
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

-- Sebastian

>  drivers/gpu/drm/bridge/display-connector.c | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
> 
> diff --git a/drivers/gpu/drm/bridge/display-connector.c b/drivers/gpu/drm/bridge/display-connector.c
> index 16c0631adeb1..6bb1134f75c3 100644
> --- a/drivers/gpu/drm/bridge/display-connector.c
> +++ b/drivers/gpu/drm/bridge/display-connector.c
> @@ -87,6 +87,20 @@ display_connector_bridge_detect(struct drm_bridge *bridge, struct drm_connector
>  	return display_connector_detect(bridge);
>  }
>  
> +static void display_connector_hpd_enable(struct drm_bridge *bridge)
> +{
> +	struct display_connector *conn = to_display_connector(bridge);
> +
> +	enable_irq(conn->hpd_irq);
> +}
> +
> +static void display_connector_hpd_disable(struct drm_bridge *bridge)
> +{
> +	struct display_connector *conn = to_display_connector(bridge);
> +
> +	disable_irq(conn->hpd_irq);
> +}
> +
>  static const struct drm_edid *display_connector_edid_read(struct drm_bridge *bridge,
>  							  struct drm_connector *connector)
>  {
> @@ -178,6 +192,8 @@ static u32 *display_connector_get_input_bus_fmts(struct drm_bridge *bridge,
>  static const struct drm_bridge_funcs display_connector_bridge_funcs = {
>  	.attach = display_connector_attach,
>  	.detect = display_connector_bridge_detect,
> +	.hpd_enable = display_connector_hpd_enable,
> +	.hpd_disable = display_connector_hpd_disable,
>  	.edid_read = display_connector_edid_read,
>  	.atomic_get_output_bus_fmts = display_connector_get_output_bus_fmts,
>  	.atomic_get_input_bus_fmts = display_connector_get_input_bus_fmts,
> @@ -307,6 +323,7 @@ static int display_connector_probe(struct platform_device *pdev)
>  						NULL, display_connector_hpd_irq,
>  						IRQF_TRIGGER_RISING |
>  						IRQF_TRIGGER_FALLING |
> +						IRQF_NO_AUTOEN |
>  						IRQF_ONESHOT,
>  						"HPD", conn);
>  		if (ret) {
> 
> -- 
> 2.47.3
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 3/3] drm/bridge: display-connector: trigger initial HPD event for DP
  2026-05-28  7:10 ` [PATCH v3 3/3] drm/bridge: display-connector: trigger initial HPD event for DP Dmitry Baryshkov
@ 2026-06-01 16:02   ` Sebastian Reichel
  0 siblings, 0 replies; 9+ messages in thread
From: Sebastian Reichel @ 2026-06-01 16:02 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Tomi Valkeinen,
	Boris Brezillon, Sam Ravnborg, Yongxing Mou, dri-devel,
	linux-kernel

[-- Attachment #1: Type: text/plain, Size: 3734 bytes --]

Hi,

On Thu, May 28, 2026 at 10:10:50AM +0300, Dmitry Baryshkov wrote:
> If the DisplayPort drivers use display-connector for the HPD detection,
> the internal HPD state machine might be not active and thus the hardware
> might be not able to handle cable detection correctly. Instead it will
> depend on the external HPD notifications to set the cable state,
> bypassing the internal HPD state machine (for example this is the case
> for the msm DP driver).
> 
> However if the cable has been plugged before the HPD IRQ has been
> enabled, there will be no HPD event coming. The drivers might fail
> detection in such a case. Trigger the HPD notification after enabling
> the HPD IRQ, propagating the cable insertion state.
> 
> Note, this issue only affects drivers which set OP_HPD but not OP_DETECT
> (like dp-connector). Here DP differs from HDMI. For HDMI there is no
> additional state or extra "bridge with no sinks plugged" cases. The HPD
> pin state is equal to the display plugged state. Nor do we have an AUX
> bus with timeouts, etc.
> 
> Fixes: 2e2bf3a5584d ("drm/bridge: display-connector: add DP support")
> Reported-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

Greetings,

-- Sebastian

>  drivers/gpu/drm/bridge/display-connector.c | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 
> diff --git a/drivers/gpu/drm/bridge/display-connector.c b/drivers/gpu/drm/bridge/display-connector.c
> index 6bb1134f75c3..f7a5bfd9c075 100644
> --- a/drivers/gpu/drm/bridge/display-connector.c
> +++ b/drivers/gpu/drm/bridge/display-connector.c
> @@ -12,6 +12,7 @@
>  #include <linux/of.h>
>  #include <linux/platform_device.h>
>  #include <linux/regulator/consumer.h>
> +#include <linux/workqueue.h>
>  
>  #include <drm/drm_atomic_helper.h>
>  #include <drm/drm_bridge.h>
> @@ -25,6 +26,8 @@ struct display_connector {
>  
>  	struct regulator	*supply;
>  	struct gpio_desc	*ddc_en;
> +
> +	struct work_struct	hpd_work;
>  };
>  
>  static inline struct display_connector *
> @@ -92,15 +95,29 @@ static void display_connector_hpd_enable(struct drm_bridge *bridge)
>  	struct display_connector *conn = to_display_connector(bridge);
>  
>  	enable_irq(conn->hpd_irq);
> +
> +	if (conn->bridge.type == DRM_MODE_CONNECTOR_DisplayPort)
> +		schedule_work(&conn->hpd_work);
>  }
>  
>  static void display_connector_hpd_disable(struct drm_bridge *bridge)
>  {
>  	struct display_connector *conn = to_display_connector(bridge);
>  
> +	if (conn->bridge.type == DRM_MODE_CONNECTOR_DisplayPort)
> +		cancel_work_sync(&conn->hpd_work);
> +
>  	disable_irq(conn->hpd_irq);
>  }
>  
> +static void display_connector_hpd_work(struct work_struct *work)
> +{
> +	struct display_connector *conn = container_of(work, struct display_connector, hpd_work);
> +	struct drm_bridge *bridge = &conn->bridge;
> +
> +	drm_bridge_hpd_notify(bridge, display_connector_detect(bridge));
> +}
> +
>  static const struct drm_edid *display_connector_edid_read(struct drm_bridge *bridge,
>  							  struct drm_connector *connector)
>  {
> @@ -395,6 +412,8 @@ static int display_connector_probe(struct platform_device *pdev)
>  		conn->bridge.ops |= DRM_BRIDGE_OP_DETECT;
>  	if (conn->hpd_irq >= 0)
>  		conn->bridge.ops |= DRM_BRIDGE_OP_HPD;
> +	if (conn->hpd_irq >= 0 && type == DRM_MODE_CONNECTOR_DisplayPort)
> +		INIT_WORK(&conn->hpd_work, display_connector_hpd_work);
>  
>  	dev_dbg(&pdev->dev,
>  		"Found %s display connector '%s' %s DDC bus and %s HPD GPIO (ops 0x%x)\n",
> 
> -- 
> 2.47.3
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 0/3] drm/bridge: display-connector: detect DP state if cable is plugged on boot
  2026-05-28  7:10 [PATCH v3 0/3] drm/bridge: display-connector: detect DP state if cable is plugged on boot Dmitry Baryshkov
                   ` (2 preceding siblings ...)
  2026-05-28  7:10 ` [PATCH v3 3/3] drm/bridge: display-connector: trigger initial HPD event for DP Dmitry Baryshkov
@ 2026-06-08  6:49 ` Dmitry Baryshkov
  3 siblings, 0 replies; 9+ messages in thread
From: Dmitry Baryshkov @ 2026-06-08  6:49 UTC (permalink / raw)
  To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Tomi Valkeinen,
	Boris Brezillon, Sam Ravnborg, Sebastian Reichel, Yongxing Mou,
	Jonas Karlman, Dmitry Baryshkov
  Cc: dri-devel, linux-kernel

On Thu, 28 May 2026 10:10:47 +0300, Dmitry Baryshkov wrote:
> Unlike the USB-C AltMode handling and unlike the DP controller handling
> the HPD on its own, if the display-connector is being used to handle the
> HPD pin, DP controller might not be able to get either the HPD
> notification nor detect the cable state if the cable is plugged in
> before the system has booted.
> 
> Make the display-connector send the HPD notifications during system
> startup for DisplayPort connectors.
> 
> [...]

Applied to drm-misc-next, thanks!

[1/3] drm/bridge: split hpd_mutex into two mutexes
      commit: cd0d23939b8775482c30ca7ab207f185aecd6555
[2/3] drm/bridge: display-connector: don't autoenable HPD IRQ
      commit: 8e9c475060bff87077cfa3bd42011edcb7fb3b0d
[3/3] drm/bridge: display-connector: trigger initial HPD event for DP
      commit: 60dc0946bbad3eef8bc66a5a8b09b98dbc6e09c0

Best regards,
-- 
With best wishes
Dmitry



^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-06-08  6:49 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-05-28  7:10 [PATCH v3 0/3] drm/bridge: display-connector: detect DP state if cable is plugged on boot Dmitry Baryshkov
2026-05-28  7:10 ` [PATCH v3 1/3] drm/bridge: split hpd_mutex into two mutexes Dmitry Baryshkov
2026-06-01 16:01   ` Sebastian Reichel
2026-05-28  7:10 ` [PATCH v3 2/3] drm/bridge: display-connector: don't autoenable HPD IRQ Dmitry Baryshkov
2026-05-28 11:07   ` Neil Armstrong
2026-06-01 16:01   ` Sebastian Reichel
2026-05-28  7:10 ` [PATCH v3 3/3] drm/bridge: display-connector: trigger initial HPD event for DP Dmitry Baryshkov
2026-06-01 16:02   ` Sebastian Reichel
2026-06-08  6:49 ` [PATCH v3 0/3] drm/bridge: display-connector: detect DP state if cable is plugged on boot Dmitry Baryshkov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®