[v6,14/22] drm: bridge: dw_hdmi: Update EDID and CEC phys addr in bridge detect()

Message ID 20260516183838.2024991-15-jonas@kwiboo.se (mailing list archive)
State New
Headers
Series drm: bridge: dw_hdmi: Misc enable/disable, CEC and EDID cleanup |

Commit Message

Jonas Karlman May 16, 2026, 6:38 p.m. UTC
Update EDID and CEC phys addr in the bridge detect() func to closely
match the behavior of a bridge connector with a HDMI bridge attached
and the dw-hdmi connector.

Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
v6: New patch

This is a temporary change until dw-hdmi is fully converted into a
HDMI bridge in a future part of this multi-series effort.
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)
  

Comments

sashiko-bot@kernel.org May 16, 2026, 7:52 p.m. UTC | #1
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Redundant, back-to-back EDID reads over I2C causing significant latency during probe.
- [High] Unchecked return value from `drm_edid_raw()` causes a NULL pointer dereference on malformed EDIDs.
--

commit 795c172faddaba022a4fd3aecfe0898f0291550f
Author: Jonas Karlman <jonas@kwiboo.se>

drm: bridge: dw_hdmi: Update EDID and CEC phys addr in bridge detect()

This commit updates the EDID and CEC physical address in the bridge
detect() function. This is intended to closely match the behavior of a
bridge connector with an HDMI bridge attached and the dw-hdmi connector.

> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 2bb043d64b658..3649ccf8d994e 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -2969,8 +2969,17 @@ static enum drm_connector_status
>  dw_hdmi_bridge_detect(struct drm_bridge *bridge, struct drm_connector *connector)
>  {
>  	struct dw_hdmi *hdmi = bridge->driver_private;
> +	enum drm_connector_status status;
> +
> +	status = dw_hdmi_detect(hdmi);
> +
> +	/*
> +	 * Update EDID and CEC phys addr to match the behavior of a bridge
> +	 * connector with a HDMI bridge attached and the dw-hdmi connector.
> +	 */
> +	dw_hdmi_connector_status_update(hdmi, connector, status);

Does this cause redundant EDID reads over I2C during probe?

Because the driver does not set DRM_BRIDGE_OP_HDMI, the DRM core bridge
framework (drm_bridge_connector_get_modes_edid) is unaware of this EDID
update.

Consequently, during a standard modeset probe, the core framework calls
detect() again and then edid_read(), resulting in up to three separate
I2C EDID reads per probe cycle (one from initial detect, one from
get_modes detect, and one from get_modes edid_read). Since DDC reads are
slow, could this cause a latency regression?

Additionally, could calling dw_hdmi_connector_status_update() here trigger
a NULL pointer dereference on malformed EDIDs?

dw_hdmi_connector_status_update() calls dw_hdmi_edid_read(), which
unconditionally calls drm_edid_raw() and dereferences the result. However,
drm_edid_raw() can return NULL for malformed EDIDs where the extension
count indicates a size larger than the read buffer.

While this behavior existed previously, hooking the EDID read into the
detect() callback makes this bug significantly more reachable. Could this
cause a kernel panic simply by connecting a monitor with a malformed
EDID on hotplug?

>  
> -	return dw_hdmi_detect(hdmi);
> +	return status;
>  }
  

Patch

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 2bb043d64b65..3649ccf8d994 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2969,8 +2969,17 @@  static enum drm_connector_status
 dw_hdmi_bridge_detect(struct drm_bridge *bridge, struct drm_connector *connector)
 {
 	struct dw_hdmi *hdmi = bridge->driver_private;
+	enum drm_connector_status status;
 
-	return dw_hdmi_detect(hdmi);
+	status = dw_hdmi_detect(hdmi);
+
+	/*
+	 * Update EDID and CEC phys addr to match the behavior of a bridge
+	 * connector with a HDMI bridge attached and the dw-hdmi connector.
+	 */
+	dw_hdmi_connector_status_update(hdmi, connector, status);
+
+	return status;
 }
 
 static const struct drm_edid *dw_hdmi_bridge_edid_read(struct drm_bridge *bridge,