From nobody Wed Oct 1 23:27:51 2025 Received: from smtpout-04.galae.net (smtpout-04.galae.net [185.171.202.116]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D831B14658D for ; Thu, 25 Sep 2025 17:20:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.171.202.116 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758820816; cv=none; b=c4Un61rzU/upI6se6fF8wwOF89K3HycptuMEsQJQXRq83AUUbHOyEkiHbokpoJOG2Ecc2lcT535oeVWsOZTRvYdjGTeH3Mi2V4LQuHlfWz0j91/U4rvVSULsmR5DDNk0qDVkt8XQ0R7bJgXvZ9oGYRTeuwVhzPCF9qjWLEV1vuE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758820816; c=relaxed/simple; bh=FMldVev/xV/swbnn0A2UVed8DEgJs+vvTzf6WW3AY3g=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=N8IKbUVZoMfvFShafMUErzXUox5B0/TMNAsD91cEzGa4esQSNMOpB0dX5hJGVjoqtjfnXYng8aw156QsNFvQ09F13jjG0FIuNrjBo9+MOoyPCgLpQ/NxKeXebeEC5yZaJKl1xnr4nRMgMavozK2pwVah1NIKVDUuzfNKISdtFek= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=iOpkIZ6M; arc=none smtp.client-ip=185.171.202.116 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="iOpkIZ6M" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id 1C159C011FF; Thu, 25 Sep 2025 17:19:55 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 64BE060665; Thu, 25 Sep 2025 17:20:12 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 36952102F18A6; Thu, 25 Sep 2025 19:20:09 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1758820811; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=xHjzQbM/4RJWH0CChP1hj2HXRcgPGp7OejUh4qefmG0=; b=iOpkIZ6MraXlaLq3hs/jbA/mLz0DmdJ+9nEQHFO1/iIwjjkzLZln5Ril8MpIUAItw2Qfua tyu5D+f3jZXsMKcrPhT8Zhnwf3iw5n5iNUt8FI1yRVqexgmR+cqhZKYq8by2nvGSQJvGQZ 7gmjv2mx53Vd+KywFNpeea0CCxMTC+sM5ynUqJ0DdWq/C39AAZiRQW+8lVkUyjsSMIPsr4 e2zHPnBVOONEgfGJzJHf+lmSpaGiXdEud97ABlHeUn5Tkw4Qb9hZu2m131vGg3/K0KdWGT T2SwFKY54sAXAsScuTqkVZImbMQlJa3FQUfpYaGWqOMHbnvihwe7PsZSA3c3ow== From: Luca Ceresoli Date: Thu, 25 Sep 2025 19:19:49 +0200 Subject: [PATCH 1/2] drm/connector: allow a .destroy callback for drmm-allocated connectors Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250925-drm-bridge-alloc-getput-bridge-connector-v1-1-f0736e1c73ee@bootlin.com> References: <20250925-drm-bridge-alloc-getput-bridge-connector-v1-0-f0736e1c73ee@bootlin.com> In-Reply-To: <20250925-drm-bridge-alloc-getput-bridge-connector-v1-0-f0736e1c73ee@bootlin.com> To: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Dmitry Baryshkov Cc: Hui Pu , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Luca Ceresoli X-Mailer: b4 0.14.2 X-Last-TLS-Session-Version: TLSv1.3 Some code is going to need connector-specific cleanup actions (namely drm_bridge_connector will need to put refcounted bridges). The .destroy callback is appropriate for this task but it is currently forbidden by drmm_connector_init(). Relax this limitation and document it. Signed-off-by: Luca Ceresoli --- The other obvious approach would be adding a separate .cleanup callback for the cleanup-only actions. I tried both, they both apparently work, so any arguments and opinions on which approach is best within the overall DRM design would be very useful here. --- drivers/gpu/drm/drm_connector.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connecto= r.c index 272d6254ea4784e97ca894ec4d463beebf9fdbf0..bd0220513a23afcb096b0c4c4d2= b957b81f21ee1 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -513,7 +513,8 @@ static void drm_connector_cleanup_action(struct drm_dev= ice *dev, * * The connector structure should be allocated with drmm_kzalloc(). * - * The @drm_connector_funcs.destroy hook must be NULL. + * The @drm_connector_funcs.destroy hook must only do connector-specific + * cleanups if any is needed, not dealloacte the connector. * * Returns: * Zero on success, error code on failure. @@ -526,9 +527,6 @@ int drmm_connector_init(struct drm_device *dev, { int ret; =20 - if (drm_WARN_ON(dev, funcs && funcs->destroy)) - return -EINVAL; - ret =3D drm_connector_init_and_add(dev, connector, funcs, connector_type,= ddc); if (ret) return ret; --=20 2.51.0 From nobody Wed Oct 1 23:27:51 2025 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6AEBB30C61E for ; Thu, 25 Sep 2025 17:20:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758820819; cv=none; b=XN+CI1RXvjWlNoG/Mzpkn8pMRlTYueX0vPQiYCDyT99yz3QEEqX2AVeaEit9En7ia0WSbi/ocwN+FeE2MCGt2Lh6U6qTJLqEu3oq+GXKSuu+1wLfMcLZObcVr3SjsvtEuP6BvHJ1l6DSzGsewRH5UZsH9gaSbgA2zRlgO6ZqatI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758820819; c=relaxed/simple; bh=hNgK/Uzgk3tiejJ33kqYpwo+r70mcWbyh9veVNBb6RQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Fop2vBDXJ2l2lJGgXhbH7TnVvrOACqV7nC+x8hhSHpIfSKkojGo559/qDK/L9ma2+h74eqFrXkXNmdvbFlgeCatdvu2RTBlxqQFrYE0n0vo1uIrcFW78rwtDr9IZREplmpMd52KW2g8GMhX9CFx4wRdmZ4XjWUJi7KIOuGbDxNo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=QA8pCY8/; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="QA8pCY8/" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id B756C1A0FB7; Thu, 25 Sep 2025 17:20:14 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 87FD560665; Thu, 25 Sep 2025 17:20:14 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id BE065102F18A1; Thu, 25 Sep 2025 19:20:11 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1758820813; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=0sMYzovaJDmQt5RrIh8C89vIF4dc6AtroV+cbqJJWgU=; b=QA8pCY8/lmMejdNVj6KIydE8Qkk4gdDe8/XOJjLefAcgEAkBdflA+weSm/6Vu8r6wqpf49 o64OyAmPuNTMwzTli/wwq1g+CbhuHtMI4arIp3Hgv23mncEJx1H8MlkP7PCEMkd+2TbsA2 7HWkI0RcaEgMNiknk26vYc4ljZc5+Nudfn0QopkQEpf9WgG4GRMPS8O4WsW5R/90SW1JTT +eqTHTi+zLt5iDkGEbrm1/oZDxmUlWfSE3Xgp1H4O9rJBMGs/x+MFL4gSDhbd8TaiNDWVK R875WN1DDIuVoSbJ0ihc8txc5auR1k5L4yQp4/mCBTKDrhiiXE8os8olQ1tcRw== From: Luca Ceresoli Date: Thu, 25 Sep 2025 19:19:50 +0200 Subject: [PATCH 2/2] drm/display: bridge-connector: get/put the stored bridges Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250925-drm-bridge-alloc-getput-bridge-connector-v1-2-f0736e1c73ee@bootlin.com> References: <20250925-drm-bridge-alloc-getput-bridge-connector-v1-0-f0736e1c73ee@bootlin.com> In-Reply-To: <20250925-drm-bridge-alloc-getput-bridge-connector-v1-0-f0736e1c73ee@bootlin.com> To: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Dmitry Baryshkov Cc: Hui Pu , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Luca Ceresoli X-Mailer: b4 0.14.2 X-Last-TLS-Session-Version: TLSv1.3 drm_bridge_connector_init() takes eight pointers to various bridges, some of which can be identical, and stores them in pointers inside struct drm_bridge_connector. Get a reference to each of the taken bridges and put it on cleanup. This is tricky because the pointers are currently stored directly in the drm_bridge_connector in the loop, but there is no nice and clean way to put those pointers on error return paths. To overcome this, store all pointers in temporary local variables with a cleanup action, and only on success copy them into struct drm_bridge_connector (getting another ref while copying). Additionally four of these pointers (edid, hpd, detect and modes) can be written in multiple loop iterations, in order to eventually store the last matching bridge. However when one of those pointers is overwritten once we need to put the reference that we got during the previous assignment. Add a drm_bridge_put() before writing them to handle this. Finally, there is also a function-local panel_bridge pointer taken inside the loop and used after the loop. Due to the various return points, use a __free() cleanup action to ensure it is put on return. Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/display/drm_bridge_connector.c | 112 +++++++++++++++++----= ---- 1 file changed, 76 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/d= rm/display/drm_bridge_connector.c index a5bdd6c1064399ece6b19560f145b877c9e0680e..4bcebbb8c9935fa55010a9d317f= 3d9e70b2ff7a3 100644 --- a/drivers/gpu/drm/display/drm_bridge_connector.c +++ b/drivers/gpu/drm/display/drm_bridge_connector.c @@ -268,11 +268,27 @@ static void drm_bridge_connector_reset(struct drm_con= nector *connector) connector->state); } =20 +static void drm_bridge_connector_destroy(struct drm_connector *connector) +{ + struct drm_bridge_connector *bridge_connector =3D + to_drm_bridge_connector(connector); + + drm_bridge_put(bridge_connector->bridge_edid); + drm_bridge_put(bridge_connector->bridge_hpd); + drm_bridge_put(bridge_connector->bridge_detect); + drm_bridge_put(bridge_connector->bridge_modes); + drm_bridge_put(bridge_connector->bridge_hdmi); + drm_bridge_put(bridge_connector->bridge_hdmi_audio); + drm_bridge_put(bridge_connector->bridge_dp_audio); + drm_bridge_put(bridge_connector->bridge_hdmi_cec); +} + static const struct drm_connector_funcs drm_bridge_connector_funcs =3D { .reset =3D drm_bridge_connector_reset, .detect =3D drm_bridge_connector_detect, .force =3D drm_bridge_connector_force, .fill_modes =3D drm_helper_probe_single_connector_modes, + .destroy =3D drm_bridge_connector_destroy, .atomic_duplicate_state =3D drm_atomic_helper_connector_duplicate_state, .atomic_destroy_state =3D drm_atomic_helper_connector_destroy_state, .debugfs_init =3D drm_bridge_connector_debugfs_init, @@ -638,7 +654,15 @@ struct drm_connector *drm_bridge_connector_init(struct= drm_device *drm, struct drm_bridge_connector *bridge_connector; struct drm_connector *connector; struct i2c_adapter *ddc =3D NULL; - struct drm_bridge *panel_bridge =3D NULL; + struct drm_bridge *panel_bridge __free(drm_bridge_put) =3D NULL; + struct drm_bridge *bridge_edid __free(drm_bridge_put) =3D NULL; + struct drm_bridge *bridge_hpd __free(drm_bridge_put) =3D NULL; + struct drm_bridge *bridge_detect __free(drm_bridge_put) =3D NULL; + struct drm_bridge *bridge_modes __free(drm_bridge_put) =3D NULL; + struct drm_bridge *bridge_hdmi __free(drm_bridge_put) =3D NULL; + struct drm_bridge *bridge_hdmi_audio __free(drm_bridge_put) =3D NULL; + struct drm_bridge *bridge_dp_audio __free(drm_bridge_put) =3D NULL; + struct drm_bridge *bridge_hdmi_cec __free(drm_bridge_put) =3D NULL; unsigned int supported_formats =3D BIT(HDMI_COLORSPACE_RGB); unsigned int max_bpc =3D 8; bool support_hdcp =3D false; @@ -672,22 +696,30 @@ struct drm_connector *drm_bridge_connector_init(struc= t drm_device *drm, if (!bridge->ycbcr_420_allowed) connector->ycbcr_420_allowed =3D false; =20 - if (bridge->ops & DRM_BRIDGE_OP_EDID) - bridge_connector->bridge_edid =3D bridge; - if (bridge->ops & DRM_BRIDGE_OP_HPD) - bridge_connector->bridge_hpd =3D bridge; - if (bridge->ops & DRM_BRIDGE_OP_DETECT) - bridge_connector->bridge_detect =3D bridge; - if (bridge->ops & DRM_BRIDGE_OP_MODES) - bridge_connector->bridge_modes =3D bridge; + if (bridge->ops & DRM_BRIDGE_OP_EDID) { + drm_bridge_put(bridge_edid); + bridge_edid =3D drm_bridge_get(bridge); + } + if (bridge->ops & DRM_BRIDGE_OP_HPD) { + drm_bridge_put(bridge_hpd); + bridge_hpd =3D drm_bridge_get(bridge); + } + if (bridge->ops & DRM_BRIDGE_OP_DETECT) { + drm_bridge_put(bridge_detect); + bridge_detect =3D drm_bridge_get(bridge); + } + if (bridge->ops & DRM_BRIDGE_OP_MODES) { + drm_bridge_put(bridge_modes); + bridge_modes =3D drm_bridge_get(bridge); + } if (bridge->ops & DRM_BRIDGE_OP_HDMI) { - if (bridge_connector->bridge_hdmi) + if (bridge_hdmi) return ERR_PTR(-EBUSY); if (!bridge->funcs->hdmi_write_infoframe || !bridge->funcs->hdmi_clear_infoframe) return ERR_PTR(-EINVAL); =20 - bridge_connector->bridge_hdmi =3D bridge; + bridge_hdmi =3D drm_bridge_get(bridge); =20 if (bridge->supported_formats) supported_formats =3D bridge->supported_formats; @@ -696,10 +728,10 @@ struct drm_connector *drm_bridge_connector_init(struc= t drm_device *drm, } =20 if (bridge->ops & DRM_BRIDGE_OP_HDMI_AUDIO) { - if (bridge_connector->bridge_hdmi_audio) + if (bridge_hdmi_audio) return ERR_PTR(-EBUSY); =20 - if (bridge_connector->bridge_dp_audio) + if (bridge_dp_audio) return ERR_PTR(-EBUSY); =20 if (!bridge->hdmi_audio_max_i2s_playback_channels && @@ -710,14 +742,14 @@ struct drm_connector *drm_bridge_connector_init(struc= t drm_device *drm, !bridge->funcs->hdmi_audio_shutdown) return ERR_PTR(-EINVAL); =20 - bridge_connector->bridge_hdmi_audio =3D bridge; + bridge_hdmi_audio =3D drm_bridge_get(bridge); } =20 if (bridge->ops & DRM_BRIDGE_OP_DP_AUDIO) { - if (bridge_connector->bridge_dp_audio) + if (bridge_dp_audio) return ERR_PTR(-EBUSY); =20 - if (bridge_connector->bridge_hdmi_audio) + if (bridge_hdmi_audio) return ERR_PTR(-EBUSY); =20 if (!bridge->hdmi_audio_max_i2s_playback_channels && @@ -728,7 +760,7 @@ struct drm_connector *drm_bridge_connector_init(struct = drm_device *drm, !bridge->funcs->dp_audio_shutdown) return ERR_PTR(-EINVAL); =20 - bridge_connector->bridge_dp_audio =3D bridge; + bridge_dp_audio =3D drm_bridge_get(bridge); } =20 if (bridge->ops & DRM_BRIDGE_OP_HDMI_CEC_NOTIFIER) { @@ -739,10 +771,10 @@ struct drm_connector *drm_bridge_connector_init(struc= t drm_device *drm, } =20 if (bridge->ops & DRM_BRIDGE_OP_HDMI_CEC_ADAPTER) { - if (bridge_connector->bridge_hdmi_cec) + if (bridge_hdmi_cec) return ERR_PTR(-EBUSY); =20 - bridge_connector->bridge_hdmi_cec =3D bridge; + bridge_hdmi_cec =3D drm_bridge_get(bridge); =20 if (!bridge->funcs->hdmi_cec_enable || !bridge->funcs->hdmi_cec_log_addr || @@ -762,7 +794,7 @@ struct drm_connector *drm_bridge_connector_init(struct = drm_device *drm, ddc =3D bridge->ddc; =20 if (drm_bridge_is_panel(bridge)) - panel_bridge =3D bridge; + panel_bridge =3D drm_bridge_get(bridge); =20 if (bridge->support_hdcp) support_hdcp =3D true; @@ -771,13 +803,13 @@ struct drm_connector *drm_bridge_connector_init(struc= t drm_device *drm, if (connector_type =3D=3D DRM_MODE_CONNECTOR_Unknown) return ERR_PTR(-EINVAL); =20 - if (bridge_connector->bridge_hdmi) { + if (bridge_hdmi) { if (!connector->ycbcr_420_allowed) supported_formats &=3D ~BIT(HDMI_COLORSPACE_YUV420); =20 ret =3D drmm_connector_hdmi_init(drm, connector, - bridge_connector->bridge_hdmi->vendor, - bridge_connector->bridge_hdmi->product, + bridge_hdmi->vendor, + bridge_hdmi->product, &drm_bridge_connector_funcs, &drm_bridge_connector_hdmi_funcs, connector_type, ddc, @@ -793,15 +825,14 @@ struct drm_connector *drm_bridge_connector_init(struc= t drm_device *drm, return ERR_PTR(ret); } =20 - if (bridge_connector->bridge_hdmi_audio || - bridge_connector->bridge_dp_audio) { + if (bridge_hdmi_audio || bridge_dp_audio) { struct device *dev; struct drm_bridge *bridge; =20 - if (bridge_connector->bridge_hdmi_audio) - bridge =3D bridge_connector->bridge_hdmi_audio; + if (bridge_hdmi_audio) + bridge =3D bridge_hdmi_audio; else - bridge =3D bridge_connector->bridge_dp_audio; + bridge =3D bridge_dp_audio; =20 dev =3D bridge->hdmi_audio_dev; =20 @@ -815,9 +846,9 @@ struct drm_connector *drm_bridge_connector_init(struct = drm_device *drm, return ERR_PTR(ret); } =20 - if (bridge_connector->bridge_hdmi_cec && - bridge_connector->bridge_hdmi_cec->ops & DRM_BRIDGE_OP_HDMI_CEC_NOTIF= IER) { - struct drm_bridge *bridge =3D bridge_connector->bridge_hdmi_cec; + if (bridge_hdmi_cec && + bridge_hdmi_cec->ops & DRM_BRIDGE_OP_HDMI_CEC_NOTIFIER) { + struct drm_bridge *bridge =3D bridge_hdmi_cec; =20 ret =3D drmm_connector_hdmi_cec_notifier_register(connector, NULL, @@ -826,9 +857,9 @@ struct drm_connector *drm_bridge_connector_init(struct = drm_device *drm, return ERR_PTR(ret); } =20 - if (bridge_connector->bridge_hdmi_cec && - bridge_connector->bridge_hdmi_cec->ops & DRM_BRIDGE_OP_HDMI_CEC_ADAPT= ER) { - struct drm_bridge *bridge =3D bridge_connector->bridge_hdmi_cec; + if (bridge_hdmi_cec && + bridge_hdmi_cec->ops & DRM_BRIDGE_OP_HDMI_CEC_ADAPTER) { + struct drm_bridge *bridge =3D bridge_hdmi_cec; =20 ret =3D drmm_connector_hdmi_cec_register(connector, &drm_bridge_connector_hdmi_cec_funcs, @@ -841,9 +872,9 @@ struct drm_connector *drm_bridge_connector_init(struct = drm_device *drm, =20 drm_connector_helper_add(connector, &drm_bridge_connector_helper_funcs); =20 - if (bridge_connector->bridge_hpd) + if (bridge_hpd) connector->polled =3D DRM_CONNECTOR_POLL_HPD; - else if (bridge_connector->bridge_detect) + else if (bridge_detect) connector->polled =3D DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; =20 @@ -854,6 +885,15 @@ struct drm_connector *drm_bridge_connector_init(struct= drm_device *drm, IS_ENABLED(CONFIG_DRM_DISPLAY_HDCP_HELPER)) drm_connector_attach_content_protection_property(connector, true); =20 + bridge_connector->bridge_edid =3D drm_bridge_get(bridge_edid); + bridge_connector->bridge_hpd =3D drm_bridge_get(bridge_hpd); + bridge_connector->bridge_detect =3D drm_bridge_get(bridge_detect); + bridge_connector->bridge_modes =3D drm_bridge_get(bridge_modes); + bridge_connector->bridge_hdmi =3D drm_bridge_get(bridge_hdmi); + bridge_connector->bridge_hdmi_audio =3D drm_bridge_get(bridge_hdmi_audio); + bridge_connector->bridge_dp_audio =3D drm_bridge_get(bridge_dp_audio); + bridge_connector->bridge_hdmi_cec =3D drm_bridge_get(bridge_hdmi_cec); + return connector; } EXPORT_SYMBOL_GPL(drm_bridge_connector_init); --=20 2.51.0