From nobody Mon May 25 01:57:46 2026 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 DA64635203B for ; Tue, 19 May 2026 10:38:11 +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=1779187093; cv=none; b=A+axNIjSOyLhu1WcHl5NQCKcqcVtt4QO2VgTsMl+xdG/mUWoG7O+gGhr72cIAA6WkGHVKaRuuVSLz3QyXA+KoburUWWHNsKTfyAnm6LOTDqC4+ZVqULuXPv+Tda7LhS+Hp3Xsk2GipGF44o3gjEHQr5K4JOc8yGnw0GGqHQ+zWA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187093; c=relaxed/simple; bh=cPeDAyvQg4XpfYpV4wQkA7Syl5qYKPeL/Ro5YVklY70=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=uPVORdKa/JC8Zj4bHMlTaxSb7tDRIog0jajgIy4qzTH+uHyhyR3NB9nME5toKOhVJ9q81zCNA1iD6+2lihZ5O3pXDVFxsqITL2R8fXaGUNINQ44L4JvqQwXKF3gI8RKCdVn0as4sdRpBwB9b4ZTIVFzlbQpn5uojn5uYJCH8PHA= 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=i6mHAuI7; 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="i6mHAuI7" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 7506E1A3628; Tue, 19 May 2026 10:38:10 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 46C0F606E9; Tue, 19 May 2026 10:38:10 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id C05FF107E8ABD; Tue, 19 May 2026 12:38:04 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187088; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=blKbTTwyDFAtSUCP5vAQgBxGuxdjJMITQpGkNOB3QT8=; b=i6mHAuI7Z6z0XXyfO6xvodt2fFIx7CJsxEsXRW7q8+ucjA2ZtN1qD15+9+DPBMmDDPXp0N L7TMVhvoLE3xeeJH1VKk4AuI1GWV7draVlvdZCbkLmNgShstoc07BVap1VQZDEXgeUWfHu dgFdDrhDxSgf+pqqDCNJSMDqrQ7j0XHh42yvfoFUYtHExwaODG7cdMIkRAPrVPcIN1Tjf2 AjPgy1lr3Id3fOPvIv7TTzaQ1waE29boOCHArNDiJgFNVvy5JarkQo3J/8JKEZXm142FPO hgL/PY9C2miGODN0aeWlppLIXyJClO6hWfmdAFM9wDedhR747M0ViuDSxMFHpQ== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:18 +0200 Subject: [PATCH 01/37] drm/connector: split drmm_connector_hdmi_init() in 3 parts 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: <20260519-drm-bridge-hotplug-v1-1-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 In preparation for adding a dynamic variant of drmm_connector_hdmi_init(), split reusable parts of the code to subfunctions. drmm_connector_hdmi_init() currently has 3 sections: 1. sanity checks 2. call drmm_connector_init() 3. initialize HDMI-specific fields not initialized at step 2 Split 1 and 3 to new functions, reusable independently. No functional changes. Just moving code around. Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/drm_connector.c | 105 +++++++++++++++++++++++++-----------= ---- 1 file changed, 65 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connecto= r.c index 3fa4d2082cd7..37ed73300a18 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -542,44 +542,13 @@ int drmm_connector_init(struct drm_device *dev, } EXPORT_SYMBOL(drmm_connector_init); =20 -/** - * drmm_connector_hdmi_init - Init a preallocated HDMI connector - * @dev: DRM device - * @connector: A pointer to the HDMI connector to init - * @vendor: HDMI Controller Vendor name - * @product: HDMI Controller Product name - * @funcs: callbacks for this connector - * @hdmi_funcs: HDMI-related callbacks for this connector - * @connector_type: user visible type of the connector - * @ddc: optional pointer to the associated ddc adapter - * @supported_formats: Bitmask of @drm_output_color_format listing support= ed output formats - * @max_bpc: Maximum bits per char the HDMI connector supports - * - * Initialises a preallocated HDMI connector. Connectors can be - * subclassed as part of driver connector objects. - * - * Cleanup is automatically handled with a call to - * drm_connector_cleanup() in a DRM-managed action. - * - * The connector structure should be allocated with drmm_kzalloc(). - * - * The @drm_connector_funcs.destroy hook must be NULL. - * - * Returns: - * Zero on success, error code on failure. - */ -int drmm_connector_hdmi_init(struct drm_device *dev, - struct drm_connector *connector, - const char *vendor, const char *product, - const struct drm_connector_funcs *funcs, - const struct drm_connector_hdmi_funcs *hdmi_funcs, - int connector_type, - struct i2c_adapter *ddc, - unsigned long supported_formats, - unsigned int max_bpc) +static int drm_connector_hdmi_sanity_checks(struct drm_connector *connecto= r, + const char *vendor, const char *product, + const struct drm_connector_hdmi_funcs *hdmi_funcs, + int connector_type, + unsigned long supported_formats, + unsigned int max_bpc) { - int ret; - if (!vendor || !product) return -EINVAL; =20 @@ -606,10 +575,15 @@ int drmm_connector_hdmi_init(struct drm_device *dev, !hdmi_funcs->hdmi.write_infoframe) return -EINVAL; =20 - ret =3D drmm_connector_init(dev, connector, funcs, connector_type, ddc); - if (ret) - return ret; + return 0; +} =20 +static void drm_connector_hdmi_init(struct drm_connector *connector, + const char *vendor, const char *product, + const struct drm_connector_hdmi_funcs *hdmi_funcs, + unsigned long supported_formats, + unsigned int max_bpc) +{ connector->hdmi.supported_formats =3D supported_formats; strtomem_pad(connector->hdmi.vendor, vendor, 0); strtomem_pad(connector->hdmi.product, product, 0); @@ -628,6 +602,57 @@ int drmm_connector_hdmi_init(struct drm_device *dev, drm_connector_attach_hdr_output_metadata_property(connector); =20 connector->hdmi.funcs =3D hdmi_funcs; +} + +/** + * drmm_connector_hdmi_init - Init a preallocated HDMI connector + * @dev: DRM device + * @connector: A pointer to the HDMI connector to init + * @vendor: HDMI Controller Vendor name + * @product: HDMI Controller Product name + * @funcs: callbacks for this connector + * @hdmi_funcs: HDMI-related callbacks for this connector + * @connector_type: user visible type of the connector + * @ddc: optional pointer to the associated ddc adapter + * @supported_formats: Bitmask of @drm_output_color_format listing support= ed output formats + * @max_bpc: Maximum bits per char the HDMI connector supports + * + * Initialises a preallocated HDMI connector. Connectors can be + * subclassed as part of driver connector objects. + * + * Cleanup is automatically handled with a call to + * drm_connector_cleanup() in a DRM-managed action. + * + * The connector structure should be allocated with drmm_kzalloc(). + * + * The @drm_connector_funcs.destroy hook must be NULL. + * + * Returns: + * Zero on success, error code on failure. + */ +int drmm_connector_hdmi_init(struct drm_device *dev, + struct drm_connector *connector, + const char *vendor, const char *product, + const struct drm_connector_funcs *funcs, + const struct drm_connector_hdmi_funcs *hdmi_funcs, + int connector_type, + struct i2c_adapter *ddc, + unsigned long supported_formats, + unsigned int max_bpc) +{ + int ret; + + ret =3D drm_connector_hdmi_sanity_checks(connector, vendor, product, hdmi= _funcs, + connector_type, supported_formats, max_bpc); + if (ret) + return ret; + + ret =3D drmm_connector_init(dev, connector, funcs, connector_type, ddc); + if (ret) + return ret; + + drm_connector_hdmi_init(connector, vendor, product, + hdmi_funcs, supported_formats, max_bpc); =20 return 0; } --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 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 DA5B5370ADA for ; Tue, 19 May 2026 10:38:15 +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=1779187097; cv=none; b=TSGMj3S2D6wXEnnE3iIEME/jRzWKAgDb414IALImJa7aTlc1M8c4i7EFlC7uqiQHOSxh/iu5kXT3K7LC9ovHawbhF6ZOHnOnE8sAynVUDN0FZtN2NRf07LuSQcpBGASVCsQ6/wUO3rDmXBXeGwSlteSFj7vXhyf8uF2trDR/Eac= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187097; c=relaxed/simple; bh=vL3kR1hNzeRzmT9cU7GZ5YnpAuR7rIDhz0VHkNANYyM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=YZeL77nUxmXDLvlzmo9X6jSq3/MlqLUmHJhduSo1NWGmi0k8+ki/3W0MTS4Oj+Ra2Ac9B+mkCV0GNGi+r+l7Sizet44JpWHA8bDRYzRbkj28wItDsEF3bhnXiaP26OAmbR4U4mAMJKN0cggpj7c7jbFSMOR2/dwQMDADATk3AzY= 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=wfRUbZv9; 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="wfRUbZv9" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 903D91A3627; Tue, 19 May 2026 10:38:14 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 62F5B606E9; Tue, 19 May 2026 10:38:14 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id DF45B107E8AB2; Tue, 19 May 2026 12:38:08 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187092; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=9aDTr9w2iMM3B9icFD9CXFezhKLvHw/SAcu5pC+lah0=; b=wfRUbZv9vuadgyhkI0IbLyIInUMKLCCshiB9JgwNWe71jeAV6dGs4xzdUGajngzCaiaDHL vZ9eMzkCfNca5i8A89tHxSqj5zTcQIRhU3gdk9jzvjbP0R1hqPdQ6NYtASJVUDomO0FS80 OOmWAcf4i77WAVxg+3g3G6vOZzZkR/2rXDG8vQd26tLcACS5aOlDPplDKlWPvpVHSaK0dF mpfdEKz43EZmZ9tFw9Pe9iipEj8R9LczJMUZj1Tpq7vFc2kuZskyJBvt0AlmNgvhE12BJt Xo1jsdY5eJMOt/YCzw/uVlvTxy9KQd9gsqNk3NZkKdnlqk7jKV6wx1duEviBqg== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:19 +0200 Subject: [PATCH 02/37] drm/connector: add drm_connector_hdmi_dynamic_init() 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: <20260519-drm-bridge-hotplug-v1-2-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 In preparation for adding hotpluggable bridges into the drm_bridge_connector, we need connectors to be created dynamically, both regular connectors and HDMI ones. drm_connector_init() already has a dynamic variant, add one for HDMI connectors too. Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/drm_connector.c | 50 +++++++++++++++++++++++++++++++++++++= ++++ include/drm/drm_connector.h | 9 ++++++++ 2 files changed, 59 insertions(+) diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connecto= r.c index 37ed73300a18..5e7a3a438e5d 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -658,6 +658,56 @@ int drmm_connector_hdmi_init(struct drm_device *dev, } EXPORT_SYMBOL(drmm_connector_hdmi_init); =20 +/** + * drm_connector_hdmi_dynamic_init - Init a preallocated dynamic HDMI conn= ector + * @dev: DRM device + * @connector: A pointer to the HDMI connector to init + * @vendor: HDMI Controller Vendor name + * @product: HDMI Controller Product name + * @funcs: callbacks for this connector + * @hdmi_funcs: HDMI-related callbacks for this connector + * @connector_type: user visible type of the connector + * @ddc: optional pointer to the associated ddc adapter + * @supported_formats: Bitmask of @hdmi_colorspace listing supported outpu= t formats + * @max_bpc: Maximum bits per char the HDMI connector supports + * + * Initialises a preallocated dynamic HDMI connector. Connectors can be + * subclassed as part of driver connector objects. + * + * See drm_connector_dynamic_init(), the same constraints apply here. This + * is just the HDMI version. + * + * Returns: + * Zero on success, error code on failure. + */ +int drm_connector_hdmi_dynamic_init(struct drm_device *dev, + struct drm_connector *connector, + const char *vendor, const char *product, + const struct drm_connector_funcs *funcs, + const struct drm_connector_hdmi_funcs *hdmi_funcs, + int connector_type, + struct i2c_adapter *ddc, + unsigned long supported_formats, + unsigned int max_bpc) +{ + int ret; + + ret =3D drm_connector_hdmi_sanity_checks(connector, vendor, product, hdmi= _funcs, + connector_type, supported_formats, max_bpc); + if (ret) + return ret; + + ret =3D drm_connector_dynamic_init(dev, connector, funcs, connector_type,= ddc); + if (ret) + return ret; + + drm_connector_hdmi_init(connector, vendor, product, + hdmi_funcs, supported_formats, max_bpc); + + return 0; +} +EXPORT_SYMBOL(drm_connector_hdmi_dynamic_init); + /** * drm_connector_attach_edid_property - attach edid property. * @connector: the connector diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 5ad62c207d00..1f5dba947748 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -2442,6 +2442,15 @@ int drmm_connector_hdmi_init(struct drm_device *dev, struct i2c_adapter *ddc, unsigned long supported_formats, unsigned int max_bpc); +int drm_connector_hdmi_dynamic_init(struct drm_device *dev, + struct drm_connector *connector, + const char *vendor, const char *product, + const struct drm_connector_funcs *funcs, + const struct drm_connector_hdmi_funcs *hdmi_funcs, + int connector_type, + struct i2c_adapter *ddc, + unsigned long supported_formats, + unsigned int max_bpc); void drm_connector_attach_edid_property(struct drm_connector *connector); int drm_connector_register(struct drm_connector *connector); int drm_connector_dynamic_register(struct drm_connector *connector); --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 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 06BC6370ADD for ; Tue, 19 May 2026 10:38:19 +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=1779187101; cv=none; b=csfxOwXu2xohjXOwPZGeG7AF2Vd27XGtWO48OSHRAwOUD9KCWSZcWfpkSmedbZJ8frK4OkOiy43Qexd4U9x1qC1j9uO1E4As5RYRqeFDCQZk/9fIxhubirZs0IEO02MFzAOIhtUqyNRD8sY1qW/g0HswNAa0+qPetl0Bi2Xf2tk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187101; c=relaxed/simple; bh=qa0OFXjHmmzKFPRmIR0Zm2i2uzdIC0kuazb1S7D17vw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=PgQrKmxedjJ9Z6jPCl9jARm6bztrEvuBIthHZwOfOOdwz3M7WPJjKvqTntHVkVciT6SWKZpeQ4xUHNvGNV6AW+BZs9X4XF95iho3LOwMbNxzsZfVjs14MSxRCpfcZ6fEgx1lKAs10YbUUZsdP06jBWHyWnNGl0FBUfUpT7FUIso= 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=fl4SN8gA; 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="fl4SN8gA" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id BB4581A3627; Tue, 19 May 2026 10:38:18 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 88012606E9; Tue, 19 May 2026 10:38:18 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 3E6BD107E8AC3; Tue, 19 May 2026 12:38:12 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187096; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=fRIgFduSx5LrCBKqsod6YR/tv16FPuPFSGj6OkltIK0=; b=fl4SN8gAWvj/PAiytK2mcEd2traVpn5cG4m+z9kQKTNCNDfgWVHadA/ResQaAPMBDhSf2a 2fcKYgI8FG4j2mS/8mivgiNk2FGbRzn7YJhQ/FYmvJTAtl9MlKS9Azt+aY7Z5WYYPYF6iA 6y1j39oW/ih8WimyqqcBX9t6mZwHjaeV81Xv58upXqf3DR1ufWU4A8hi1rpEnepdec3/zi sOUhea5qCZrzitRgzqn5ugyewn87IguREaVbkLxu+iI+X9rk+5wmp/wa5Yh6cSZIZkCbRk DvmhUpAML1cXNeCUw/gYfGdVZj01oNQwMsqGO6OBLdrB6kdyPCYZEocOYFhJ1g== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:20 +0200 Subject: [PATCH 03/37] drm/display: bridge-connector: rename variable for consistency 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: <20260519-drm-bridge-hotplug-v1-3-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 All struct drm_bridge_connector pointers are called bridge_connector except this one. Rename it for consistency. Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/display/drm_bridge_connector.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/d= rm/display/drm_bridge_connector.c index 649969fca141..bf9b8a6bca78 100644 --- a/drivers/gpu/drm/display/drm_bridge_connector.c +++ b/drivers/gpu/drm/display/drm_bridge_connector.c @@ -153,10 +153,10 @@ static void drm_bridge_connector_hpd_notify(struct dr= m_connector *connector, } } =20 -static void drm_bridge_connector_handle_hpd(struct drm_bridge_connector *d= rm_bridge_connector, +static void drm_bridge_connector_handle_hpd(struct drm_bridge_connector *b= ridge_connector, enum drm_connector_status status) { - struct drm_connector *connector =3D &drm_bridge_connector->base; + struct drm_connector *connector =3D &bridge_connector->base; struct drm_device *dev =3D connector->dev; =20 mutex_lock(&dev->mode_config.mutex); --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (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 F027B370AD4 for ; Tue, 19 May 2026 10:38:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187106; cv=none; b=gXKKtm5uy1DM8p46n3NIp5R0Bj2SP17Iyin9Zi5gmQsVYzLkmKCFV/VQvBotU8CSO+UigH3hDJBiCKwucBZIFQJLhKmVzBo8TpJQrYza+qME2i7U4Q0cTwcyE4G6jBpu50rztNVSCOAtGOV468xb3nuOUon2rqcR38a7cT4rFVs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187106; c=relaxed/simple; bh=C5wGDyHN494Et5weLKkq6t7JvIdVjHdO88C0ifdNGt4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=S5OAxN+V7P9w7c+CZMxW3Gj1/U3bm/Ea345ib4fJUgob57xywz40+u5GUedPYtH5vMKCkQGzpyJNIAa8uShpx0i5rExlTv+BBZJc2PB//4gNfyd/iCHaEp7149px9Y0MLyW7H3Bvpi7H6Wz4O9OECjgzBq5uD0QFenBIPS1gUyg= 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=kHr+SgeM; arc=none smtp.client-ip=185.246.85.4 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="kHr+SgeM" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id A984F4E42CF1; Tue, 19 May 2026 10:38:23 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 7662D606E9; Tue, 19 May 2026 10:38:23 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 59BD0107E8AC6; Tue, 19 May 2026 12:38:17 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187101; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=n+kT7vAmUewDgxn0HFnyrYRIIpXTDKvHS24hGWBZNk8=; b=kHr+SgeMkKDgHfFsBa+jwf3WSU+g6MmNk/Zd47ZGKQzMTxsmVgm/iEanabVx+q6IT7wS0q tMk6l552cVuw6bofUI3j/qxXtUyAQUwE8HwsbE3LJV/782dzziRnN/lSKp5NGTs2eA6tdp R7bG0UYPTZyhpM8dIFLPDM2D7bMSJYmYVpMmAkGKqA7UEGTyd4EeTM1FYjnHCghdQD5c5G liZfh0xicJEwiqBL2kvDWQxavhLJnP4Sfzz3nbkEcjyp1hHIgHCRz5I2bXKLPHFbhM3mNF i5uWNB0i/MKl37Itesk4hc+40tgMtRg5nYbL4CoEX7ORJVQ6yq/M3s9EjVfo0Q== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:21 +0200 Subject: [PATCH 04/37] drm/display: bridge-connector: store the drm_device pointer 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: <20260519-drm-bridge-hotplug-v1-4-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 Currently the struct drm_device pointer is only needed during the initial drm_bridge_connector_init() and in drm_bridge_connector_handle_hpd() which gets it from the struct drm_connector. This will be insufficient when introducing bridge hotplugging, because: * some of the actions in drm_bridge_connector_init() will have to be performed later on, when a bridge is hot(un)plugged * the connector will be removed and re-added based on hotplug events, so the drm_connector might just not exist or its content be cleared Store the drm_device pointer in struct drm_bridge_connector for any later needs. Also convert drm_bridge_connector_handle_hpd() to use the newly stored value. Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/display/drm_bridge_connector.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/d= rm/display/drm_bridge_connector.c index bf9b8a6bca78..62c4cb1e241f 100644 --- a/drivers/gpu/drm/display/drm_bridge_connector.c +++ b/drivers/gpu/drm/display/drm_bridge_connector.c @@ -60,6 +60,10 @@ struct drm_bridge_connector { * @base: The base DRM connector */ struct drm_connector base; + /** + * @drm: The DRM device we belong to + */ + struct drm_device *drm; /** * @encoder: * @@ -157,7 +161,7 @@ static void drm_bridge_connector_handle_hpd(struct drm_= bridge_connector *bridge_ enum drm_connector_status status) { struct drm_connector *connector =3D &bridge_connector->base; - struct drm_device *dev =3D connector->dev; + struct drm_device *dev =3D bridge_connector->drm; =20 mutex_lock(&dev->mode_config.mutex); connector->status =3D status; @@ -806,6 +810,7 @@ struct drm_connector *drm_bridge_connector_init(struct = drm_device *drm, if (ret) return ERR_PTR(ret); =20 + bridge_connector->drm =3D drm; bridge_connector->encoder =3D encoder; =20 /* --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 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 EC5163A641C for ; Tue, 19 May 2026 10:38:28 +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=1779187110; cv=none; b=Z/myfIjDCqxW7Z6ItTbPfy4vIT4WGy7/k6LKFNcrvDVJ6LgMwUoW5MTMARQWdS8RLjvC1D8efb9dOOiobIPBRc+psoWlR5nOqp4qsjOWKef91xeGhhBGY5ueZ9oX0B3vYZSyWQVy+lNb4WYQ/6Em2MmJfW6Y8qXGjrniYoJoXJk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187110; c=relaxed/simple; bh=c5VwM0zOXf52fMgluI/UhyL/8m78TvXodDVSx3JscIE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Sg8OSptCVECxa0P98u9/l+yMVidMoE1ATJWyQ0OCbr4OabKEIFF2pWz27s0KsroTsQyyUuLnEQ3yG8VlUrtFL5xvv70nm5uAA8AQd1IEvOOsCq/MknKuw3OwnVF8FhICm8IBajnq38MeFCPdYQjj6vQnm3kE5qhSX2VmtobWqZ4= 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=fRLPMHBu; 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="fRLPMHBu" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id A438BC2B9DB; Tue, 19 May 2026 10:39:20 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 79416606E9; Tue, 19 May 2026 10:38:27 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id CE763107E8ACB; Tue, 19 May 2026 12:38:21 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187105; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=KI66U/01m5OEBxUl36NyMu4JublFhpjqljtSlWdzHko=; b=fRLPMHBuiYiV/qsr2Jj2gZRh5XI18yoYzKXjyJ7++lceEmZOdXzcoIXMr/DttS8tA3bCT3 AOMLo3vDiAgYbK6rClApHhfs1cVH579q8077g2uQk7/8vUMdl34oFJ5YrkKd+xaSzzJUvr uYCJ0uOv953A1aiJr1u9u2WGX3xWiNs8KDwDy4w2VtAS7wxUTSfmHut0XH87qqO2upbP0Q bV7+6DkOSgQooMZr70kk2r7Ct5o75cV/MgdUE43YZvEGIBv4RKD8YxgMWc9h0YD7hVUgxR ccDQydCfxkeQm0JvfsDlmYo7EuacwTUT6bHsLtxq3g+GllM/C5xuWwjvYWWkHw== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:22 +0200 Subject: [PATCH 05/37] drm/display: bridge-connector: split code creating the connector to a subfunction 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: <20260519-drm-bridge-hotplug-v1-5-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 In preparation to introduce bridge hotplug, split out from drm_bridge_connector_init() the code adding the drm_connector into a dedicated function. This will be needed to be able to add (and re-add) the connector from different code paths. No functional changes. Just moving code around. Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/display/drm_bridge_connector.c | 81 ++++++++++++++++------= ---- 1 file changed, 50 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/d= rm/display/drm_bridge_connector.c index 62c4cb1e241f..6813c6008985 100644 --- a/drivers/gpu/drm/display/drm_bridge_connector.c +++ b/drivers/gpu/drm/display/drm_bridge_connector.c @@ -773,26 +773,19 @@ static void drm_bridge_connector_put_bridges(struct d= rm_device *dev, void *data) } =20 /** - * drm_bridge_connector_init - Initialise a connector for a chain of bridg= es - * @drm: the DRM device - * @encoder: the encoder where the bridge chain starts - * - * Create a new &drm_bridge_connector for the @drm device. The connector is - * allocated, initialised, registered with the @drm device and attached to - * @encoder. + * drm_bridge_connector_add_connector - add the drm_connector + * @bridge_connector: drm_bridge_connector to add the drm_connector to * - * The connector is associated with a chain of bridges that starts at - * the @encoder. All bridges in the chain shall report bridge operation fl= ags - * (&drm_bridge->ops) and bridge output type (&drm_bridge->type), and none= of - * them may create a DRM connector directly. + * Preconditions: the drm_bridge_connector is initialized (the + * @bridge_connector->drm and @bridge_connector->encoder fields are + * assigned at least) * - * Returns a pointer to the new connector on success, or a negative error - * pointer otherwise. + * Returns a pointer to the new drm_connector on success, or a negative + * error pointer otherwise. */ -struct drm_connector *drm_bridge_connector_init(struct drm_device *drm, - struct drm_encoder *encoder) +static struct drm_connector * +drm_bridge_connector_add_connector(struct drm_bridge_connector *bridge_con= nector) { - struct drm_bridge_connector *bridge_connector; struct drm_connector *connector; struct i2c_adapter *ddc =3D NULL; struct drm_bridge *panel_bridge __free(drm_bridge_put) =3D NULL; @@ -802,17 +795,6 @@ struct drm_connector *drm_bridge_connector_init(struct= drm_device *drm, int connector_type; int ret; =20 - bridge_connector =3D drmm_kzalloc(drm, sizeof(*bridge_connector), GFP_KER= NEL); - if (!bridge_connector) - return ERR_PTR(-ENOMEM); - - ret =3D drmm_add_action(drm, drm_bridge_connector_put_bridges, bridge_con= nector); - if (ret) - return ERR_PTR(ret); - - bridge_connector->drm =3D drm; - bridge_connector->encoder =3D encoder; - /* * TODO: Handle doublescan_allowed and stereo_allowed. */ @@ -828,7 +810,7 @@ struct drm_connector *drm_bridge_connector_init(struct = drm_device *drm, * detection are available, we don't support hotplug detection at all. */ connector_type =3D DRM_MODE_CONNECTOR_Unknown; - drm_for_each_bridge_in_chain_scoped(encoder, bridge) { + drm_for_each_bridge_in_chain_scoped(bridge_connector->encoder, bridge) { if (!bridge->interlace_allowed) connector->interlace_allowed =3D false; if (!bridge->ycbcr_420_allowed) @@ -984,7 +966,7 @@ struct drm_connector *drm_bridge_connector_init(struct = drm_device *drm, bridge_connector->hdmi_funcs.spd =3D drm_bridge_connector_hdmi_spd_infoframe; =20 - ret =3D drmm_connector_hdmi_init(drm, connector, + ret =3D drmm_connector_hdmi_init(bridge_connector->drm, connector, bridge_connector->bridge_hdmi->vendor, bridge_connector->bridge_hdmi->product, &drm_bridge_connector_funcs, @@ -995,7 +977,7 @@ struct drm_connector *drm_bridge_connector_init(struct = drm_device *drm, if (ret) return ERR_PTR(ret); } else { - ret =3D drmm_connector_init(drm, connector, + ret =3D drmm_connector_init(bridge_connector->drm, connector, &drm_bridge_connector_funcs, connector_type, ddc); if (ret) @@ -1063,10 +1045,47 @@ struct drm_connector *drm_bridge_connector_init(str= uct drm_device *drm, IS_ENABLED(CONFIG_DRM_DISPLAY_HDCP_HELPER)) drm_connector_attach_content_protection_property(connector, true); =20 - ret =3D drm_connector_attach_encoder(connector, encoder); + ret =3D drm_connector_attach_encoder(connector, bridge_connector->encoder= ); if (ret) return ERR_PTR(ret); =20 return connector; } + +/** + * drm_bridge_connector_init - Initialise a connector for a chain of bridg= es + * @drm: the DRM device + * @encoder: the encoder where the bridge chain starts + * + * Create a new &drm_bridge_connector for the @drm device. The connector is + * allocated, initialised, registered with the @drm device and attached to + * @encoder. + * + * The connector is associated with a chain of bridges that starts at + * the @encoder. All bridges in the chain shall report bridge operation fl= ags + * (&drm_bridge->ops) and bridge output type (&drm_bridge->type), and none= of + * them may create a DRM connector directly. + * + * Returns a pointer to the new connector on success, or a negative error + * pointer otherwise. + */ +struct drm_connector *drm_bridge_connector_init(struct drm_device *drm, + struct drm_encoder *encoder) +{ + struct drm_bridge_connector *bridge_connector; + int ret; + + bridge_connector =3D drmm_kzalloc(drm, sizeof(*bridge_connector), GFP_KER= NEL); + if (!bridge_connector) + return ERR_PTR(-ENOMEM); + + ret =3D drmm_add_action(drm, drm_bridge_connector_put_bridges, bridge_con= nector); + if (ret) + return ERR_PTR(ret); + + bridge_connector->drm =3D drm; + bridge_connector->encoder =3D encoder; + + return drm_bridge_connector_add_connector(bridge_connector); +} EXPORT_SYMBOL_GPL(drm_bridge_connector_init); --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 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 6D1AD3E00BD for ; Tue, 19 May 2026 10:38:33 +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=1779187115; cv=none; b=NCwUbxX8IReGmivwRLy58Vm6hqESq5xOkoG7s6Cbpj0CB5Qyh3RKWshQ/l5l1Zd78EJTJhHH1zm3U93whniOIq4ABHyQgW9hpg3HHb72h4w3YJKHHMF+HSDvdELa1pYreJswYka/dKlg4JdNFCMWdu+3cIK4ZjOnxQ6Yf9Jce/8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187115; c=relaxed/simple; bh=fwbPjl665qihwFqoaFRATcMGbsfXX/jIm4HwMdg2320=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=neZG8TGbcu7wOc8mbX+jFhWkgbR2APueIs5dxOg8PXpSNQP19rq7++ItucEupwCiakZ7gm1sLbJUwByS8JSD9F/vp163v+CNXmr0/fIlfw8kzPPBBHna1uFmV/QzLtOOedHMyF5VBFnSamtkHnjdLVUuKWZorp5+LEzRk6JidDI= 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=J0EO0XJf; 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="J0EO0XJf" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id 53DD6C2B9E5; Tue, 19 May 2026 10:39:25 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 2A329606E9; Tue, 19 May 2026 10:38:32 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 8E1EB107E8ACA; Tue, 19 May 2026 12:38:26 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187110; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=pGMsYlYt9mcY7NwGwKaGJYaOC5KWQAxBqwt/f2CcMdA=; b=J0EO0XJfuiOfRnAq8HMXUUMSgfogKn0SYvWGsY1bBlP4dK4F6wbQsQzoXWuD9nMNm0sPwt C4C7T6/FRsSvoxtE3Qg2Xzr0qBZ4J5taiALqLJysPU1Pmt7hhXUheAV029REJ0Bd/VP9XR VC7nwp6+lAfA4iLCES7ENAYrqs0tPlVC7Nb17FF86L0xzevNKe735Wc3MGyzaXDh6wmGn1 +Mrv7hem3dPmr8XrIK08uY6oVQ7KKSW7SI0xyUjnzZUN6h70EiOTEZar9Bjn+36LBHgeRj pC5U9faLWhg8Lz6WFaNN+VOriV4brh0RJyGf9mmK+CEtD7DK9iLRPOXCqLtVaA== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:23 +0200 Subject: [PATCH 06/37] drm/display: bridge-connector: use a drm_bridge_connector internally, not a drm_connector 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: <20260519-drm-bridge-hotplug-v1-6-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 Currently drm_bridge_connector_init() always returns the added connector or errors out. When adding bridge hotplug the bridge-connector can be successfully initialized without creating a connector, which can be added later when the pipeline will be complete. For this the internal function drm_bridge_connector_add_connector() must be able to return a valid drm_bridge_connector even without any drm_connector. In preparation to support bridge hotplug, change its return value to be the same drm_bridge_connector pointer it gets as input, or a PTR_ERR. No functional changes, just changing an internal API. Note the return value could now become an int (0 or negative error) because returning the same value received as input does not carry any added value. However this would be change a lot of lines, so leave such change as a future cleanup. Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/display/drm_bridge_connector.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/d= rm/display/drm_bridge_connector.c index 6813c6008985..eb1912611cd6 100644 --- a/drivers/gpu/drm/display/drm_bridge_connector.c +++ b/drivers/gpu/drm/display/drm_bridge_connector.c @@ -780,10 +780,10 @@ static void drm_bridge_connector_put_bridges(struct d= rm_device *dev, void *data) * @bridge_connector->drm and @bridge_connector->encoder fields are * assigned at least) * - * Returns a pointer to the new drm_connector on success, or a negative - * error pointer otherwise. + * Returns a pointer to @bridge_connector on success, or a negative error + * pointer otherwise. */ -static struct drm_connector * +static struct drm_bridge_connector * drm_bridge_connector_add_connector(struct drm_bridge_connector *bridge_con= nector) { struct drm_connector *connector; @@ -1049,7 +1049,7 @@ drm_bridge_connector_add_connector(struct drm_bridge_= connector *bridge_connector if (ret) return ERR_PTR(ret); =20 - return connector; + return bridge_connector; } =20 /** @@ -1086,6 +1086,10 @@ struct drm_connector *drm_bridge_connector_init(stru= ct drm_device *drm, bridge_connector->drm =3D drm; bridge_connector->encoder =3D encoder; =20 - return drm_bridge_connector_add_connector(bridge_connector); + bridge_connector =3D drm_bridge_connector_add_connector(bridge_connector); + if (IS_ERR(bridge_connector)) + return ERR_CAST(bridge_connector); + + return &bridge_connector->base; } EXPORT_SYMBOL_GPL(drm_bridge_connector_init); --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 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 BBD1748C41B for ; Tue, 19 May 2026 10:38:37 +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=1779187119; cv=none; b=UV6Ckvo6AeKgv2rOuJfmSD67u/amdTWYdhYO/riCUt7VWjnMogmeGFMVWpFv5zNl9viEDEQ9zi5BBKLY9wU7NpcDqBGUs4JtXTaq51gK8HifxIiU7ZeoKPBVYnGVQbtbZKcddDi1F6wwVk6kfyIGuylt8Uah9Zk/YX1mWAxSOrU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187119; c=relaxed/simple; bh=W3gYNt28HCJPPl52MlnUmOef/1PTN9AVU+LuLuCBPqE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=tMgnlt2U6ZEaM0Qh/ZB7XNkY85uoTreufIm4IWTtX4ONgSYQLV8PJZroqYqGab3pg3xvjiwCyEklRtIrrnYTYWTyGVEK4n4WA+TACtTIZy9aK+iwfCxxEYTdAQqIArqi/Kd1ZQIzHTc2BAjERu8cur9/xLVrDeu5YU4MivvHOdU= 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=QOdOdnBF; 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="QOdOdnBF" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id A9F03C2B9DB; Tue, 19 May 2026 10:39:29 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 80193606E9; Tue, 19 May 2026 10:38:36 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id EDBCC107E8AC4; Tue, 19 May 2026 12:38:30 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187114; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=rGciLf3NjCBPoc0UQ4+x/z7o6dllLIML7luNF7S0QvE=; b=QOdOdnBFA3u8nc64QbRf7A4cZQCMLbAc551RI9YUbue/r1WzVdQ5EtZgEHuPO+pOOSoMqh dTkseuBv8AbZAWpyJ8ht1eeWIeX643g7mbJYlPRcJX9pyh3UuUrtx2da9nXgHR5jxVjbkX tTQFfsnQjJAjwRaSjiridai41ikNAHZHFfLT8cKRIZGnygRmlPBObukK0qv2XA283hMdXU DPsAIDx1faViqsF9f4vHV+6Y9a3ekjOnHtKpDmpNRXIsH1QzVC9oRjTQIwZDrSwZPLQrJf L6A1+xWoDhidqVjbFDRmITn8DpR1SbAQcwe+l/8GAKixjZMnkMBjsqo2iIZwfw== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:24 +0200 Subject: [PATCH 07/37] drm/display: bridge-connector: extract drm_bridge_connector_get_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: <20260519-drm-bridge-hotplug-v1-7-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 To support bridge hotplug we will need better control over the steps involved in the crm_connector creation, especially in terms of error management. This will be complicated by the length and amount of return points in this function. In preparation, split the code to grab the various bridge pointers out to a separate function. No functional changes. Just moving code around. Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/display/drm_bridge_connector.c | 86 +++++++++++++++-------= ---- 1 file changed, 50 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 eb1912611cd6..97d9a4c6d166 100644 --- a/drivers/gpu/drm/display/drm_bridge_connector.c +++ b/drivers/gpu/drm/display/drm_bridge_connector.c @@ -772,44 +772,24 @@ static void drm_bridge_connector_put_bridges(struct d= rm_device *dev, void *data) drm_bridge_put(bridge_connector->bridge_hdmi_cec); } =20 -/** - * drm_bridge_connector_add_connector - add the drm_connector - * @bridge_connector: drm_bridge_connector to add the drm_connector to - * - * Preconditions: the drm_bridge_connector is initialized (the - * @bridge_connector->drm and @bridge_connector->encoder fields are - * assigned at least) - * - * Returns a pointer to @bridge_connector on success, or a negative error - * pointer otherwise. - */ static struct drm_bridge_connector * -drm_bridge_connector_add_connector(struct drm_bridge_connector *bridge_con= nector) +drm_bridge_connector_get_bridges(struct drm_bridge_connector *bridge_conne= ctor, + int *connector_type, + unsigned int *supported_formats, + unsigned int *max_bpc, + struct i2c_adapter **ddc, + struct drm_bridge **panel_bridge, + bool *support_hdcp) { - struct drm_connector *connector; - struct i2c_adapter *ddc =3D NULL; - struct drm_bridge *panel_bridge __free(drm_bridge_put) =3D NULL; - unsigned int supported_formats =3D BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444); - unsigned int max_bpc =3D 8; - bool support_hdcp =3D false; - int connector_type; - int ret; + struct drm_connector *connector =3D &bridge_connector->base; =20 /* * TODO: Handle doublescan_allowed and stereo_allowed. */ - connector =3D &bridge_connector->base; connector->interlace_allowed =3D true; connector->ycbcr_420_allowed =3D true; + *connector_type =3D DRM_MODE_CONNECTOR_Unknown; =20 - /* - * Initialise connector status handling. First locate the furthest - * bridges in the pipeline that support HPD and output detection. Then - * initialise the connector polling mode, using HPD if available and - * falling back to polling if supported. If neither HPD nor output - * detection are available, we don't support hotplug detection at all. - */ - connector_type =3D DRM_MODE_CONNECTOR_Unknown; drm_for_each_bridge_in_chain_scoped(bridge_connector->encoder, bridge) { if (!bridge->interlace_allowed) connector->interlace_allowed =3D false; @@ -865,9 +845,9 @@ drm_bridge_connector_add_connector(struct drm_bridge_co= nnector *bridge_connector bridge_connector->bridge_hdmi =3D drm_bridge_get(bridge); =20 if (bridge->supported_formats) - supported_formats =3D bridge->supported_formats; + *supported_formats =3D bridge->supported_formats; if (bridge->max_bpc) - max_bpc =3D bridge->max_bpc; + *max_bpc =3D bridge->max_bpc; } =20 if (bridge->ops & DRM_BRIDGE_OP_HDMI_AUDIO) { @@ -926,7 +906,7 @@ drm_bridge_connector_add_connector(struct drm_bridge_co= nnector *bridge_connector } =20 if (drm_bridge_is_last(bridge)) - connector_type =3D bridge->type; + *connector_type =3D bridge->type; =20 #ifdef CONFIG_OF if (drm_bridge_is_last(bridge) && bridge->of_node) @@ -934,20 +914,54 @@ drm_bridge_connector_add_connector(struct drm_bridge_= connector *bridge_connector #endif =20 if (bridge->ddc) - ddc =3D bridge->ddc; + *ddc =3D bridge->ddc; =20 if (drm_bridge_is_panel(bridge)) { - drm_bridge_put(panel_bridge); - panel_bridge =3D drm_bridge_get(bridge); + drm_bridge_put(*panel_bridge); + *panel_bridge =3D drm_bridge_get(bridge); } =20 if (bridge->support_hdcp) - support_hdcp =3D true; + *support_hdcp =3D true; } =20 if (connector_type =3D=3D DRM_MODE_CONNECTOR_Unknown) return ERR_PTR(-EINVAL); =20 + return bridge_connector; +} + +/** + * drm_bridge_connector_add_connector - add the drm_connector + * @bridge_connector: drm_bridge_connector to add the drm_connector to + * + * Preconditions: the drm_bridge_connector is initialized (the + * @bridge_connector->drm and @bridge_connector->encoder fields are + * assigned at least) + * + * Returns a pointer to @bridge_connector on success, or a negative error + * pointer otherwise. + */ +static struct drm_bridge_connector * +drm_bridge_connector_add_connector(struct drm_bridge_connector *bridge_con= nector) +{ + struct drm_connector *connector; + struct i2c_adapter *ddc =3D NULL; + struct drm_bridge *panel_bridge __free(drm_bridge_put) =3D NULL; + unsigned int supported_formats =3D BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444); + unsigned int max_bpc =3D 8; + bool support_hdcp =3D false; + int connector_type; + int ret; + + connector =3D &bridge_connector->base; + + bridge_connector =3D drm_bridge_connector_get_bridges(bridge_connector, &= connector_type, + &supported_formats, &max_bpc, &ddc, + &panel_bridge, &support_hdcp); + if (IS_ERR(bridge_connector)) + return bridge_connector; + if (bridge_connector->bridge_hdmi) { if (!connector->ycbcr_420_allowed) supported_formats &=3D ~BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR420); --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 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 66F1C3A1A38 for ; Tue, 19 May 2026 10:38:42 +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=1779187124; cv=none; b=f81Gf+rebeK/uJvEkXKYEHy7KD49EqtsDiDoPSH/xYMAUi7Bgd37wYE6HKUMlT4iQoDt3CwiW6SvJly+sYlYMllRih/3IHsmRLDohgYP0y0T5rbYhH4dfk6QWew+FtGKn/k2oeORtWvGZfMYjK/Wf5RL+BGuX4rfBwElPet4Ycc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187124; c=relaxed/simple; bh=ORraiVM5xRGoKCEQfhJEwM/1gAc6itzDbntC5kcW9jc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=C+B/UutTXgE1VUchRl1VuiddgCYIMyknAXwAUvI1qNuKIazff0yEqAq+FWflveDeUjCVBv7Vp5TYfVridvmqVNGHJ/SyepXvN3qxv7pc/DCghPGBAwIZqKn68n5rZq1QNHG48ysn9Cefe7U3vlsmYxo/qMSQcZFKv2DuCmBfXQM= 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=wSuFZS48; 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="wSuFZS48" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id 3AB3BC2B9DB; Tue, 19 May 2026 10:39:34 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 10C99606E9; Tue, 19 May 2026 10:38:41 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 531A1107E8ACA; Tue, 19 May 2026 12:38:35 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187119; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=xJoUF1IkVlOZYxAgNMP8prmYYcvN97zlEjbFr/2f2Tw=; b=wSuFZS48WrOXLF1huzOWOX2I009n21Dn2TUZBOGSogCD1S3yJcBB7sX1OzRf5EP4P3Q1b/ snTJI+Bi89+upN0esGvmQGFUXecJSHazcA/Qbh8fnRISaLtDJh8pb3OpE0sIrSUpoIO2Xe 4UVfgSdPts/m87SP6W7FqSJYGHrRYDaOG8okESkiUJmX6qEzOPv0pKNIfh1ZG2ZzSqlNpP IKrZ6PbXCo9tZYepuhNOonx3wTle+mXEkdYDyBBpkWcpT2T+3wNzaJ9Sm+I7D+QT51IuUA Xfr4RUg9ZnLdXDG82zE4NNUH5TnjKNxbRvhnij6B+bBpWuyM9/Lk/0FvQWMmGw== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:25 +0200 Subject: [PATCH 08/37] drm/display: bridge-connector: return int from drm_bridge_connector_get_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: <20260519-drm-bridge-hotplug-v1-8-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 This function returns a struct drm_bridge_connector * because this was the case in the origin of its code. In current code it does not make sense anymore: it can only return either the same pointer it received as input or a negative ERR_PTR. Simplify up error management by just returning an int (0 or negative error). No functional changes. Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/display/drm_bridge_connector.c | 61 +++++++++++++---------= ---- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/d= rm/display/drm_bridge_connector.c index 97d9a4c6d166..d8a033ed8f41 100644 --- a/drivers/gpu/drm/display/drm_bridge_connector.c +++ b/drivers/gpu/drm/display/drm_bridge_connector.c @@ -772,14 +772,13 @@ static void drm_bridge_connector_put_bridges(struct d= rm_device *dev, void *data) drm_bridge_put(bridge_connector->bridge_hdmi_cec); } =20 -static struct drm_bridge_connector * -drm_bridge_connector_get_bridges(struct drm_bridge_connector *bridge_conne= ctor, - int *connector_type, - unsigned int *supported_formats, - unsigned int *max_bpc, - struct i2c_adapter **ddc, - struct drm_bridge **panel_bridge, - bool *support_hdcp) +static int drm_bridge_connector_get_bridges(struct drm_bridge_connector *b= ridge_connector, + int *connector_type, + unsigned int *supported_formats, + unsigned int *max_bpc, + struct i2c_adapter **ddc, + struct drm_bridge **panel_bridge, + bool *support_hdcp) { struct drm_connector *connector =3D &bridge_connector->base; =20 @@ -820,27 +819,27 @@ drm_bridge_connector_get_bridges(struct drm_bridge_co= nnector *bridge_connector, } if (bridge->ops & DRM_BRIDGE_OP_HDMI) { if (bridge_connector->bridge_hdmi) - return ERR_PTR(-EBUSY); + return -EBUSY; if (!bridge->funcs->hdmi_write_avi_infoframe || !bridge->funcs->hdmi_clear_avi_infoframe || !bridge->funcs->hdmi_write_hdmi_infoframe || !bridge->funcs->hdmi_clear_hdmi_infoframe) - return ERR_PTR(-EINVAL); + return -EINVAL; =20 if (bridge->ops & DRM_BRIDGE_OP_HDMI_AUDIO && (!bridge->funcs->hdmi_write_audio_infoframe || !bridge->funcs->hdmi_clear_audio_infoframe)) - return ERR_PTR(-EINVAL); + return -EINVAL; =20 if (bridge->ops & DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME && (!bridge->funcs->hdmi_write_hdr_drm_infoframe || !bridge->funcs->hdmi_clear_hdr_drm_infoframe)) - return ERR_PTR(-EINVAL); + return -EINVAL; =20 if (bridge->ops & DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME && (!bridge->funcs->hdmi_write_spd_infoframe || !bridge->funcs->hdmi_clear_spd_infoframe)) - return ERR_PTR(-EINVAL); + return -EINVAL; =20 bridge_connector->bridge_hdmi =3D drm_bridge_get(bridge); =20 @@ -852,57 +851,57 @@ drm_bridge_connector_get_bridges(struct drm_bridge_co= nnector *bridge_connector, =20 if (bridge->ops & DRM_BRIDGE_OP_HDMI_AUDIO) { if (bridge_connector->bridge_hdmi_audio) - return ERR_PTR(-EBUSY); + return -EBUSY; =20 if (bridge_connector->bridge_dp_audio) - return ERR_PTR(-EBUSY); + return -EBUSY; =20 if (!bridge->hdmi_audio_max_i2s_playback_channels && !bridge->hdmi_audio_spdif_playback) - return ERR_PTR(-EINVAL); + return -EINVAL; =20 if (!bridge->funcs->hdmi_audio_prepare || !bridge->funcs->hdmi_audio_shutdown) - return ERR_PTR(-EINVAL); + return -EINVAL; =20 bridge_connector->bridge_hdmi_audio =3D drm_bridge_get(bridge); } =20 if (bridge->ops & DRM_BRIDGE_OP_DP_AUDIO) { if (bridge_connector->bridge_dp_audio) - return ERR_PTR(-EBUSY); + return -EBUSY; =20 if (bridge_connector->bridge_hdmi_audio) - return ERR_PTR(-EBUSY); + return -EBUSY; =20 if (!bridge->hdmi_audio_max_i2s_playback_channels && !bridge->hdmi_audio_spdif_playback) - return ERR_PTR(-EINVAL); + return -EINVAL; =20 if (!bridge->funcs->dp_audio_prepare || !bridge->funcs->dp_audio_shutdown) - return ERR_PTR(-EINVAL); + return -EINVAL; =20 bridge_connector->bridge_dp_audio =3D drm_bridge_get(bridge); } =20 if (bridge->ops & DRM_BRIDGE_OP_HDMI_CEC_NOTIFIER) { if (bridge_connector->bridge_hdmi_cec) - return ERR_PTR(-EBUSY); + return -EBUSY; =20 bridge_connector->bridge_hdmi_cec =3D drm_bridge_get(bridge); } =20 if (bridge->ops & DRM_BRIDGE_OP_HDMI_CEC_ADAPTER) { if (bridge_connector->bridge_hdmi_cec) - return ERR_PTR(-EBUSY); + return -EBUSY; =20 bridge_connector->bridge_hdmi_cec =3D drm_bridge_get(bridge); =20 if (!bridge->funcs->hdmi_cec_enable || !bridge->funcs->hdmi_cec_log_addr || !bridge->funcs->hdmi_cec_transmit) - return ERR_PTR(-EINVAL); + return -EINVAL; } =20 if (drm_bridge_is_last(bridge)) @@ -926,9 +925,9 @@ drm_bridge_connector_get_bridges(struct drm_bridge_conn= ector *bridge_connector, } =20 if (connector_type =3D=3D DRM_MODE_CONNECTOR_Unknown) - return ERR_PTR(-EINVAL); + return -EINVAL; =20 - return bridge_connector; + return 0; } =20 /** @@ -956,11 +955,11 @@ drm_bridge_connector_add_connector(struct drm_bridge_= connector *bridge_connector =20 connector =3D &bridge_connector->base; =20 - bridge_connector =3D drm_bridge_connector_get_bridges(bridge_connector, &= connector_type, - &supported_formats, &max_bpc, &ddc, - &panel_bridge, &support_hdcp); - if (IS_ERR(bridge_connector)) - return bridge_connector; + ret =3D drm_bridge_connector_get_bridges(bridge_connector, &connector_typ= e, + &supported_formats, &max_bpc, &ddc, + &panel_bridge, &support_hdcp); + if (ret) + return ERR_PTR(ret); =20 if (bridge_connector->bridge_hdmi) { if (!connector->ycbcr_420_allowed) --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (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 C67A2370AEF for ; Tue, 19 May 2026 10:38:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187128; cv=none; b=KfjIWGBFt1J80nb2As29jX72cQkutRHJtIwXaj83e/5H6tEyMxHu72WHDmcQHmpSW7yCy0RPDMLx96I9VgKlR+V95xNu0DA2aBmmWu3SGBd6TVqvUeusgt6Mlk0T1rk+A4p7/QKNvfA17stfk9OdPWW5KmjWiD5GI1RTixA29yg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187128; c=relaxed/simple; bh=NQgqgP5D8jvqfhFhEZnjrutRhuluBbJWXfak1wuy7b0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hPSESOa5J7PTOaFALN0B+pSshEyYN0XT3FyiKygDTVqr97qmbdEtqzO/TQtWs28X3hsfmjWQrOwHhM5S5P8tnpVZRC00XzEmyrIff8oH1GqJ0GpAAfAkRm1RlhME34dNWKp+ZF/0twuhXXzWaNMLsooeAB/F3RNw3H3Uuv9QQUg= 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=nn+E8RLx; arc=none smtp.client-ip=185.246.85.4 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="nn+E8RLx" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 641F94E42CF2; Tue, 19 May 2026 10:38:45 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 3112B606E9; Tue, 19 May 2026 10:38:45 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id EDA09107E8ACB; Tue, 19 May 2026 12:38:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187123; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=S5WFJQqOqjQzKJf/CECXTNKa8ItDPlAdG2fp5Z2XuTU=; b=nn+E8RLxi9zZ81a2PX2w9Xp+wfPFMkRzIzARFzLbHfV+tGVjr2IVm71PoNCMng87IJ3U5W 4T8ZdRkZBGAX5VWZQ1jY3en+WJBUHlMWFJ/rZb3hzPVfjlUKO2E9VTUpzTw2vhy3vAEyUL GUCafz3iT06OkddxAdovlrwU/BkCvqML3jCY0tS5LsIw5hE8fUQb6IA0sbJP3pEvAZZoTl Q33B0RIxxBcDn5gaIeK3U8k20TZ4dzJDWkVjDfnz7zyYv3KZDBeLB7EpYW85tq54BFCaw0 GQbzuVOurCgPYl7lRZePfSWtVpolymGhGAcfrYdGJ08ZVnorSEgW+V4IcejeuQ== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:26 +0200 Subject: [PATCH 09/37] drm/display: bridge-connector: extract drm_bridge_connector_init_hdmi_audio_cec() 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: <20260519-drm-bridge-hotplug-v1-9-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 To support bridge hotplug we will need better control over the steps involved in the crm_connector creation, especially in terms of error management. This will be complicated by the length and amount of return points in this function. In preparation, split the code to initialize HDMI audio and CEC fields out to a separate function. No functional changes. Just moving code around. Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/display/drm_bridge_connector.c | 102 ++++++++++++++-------= ---- 1 file changed, 57 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/d= rm/display/drm_bridge_connector.c index d8a033ed8f41..e6306e98a167 100644 --- a/drivers/gpu/drm/display/drm_bridge_connector.c +++ b/drivers/gpu/drm/display/drm_bridge_connector.c @@ -930,6 +930,60 @@ static int drm_bridge_connector_get_bridges(struct drm= _bridge_connector *bridge_ return 0; } =20 +static struct drm_bridge_connector * +drm_bridge_connector_init_hdmi_audio_cec(struct drm_bridge_connector *brid= ge_connector) +{ + int ret; + + if (bridge_connector->bridge_hdmi_audio || + bridge_connector->bridge_dp_audio) { + struct device *dev; + struct drm_bridge *bridge; + + if (bridge_connector->bridge_hdmi_audio) + bridge =3D bridge_connector->bridge_hdmi_audio; + else + bridge =3D bridge_connector->bridge_dp_audio; + + dev =3D bridge->hdmi_audio_dev; + + ret =3D drm_connector_hdmi_audio_init(&bridge_connector->base, dev, + &drm_bridge_connector_hdmi_audio_funcs, + bridge->hdmi_audio_max_i2s_playback_channels, + bridge->hdmi_audio_i2s_formats, + bridge->hdmi_audio_spdif_playback, + bridge->hdmi_audio_dai_port); + if (ret) + return ERR_PTR(ret); + } + + 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; + + ret =3D drmm_connector_hdmi_cec_notifier_register(&bridge_connector->bas= e, + NULL, + bridge->hdmi_cec_dev); + if (ret) + return ERR_PTR(ret); + } + + 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; + + ret =3D drmm_connector_hdmi_cec_register(&bridge_connector->base, + &drm_bridge_connector_hdmi_cec_funcs, + bridge->hdmi_cec_adapter_name, + bridge->hdmi_cec_available_las, + bridge->hdmi_cec_dev); + if (ret) + return ERR_PTR(ret); + } + + return bridge_connector; +} + /** * drm_bridge_connector_add_connector - add the drm_connector * @bridge_connector: drm_bridge_connector to add the drm_connector to @@ -997,51 +1051,9 @@ drm_bridge_connector_add_connector(struct drm_bridge_= connector *bridge_connector return ERR_PTR(ret); } =20 - if (bridge_connector->bridge_hdmi_audio || - bridge_connector->bridge_dp_audio) { - struct device *dev; - struct drm_bridge *bridge; - - if (bridge_connector->bridge_hdmi_audio) - bridge =3D bridge_connector->bridge_hdmi_audio; - else - bridge =3D bridge_connector->bridge_dp_audio; - - dev =3D bridge->hdmi_audio_dev; - - ret =3D drm_connector_hdmi_audio_init(connector, dev, - &drm_bridge_connector_hdmi_audio_funcs, - bridge->hdmi_audio_max_i2s_playback_channels, - bridge->hdmi_audio_i2s_formats, - bridge->hdmi_audio_spdif_playback, - bridge->hdmi_audio_dai_port); - if (ret) - return ERR_PTR(ret); - } - - 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; - - ret =3D drmm_connector_hdmi_cec_notifier_register(connector, - NULL, - bridge->hdmi_cec_dev); - if (ret) - return ERR_PTR(ret); - } - - 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; - - ret =3D drmm_connector_hdmi_cec_register(connector, - &drm_bridge_connector_hdmi_cec_funcs, - bridge->hdmi_cec_adapter_name, - bridge->hdmi_cec_available_las, - bridge->hdmi_cec_dev); - if (ret) - return ERR_PTR(ret); - } + bridge_connector =3D drm_bridge_connector_init_hdmi_audio_cec(bridge_conn= ector); + if (IS_ERR(bridge_connector)) + return bridge_connector; =20 drm_connector_helper_add(connector, &drm_bridge_connector_helper_funcs); =20 --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 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 9495C370AFE for ; Tue, 19 May 2026 10:38:50 +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=1779187132; cv=none; b=WM3QeTsZDkvrMbFlbF2jbqzwSSFncE/e9PnzIiNey+eLpte4AYW/Ow12omhb7Sn5bFiukRj/a9SgDl4RukDTwoiPxC6+nxz/vzZA2hTq/xmBlBOg0ChgQN9EnqKDjWpXVSc06ZukJRTgbX1tOBnQTEJmA3xi0Tm0ecPDYFgDuDM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187132; c=relaxed/simple; bh=0N5vk3VKv5pJ8jFY+t+uy4qJ/0erV8oEQXerqdUUkLI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=nESoaE0R/H0q6bXHCyZFvtohhtEZUsPN8ZX2ll4EQissMxZTBrhgHk0L2ZC6w0TiwDlW3Rs5AWyF8gY8U69wuc13zZ0dxEIV9aVIYgJmnFGA3DUvHTiP0AHokoG4RhI0QnA4rkYn2xifa46R1RHhwpAAXXvkRmsARQZxNY7X/xI= 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=mN29/H1d; 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="mN29/H1d" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 601881A3628; Tue, 19 May 2026 10:38:49 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 33FF4606E9; Tue, 19 May 2026 10:38:49 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 14C5C107E8AC3; Tue, 19 May 2026 12:38:43 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187127; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=Di2t9C3Wga7u13endyDgbNt60je3EfQ2HxxTrMzvD30=; b=mN29/H1dlWQgyTgztrhOqG93sBuV28HHJ43/F+Zd/4GyUw6vHmmtlBG693qH6KjfCe9QYw OES8DUkhvsB+hi5YAUAP1XxlLr34ku+aUezCyP5G97iFnOddGtOuUhFf3SYDIw7Ndc0z1/ lMquoJcTfROUqySTdyM3vAT/xD3WR5FKIgrx9ikqzPk004e7B66XSWxbmnS+lsCFZfkYCK hE8YhL0fFd485kmIbQ5Zb84nAJohjSJJgUeDg2XckAl7HIJFMmwUWr4VPUxB5oWE+ZqF1U dr8cwuM4Y52/4ZEwWkki9n4TAgU4O6OWJSuLEGz6/EYbLRdEFlfNJDJCb2oWPg== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:27 +0200 Subject: [PATCH 10/37] drm/display: bridge-connector: return int from drm_bridge_connector_init_hdmi_audio_cec() 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: <20260519-drm-bridge-hotplug-v1-10-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 This function returns a struct drm_bridge_connector * because this was the case in the origin of its code. In current code it does not make sense anymore: it can only return either the same pointer it received as input or a negative ERR_PTR. Simplify up error management by just returning an int (0 or negative error). No functional changes. Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/display/drm_bridge_connector.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/d= rm/display/drm_bridge_connector.c index e6306e98a167..6066ca0c5624 100644 --- a/drivers/gpu/drm/display/drm_bridge_connector.c +++ b/drivers/gpu/drm/display/drm_bridge_connector.c @@ -930,8 +930,7 @@ static int drm_bridge_connector_get_bridges(struct drm_= bridge_connector *bridge_ return 0; } =20 -static struct drm_bridge_connector * -drm_bridge_connector_init_hdmi_audio_cec(struct drm_bridge_connector *brid= ge_connector) +static int drm_bridge_connector_init_hdmi_audio_cec(struct drm_bridge_conn= ector *bridge_connector) { int ret; =20 @@ -954,7 +953,7 @@ drm_bridge_connector_init_hdmi_audio_cec(struct drm_bri= dge_connector *bridge_con bridge->hdmi_audio_spdif_playback, bridge->hdmi_audio_dai_port); if (ret) - return ERR_PTR(ret); + return ret; } =20 if (bridge_connector->bridge_hdmi_cec && @@ -965,7 +964,7 @@ drm_bridge_connector_init_hdmi_audio_cec(struct drm_bri= dge_connector *bridge_con NULL, bridge->hdmi_cec_dev); if (ret) - return ERR_PTR(ret); + return ret; } =20 if (bridge_connector->bridge_hdmi_cec && @@ -978,10 +977,10 @@ drm_bridge_connector_init_hdmi_audio_cec(struct drm_b= ridge_connector *bridge_con bridge->hdmi_cec_available_las, bridge->hdmi_cec_dev); if (ret) - return ERR_PTR(ret); + return ret; } =20 - return bridge_connector; + return 0; } =20 /** @@ -1051,9 +1050,9 @@ drm_bridge_connector_add_connector(struct drm_bridge_= connector *bridge_connector return ERR_PTR(ret); } =20 - bridge_connector =3D drm_bridge_connector_init_hdmi_audio_cec(bridge_conn= ector); - if (IS_ERR(bridge_connector)) - return bridge_connector; + ret =3D drm_bridge_connector_init_hdmi_audio_cec(bridge_connector); + if (ret) + return ERR_PTR(ret); =20 drm_connector_helper_add(connector, &drm_bridge_connector_helper_funcs); =20 --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 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 71C2D3A4510 for ; Tue, 19 May 2026 10:38:54 +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=1779187136; cv=none; b=hNGtHvfNapVj333n9EPsKZcegNdj6z8XuiM0drk6DGYpSbxTbk6sGoZIiOSkHlfLYmPk//niYVRzo/+PsYQeRPJFpwSxZEgVGvIdxZuqKO4d95GCaw6xRFlhwoXIVz5oaxldKJRqeJ0W82vjIs3wIY4vQP7uhU4lpEBM+M6faL8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187136; c=relaxed/simple; bh=uLCGBPmwcAyR7Yedf8D/a/H5VJXzL0BHZ57OTPC5iHE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=snXOvxZDNpKU4b3O2ECP9280PXLaqs14Mz+mTtRTb7TXfQLf526wyALOfvWayZvfxGvFwFjgQXtHF2jWCM6smR8iGWlCBnbZLXCp98EH8jUi8cVAKgbJsAdv8hUZrImutPjoexzgAHkQXJUhuVtBovKh3qcD4v+C3JEItJZXF+0= 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=hVK9PFdC; 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="hVK9PFdC" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id 77A41C2B9DB; Tue, 19 May 2026 10:39:46 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 4C791606E9; Tue, 19 May 2026 10:38:53 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 08D0B107E8AD3; Tue, 19 May 2026 12:38:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187131; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=f8PX3xqkM3heELg2F4nk1n3EZygfl3IAuY8PxbEGuV8=; b=hVK9PFdCFanPiC++87SKl4nRw4HidvStVJOu7ExZ13QI0X1ADjMwDSo5cskAGsbtTTuD5f x5vdeQb0pA9gzASKtJIO1aF+bdcgw9JHF0aUWz/iYFMg2RK0uvJei1tk1gMUo8+VceDpOw jKf8FeZTIHUTY/R3TRwSe1C5EBmZlOPq5AryjSrXfoB1Pm+nO+lH0EknflBYVBoLEvgkzb qheTh7C8sYPnbu6d3KvjGxYM3Gb3m9Up8DRNmVpcwf72nHtCaukRsT/p0C0Hk2TNsPIQ62 9UslQ35QoYXaQImhYCIldCD1bUwZkM9G3y1pUU0+bOG1Fxbgg9CScMFTUmhNUg== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:28 +0200 Subject: [PATCH 11/37] drm/display: bridge-connector: return int from drm_bridge_connector_add_connector() 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: <20260519-drm-bridge-hotplug-v1-11-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 This function returns a struct drm_bridge_connector * because this was the case in the origin of its code. In current code it does not make sense: it can only return either the same pointer it received as input or a negative ERR_PTR. This forces users to an unnecessarily complex error management code. Clean up error management by just returning an int (0 or negative error). Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/display/drm_bridge_connector.c | 24 +++++++++++-----------= -- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/d= rm/display/drm_bridge_connector.c index 6066ca0c5624..982bc64d8361 100644 --- a/drivers/gpu/drm/display/drm_bridge_connector.c +++ b/drivers/gpu/drm/display/drm_bridge_connector.c @@ -991,11 +991,9 @@ static int drm_bridge_connector_init_hdmi_audio_cec(st= ruct drm_bridge_connector * @bridge_connector->drm and @bridge_connector->encoder fields are * assigned at least) * - * Returns a pointer to @bridge_connector on success, or a negative error - * pointer otherwise. + * Returns 0 on success or a negative error otherwise. */ -static struct drm_bridge_connector * -drm_bridge_connector_add_connector(struct drm_bridge_connector *bridge_con= nector) +static int drm_bridge_connector_add_connector(struct drm_bridge_connector = *bridge_connector) { struct drm_connector *connector; struct i2c_adapter *ddc =3D NULL; @@ -1012,7 +1010,7 @@ drm_bridge_connector_add_connector(struct drm_bridge_= connector *bridge_connector &supported_formats, &max_bpc, &ddc, &panel_bridge, &support_hdcp); if (ret) - return ERR_PTR(ret); + return ret; =20 if (bridge_connector->bridge_hdmi) { if (!connector->ycbcr_420_allowed) @@ -1041,18 +1039,18 @@ drm_bridge_connector_add_connector(struct drm_bridg= e_connector *bridge_connector supported_formats, max_bpc); if (ret) - return ERR_PTR(ret); + return ret; } else { ret =3D drmm_connector_init(bridge_connector->drm, connector, &drm_bridge_connector_funcs, connector_type, ddc); if (ret) - return ERR_PTR(ret); + return ret; } =20 ret =3D drm_bridge_connector_init_hdmi_audio_cec(bridge_connector); if (ret) - return ERR_PTR(ret); + return ret; =20 drm_connector_helper_add(connector, &drm_bridge_connector_helper_funcs); =20 @@ -1071,9 +1069,9 @@ drm_bridge_connector_add_connector(struct drm_bridge_= connector *bridge_connector =20 ret =3D drm_connector_attach_encoder(connector, bridge_connector->encoder= ); if (ret) - return ERR_PTR(ret); + return ret; =20 - return bridge_connector; + return 0; } =20 /** @@ -1110,9 +1108,9 @@ struct drm_connector *drm_bridge_connector_init(struc= t drm_device *drm, bridge_connector->drm =3D drm; bridge_connector->encoder =3D encoder; =20 - bridge_connector =3D drm_bridge_connector_add_connector(bridge_connector); - if (IS_ERR(bridge_connector)) - return ERR_CAST(bridge_connector); + ret =3D drm_bridge_connector_add_connector(bridge_connector); + if (ret) + return ERR_PTR(ret); =20 return &bridge_connector->base; } --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 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 E22F43A9639 for ; Tue, 19 May 2026 10:38:58 +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=1779187140; cv=none; b=WJq8RsLX2WoqlyOCBQDnwGlmUd7fBVHgD/vuhZn+/yfEwQsQ8hnv+K1JffLQoEKOo2vv+AQKruaURi1KkL3NA7avajHoIlxd9WSSXelL5zijkpKCEqSHXz0AZtHeh/3PpNWxghN+MGHILPzd47RWhgtrwuBjX+IgOPm6bQT9gMc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187140; c=relaxed/simple; bh=tD6jz0tluUfAZZTuF9nGIm1I3KFiy45BKgqgNs80pY4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=X2ctHcj6LnSS/GddGlX25AcaAkZpxydWsC2QMUmSPY6tArfr42rQ2FbCczYKefP9hpGZraV5EDgwm9TYopQlnvtkBcjCtt/FRrAA4fBdn8kxxuv1cMrFhonVy/GzMdr7tGCALydmBa14Dpr4cHsppi6gPVMXSxc+3fHH3kPo+Ak= 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=O3s+Psyf; 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="O3s+Psyf" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id BE3A91A3628; Tue, 19 May 2026 10:38:57 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 90BF0606E9; Tue, 19 May 2026 10:38:57 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 4C29D107E8AD7; Tue, 19 May 2026 12:38:52 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187136; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=ZsHKRRMUeu27tf1v274f8WMZN92s4xeRokkanZhzAqA=; b=O3s+Psyf4Zu4itRxyHYLnWzhOGp9YTgdPLH/FoA1MJLe7MCR0AASwOwyBuGOx9TPSXHNO4 QKDh2+Qaf9CCmvXE4JrfAaSFfe00UZxQRXogi/O179EBZEy+i5Hj11ocVOrBpw0iR7XPj/ SRjRTptJJS2Rfp/grqwqVlS6BP1eqK2iQ0PMGDn9g11Owx+vPvU+UoyqeKF6RS7dkIZ4Ad ek5axwNTgeru/q1xdMBI+29FKMxVAeH9oYWkwSTf8thEc+um+dv/0gLWCSYooiuG4u5I4H wj9mHWB7ALGae5AXrmEEElVNwt87uCgXQ2spDIjHq0U4EZ6KVVsH0c/3HrctRQ== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:29 +0200 Subject: [PATCH 12/37] drm/display: bridge-connector: hoist error management to common code 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: <20260519-drm-bridge-hotplug-v1-12-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 In prepataion to add more error management code common to the HDMI and non-HDMI branches, move error management to be common to both cases. Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/display/drm_bridge_connector.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/d= rm/display/drm_bridge_connector.c index 982bc64d8361..defe29e339b0 100644 --- a/drivers/gpu/drm/display/drm_bridge_connector.c +++ b/drivers/gpu/drm/display/drm_bridge_connector.c @@ -1038,15 +1038,13 @@ static int drm_bridge_connector_add_connector(struc= t drm_bridge_connector *bridg connector_type, ddc, supported_formats, max_bpc); - if (ret) - return ret; } else { ret =3D drmm_connector_init(bridge_connector->drm, connector, &drm_bridge_connector_funcs, connector_type, ddc); - if (ret) - return ret; } + if (ret) + return ret; =20 ret =3D drm_bridge_connector_init_hdmi_audio_cec(bridge_connector); if (ret) --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 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 386EC37E303 for ; Tue, 19 May 2026 10:39:03 +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=1779187144; cv=none; b=Dsh+9Jq95E/Sb2Q2OQ8owNT1VWj9Mu/+YIvPxt1VH1At9nvqx7ZefCzrwL3uYVmuKlaJedZpppzSnvazPTsFb9w2+GItMBtgDVFoIGSBVJyQfnwYt+Bj47LQj+d/Y5pjhbjIR2oP3rgdUDISXisHBZBBgRlsH37oSfIk/LyuFS0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187144; c=relaxed/simple; bh=zNX7ZP4bATyMe0VbnJRflDbvEQlRNgwODK4r4YRj0LA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=gaFCPg4iZ2ttEDPhNSq1u7kXDY7fo6wJw+jeaia0MFbjXwNUMUjHKNi2cWGrzblndsDcsbo4KH0YtJBNtSGsiW3XwMqXyus7GEtvZJAgi6OZRKrTA9LHjxYpBxEXV6yDKfYgJGowTTWWFWuCNmikbBLthblNwBSFj7vBVE7A8FM= 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=GKHaypOT; 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="GKHaypOT" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id E7E811A3628; Tue, 19 May 2026 10:39:01 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id BC99F606E9; Tue, 19 May 2026 10:39:01 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 62166107E8ABA; Tue, 19 May 2026 12:38:56 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187140; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=eXrW0ECpdGk5EiWuXlmwmG6z3fjuIFkFvy0niDvkinM=; b=GKHaypOT9EOpAT/GxwwkPK46WJ1CA+Uh9a8HtbOMpYsDRAGLIwUJFM8pefN+wQ7OXKEaKG 8/x0SVw6OeAoVvtqfeTIEzPAYfaN7rVWNY4V8st4UfLCocQq0pTC+7QMNGcJQAp1YjVscx Jz1sR9KE3uZgbGgyeL2VB0x+kRkuqng9jdH6VUmo5z3KedHbDzM+Ml8V+/vocaIa0j97eQ Jqlj8eT+kjHzScNSYgYehnOf83QQFuI7AWVqV5iSjeU3tSFjT13ZNA+1SEUblUTp+y7KOj GzacZcazm9OoXDnefCmB0VqH1dx2ot0OTq5o+KI33MhCSogWFyc/IQL6ahxVUQ== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:30 +0200 Subject: [PATCH 13/37] drm/display: bridge-connector: move drm_bridge_connector_put_bridges() definition eariler 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: <20260519-drm-bridge-hotplug-v1-13-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 drm_bridge_connector_put_bridges() will have to be called in other places to support bridge hot-plugging. In preparation for bridge hotplug support, move it near the top of the file. No functional changes. Just moving code around. Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/display/drm_bridge_connector.c | 28 +++++++++++++---------= ---- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/d= rm/display/drm_bridge_connector.c index defe29e339b0..2e96af8efb55 100644 --- a/drivers/gpu/drm/display/drm_bridge_connector.c +++ b/drivers/gpu/drm/display/drm_bridge_connector.c @@ -140,6 +140,20 @@ struct drm_bridge_connector { #define to_drm_bridge_connector(x) \ container_of(x, struct drm_bridge_connector, base) =20 +static void drm_bridge_connector_put_bridges(struct drm_device *dev, void = *data) +{ + struct drm_bridge_connector *bridge_connector =3D (struct drm_bridge_conn= ector *)data; + + 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); +} + /* -----------------------------------------------------------------------= ------ * Bridge Connector Hot-Plug Handling */ @@ -758,20 +772,6 @@ static const struct drm_connector_hdmi_cec_funcs drm_b= ridge_connector_hdmi_cec_f * Bridge Connector Initialisation */ =20 -static void drm_bridge_connector_put_bridges(struct drm_device *dev, void = *data) -{ - struct drm_bridge_connector *bridge_connector =3D (struct drm_bridge_conn= ector *)data; - - 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 int drm_bridge_connector_get_bridges(struct drm_bridge_connector *b= ridge_connector, int *connector_type, unsigned int *supported_formats, --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (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 149214CA287 for ; Tue, 19 May 2026 10:39:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187149; cv=none; b=EcrOtIGflCoVAHWzhTpIKXnrelJ75RH+E4f2nu7wAgzPdMMdFUhRdnXHfkE+PtuVApDHXvfBNsOjU2MlFqYPPbgeD72qy9DDHjzgyhu0fXNqKtkItHgIlpyhyyCquU1WBOUb6sV/wFujmqhB8xHauVMNPglOiQ1N00LF9Kx7k6I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187149; c=relaxed/simple; bh=tmhahMhHtslRheRjGpc6XZyT6YbZPI0cQYdJQHNSbJs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=cl0/ThX+821FtXHLbQnGfIPRlrMXs0QcMVWl70HBC5/RhJsmPLwkXiuGSAbLY+mYNWXqa3oQQuI2auu6CZib78pSxl14JCKARg9poDSZqdDaMZL1cMIdE+Q+Ap/tOClIc4KU8lGn9oE/lp1uMOIS/rgiFoZceCD/FSPvyt05nR0= 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=mvr5e0VV; arc=none smtp.client-ip=185.246.85.4 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="mvr5e0VV" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id B28014E42CF2; Tue, 19 May 2026 10:39:06 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 7F33E606E9; Tue, 19 May 2026 10:39:06 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id D9ADA107E8AC3; Tue, 19 May 2026 12:39:00 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187144; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=MXzXfL976Jh5LzLUVnfB4dSuaOKmXeLa4YHSSt3GjME=; b=mvr5e0VVd1QTAoTY4anq7bRyw806/vu0HCW5SbK80z86N8zp0Mfl3BqaF33jMA/doGTFo5 k3U0N0lmciuV/30HYvH2FXk/QJy/2fDqpN0rCSVyB3+/xpy61VRFQOdjDyYq/cViH9MVqL HXAfdtuT9GVGvDqMMJEJD8NFWLOWa8GI5ApFLC6gtc6pN8/RbfIKt53lJQHkA2NM7H7pF1 PsaiVu3x4XZebT/g5MQ3GL2l3wnHvFc5waYJRTdeqHYemx/Pb6QsVfhq0fAX5ab4CpxLVn 1BzgrKx05o/youqmRQi2Tar7gFmUpG3RH32mTBh+EAxIwlS51Ox3BralXNDE6A== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:31 +0200 Subject: [PATCH 14/37] drm/display: bridge-connector: add non-drmm variant of drm_bridge_connector_put_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: <20260519-drm-bridge-hotplug-v1-14-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 drm_bridge_connector_put_bridges() is currently meant as a drmm cleanup action. In preparation for bridge hotplug add a non-drmm action, so it can be called more simply in non-drmm context. To do this split drm_bridge_connector_put_bridges() in two variants, both doing the same actions and only differing in the name and arguments: * drm_bridge_connector_put_bridges() (same name as before) to be called directly by the drm_bridge_connector code with a drm_bridge_connector pointer as the only parameter * drmm_bridge_connector_put_bridges() (same name + drmm prefix) providing the same drmm calling convention as before Update the only call site accordingly. No functional changes. Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/display/drm_bridge_connector.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/d= rm/display/drm_bridge_connector.c index 2e96af8efb55..1fd104f1647b 100644 --- a/drivers/gpu/drm/display/drm_bridge_connector.c +++ b/drivers/gpu/drm/display/drm_bridge_connector.c @@ -140,10 +140,8 @@ struct drm_bridge_connector { #define to_drm_bridge_connector(x) \ container_of(x, struct drm_bridge_connector, base) =20 -static void drm_bridge_connector_put_bridges(struct drm_device *dev, void = *data) +static void drm_bridge_connector_put_bridges(struct drm_bridge_connector *= bridge_connector) { - struct drm_bridge_connector *bridge_connector =3D (struct drm_bridge_conn= ector *)data; - drm_bridge_put(bridge_connector->bridge_edid); drm_bridge_put(bridge_connector->bridge_hpd); drm_bridge_put(bridge_connector->bridge_detect); @@ -154,6 +152,13 @@ static void drm_bridge_connector_put_bridges(struct dr= m_device *dev, void *data) drm_bridge_put(bridge_connector->bridge_hdmi_cec); } =20 +static void drmm_bridge_connector_put_bridges(struct drm_device *dev, void= *data) +{ + struct drm_bridge_connector *bridge_connector =3D (struct drm_bridge_conn= ector *)data; + + drm_bridge_connector_put_bridges(bridge_connector); +} + /* -----------------------------------------------------------------------= ------ * Bridge Connector Hot-Plug Handling */ @@ -1099,7 +1104,7 @@ struct drm_connector *drm_bridge_connector_init(struc= t drm_device *drm, if (!bridge_connector) return ERR_PTR(-ENOMEM); =20 - ret =3D drmm_add_action(drm, drm_bridge_connector_put_bridges, bridge_con= nector); + ret =3D drmm_add_action(drm, drmm_bridge_connector_put_bridges, bridge_co= nnector); if (ret) return ERR_PTR(ret); =20 --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 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 EFA383F074E for ; Tue, 19 May 2026 10:39:12 +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=1779187154; cv=none; b=bV/YGbkT1BWXPHtsGBm/MZG6pM8fwLGGlFznKRxytWPsPJ70prSbc1E6fCYxVvgzBYz0P5ats8TVn1scuUbf40Wx7ThHOONMbEYxT1o7SdJpM+XDRibyEgYHfCsgZ+mQXaxlDUa2SQ0ZS8bnPAz2g+EE+ljjRz+1fYbc23O4gn0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187154; c=relaxed/simple; bh=vzRY+VHUKm4kn3RsYSw1C6MQU/lBZIvm0ScLge4JPFA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=MKAp1FKAukrM+9N15zApFlRi5+lrQEC6JuQHjX0q9tZfjv1LaT5cht8Ww3pBte64R498noefXSIApabmwGwzzMWZrMx01tb7gxxxtaiPgTekcn1/Nvi/U5YEKsK5U2m77Qo0Pbm42bE3FJ3UZ/nGPdV7pqzMTTAAtBdIBjxe6WM= 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=mtyRsCSz; 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="mtyRsCSz" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 9CAE21A3629; Tue, 19 May 2026 10:39:11 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 70AE2606E9; Tue, 19 May 2026 10:39:11 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 68DB3107E8AE0; Tue, 19 May 2026 12:39:05 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187149; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=eS4OkpPo3Swd0wt5kHHS/3W+S57omlVkKazU9Pal7D8=; b=mtyRsCSzFmZ6Bh7It/Gd+7gkxzfBqnwhmdPUoj/0O6THnwURGcFPWO55bMlrEXQSk2igzA 2Wal0KRnYQtVANEGKW/uQOq94KwNeponq3N+oVxrzwspsjykLBty6JhVXINru8ikhQSSGb X0/8Wge4LvUDfWPMpwTbeOiNknPPmF8La7NGB7xzkbOj8BpDkVVEqx1qpLZqyBZgs7O2Ba A7BJUNL477G/WFs7iO3TZ48jgcMxChcO9GhA6c2/+ritutWMIirEE4z7aCv83BkPxL7/VH 8hYahm1ixjdAlHgjj8JiWpLfGY7Vk+oFdlX2rVExJqXKBtJs7t4JGDH8KtXcrw== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:32 +0200 Subject: [PATCH 15/37] drm/display: bridge-connector: allocate the connector dynamically 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: <20260519-drm-bridge-hotplug-v1-15-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 Currently the drm_bridge_connector has an embedded drm_connector, so their allocation lifetimes are tied to each other. This is insufficient to support DRM bridge hotplugging, which requires the connector to be added and removed dynamically at runtime multiple times based on hotplug/unplug events while the drm_bridge_connector is persistent. Moreover the drm_connector is exposed to user space and thus an ongoing operation (e.g. an ioctl) might last for an arbitrarily long time even after the hardware gets removed. This means a new connector might have to be added when the previous one is still referenced by user space. In preparation to handle hotplug, allocate the drm-connector dynamically, to allow: * creating and destroying a connector multiple times during a single drm_bridge_connector lifetime * creating a new connector even though the previous one is still in use and thus still refcounted and not yet freed This commit does not introduce the actions in the two bullets (it will happen in a later commit), it only moves to dynamic APIs for connector allocation and init. Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/display/drm_bridge_connector.c | 156 ++++++++++++++++++---= ---- 1 file changed, 114 insertions(+), 42 deletions(-) diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/d= rm/display/drm_bridge_connector.c index 1fd104f1647b..b4e2c8f1d32d 100644 --- a/drivers/gpu/drm/display/drm_bridge_connector.c +++ b/drivers/gpu/drm/display/drm_bridge_connector.c @@ -1,6 +1,8 @@ // SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2019 Laurent Pinchart + * Copyright (C) 2026 GE HealthCare + * Author: Luca Ceresoli */ =20 #include @@ -53,13 +55,24 @@ */ =20 /** - * struct drm_bridge_connector - A connector backed by a chain of bridges + * drm_bridge_connector_dynconn - wrapper struct for the dynamically + * created drm_connector */ -struct drm_bridge_connector { +struct drm_bridge_connector_dynconn { /** - * @base: The base DRM connector + * @bridge_connector: the owning bridge connector */ - struct drm_connector base; + struct drm_bridge_connector *bridge_connector; + /** + * @connector: the drm_connector exposed to user space + */ + struct drm_connector connector; +}; + +/** + * struct drm_bridge_connector - A connector backed by a chain of bridges + */ +struct drm_bridge_connector { /** * @drm: The DRM device we belong to */ @@ -70,6 +83,10 @@ struct drm_bridge_connector { * The encoder at the start of the bridges chain. */ struct drm_encoder *encoder; + /** + * @dynconn: The DRM connector added by the drm_bridge_connector + */ + struct drm_bridge_connector_dynconn *dynconn; /** * @bridge_edid: * @@ -137,8 +154,13 @@ struct drm_bridge_connector { struct drm_connector_hdmi_funcs hdmi_funcs; }; =20 -#define to_drm_bridge_connector(x) \ - container_of(x, struct drm_bridge_connector, base) +static struct drm_bridge_connector *to_drm_bridge_connector(const struct d= rm_connector *connector) +{ + const struct drm_bridge_connector_dynconn *dynconn =3D + container_of(connector, struct drm_bridge_connector_dynconn, connector); + + return dynconn->bridge_connector; +} =20 static void drm_bridge_connector_put_bridges(struct drm_bridge_connector *= bridge_connector) { @@ -152,13 +174,6 @@ static void drm_bridge_connector_put_bridges(struct dr= m_bridge_connector *bridge drm_bridge_put(bridge_connector->bridge_hdmi_cec); } =20 -static void drmm_bridge_connector_put_bridges(struct drm_device *dev, void= *data) -{ - struct drm_bridge_connector *bridge_connector =3D (struct drm_bridge_conn= ector *)data; - - drm_bridge_connector_put_bridges(bridge_connector); -} - /* -----------------------------------------------------------------------= ------ * Bridge Connector Hot-Plug Handling */ @@ -179,7 +194,7 @@ static void drm_bridge_connector_hpd_notify(struct drm_= connector *connector, static void drm_bridge_connector_handle_hpd(struct drm_bridge_connector *b= ridge_connector, enum drm_connector_status status) { - struct drm_connector *connector =3D &bridge_connector->base; + struct drm_connector *connector =3D &bridge_connector->dynconn->connector; struct drm_device *dev =3D bridge_connector->drm; =20 mutex_lock(&dev->mode_config.mutex); @@ -299,6 +314,16 @@ static void drm_bridge_connector_reset(struct drm_conn= ector *connector) connector->state); } =20 +static void drm_bridge_connector_dynconn_destroy(struct drm_connector *con= nector) +{ + struct drm_bridge_connector_dynconn *dynconn =3D + container_of(connector, struct drm_bridge_connector_dynconn, connector); + + drm_connector_cleanup(connector); + drm_bridge_connector_put_bridges(dynconn->bridge_connector); + kfree(dynconn); +} + static const struct drm_connector_funcs drm_bridge_connector_funcs =3D { .reset =3D drm_bridge_connector_reset, .detect =3D drm_bridge_connector_detect, @@ -308,6 +333,7 @@ static const struct drm_connector_funcs drm_bridge_conn= ector_funcs =3D { .atomic_destroy_state =3D drm_atomic_helper_connector_destroy_state, .debugfs_init =3D drm_bridge_connector_debugfs_init, .oob_hotplug_event =3D drm_bridge_connector_oob_hotplug_event, + .destroy =3D drm_bridge_connector_dynconn_destroy, }; =20 /* -----------------------------------------------------------------------= ------ @@ -777,7 +803,17 @@ static const struct drm_connector_hdmi_cec_funcs drm_b= ridge_connector_hdmi_cec_f * Bridge Connector Initialisation */ =20 -static int drm_bridge_connector_get_bridges(struct drm_bridge_connector *b= ridge_connector, +static void drm_bridge_connector_dynconn_release(struct drm_bridge_connect= or *bridge_connector) +{ + if (!bridge_connector->dynconn) + return; + + drm_connector_unregister(&bridge_connector->dynconn->connector); + drm_connector_put(&bridge_connector->dynconn->connector); + bridge_connector->dynconn =3D NULL; +} + +static int drm_bridge_connector_get_bridges(struct drm_bridge_connector_dy= nconn *dynconn, int *connector_type, unsigned int *supported_formats, unsigned int *max_bpc, @@ -785,7 +821,8 @@ static int drm_bridge_connector_get_bridges(struct drm_= bridge_connector *bridge_ struct drm_bridge **panel_bridge, bool *support_hdcp) { - struct drm_connector *connector =3D &bridge_connector->base; + struct drm_bridge_connector *bridge_connector =3D dynconn->bridge_connect= or; + struct drm_connector *connector =3D &dynconn->connector; =20 /* * TODO: Handle doublescan_allowed and stereo_allowed. @@ -937,6 +974,7 @@ static int drm_bridge_connector_get_bridges(struct drm_= bridge_connector *bridge_ =20 static int drm_bridge_connector_init_hdmi_audio_cec(struct drm_bridge_conn= ector *bridge_connector) { + struct drm_connector *connector =3D &bridge_connector->dynconn->connector; int ret; =20 if (bridge_connector->bridge_hdmi_audio || @@ -951,7 +989,7 @@ static int drm_bridge_connector_init_hdmi_audio_cec(str= uct drm_bridge_connector =20 dev =3D bridge->hdmi_audio_dev; =20 - ret =3D drm_connector_hdmi_audio_init(&bridge_connector->base, dev, + ret =3D drm_connector_hdmi_audio_init(connector, dev, &drm_bridge_connector_hdmi_audio_funcs, bridge->hdmi_audio_max_i2s_playback_channels, bridge->hdmi_audio_i2s_formats, @@ -965,8 +1003,7 @@ static int drm_bridge_connector_init_hdmi_audio_cec(st= ruct drm_bridge_connector bridge_connector->bridge_hdmi_cec->ops & DRM_BRIDGE_OP_HDMI_CEC_NOTIF= IER) { struct drm_bridge *bridge =3D bridge_connector->bridge_hdmi_cec; =20 - ret =3D drmm_connector_hdmi_cec_notifier_register(&bridge_connector->bas= e, - NULL, + ret =3D drmm_connector_hdmi_cec_notifier_register(connector, NULL, bridge->hdmi_cec_dev); if (ret) return ret; @@ -976,7 +1013,7 @@ static int drm_bridge_connector_init_hdmi_audio_cec(st= ruct drm_bridge_connector bridge_connector->bridge_hdmi_cec->ops & DRM_BRIDGE_OP_HDMI_CEC_ADAPT= ER) { struct drm_bridge *bridge =3D bridge_connector->bridge_hdmi_cec; =20 - ret =3D drmm_connector_hdmi_cec_register(&bridge_connector->base, + ret =3D drmm_connector_hdmi_cec_register(connector, &drm_bridge_connector_hdmi_cec_funcs, bridge->hdmi_cec_adapter_name, bridge->hdmi_cec_available_las, @@ -1009,13 +1046,20 @@ static int drm_bridge_connector_add_connector(struc= t drm_bridge_connector *bridg int connector_type; int ret; =20 - connector =3D &bridge_connector->base; + struct drm_bridge_connector_dynconn *dynconn =3D kzalloc_obj(*dynconn); + if (!dynconn) + return -ENOMEM; =20 - ret =3D drm_bridge_connector_get_bridges(bridge_connector, &connector_typ= e, + dynconn->bridge_connector =3D bridge_connector; + connector =3D &dynconn->connector; + + ret =3D drm_bridge_connector_get_bridges(dynconn, &connector_type, &supported_formats, &max_bpc, &ddc, &panel_bridge, &support_hdcp); - if (ret) + if (ret) { + kfree(dynconn); return ret; + } =20 if (bridge_connector->bridge_hdmi) { if (!connector->ycbcr_420_allowed) @@ -1035,25 +1079,34 @@ static int drm_bridge_connector_add_connector(struc= t drm_bridge_connector *bridg bridge_connector->hdmi_funcs.spd =3D drm_bridge_connector_hdmi_spd_infoframe; =20 - ret =3D drmm_connector_hdmi_init(bridge_connector->drm, connector, - bridge_connector->bridge_hdmi->vendor, - bridge_connector->bridge_hdmi->product, - &drm_bridge_connector_funcs, - &bridge_connector->hdmi_funcs, - connector_type, ddc, - supported_formats, - max_bpc); + ret =3D drm_connector_hdmi_dynamic_init(bridge_connector->drm, connector, + bridge_connector->bridge_hdmi->vendor, + bridge_connector->bridge_hdmi->product, + &drm_bridge_connector_funcs, + &bridge_connector->hdmi_funcs, + connector_type, ddc, + supported_formats, + max_bpc); } else { - ret =3D drmm_connector_init(bridge_connector->drm, connector, - &drm_bridge_connector_funcs, - connector_type, ddc); + ret =3D drm_connector_dynamic_init(bridge_connector->drm, connector, + &drm_bridge_connector_funcs, + connector_type, ddc); } - if (ret) + if (ret) { + drm_bridge_connector_put_bridges(dynconn->bridge_connector); + kfree(dynconn); return ret; + } + + /* From now on the connector is referenced and has to be put, not kfreed = */ + + bridge_connector->dynconn =3D dynconn; + + drm_bridge_connector_reset(connector); =20 ret =3D drm_bridge_connector_init_hdmi_audio_cec(bridge_connector); if (ret) - return ret; + goto err_put; =20 drm_connector_helper_add(connector, &drm_bridge_connector_helper_funcs); =20 @@ -1072,9 +1125,25 @@ static int drm_bridge_connector_add_connector(struct= drm_bridge_connector *bridg =20 ret =3D drm_connector_attach_encoder(connector, bridge_connector->encoder= ); if (ret) - return ret; + goto err_put; + + ret =3D drm_connector_dynamic_register(connector); + if (ret) + goto err_put; =20 return 0; + +err_put: + drm_connector_put(connector); + bridge_connector->dynconn =3D NULL; + return ret; +} + +static void drm_bridge_connector_fini(struct drm_device *dev, void *res) +{ + struct drm_bridge_connector *bridge_connector =3D (struct drm_bridge_conn= ector *)res; + + drm_bridge_connector_dynconn_release(bridge_connector); } =20 /** @@ -1104,10 +1173,6 @@ struct drm_connector *drm_bridge_connector_init(stru= ct drm_device *drm, if (!bridge_connector) return ERR_PTR(-ENOMEM); =20 - ret =3D drmm_add_action(drm, drmm_bridge_connector_put_bridges, bridge_co= nnector); - if (ret) - return ERR_PTR(ret); - bridge_connector->drm =3D drm; bridge_connector->encoder =3D encoder; =20 @@ -1115,6 +1180,13 @@ struct drm_connector *drm_bridge_connector_init(stru= ct drm_device *drm, if (ret) return ERR_PTR(ret); =20 - return &bridge_connector->base; + ret =3D drmm_add_action_or_reset(drm, drm_bridge_connector_fini, bridge_c= onnector); + if (ret) + return ERR_PTR(ret); + + if (!bridge_connector->dynconn) + return ERR_PTR(-EINVAL); + + return &bridge_connector->dynconn->connector; } EXPORT_SYMBOL_GPL(drm_bridge_connector_init); --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 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 3F6F845BD6C for ; Tue, 19 May 2026 10:39:17 +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=1779187160; cv=none; b=kdP8PTYCqCFr0TW46bFk69iITuQHmovpKBCSA188Ourfe2YQ6z8WxQrkPCe+RcwsgI9Abxn2Y72++yXq+CKbwR94kajN8bVXjrGt+oS1X9B6bkbfNlvF18I6amL7uVF9wSOJ2tN3UOYEcSo/6/GkBjNJ0xn+kSCG0jn0IJO4mHY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187160; c=relaxed/simple; bh=SqjWNc/AAbNdTZTROE+I1g9y6tALQIyEtva6+Jc7GTA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hRLtSMFYEZ322CuuM38qkgaCsRvt48heCOD5/Sd7WZwNo61zFAlDQ4o1GVhsmt1nJPhcq1GOWW4MPpgi9a04v/xz6+7LbgzGL7oWAmzcvj6TTKDSVAN8G84n/370k0dtmwLm0a9aAbenWpvs5Gnc3FGEnDibDvZZooDmyoOBmqY= 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=0BJG74P8; 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="0BJG74P8" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 0001C1A3629; Tue, 19 May 2026 10:39:15 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id C76C5606E9; Tue, 19 May 2026 10:39:15 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 42623107E8AE1; Tue, 19 May 2026 12:39:10 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187153; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=6Kk3lX1KY2eCXTfU74I0d1YFIDad5SvyHhY6xeby2Ic=; b=0BJG74P8irxrxeCnn5GOnqAWLhMGDQVe6vG7n63qU1pEiN7UR0UmCFb2VTINBi2J7TRZTZ 1YApi9oLLO49DS0foJg2OE/FoVj7do1CjRhNZT/2WSw2w502HYI0WkWmPeRTsGe/8mA3Lk FI804bTOFZ/lwjWhROxJgevPsDYlGL//w37jyhwlOOS8V6eaMprZSg/aoWyly6kyqBgpOa WsmyazIpFEexM8gUjet5k3hHPsnXxmsF1s4VRakpqvm+00kfDXIlO3UmmqtOD1F70QqB0a BAI7bZ8z27S7IGz5BD2e3GKaoRf4WVwQjZvi49Je3RemFQNGldevHrL+4z8hSQ== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:33 +0200 Subject: [PATCH 16/37] drm/display: bridge-connector: move per-connector fields to the dynamic connector 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: <20260519-drm-bridge-hotplug-v1-16-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 The various bridge pointers and the hdmi_funcs pointer are per-connector specific. In other words, when introducing bridge hotplug and the dynamically-created connector, they will have to be set per each created connector, possibly with different values from any previously created connector. Those pointers are currently in struct drm_bridge_connector, which will persist across multiple connector creations and destructions. This means when a dynamic connector is created before the previous one is destroyed, these fields would be overwritten by the new connector but the old one will still reference them. This would lead to possible put of incorrect briges, resulting in use-after-free and leaks. In preparation for bridge hotplug, move all those fields from struct drm_bridge_connector to struct drm_bridge_connector_dynconn, so they have the same allocation and lifetime of the connector they refer to. Update the many locations where these fields are used. Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/display/drm_bridge_connector.c | 370 +++++++++++++--------= ---- 1 file changed, 187 insertions(+), 183 deletions(-) diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/d= rm/display/drm_bridge_connector.c index b4e2c8f1d32d..bd421b6beb7c 100644 --- a/drivers/gpu/drm/display/drm_bridge_connector.c +++ b/drivers/gpu/drm/display/drm_bridge_connector.c @@ -67,26 +67,6 @@ struct drm_bridge_connector_dynconn { * @connector: the drm_connector exposed to user space */ struct drm_connector connector; -}; - -/** - * struct drm_bridge_connector - A connector backed by a chain of bridges - */ -struct drm_bridge_connector { - /** - * @drm: The DRM device we belong to - */ - struct drm_device *drm; - /** - * @encoder: - * - * The encoder at the start of the bridges chain. - */ - struct drm_encoder *encoder; - /** - * @dynconn: The DRM connector added by the drm_bridge_connector - */ - struct drm_bridge_connector_dynconn *dynconn; /** * @bridge_edid: * @@ -154,24 +134,47 @@ struct drm_bridge_connector { struct drm_connector_hdmi_funcs hdmi_funcs; }; =20 -static struct drm_bridge_connector *to_drm_bridge_connector(const struct d= rm_connector *connector) +/** + * struct drm_bridge_connector - A connector backed by a chain of bridges + */ +struct drm_bridge_connector { + /** + * @drm: The DRM device we belong to + */ + struct drm_device *drm; + /** + * @encoder: + * + * The encoder at the start of the bridges chain. + */ + struct drm_encoder *encoder; + /** + * @dynconn: The DRM connector added by the drm_bridge_connector + */ + struct drm_bridge_connector_dynconn *dynconn; +}; + +static struct drm_bridge_connector_dynconn * +to_drm_bridge_connector_dynconn(const struct drm_connector *connector) { - const struct drm_bridge_connector_dynconn *dynconn =3D - container_of(connector, struct drm_bridge_connector_dynconn, connector); + return container_of(connector, struct drm_bridge_connector_dynconn, conne= ctor); +} =20 - return dynconn->bridge_connector; +static struct drm_bridge_connector *to_drm_bridge_connector(const struct d= rm_connector *connector) +{ + return to_drm_bridge_connector_dynconn(connector)->bridge_connector; } =20 -static void drm_bridge_connector_put_bridges(struct drm_bridge_connector *= bridge_connector) +static void drm_bridge_connector_put_bridges(struct drm_bridge_connector_d= ynconn *dynconn) { - 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); + drm_bridge_put(dynconn->bridge_edid); + drm_bridge_put(dynconn->bridge_hpd); + drm_bridge_put(dynconn->bridge_detect); + drm_bridge_put(dynconn->bridge_modes); + drm_bridge_put(dynconn->bridge_hdmi); + drm_bridge_put(dynconn->bridge_hdmi_audio); + drm_bridge_put(dynconn->bridge_dp_audio); + drm_bridge_put(dynconn->bridge_hdmi_cec); } =20 /* -----------------------------------------------------------------------= ------ @@ -225,7 +228,9 @@ static void drm_bridge_connector_enable_hpd(struct drm_= connector *connector) { struct drm_bridge_connector *bridge_connector =3D to_drm_bridge_connector(connector); - struct drm_bridge *hpd =3D bridge_connector->bridge_hpd; + struct drm_bridge_connector_dynconn *dynconn =3D + to_drm_bridge_connector_dynconn(connector); + struct drm_bridge *hpd =3D dynconn->bridge_hpd; =20 if (hpd) drm_bridge_hpd_enable(hpd, drm_bridge_connector_hpd_cb, @@ -234,9 +239,9 @@ static void drm_bridge_connector_enable_hpd(struct drm_= connector *connector) =20 static void drm_bridge_connector_disable_hpd(struct drm_connector *connect= or) { - struct drm_bridge_connector *bridge_connector =3D - to_drm_bridge_connector(connector); - struct drm_bridge *hpd =3D bridge_connector->bridge_hpd; + struct drm_bridge_connector_dynconn *dynconn =3D + to_drm_bridge_connector_dynconn(connector); + struct drm_bridge *hpd =3D dynconn->bridge_hpd; =20 if (hpd) drm_bridge_hpd_disable(hpd); @@ -249,10 +254,10 @@ static void drm_bridge_connector_disable_hpd(struct d= rm_connector *connector) static enum drm_connector_status drm_bridge_connector_detect(struct drm_connector *connector, bool force) { - struct drm_bridge_connector *bridge_connector =3D - to_drm_bridge_connector(connector); - struct drm_bridge *detect =3D bridge_connector->bridge_detect; - struct drm_bridge *hdmi =3D bridge_connector->bridge_hdmi; + struct drm_bridge_connector_dynconn *dynconn =3D + to_drm_bridge_connector_dynconn(connector); + struct drm_bridge *detect =3D dynconn->bridge_detect; + struct drm_bridge *hdmi =3D dynconn->bridge_hdmi; enum drm_connector_status status; =20 if (detect) { @@ -281,9 +286,9 @@ drm_bridge_connector_detect(struct drm_connector *conne= ctor, bool force) =20 static void drm_bridge_connector_force(struct drm_connector *connector) { - struct drm_bridge_connector *bridge_connector =3D - to_drm_bridge_connector(connector); - struct drm_bridge *hdmi =3D bridge_connector->bridge_hdmi; + struct drm_bridge_connector_dynconn *dynconn =3D + to_drm_bridge_connector_dynconn(connector); + struct drm_bridge *hdmi =3D dynconn->bridge_hdmi; =20 if (hdmi) drm_atomic_helper_connector_hdmi_force(connector); @@ -305,11 +310,11 @@ static void drm_bridge_connector_debugfs_init(struct = drm_connector *connector, =20 static void drm_bridge_connector_reset(struct drm_connector *connector) { - struct drm_bridge_connector *bridge_connector =3D - to_drm_bridge_connector(connector); + struct drm_bridge_connector_dynconn *dynconn =3D + to_drm_bridge_connector_dynconn(connector); =20 drm_atomic_helper_connector_reset(connector); - if (bridge_connector->bridge_hdmi) + if (dynconn->bridge_hdmi) __drm_atomic_helper_connector_hdmi_reset(connector, connector->state); } @@ -320,7 +325,7 @@ static void drm_bridge_connector_dynconn_destroy(struct= drm_connector *connector container_of(connector, struct drm_bridge_connector_dynconn, connector); =20 drm_connector_cleanup(connector); - drm_bridge_connector_put_bridges(dynconn->bridge_connector); + drm_bridge_connector_put_bridges(dynconn); kfree(dynconn); } =20 @@ -370,15 +375,15 @@ static int drm_bridge_connector_get_modes_edid(struct= drm_connector *connector, =20 static int drm_bridge_connector_get_modes(struct drm_connector *connector) { - struct drm_bridge_connector *bridge_connector =3D - to_drm_bridge_connector(connector); + struct drm_bridge_connector_dynconn *dynconn =3D + to_drm_bridge_connector_dynconn(connector); struct drm_bridge *bridge; =20 /* * If there is a HDMI bridge, EDID has been updated as a part of * the .detect(). Just update the modes here. */ - bridge =3D bridge_connector->bridge_hdmi; + bridge =3D dynconn->bridge_hdmi; if (bridge) return drm_edid_connector_add_modes(connector); =20 @@ -386,7 +391,7 @@ static int drm_bridge_connector_get_modes(struct drm_co= nnector *connector) * If display exposes EDID, then we parse that in the normal way to * build table of supported modes. */ - bridge =3D bridge_connector->bridge_edid; + bridge =3D dynconn->bridge_edid; if (bridge) return drm_bridge_connector_get_modes_edid(connector, bridge); =20 @@ -394,7 +399,7 @@ static int drm_bridge_connector_get_modes(struct drm_co= nnector *connector) * Otherwise if the display pipeline reports modes (e.g. with a fixed * resolution panel or an analog TV output), query it. */ - bridge =3D bridge_connector->bridge_modes; + bridge =3D dynconn->bridge_modes; if (bridge) return bridge->funcs->get_modes(bridge, connector); =20 @@ -410,10 +415,10 @@ static enum drm_mode_status drm_bridge_connector_mode_valid(struct drm_connector *connector, const struct drm_display_mode *mode) { - struct drm_bridge_connector *bridge_connector =3D - to_drm_bridge_connector(connector); + struct drm_bridge_connector_dynconn *dynconn =3D + to_drm_bridge_connector_dynconn(connector); =20 - if (bridge_connector->bridge_hdmi) + if (dynconn->bridge_hdmi) return drm_hdmi_connector_mode_valid(connector, mode); =20 return MODE_OK; @@ -422,10 +427,10 @@ drm_bridge_connector_mode_valid(struct drm_connector = *connector, static int drm_bridge_connector_atomic_check(struct drm_connector *connect= or, struct drm_atomic_commit *state) { - struct drm_bridge_connector *bridge_connector =3D - to_drm_bridge_connector(connector); + struct drm_bridge_connector_dynconn *dynconn =3D + to_drm_bridge_connector_dynconn(connector); =20 - if (bridge_connector->bridge_hdmi) + if (dynconn->bridge_hdmi) return drm_atomic_helper_connector_hdmi_check(connector, state); =20 return 0; @@ -444,11 +449,11 @@ drm_bridge_connector_tmds_char_rate_valid(const struc= t drm_connector *connector, const struct drm_display_mode *mode, unsigned long long tmds_rate) { - struct drm_bridge_connector *bridge_connector =3D - to_drm_bridge_connector(connector); + struct drm_bridge_connector_dynconn *dynconn =3D + to_drm_bridge_connector_dynconn(connector); struct drm_bridge *bridge; =20 - bridge =3D bridge_connector->bridge_hdmi; + bridge =3D dynconn->bridge_hdmi; if (!bridge) return MODE_ERROR; =20 @@ -460,11 +465,11 @@ drm_bridge_connector_tmds_char_rate_valid(const struc= t drm_connector *connector, =20 static int drm_bridge_connector_clear_avi_infoframe(struct drm_connector *= connector) { - struct drm_bridge_connector *bridge_connector =3D - to_drm_bridge_connector(connector); + struct drm_bridge_connector_dynconn *dynconn =3D + to_drm_bridge_connector_dynconn(connector); struct drm_bridge *bridge; =20 - bridge =3D bridge_connector->bridge_hdmi; + bridge =3D dynconn->bridge_hdmi; if (!bridge) return -EINVAL; =20 @@ -474,11 +479,11 @@ static int drm_bridge_connector_clear_avi_infoframe(s= truct drm_connector *connec static int drm_bridge_connector_write_avi_infoframe(struct drm_connector *= connector, const u8 *buffer, size_t len) { - struct drm_bridge_connector *bridge_connector =3D - to_drm_bridge_connector(connector); + struct drm_bridge_connector_dynconn *dynconn =3D + to_drm_bridge_connector_dynconn(connector); struct drm_bridge *bridge; =20 - bridge =3D bridge_connector->bridge_hdmi; + bridge =3D dynconn->bridge_hdmi; if (!bridge) return -EINVAL; =20 @@ -487,11 +492,11 @@ static int drm_bridge_connector_write_avi_infoframe(s= truct drm_connector *connec =20 static int drm_bridge_connector_clear_hdmi_infoframe(struct drm_connector = *connector) { - struct drm_bridge_connector *bridge_connector =3D - to_drm_bridge_connector(connector); + struct drm_bridge_connector_dynconn *dynconn =3D + to_drm_bridge_connector_dynconn(connector); struct drm_bridge *bridge; =20 - bridge =3D bridge_connector->bridge_hdmi; + bridge =3D dynconn->bridge_hdmi; if (!bridge) return -EINVAL; =20 @@ -501,11 +506,11 @@ static int drm_bridge_connector_clear_hdmi_infoframe(= struct drm_connector *conne static int drm_bridge_connector_write_hdmi_infoframe(struct drm_connector = *connector, const u8 *buffer, size_t len) { - struct drm_bridge_connector *bridge_connector =3D - to_drm_bridge_connector(connector); + struct drm_bridge_connector_dynconn *dynconn =3D + to_drm_bridge_connector_dynconn(connector); struct drm_bridge *bridge; =20 - bridge =3D bridge_connector->bridge_hdmi; + bridge =3D dynconn->bridge_hdmi; if (!bridge) return -EINVAL; =20 @@ -514,11 +519,11 @@ static int drm_bridge_connector_write_hdmi_infoframe(= struct drm_connector *conne =20 static int drm_bridge_connector_clear_audio_infoframe(struct drm_connector= *connector) { - struct drm_bridge_connector *bridge_connector =3D - to_drm_bridge_connector(connector); + struct drm_bridge_connector_dynconn *dynconn =3D + to_drm_bridge_connector_dynconn(connector); struct drm_bridge *bridge; =20 - bridge =3D bridge_connector->bridge_hdmi; + bridge =3D dynconn->bridge_hdmi; if (!bridge) return -EINVAL; =20 @@ -528,11 +533,11 @@ static int drm_bridge_connector_clear_audio_infoframe= (struct drm_connector *conn static int drm_bridge_connector_write_audio_infoframe(struct drm_connector= *connector, const u8 *buffer, size_t len) { - struct drm_bridge_connector *bridge_connector =3D - to_drm_bridge_connector(connector); + struct drm_bridge_connector_dynconn *dynconn =3D + to_drm_bridge_connector_dynconn(connector); struct drm_bridge *bridge; =20 - bridge =3D bridge_connector->bridge_hdmi; + bridge =3D dynconn->bridge_hdmi; if (!bridge) return -EINVAL; =20 @@ -541,11 +546,11 @@ static int drm_bridge_connector_write_audio_infoframe= (struct drm_connector *conn =20 static int drm_bridge_connector_clear_hdr_drm_infoframe(struct drm_connect= or *connector) { - struct drm_bridge_connector *bridge_connector =3D - to_drm_bridge_connector(connector); + struct drm_bridge_connector_dynconn *dynconn =3D + to_drm_bridge_connector_dynconn(connector); struct drm_bridge *bridge; =20 - bridge =3D bridge_connector->bridge_hdmi; + bridge =3D dynconn->bridge_hdmi; if (!bridge) return -EINVAL; =20 @@ -555,11 +560,11 @@ static int drm_bridge_connector_clear_hdr_drm_infofra= me(struct drm_connector *co static int drm_bridge_connector_write_hdr_drm_infoframe(struct drm_connect= or *connector, const u8 *buffer, size_t len) { - struct drm_bridge_connector *bridge_connector =3D - to_drm_bridge_connector(connector); + struct drm_bridge_connector_dynconn *dynconn =3D + to_drm_bridge_connector_dynconn(connector); struct drm_bridge *bridge; =20 - bridge =3D bridge_connector->bridge_hdmi; + bridge =3D dynconn->bridge_hdmi; if (!bridge) return -EINVAL; =20 @@ -568,11 +573,11 @@ static int drm_bridge_connector_write_hdr_drm_infofra= me(struct drm_connector *co =20 static int drm_bridge_connector_clear_spd_infoframe(struct drm_connector *= connector) { - struct drm_bridge_connector *bridge_connector =3D - to_drm_bridge_connector(connector); + struct drm_bridge_connector_dynconn *dynconn =3D + to_drm_bridge_connector_dynconn(connector); struct drm_bridge *bridge; =20 - bridge =3D bridge_connector->bridge_hdmi; + bridge =3D dynconn->bridge_hdmi; if (!bridge) return -EINVAL; =20 @@ -582,11 +587,11 @@ static int drm_bridge_connector_clear_spd_infoframe(s= truct drm_connector *connec static int drm_bridge_connector_write_spd_infoframe(struct drm_connector *= connector, const u8 *buffer, size_t len) { - struct drm_bridge_connector *bridge_connector =3D - to_drm_bridge_connector(connector); + struct drm_bridge_connector_dynconn *dynconn =3D + to_drm_bridge_connector_dynconn(connector); struct drm_bridge *bridge; =20 - bridge =3D bridge_connector->bridge_hdmi; + bridge =3D dynconn->bridge_hdmi; if (!bridge) return -EINVAL; =20 @@ -596,11 +601,11 @@ static int drm_bridge_connector_write_spd_infoframe(s= truct drm_connector *connec static const struct drm_edid * drm_bridge_connector_read_edid(struct drm_connector *connector) { - struct drm_bridge_connector *bridge_connector =3D - to_drm_bridge_connector(connector); + struct drm_bridge_connector_dynconn *dynconn =3D + to_drm_bridge_connector_dynconn(connector); struct drm_bridge *bridge; =20 - bridge =3D bridge_connector->bridge_edid; + bridge =3D dynconn->bridge_edid; if (!bridge) return NULL; =20 @@ -638,12 +643,12 @@ static const struct drm_connector_infoframe_funcs drm= _bridge_connector_hdmi_spd_ =20 static int drm_bridge_connector_audio_startup(struct drm_connector *connec= tor) { - struct drm_bridge_connector *bridge_connector =3D - to_drm_bridge_connector(connector); + struct drm_bridge_connector_dynconn *dynconn =3D + to_drm_bridge_connector_dynconn(connector); struct drm_bridge *bridge; =20 - if (bridge_connector->bridge_hdmi_audio) { - bridge =3D bridge_connector->bridge_hdmi_audio; + if (dynconn->bridge_hdmi_audio) { + bridge =3D dynconn->bridge_hdmi_audio; =20 if (!bridge->funcs->hdmi_audio_startup) return 0; @@ -651,8 +656,8 @@ static int drm_bridge_connector_audio_startup(struct dr= m_connector *connector) return bridge->funcs->hdmi_audio_startup(bridge, connector); } =20 - if (bridge_connector->bridge_dp_audio) { - bridge =3D bridge_connector->bridge_dp_audio; + if (dynconn->bridge_dp_audio) { + bridge =3D dynconn->bridge_dp_audio; =20 if (!bridge->funcs->dp_audio_startup) return 0; @@ -667,18 +672,18 @@ static int drm_bridge_connector_audio_prepare(struct = drm_connector *connector, struct hdmi_codec_daifmt *fmt, struct hdmi_codec_params *hparms) { - struct drm_bridge_connector *bridge_connector =3D - to_drm_bridge_connector(connector); + struct drm_bridge_connector_dynconn *dynconn =3D + to_drm_bridge_connector_dynconn(connector); struct drm_bridge *bridge; =20 - if (bridge_connector->bridge_hdmi_audio) { - bridge =3D bridge_connector->bridge_hdmi_audio; + if (dynconn->bridge_hdmi_audio) { + bridge =3D dynconn->bridge_hdmi_audio; =20 return bridge->funcs->hdmi_audio_prepare(bridge, connector, fmt, hparms); } =20 - if (bridge_connector->bridge_dp_audio) { - bridge =3D bridge_connector->bridge_dp_audio; + if (dynconn->bridge_dp_audio) { + bridge =3D dynconn->bridge_dp_audio; =20 return bridge->funcs->dp_audio_prepare(bridge, connector, fmt, hparms); } @@ -688,17 +693,17 @@ static int drm_bridge_connector_audio_prepare(struct = drm_connector *connector, =20 static void drm_bridge_connector_audio_shutdown(struct drm_connector *conn= ector) { - struct drm_bridge_connector *bridge_connector =3D - to_drm_bridge_connector(connector); + struct drm_bridge_connector_dynconn *dynconn =3D + to_drm_bridge_connector_dynconn(connector); struct drm_bridge *bridge; =20 - if (bridge_connector->bridge_hdmi_audio) { - bridge =3D bridge_connector->bridge_hdmi_audio; + if (dynconn->bridge_hdmi_audio) { + bridge =3D dynconn->bridge_hdmi_audio; bridge->funcs->hdmi_audio_shutdown(bridge, connector); } =20 - if (bridge_connector->bridge_dp_audio) { - bridge =3D bridge_connector->bridge_dp_audio; + if (dynconn->bridge_dp_audio) { + bridge =3D dynconn->bridge_dp_audio; bridge->funcs->dp_audio_shutdown(bridge, connector); } } @@ -706,12 +711,12 @@ static void drm_bridge_connector_audio_shutdown(struc= t drm_connector *connector) static int drm_bridge_connector_audio_mute_stream(struct drm_connector *co= nnector, bool enable, int direction) { - struct drm_bridge_connector *bridge_connector =3D - to_drm_bridge_connector(connector); + struct drm_bridge_connector_dynconn *dynconn =3D + to_drm_bridge_connector_dynconn(connector); struct drm_bridge *bridge; =20 - if (bridge_connector->bridge_hdmi_audio) { - bridge =3D bridge_connector->bridge_hdmi_audio; + if (dynconn->bridge_hdmi_audio) { + bridge =3D dynconn->bridge_hdmi_audio; =20 if (!bridge->funcs->hdmi_audio_mute_stream) return -ENOTSUPP; @@ -720,8 +725,8 @@ static int drm_bridge_connector_audio_mute_stream(struc= t drm_connector *connecto enable, direction); } =20 - if (bridge_connector->bridge_dp_audio) { - bridge =3D bridge_connector->bridge_dp_audio; + if (dynconn->bridge_dp_audio) { + bridge =3D dynconn->bridge_dp_audio; =20 if (!bridge->funcs->dp_audio_mute_stream) return -ENOTSUPP; @@ -742,22 +747,22 @@ static const struct drm_connector_hdmi_audio_funcs dr= m_bridge_connector_hdmi_aud =20 static int drm_bridge_connector_hdmi_cec_enable(struct drm_connector *conn= ector, bool enable) { - struct drm_bridge_connector *bridge_connector =3D - to_drm_bridge_connector(connector); + struct drm_bridge_connector_dynconn *dynconn =3D + to_drm_bridge_connector_dynconn(connector); struct drm_bridge *bridge; =20 - bridge =3D bridge_connector->bridge_hdmi_cec; + bridge =3D dynconn->bridge_hdmi_cec; =20 return bridge->funcs->hdmi_cec_enable(bridge, enable); } =20 static int drm_bridge_connector_hdmi_cec_log_addr(struct drm_connector *co= nnector, u8 logical_addr) { - struct drm_bridge_connector *bridge_connector =3D - to_drm_bridge_connector(connector); + struct drm_bridge_connector_dynconn *dynconn =3D + to_drm_bridge_connector_dynconn(connector); struct drm_bridge *bridge; =20 - bridge =3D bridge_connector->bridge_hdmi_cec; + bridge =3D dynconn->bridge_hdmi_cec; =20 return bridge->funcs->hdmi_cec_log_addr(bridge, logical_addr); } @@ -767,11 +772,11 @@ static int drm_bridge_connector_hdmi_cec_transmit(str= uct drm_connector *connecto u32 signal_free_time, struct cec_msg *msg) { - struct drm_bridge_connector *bridge_connector =3D - to_drm_bridge_connector(connector); + struct drm_bridge_connector_dynconn *dynconn =3D + to_drm_bridge_connector_dynconn(connector); struct drm_bridge *bridge; =20 - bridge =3D bridge_connector->bridge_hdmi_cec; + bridge =3D dynconn->bridge_hdmi_cec; =20 return bridge->funcs->hdmi_cec_transmit(bridge, attempts, signal_free_time, @@ -780,11 +785,11 @@ static int drm_bridge_connector_hdmi_cec_transmit(str= uct drm_connector *connecto =20 static int drm_bridge_connector_hdmi_cec_init(struct drm_connector *connec= tor) { - struct drm_bridge_connector *bridge_connector =3D - to_drm_bridge_connector(connector); + struct drm_bridge_connector_dynconn *dynconn =3D + to_drm_bridge_connector_dynconn(connector); struct drm_bridge *bridge; =20 - bridge =3D bridge_connector->bridge_hdmi_cec; + bridge =3D dynconn->bridge_hdmi_cec; =20 if (!bridge->funcs->hdmi_cec_init) return 0; @@ -821,7 +826,6 @@ static int drm_bridge_connector_get_bridges(struct drm_= bridge_connector_dynconn struct drm_bridge **panel_bridge, bool *support_hdcp) { - struct drm_bridge_connector *bridge_connector =3D dynconn->bridge_connect= or; struct drm_connector *connector =3D &dynconn->connector; =20 /* @@ -831,7 +835,7 @@ static int drm_bridge_connector_get_bridges(struct drm_= bridge_connector_dynconn connector->ycbcr_420_allowed =3D true; *connector_type =3D DRM_MODE_CONNECTOR_Unknown; =20 - drm_for_each_bridge_in_chain_scoped(bridge_connector->encoder, bridge) { + drm_for_each_bridge_in_chain_scoped(dynconn->bridge_connector->encoder, b= ridge) { if (!bridge->interlace_allowed) connector->interlace_allowed =3D false; if (!bridge->ycbcr_420_allowed) @@ -841,26 +845,26 @@ static int drm_bridge_connector_get_bridges(struct dr= m_bridge_connector_dynconn * Ensure the last bridge declares OP_EDID or OP_MODES or both. */ if (bridge->ops & DRM_BRIDGE_OP_EDID || bridge->ops & DRM_BRIDGE_OP_MODE= S) { - drm_bridge_put(bridge_connector->bridge_edid); - bridge_connector->bridge_edid =3D NULL; - drm_bridge_put(bridge_connector->bridge_modes); - bridge_connector->bridge_modes =3D NULL; + drm_bridge_put(dynconn->bridge_edid); + dynconn->bridge_edid =3D NULL; + drm_bridge_put(dynconn->bridge_modes); + dynconn->bridge_modes =3D NULL; =20 if (bridge->ops & DRM_BRIDGE_OP_EDID) - bridge_connector->bridge_edid =3D drm_bridge_get(bridge); + dynconn->bridge_edid =3D drm_bridge_get(bridge); if (bridge->ops & DRM_BRIDGE_OP_MODES) - bridge_connector->bridge_modes =3D drm_bridge_get(bridge); + dynconn->bridge_modes =3D drm_bridge_get(bridge); } if (bridge->ops & DRM_BRIDGE_OP_HPD) { - drm_bridge_put(bridge_connector->bridge_hpd); - bridge_connector->bridge_hpd =3D drm_bridge_get(bridge); + drm_bridge_put(dynconn->bridge_hpd); + dynconn->bridge_hpd =3D drm_bridge_get(bridge); } if (bridge->ops & DRM_BRIDGE_OP_DETECT) { - drm_bridge_put(bridge_connector->bridge_detect); - bridge_connector->bridge_detect =3D drm_bridge_get(bridge); + drm_bridge_put(dynconn->bridge_detect); + dynconn->bridge_detect =3D drm_bridge_get(bridge); } if (bridge->ops & DRM_BRIDGE_OP_HDMI) { - if (bridge_connector->bridge_hdmi) + if (dynconn->bridge_hdmi) return -EBUSY; if (!bridge->funcs->hdmi_write_avi_infoframe || !bridge->funcs->hdmi_clear_avi_infoframe || @@ -883,7 +887,7 @@ static int drm_bridge_connector_get_bridges(struct drm_= bridge_connector_dynconn !bridge->funcs->hdmi_clear_spd_infoframe)) return -EINVAL; =20 - bridge_connector->bridge_hdmi =3D drm_bridge_get(bridge); + dynconn->bridge_hdmi =3D drm_bridge_get(bridge); =20 if (bridge->supported_formats) *supported_formats =3D bridge->supported_formats; @@ -892,10 +896,10 @@ static int drm_bridge_connector_get_bridges(struct dr= m_bridge_connector_dynconn } =20 if (bridge->ops & DRM_BRIDGE_OP_HDMI_AUDIO) { - if (bridge_connector->bridge_hdmi_audio) + if (dynconn->bridge_hdmi_audio) return -EBUSY; =20 - if (bridge_connector->bridge_dp_audio) + if (dynconn->bridge_dp_audio) return -EBUSY; =20 if (!bridge->hdmi_audio_max_i2s_playback_channels && @@ -906,14 +910,14 @@ static int drm_bridge_connector_get_bridges(struct dr= m_bridge_connector_dynconn !bridge->funcs->hdmi_audio_shutdown) return -EINVAL; =20 - bridge_connector->bridge_hdmi_audio =3D drm_bridge_get(bridge); + dynconn->bridge_hdmi_audio =3D drm_bridge_get(bridge); } =20 if (bridge->ops & DRM_BRIDGE_OP_DP_AUDIO) { - if (bridge_connector->bridge_dp_audio) + if (dynconn->bridge_dp_audio) return -EBUSY; =20 - if (bridge_connector->bridge_hdmi_audio) + if (dynconn->bridge_hdmi_audio) return -EBUSY; =20 if (!bridge->hdmi_audio_max_i2s_playback_channels && @@ -924,21 +928,21 @@ static int drm_bridge_connector_get_bridges(struct dr= m_bridge_connector_dynconn !bridge->funcs->dp_audio_shutdown) return -EINVAL; =20 - bridge_connector->bridge_dp_audio =3D drm_bridge_get(bridge); + dynconn->bridge_dp_audio =3D drm_bridge_get(bridge); } =20 if (bridge->ops & DRM_BRIDGE_OP_HDMI_CEC_NOTIFIER) { - if (bridge_connector->bridge_hdmi_cec) + if (dynconn->bridge_hdmi_cec) return -EBUSY; =20 - bridge_connector->bridge_hdmi_cec =3D drm_bridge_get(bridge); + dynconn->bridge_hdmi_cec =3D drm_bridge_get(bridge); } =20 if (bridge->ops & DRM_BRIDGE_OP_HDMI_CEC_ADAPTER) { - if (bridge_connector->bridge_hdmi_cec) + if (dynconn->bridge_hdmi_cec) return -EBUSY; =20 - bridge_connector->bridge_hdmi_cec =3D drm_bridge_get(bridge); + dynconn->bridge_hdmi_cec =3D drm_bridge_get(bridge); =20 if (!bridge->funcs->hdmi_cec_enable || !bridge->funcs->hdmi_cec_log_addr || @@ -972,20 +976,20 @@ static int drm_bridge_connector_get_bridges(struct dr= m_bridge_connector_dynconn return 0; } =20 -static int drm_bridge_connector_init_hdmi_audio_cec(struct drm_bridge_conn= ector *bridge_connector) +static int drm_bridge_connector_init_hdmi_audio_cec(struct drm_bridge_conn= ector_dynconn *dynconn) { - struct drm_connector *connector =3D &bridge_connector->dynconn->connector; + struct drm_connector *connector =3D &dynconn->connector; int ret; =20 - if (bridge_connector->bridge_hdmi_audio || - bridge_connector->bridge_dp_audio) { + if (dynconn->bridge_hdmi_audio || + dynconn->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 (dynconn->bridge_hdmi_audio) + bridge =3D dynconn->bridge_hdmi_audio; else - bridge =3D bridge_connector->bridge_dp_audio; + bridge =3D dynconn->bridge_dp_audio; =20 dev =3D bridge->hdmi_audio_dev; =20 @@ -999,9 +1003,9 @@ static int drm_bridge_connector_init_hdmi_audio_cec(st= ruct drm_bridge_connector return 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 (dynconn->bridge_hdmi_cec && + dynconn->bridge_hdmi_cec->ops & DRM_BRIDGE_OP_HDMI_CEC_NOTIFIER) { + struct drm_bridge *bridge =3D dynconn->bridge_hdmi_cec; =20 ret =3D drmm_connector_hdmi_cec_notifier_register(connector, NULL, bridge->hdmi_cec_dev); @@ -1009,9 +1013,9 @@ static int drm_bridge_connector_init_hdmi_audio_cec(s= truct drm_bridge_connector return 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 (dynconn->bridge_hdmi_cec && + dynconn->bridge_hdmi_cec->ops & DRM_BRIDGE_OP_HDMI_CEC_ADAPTER) { + struct drm_bridge *bridge =3D dynconn->bridge_hdmi_cec; =20 ret =3D drmm_connector_hdmi_cec_register(connector, &drm_bridge_connector_hdmi_cec_funcs, @@ -1061,29 +1065,29 @@ static int drm_bridge_connector_add_connector(struc= t drm_bridge_connector *bridg return ret; } =20 - if (bridge_connector->bridge_hdmi) { + if (dynconn->bridge_hdmi) { if (!connector->ycbcr_420_allowed) supported_formats &=3D ~BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR420); =20 - bridge_connector->hdmi_funcs =3D drm_bridge_connector_hdmi_funcs; + dynconn->hdmi_funcs =3D drm_bridge_connector_hdmi_funcs; =20 - if (bridge_connector->bridge_hdmi->ops & DRM_BRIDGE_OP_HDMI_AUDIO) - bridge_connector->hdmi_funcs.audio =3D + if (dynconn->bridge_hdmi->ops & DRM_BRIDGE_OP_HDMI_AUDIO) + dynconn->hdmi_funcs.audio =3D drm_bridge_connector_hdmi_audio_infoframe; =20 - if (bridge_connector->bridge_hdmi->ops & DRM_BRIDGE_OP_HDMI_HDR_DRM_INFO= FRAME) - bridge_connector->hdmi_funcs.hdr_drm =3D + if (dynconn->bridge_hdmi->ops & DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME) + dynconn->hdmi_funcs.hdr_drm =3D drm_bridge_connector_hdmi_hdr_drm_infoframe; =20 - if (bridge_connector->bridge_hdmi->ops & DRM_BRIDGE_OP_HDMI_SPD_INFOFRAM= E) - bridge_connector->hdmi_funcs.spd =3D + if (dynconn->bridge_hdmi->ops & DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME) + dynconn->hdmi_funcs.spd =3D drm_bridge_connector_hdmi_spd_infoframe; =20 ret =3D drm_connector_hdmi_dynamic_init(bridge_connector->drm, connector, - bridge_connector->bridge_hdmi->vendor, - bridge_connector->bridge_hdmi->product, + dynconn->bridge_hdmi->vendor, + dynconn->bridge_hdmi->product, &drm_bridge_connector_funcs, - &bridge_connector->hdmi_funcs, + &dynconn->hdmi_funcs, connector_type, ddc, supported_formats, max_bpc); @@ -1093,7 +1097,7 @@ static int drm_bridge_connector_add_connector(struct = drm_bridge_connector *bridg connector_type, ddc); } if (ret) { - drm_bridge_connector_put_bridges(dynconn->bridge_connector); + drm_bridge_connector_put_bridges(dynconn); kfree(dynconn); return ret; } @@ -1104,15 +1108,15 @@ static int drm_bridge_connector_add_connector(struc= t drm_bridge_connector *bridg =20 drm_bridge_connector_reset(connector); =20 - ret =3D drm_bridge_connector_init_hdmi_audio_cec(bridge_connector); + ret =3D drm_bridge_connector_init_hdmi_audio_cec(dynconn); if (ret) goto err_put; =20 drm_connector_helper_add(connector, &drm_bridge_connector_helper_funcs); =20 - if (bridge_connector->bridge_hpd) + if (dynconn->bridge_hpd) connector->polled =3D DRM_CONNECTOR_POLL_HPD; - else if (bridge_connector->bridge_detect) + else if (dynconn->bridge_detect) connector->polled =3D DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; =20 --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (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 3C37B4CA29D for ; Tue, 19 May 2026 10:39:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187164; cv=none; b=mbNffsooWKRQm4+6D008Yt3u+HaTt8e4qTqp+qwWym0t53xNGnLqUlsh4NVf5lstP7yYfTNoG9dmarikGYvKQD8qJd1yWAFgSEKU4fIyrHwSLHPvPdCU63IEVwF7cBK+am2TWQU9ZX4as7su8proLynj+V9Xedw8Tk8toiBzCz0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187164; c=relaxed/simple; bh=6tZr755GEhwo/7aN3+ctTOpQ+AiSu4iO5zIwvlPSnOs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=WLKulOqPwBa1T706wiLQ5nnlN93bPs7Xe3cj4xUYEyUbhH54T1Bo19Zr8RWh9fhE0zHkSgABMQ4/+xxhBWzC9C7R+EPiYDYtGDvjok4QoQ5218Ya3likiB6zdNCZY/uOLxkKxBGjvGsANA0qi5LJoc3mnkke+Ord8eIuYjo63Kg= 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=B8IVN01N; arc=none smtp.client-ip=185.246.85.4 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="B8IVN01N" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id E22854E42CF1; Tue, 19 May 2026 10:39:20 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id A9D18606E9; Tue, 19 May 2026 10:39:20 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 8938E107E8AE7; Tue, 19 May 2026 12:39:14 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187158; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=Hruhb1ZCQ/MBija+fhFHFu8qDzgA34c2IABg7xr74FQ=; b=B8IVN01NRf+lvOHxqOAWPpYJOgdPVyJMoN+pKM3crUPNsOwQ6/0jMT/Ug4Nebna24uoapa mtDelWsbPRs9BYKYo8+M24XUYWPeBUDjJUvlGvhex4UeR6lRjMVjN9saKY2tZ9mEy15VVu lynCgYEA6tVoVMJm2bBGpMjQjEfVcE0tqyqpn+tpghSSy7kZeAN10ZTRFNNi6q0iDANvbx 1n641SLj8gnd8VgQ46kfjal6Z6sEJt1e7UFwyj3mRVLK+QbgjkR4xCR0OO/rmcVAOfVA5s WryYGacIJ8LUCHaIKH2+oKLeLKLaVzB0+qGE2E3MqGh0PqBOzbOjWTwDR0W3vg== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:34 +0200 Subject: [PATCH 17/37] drm/display: bridge-connector: protect dynconn creation and destruction with a mutex 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: <20260519-drm-bridge-hotplug-v1-17-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 Bridge hotplug will make the connector dynamically created and destroyed based on hotplug events. In preparation for that, add a mutex to mutually exclude connector creation and destruction. Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/display/drm_bridge_connector.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/d= rm/display/drm_bridge_connector.c index bd421b6beb7c..b83da529cc7a 100644 --- a/drivers/gpu/drm/display/drm_bridge_connector.c +++ b/drivers/gpu/drm/display/drm_bridge_connector.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -152,6 +153,11 @@ struct drm_bridge_connector { * @dynconn: The DRM connector added by the drm_bridge_connector */ struct drm_bridge_connector_dynconn *dynconn; + /** + * @dynconn_mutex: Protect @dynconn from concurrent creation and + * destruction + */ + struct mutex dynconn_mutex; }; =20 static struct drm_bridge_connector_dynconn * @@ -810,6 +816,8 @@ static const struct drm_connector_hdmi_cec_funcs drm_br= idge_connector_hdmi_cec_f =20 static void drm_bridge_connector_dynconn_release(struct drm_bridge_connect= or *bridge_connector) { + guard(mutex)(&bridge_connector->dynconn_mutex); + if (!bridge_connector->dynconn) return; =20 @@ -1050,6 +1058,8 @@ static int drm_bridge_connector_add_connector(struct = drm_bridge_connector *bridg int connector_type; int ret; =20 + guard(mutex)(&bridge_connector->dynconn_mutex); + struct drm_bridge_connector_dynconn *dynconn =3D kzalloc_obj(*dynconn); if (!dynconn) return -ENOMEM; @@ -1177,6 +1187,7 @@ struct drm_connector *drm_bridge_connector_init(struc= t drm_device *drm, if (!bridge_connector) return ERR_PTR(-ENOMEM); =20 + mutex_init(&bridge_connector->dynconn_mutex); bridge_connector->drm =3D drm; bridge_connector->encoder =3D encoder; =20 --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 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 5C0104921AA for ; Tue, 19 May 2026 10:39:26 +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=1779187167; cv=none; b=afpYFqF/5z0xmlKydwLADGS0s9buV2TFID55yOHJ0xmeJSK6REIYk0TFCZgH/nIF4qCCj3+u5nBoVl89uZO+ND+22tGcM5MCV8IQ9KLwn+/oEXuiB1CZuuZGckyV2omUvLq1cLmk5wwsp4ISq9bSNS47VrX58HrgUB3aoVvYcWY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187167; c=relaxed/simple; bh=U2iO7K6G/XoN0sfD4STz5u/lsimDw/ZGrpK5zBP2DN8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=q/JiXrbbYuOB98fIY/6ReEuVqMQwcjZM+OM2yWucwKIdB0J4e8IweT6571lrIgs7ElGeDHevNg0+JXgdFrp2JjhEK2Uq62XRQO5ncnRNWBeNxCXddgpc7cnArphXYfXzzhIT4NslFEEdBmGnTsUxDUqyV2RuoCo5n/GCKAc1qBI= 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=ZY2oKp7d; 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="ZY2oKp7d" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 166BF1A3629; Tue, 19 May 2026 10:39:25 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id DCF30606E9; Tue, 19 May 2026 10:39:24 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 4CC8B107E8ABA; Tue, 19 May 2026 12:39:19 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187163; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=NREKLKfWOcPRruTk5u0cJPgt+kQBoWF03bP7a1G1JZo=; b=ZY2oKp7d30FIAIsJ9UVTUw/DX/O0NjcbXa3fMn7sYbGqoKkfw8V8Gtvos/MoJAFuuVJYKP TKsj2pDmWvT+qQpu+9gDAqH/tpbRJhXKmvetb8u9z+noBIrC5R5lYvCk1nF0RGcqudysQW Y/5bESKfLXeK4oYOy4oKRwt5G/hLOVzRW0BjPPoNVfpz6rFR3in5KYMwIrFhQGGYO20k+H bFU4OA4HYSLDx3hNYeTZmWgtL59yCE8/HzBthzAyyHV2z0I81/FFgUCAHmNtOhA8HqNbyG Fx1g52AXRG6YrYoLPjzvBgRn45+0MAZCQ6T8Bl7PQ+Q9nPm09LWymqCve/wG8g== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:35 +0200 Subject: [PATCH 18/37] drm/bridge: samsung-dsim: remove the panel_bridge on host_detach 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: <20260519-drm-bridge-hotplug-v1-18-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 In preparation for DRM bridge hot-plugging, we need to handle the dynamic lifetime of the following bridge in case the samsung-dsim is always present and the following bridge (next_bridge) is hot-unplugged. Based on the 'if (!IS_ERR(panel))' check in samsung_dsim_host_attach(), the next_bridge could be A) a panel bridge created by this driver via devm_drm_panel_bridge_add() or B) a pre-existing bridge obtained via of_drm_find_and_get_bridge(). For case B) we need to put that reference when the next_bridge is removed, which is already handled by calling drm_bridge_clear_and_put() in samsung_dsim_host_detach() and in the samsung_dsim_host_attach() error management code. In case A) we additionally have to remove the panel bridge. Currently it is created by devm_drm_panel_bridge_add(), which adds two devm actions with the refcounted panel bridge: - drm_bridge_put_void() via devm_drm_bridge_alloc() on panel->dev - devm_drm_panel_bridge_release() via devm_drm_panel_bridge_add_typed() on the consumer device (samsung-dsim) The first action is OK: being tied to panel->dev it will happen when the panel is unplugged. The second action is bound to the consumer device, so the devm semantics is not useful here when introducing hotplug. Indeed we need to drop the next_bridge in samsung_dsim_host_detach() anyway, before the driver .remove function, in order to support {add, {attach, detach} x N, remove} hotplug event sequences. Thus move to the non-devm drm_panel_bridge_add() along with the matching drm_panel_bridge_remove(), so the lifetime of the panel-bridge is tied to the host_attach/host_detach cycle and not the whole samsung-dsim device lifetime. Signed-off-by: Luca Ceresoli --- In a previous discussion with Maxime he mentioned a plan to make every drm_panel always have a wrapping bridge. With that done, all the code handling the panel and adding the panel_bridge would become useless here (and in many other places) and could be entirely removed. This patch is a temporary solution until that happens. The best pointer I could find to that discussion is [0], but there might be more recent material I could not find at the moment. [0] https://lore.kernel.org/lkml/20250218-faithful-white-magpie-da9ac9@houa= t/ --- drivers/gpu/drm/bridge/samsung-dsim.c | 17 ++++++++++++++--- include/drm/bridge/samsung-dsim.h | 2 ++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge= /samsung-dsim.c index 5b799619e07e..2af287221e22 100644 --- a/drivers/gpu/drm/bridge/samsung-dsim.c +++ b/drivers/gpu/drm/bridge/samsung-dsim.c @@ -1951,14 +1951,16 @@ static int samsung_dsim_host_attach(struct mipi_dsi= _host *host, if (!remote) return -ENODEV; =20 + dsi->panel_bridge_added =3D false; panel =3D of_drm_find_panel(remote); if (!IS_ERR(panel)) { - next_bridge =3D devm_drm_panel_bridge_add(dev, panel); + next_bridge =3D drm_panel_bridge_add(panel); if (IS_ERR(next_bridge)) { ret =3D PTR_ERR(next_bridge); next_bridge =3D NULL; // Inhibit the cleanup action on an ERR_PTR } else { drm_bridge_get(next_bridge); + dsi->panel_bridge_added =3D true; } } else { next_bridge =3D of_drm_find_and_get_bridge(remote); @@ -1989,7 +1991,7 @@ static int samsung_dsim_host_attach(struct mipi_dsi_h= ost *host, if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO)) { ret =3D samsung_dsim_register_te_irq(dsi, &device->dev); if (ret) - goto err_remove_bridge; + goto err_remove_panel_bridge; } =20 // The next bridge can be used by host_ops->attach @@ -2011,8 +2013,12 @@ static int samsung_dsim_host_attach(struct mipi_dsi_= host *host, drm_bridge_clear_and_put(&dsi->bridge.next_bridge); if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO)) samsung_dsim_unregister_te_irq(dsi); -err_remove_bridge: +err_remove_panel_bridge: drm_bridge_remove(&dsi->bridge); + if (dsi->panel_bridge_added) { + drm_panel_bridge_remove(next_bridge); + dsi->panel_bridge_added =3D false; + } return ret; } =20 @@ -2022,6 +2028,11 @@ static int samsung_dsim_host_detach(struct mipi_dsi_= host *host, struct samsung_dsim *dsi =3D host_to_dsi(host); const struct samsung_dsim_plat_data *pdata =3D dsi->plat_data; =20 + if (dsi->panel_bridge_added) { + drm_panel_bridge_remove(dsi->bridge.next_bridge); + dsi->panel_bridge_added =3D false; + } + if (pdata->host_ops && pdata->host_ops->detach) pdata->host_ops->detach(dsi, device); =20 diff --git a/include/drm/bridge/samsung-dsim.h b/include/drm/bridge/samsung= -dsim.h index 03005e474704..3620f7aa9394 100644 --- a/include/drm/bridge/samsung-dsim.h +++ b/include/drm/bridge/samsung-dsim.h @@ -131,6 +131,8 @@ struct samsung_dsim { const struct samsung_dsim_plat_data *plat_data; =20 void *priv; + + bool panel_bridge_added; /* true iff next_bridge is a panel_bridge we cre= ated */ }; =20 extern int samsung_dsim_probe(struct platform_device *pdev); --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 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 5789A4DBD69 for ; Tue, 19 May 2026 10:39:30 +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=1779187171; cv=none; b=Zjs6HHbn6qWPXGvTIs3gJvyCcGEIy2E7wrUtwz7jISfDkoIXXkbtGckHmwADvxnmHXP906V0GaTDi1kXFQyIrVJXfqJd6NTCzK2myXNaedytIsDnBS6YQSU7WkC1FTEq9yquGBJogsQAGTGiwstZP/Nkj25upHi4IRhuyxXIzhk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187171; c=relaxed/simple; bh=avAnBR6BIJzQQBJfeRfYXgmcOJAAOyJbcO+kCfQGJXQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZBfQB6bPchfkliLllUfWNKKJsyrXNq0hYbmKg6Wh9QbV2AH7W5evGpy1YVfssfN0FlUNbqPKjpLSUyhe1+efJ9F4Hg3LZcrzojNjROR7T8Tf3ZeCByAWNiFrazjGeXFp2ojFwRPZ87+8HimzPybdo0I5vbrAbHUu109c+G6W3+M= 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=IIQiFWvN; 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="IIQiFWvN" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 1979F1A3628; Tue, 19 May 2026 10:39:29 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id E2635606E9; Tue, 19 May 2026 10:39:28 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id AA268107E8AE0; Tue, 19 May 2026 12:39:23 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187167; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=viok0NZbuZ8e/hD57hUPyDwRDr0DwR3pZjydZmRPEJY=; b=IIQiFWvNhiB4jeRRZP+AbU7H+nswsdO7rN2CHIxfxHWCb9p85Lo2MX8g+God7kNUYM6QqT eex8Oq4KVgVP9LWOyYMRfAtUclVVk/qVJRvY9MlyVUrWnVDpqNLn9ZoIzsPdubT6m+0ozZ 72wGxTOzSj0HhmcJw6q+bYhj9qV0r8yqb9QAIoHN1Rna7oNG1nd+FO2saAWOQOkmOho3+g zwELy0KhvMn3tJ2XTIYYkEZUzYpm0NUYi7oP4qnhOdKczQfLRT9egTI3gpnAuqPFfgDPdT W50AuSHxDuUytCTc5ai93A0f25XxPAXswScof0rdzd2njB/4mGJhmR/wMJ/YZA== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:36 +0200 Subject: [PATCH 19/37] drm/bridge: samsung-dsim: move drm_bridge_add() call to probe 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: <20260519-drm-bridge-hotplug-v1-19-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 This bridge driver calls drm_bridge_add() in the DSI host .attach callback instead of in the probe function. This works for current use cases but is problematic for supporting hotplug of DRM bridges. The problematic case is when this DSI host is always present while its DSI device is hot-pluggable. In such case with the current code the DRM card will not be populated until after the DSI device attaches to the host, which could happen a very long time after booting, or even not happen at all. The reason is that the previous pipeline component (the encoder in this case) when probing cannot find the samsung-dsim bridge. What happens is: [1 and 2 can happen in any order, same result] 1) samsung-dsim probes (does not drm_bridge_add() itself) 2) The lcdif starts probing multiple times, but lcdif_probe -> lcdif_load -> lcdif_attach_bridge -> devm_drm_of_get_bridge() returns -EPROBE_DEFER because the samsung-dsim is not in the global bridge_list (deferred probe pending: imx-lcdif: Cannot connect bridge) The samsung-dsim will not drm_bridge_add() itself until a DSI device will try to mipi_dsi_attach() to the DSI Host, which can happen arbitratily late on hot-pluggable hardware. As a preliminary step to supporting hotplug move drm_bridge_add() at probe time, so that the samsung-dsim DSI host bridge is available during boot, even without a connected DSI device. This results in: 1) samsung-dsim probes (and adds to drm_bridge_add() itself) 2) The lcdif starts probing multiple times, but lcdif_probe -> lcdif_load -> lcdif_attach_bridge -> devm_drm_of_get_bridge() --> OK, returns samsung-dsim ptr Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/bridge/samsung-dsim.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge= /samsung-dsim.c index 2af287221e22..cefb20ec68ad 100644 --- a/drivers/gpu/drm/bridge/samsung-dsim.c +++ b/drivers/gpu/drm/bridge/samsung-dsim.c @@ -1980,8 +1980,6 @@ static int samsung_dsim_host_attach(struct mipi_dsi_h= ost *host, mipi_dsi_pixel_format_to_bpp(device->format), device->mode_flags); =20 - drm_bridge_add(&dsi->bridge); - /* * This is a temporary solution and should be made by more generic way. * @@ -2014,7 +2012,6 @@ static int samsung_dsim_host_attach(struct mipi_dsi_h= ost *host, if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO)) samsung_dsim_unregister_te_irq(dsi); err_remove_panel_bridge: - drm_bridge_remove(&dsi->bridge); if (dsi->panel_bridge_added) { drm_panel_bridge_remove(next_bridge); dsi->panel_bridge_added =3D false; @@ -2040,8 +2037,6 @@ static int samsung_dsim_host_detach(struct mipi_dsi_h= ost *host, =20 samsung_dsim_unregister_te_irq(dsi); =20 - drm_bridge_remove(&dsi->bridge); - return 0; } =20 @@ -2242,6 +2237,8 @@ int samsung_dsim_probe(struct platform_device *pdev) goto err_disable_runtime; } =20 + drm_bridge_add(&dsi->bridge); + return 0; =20 err_disable_runtime: @@ -2255,6 +2252,8 @@ void samsung_dsim_remove(struct platform_device *pdev) { struct samsung_dsim *dsi =3D platform_get_drvdata(pdev); =20 + drm_bridge_remove(&dsi->bridge); + pm_runtime_disable(&pdev->dev); =20 if (dsi->plat_data->host_ops && dsi->plat_data->host_ops->unregister_host) --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 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 524AC4DBD78 for ; Tue, 19 May 2026 10:39:34 +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=1779187176; cv=none; b=RKpQPW6rm7oe9L5PASX+Vv/tI6Qi0CtX8LwMAjg+eldH4MzJ3AQTHcBH/SaEwI/Z0bR4QOi/YhOfUHFmEMfTE+cuK50K30ByU8w6gLYd4SuXVVBn+B9pK/WUG4b6RnyRcpC7PNq8LHJyapNNOBo/LaQ3bI7XLyIMdoQxFQsYUDc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187176; c=relaxed/simple; bh=aUCOP+agAjxZpckDbDUVdOmdg9Hu1iDIc5tgr+R5ZRI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dys6EQSDwTq2aNZBE1IkHfuKQ01O+OPHxkeVHta2u8qYyiRHEfOcl4o1D21D0Sm4J0RLBrAEpTpwmAwyP6KoOWtsfK6+1O4gYQsi+3gF/4Zvn/V//j/Vtw1tMKJZUU9RNUtrLrzDFMQWgt6nlECETqT18fxDeN50N1EaXFJCSC8= 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=ViIgPYrO; 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="ViIgPYrO" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id 45D66C2B9E5; Tue, 19 May 2026 10:40:26 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 1B9D4606E9; Tue, 19 May 2026 10:39:33 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id E1F01107E8AE5; Tue, 19 May 2026 12:39:27 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187171; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=X+JiQ9ah3Zg0b42ga8MWBRYlO8NHJoM8q4bf6PzICZs=; b=ViIgPYrOdMaIUxl4rsKNrq8C+yslUUqrVKwjWnKL2ohmjs+1qBBlpZl2gzAKMY9GcKoCrm jP//QcpyRsQDZHyFNRiwjAn+7nIRRnvPYWGLlz+0auQ4bh2z/FTrY2943moaikGI+FGIuA Lz+qmrdRIBvZbN4Jf8WGuWadl65302xV1NR6+fHDwxgGwy06B0r1VG9H+vflq9oxZfW8WH 2HDF3kw3WtXvoYtyG+WiSLj9myhaxrBzHXXsjz9rOvI9pjZIeZmUy3W+49mlXfMHv5lZVa LIlKglv0v+lO5V4pkypRNrb6UyeMfbYAnaAP5IroqO3guOkc1rFtatTIx2R1zQ== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:37 +0200 Subject: [PATCH 20/37] drm/bridge: samsung-dsim: attach: return -EPROBE_DEFER is next bridge not yet available 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: <20260519-drm-bridge-hotplug-v1-20-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 When samsung_dsim_attach() is called but the next_bridge is not (yet) known, it calls drm_bridge_attach() unconditionally. In turn drm_bridge_attach() will return -EINVAL because the bridge pointer in NULL. -EINVAL is propagated transparently to the caller, resulting in the whole attach operation to fail. This is fine for current use cases, but not when introducing for bridge hotplug, which implies the next bridge could be hot-plugged later on. In preparation to support bridge hotplug, consider the absence of a next_bridge an -EPROBE_DEFER, not a hard error. Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/bridge/samsung-dsim.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge= /samsung-dsim.c index cefb20ec68ad..3c70a45c5dce 100644 --- a/drivers/gpu/drm/bridge/samsung-dsim.c +++ b/drivers/gpu/drm/bridge/samsung-dsim.c @@ -1828,6 +1828,9 @@ static int samsung_dsim_attach(struct drm_bridge *bri= dge, { struct samsung_dsim *dsi =3D bridge_to_dsi(bridge); =20 + if (!dsi->bridge.next_bridge) + return -EPROBE_DEFER; + return drm_bridge_attach(encoder, dsi->bridge.next_bridge, bridge, flags); } --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 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 E4DF14B8DED for ; Tue, 19 May 2026 10:39:38 +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=1779187180; cv=none; b=OqQoky+X2fEOO6W1Co1+wvqre/RG3r2aZpKmQt+H/THxyICfBganyBBuMtVWMTCduGmztzeHEyKiwZ+lIrUUGdPeiyT1sc9c9qcQ2UtLCf6zTf7YJ+pYktdELgaf6INjoMEDY2SBbLLTr4wCT5nkOrg87dKfcV/i1uGWtmYpdLU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187180; c=relaxed/simple; bh=ypAF8onyduAdlKexEaakk8l44WdGCnROVdCvJ1bcoxg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=cnlz0kKb5VSG7HoMFmtbpxIv6tuHDH4UY1RFzyhXCbGcX2Tt9UXskQ2WhdWGgwfTThwPQB5/yw8CrjJfo58GuERZ+AWx9OyjMJw1VIP6BR9mIoQrt4hy+pFuyPIomxhqIijPnJwdi2brAAxRh3fitn9QptQoImr6+gg+Id28Hng= 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=fds5ptX+; 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="fds5ptX+" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id C25161A3629; Tue, 19 May 2026 10:39:37 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 95B0B606E9; Tue, 19 May 2026 10:39:37 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 1F29C107E8AEA; Tue, 19 May 2026 12:39:31 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187175; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=Sao0yuOn9cKu8y1mwI62QTwKuextTxc4wrqkEYzJgG8=; b=fds5ptX+ISSKYE732a+mWt2C3yJ0bk/EOQU5Yg8lFWoWyvrrpHoft9W6zIvZp0p1qS/+Pj u2RTS20ixBQv2nQhXkkimN9FDNyYOQhlrO86b9HmB6xDbZESgY6d07ajiaLmcpsnh7UV5u lRSIl1YZyPCRT7fqlZNjB3BtFSWV1edY4ZN0v3JoYJYTd4eNDmJDoWbkBPq8jP9qyek1eu 7z9tc9phH/NEJ4nXXVR8L7kmBHrbKyjKulqYnXnkVUY6VrzavivWqWJtHfqTogVgDfxDdJ aePNkGH1yIdz5mpmp/IOM0FwuzVV9HxIii1pXp6X8L2vw2VvSbbpGTQi8lHqtA== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:38 +0200 Subject: [PATCH 21/37] drm/bridge: initialize chain_node list head on allocation 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: <20260519-drm-bridge-hotplug-v1-21-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 In preparation to add a check to detect whether a bridge is not yet attached, ensure the chain_node list_head is always empty [as in list_empty()] since it is allocated, until it is attached. Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/drm_bridge.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index 687b36eea0c7..657f6609d7b1 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -378,6 +378,7 @@ void *__devm_drm_bridge_alloc(struct device *dev, size_= t size, size_t offset, return ERR_PTR(-ENOMEM); =20 bridge =3D container + offset; + INIT_LIST_HEAD(&bridge->chain_node); INIT_LIST_HEAD(&bridge->list); bridge->container =3D container; bridge->funcs =3D funcs; --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (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 7AD654DBD9E for ; Tue, 19 May 2026 10:39:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187184; cv=none; b=HeyIRpQXlRk5RiNUddTCfzKdTLw7RtdS77yg9KfzWv0v2cCkM4c5ZRvR0kuoRRPd2NacAUmj9EKHAGf0QXOwNEZXrGt4gAXMkudgiz1+n2o7VLwmTfwz5KrArff8p2dPlDy8KBRx5qwzloMzCzXkVsMFX2qMjZBD87n9QIG1IDQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187184; c=relaxed/simple; bh=DncaQk2AHWLGgNYyPDik4yQlrUSO5Fizw1FRffSrDfc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=EDZaxZowXGi3AF+PrIkZlu3kVjlDFEhhEjiNy997lB+hno8UzjiZO9+i87Kjfh3RhUgOc1ielwMe7LkYlNRJqM7NJwb5KDifT2mZ3BShi6zdcePmxo3JOGproBM1yBYwcBQfT/kvgOBrXCdBa5ML4R3Gkroj1CoY1b/61hSsvz4= 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=OybRVAMD; arc=none smtp.client-ip=185.246.85.4 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="OybRVAMD" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 38F554E42CF3; Tue, 19 May 2026 10:39:42 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 0D027606E9; Tue, 19 May 2026 10:39:42 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 5A921107E8AF0; Tue, 19 May 2026 12:39:36 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187180; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=p0IuXkiCS7FheF9fCBR2Egdn9vM94EkW7JUn03rjXhw=; b=OybRVAMD2dO5fEMHg+Ev8VfZfB393AXUj4FLlrljUsRJQHHiiYj7MDk4ipxam8JTFP3FA9 RzFONZ9yfdIjX5nSYrHKQnXZUGVIQn+JV/DhU6LHPyYaHtlLzHyaZfNBYcxztckjpV1nJf TeHsEwUkb+CjPlqEnpnmy6iNdp7cmk1ALITCy007I4oDe+DbuO1a61Dy1Z99RS6bCTO3FG ElClQJttBn+xNYstMVLugFy1HT1e5m8fe1HfWIHJ/Tnn7qgotdFzqHjycPdWfIP3OVJgfR zjPJ+OVWtlL0Ok3zVm4eea64LzTmD9WDrIFgS0ek2oNtEErgdoKz0HiIS4gVqw== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:39 +0200 Subject: [PATCH 22/37] drm/bridge: initialize chain_node list head on detach and attach errors 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: <20260519-drm-bridge-hotplug-v1-22-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 When a bridge is detached it is removed from the encoder bridge_chain list, but the bridge::chain_node list head is not cleared. This is going to be problematic with the upcoming hotplug bridge support because if a bridge is detached from the encoder chain but not yet removed, when later detaching it the encoder code may think it is still attached, thus trying to detach it twice. Avoid this by clearing the list head on detach, so there's a clear and simple way to know when a bridge is not attached anymore. Do the same in the error management code in drm_bridge_attach(), so that chain_node is always empty [as in list_empty()] when it is not (yet|anymore) in the bridge chain. Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/drm_bridge.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index 657f6609d7b1..7f2d1a81d730 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -598,7 +598,7 @@ int drm_bridge_attach(struct drm_encoder *encoder, stru= ct drm_bridge *bridge, bridge->dev =3D NULL; bridge->encoder =3D NULL; mutex_lock(&encoder->bridge_chain_mutex); - list_del(&bridge->chain_node); + list_del_init(&bridge->chain_node); mutex_unlock(&encoder->bridge_chain_mutex); =20 if (ret !=3D -EPROBE_DEFER) @@ -629,7 +629,7 @@ void drm_bridge_detach(struct drm_bridge *bridge) if (bridge->funcs->detach) bridge->funcs->detach(bridge); =20 - list_del(&bridge->chain_node); + list_del_init(&bridge->chain_node); bridge->dev =3D NULL; drm_bridge_put(bridge); } --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (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 C7FDB3F0766 for ; Tue, 19 May 2026 10:39:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187189; cv=none; b=QiXQRzGnDp4sZZE6xoMYUznU18Q9i8V9vvomnQL/xY1bWoE6m967fxFOnhKkrjUJC5fWsymvErhbX3IXgh+4HDHCKkJycVVWWPvz6afV5ul4E8j+yfQ45MsT1RQrdvtioNPQQRCY0HPPblt9sJEBRYuocU3rXm8Gk4zM0D4+RWI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187189; c=relaxed/simple; bh=DUHOb6Tl13Eo/Dd7Uh/eT2VOJ/al25ZF1OrFRuioXfY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=bhE8jNUJKXz0L1Q/4X9SLtvPZ6L9Wo61vjEwbo3EZBe2G9Y0p82Hgec6yM5/21BqDFW28B1ZZ+EQtNIqcccSu4MRL+OLTJYNjMmwZCLFP2Bv3a94V0YS1wBLRIOXmbuIMjqht55cpoNoMOBnnpv52Q8oYuDcNkIRyDg1F5ArMSA= 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=oMYhhapb; arc=none smtp.client-ip=185.246.85.4 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="oMYhhapb" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 6B2484E42CF2; Tue, 19 May 2026 10:39:46 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 3EB72606E9; Tue, 19 May 2026 10:39:46 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 1F69D107E8ABA; Tue, 19 May 2026 12:39:40 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187184; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=eMMNp/n3p6D7/d1i7CLA1wHwPUN8RjNJitJFok8w0VQ=; b=oMYhhapbTf/xv1jqhd3O5ZMDHcFtGbuJ4GPXMfSMaKyskYDXknckT4kB4/y+E68DiLQEEa 9/ot4vTV+jGcRaDYjZZ8Kl2C1WgS1psI+tNLBmOoBrYfdlflkg18HdQ4OflvpN+hVOnG6A zfkukksT45OdKDwX+MnWrqVfjwoSAICaT+2pvooJtpbwABEd+R4VKdeNV2OSuP3efp4Ufp gxGppUIztvzn1CNoy5Gc3XqAaCva2pVUtMHDZzZusJ2ZfBGMp/4EKLz8Ct/q14RsJeGjhW gPP9aJbg8Rmo0F7fxakHkG2f3q8ZIxr8/ZIL7Hd3lXgEa9k8QlEdo7UT6rgIgA== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:40 +0200 Subject: [PATCH 23/37] drm/encoder: add drm_encoder_cleanup_from() 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: <20260519-drm-bridge-hotplug-v1-23-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 Supporting hardware whose final part of the DRM pipeline can be physically removed requires the ability to detach all bridges from a given point to the end of the pipeline. Introduce a variant of drm_encoder_cleanup() for this. Take care to not try detaching non-attached bridges. This is needed because when two or more bridges are removed not in the backwards order, drm_encoder_cleanup_from() is called more than once for bridges closer to the panel. Signed-off-by: Luca Ceresoli --- Note: in theory drm_encoder_cleanup() is now a superset of drm_encoder_cleanup_from() and may be simplified to just call drm_encoder_cleanup_from() and then do the extra actions. However the common code is subtly different in terms of locking and checks, so this would complicate the code in this patch and has thus been kept separate for the time being to make reviewing sompler. Reimplementing drm_encoder_cleanup() by using drm_encoder_cleanup_from() cvacn be done later on. A much simpler and now obsolete version of this patch (missing locking and checks) previously appeared in https://lore.kernel.org/lkml/20250206-hotplug-drm-bridge-v6-13-9d6f2c9c3058= @bootlin.com/ --- drivers/gpu/drm/drm_encoder.c | 38 ++++++++++++++++++++++++++++++++++++++ include/drm/drm_encoder.h | 1 + 2 files changed, 39 insertions(+) diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c index 0d5dbed06db4..40ece477b302 100644 --- a/drivers/gpu/drm/drm_encoder.c +++ b/drivers/gpu/drm/drm_encoder.c @@ -179,6 +179,44 @@ int drm_encoder_init(struct drm_device *dev, } EXPORT_SYMBOL(drm_encoder_init); =20 +/** + * drm_encoder_cleanup_from - remove a given bridge and all the following + * @encoder: encoder whole list of bridges shall be pruned + * @bridge: first bridge to remove + * + * Removes from an encoder all the bridges starting with a given bridge + * and until the end of the chain. + * + * Does nothing if the bridge is not attached to an encoder chain. + * + * This should not be used in "normal" DRM pipelines. It is only useful for + * devices whose final part of the DRM chain can be physically removed and + * later reconnected (possibly with different hardware). + */ +void drm_encoder_cleanup_from(struct drm_encoder *encoder, struct drm_brid= ge *bridge) +{ + struct drm_bridge *next; + LIST_HEAD(tmplist); + + /* + * We need the bridge_chain_mutex to modify the chain, but + * drm_bridge_detach() will call DRM_MODESET_LOCK_ALL_BEGIN() (in + * drm_modeset_lock_fini()), resulting in a possible ABBA circular + * deadlock. Avoid it by first moving all the bridges to a + * temporary list holding the lock, and then calling + * drm_bridge_detach() without the lock. + */ + mutex_lock(&encoder->bridge_chain_mutex); + if (!list_empty(&bridge->chain_node)) + list_for_each_entry_safe_from(bridge, next, &encoder->bridge_chain, chai= n_node) + list_move_tail(&bridge->chain_node, &tmplist); + mutex_unlock(&encoder->bridge_chain_mutex); + + while (!list_empty(&tmplist)) + drm_bridge_detach(list_first_entry(&tmplist, struct drm_bridge, chain_no= de)); +} +EXPORT_SYMBOL(drm_encoder_cleanup_from); + /** * drm_encoder_cleanup - cleans up an initialised encoder * @encoder: encoder to cleanup diff --git a/include/drm/drm_encoder.h b/include/drm/drm_encoder.h index eded7c34481a..d2a59f95692f 100644 --- a/include/drm/drm_encoder.h +++ b/include/drm/drm_encoder.h @@ -324,6 +324,7 @@ static inline struct drm_encoder *drm_encoder_find(stru= ct drm_device *dev, } =20 void drm_encoder_cleanup(struct drm_encoder *encoder); +void drm_encoder_cleanup_from(struct drm_encoder *encoder, struct drm_brid= ge *bridge); =20 /** * drm_for_each_encoder_mask - iterate over encoders specified by bitmask --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 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 27A0B4BC036 for ; Tue, 19 May 2026 10:39:52 +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=1779187193; cv=none; b=Urht9+zbpTKVsIE8fOO7lOY21XdTHVMX7fFk5fJbJkO3YS1gF+TN8RXZ42pLnYCrovV+F4KaXbsaudlHQZ1lMJF1T0fd5SzYfIyDZS6iE6tEtjwV6dmlCjqd80KgaUsJA1znBv9KeaaAt9ghaUdMcAqLa339z/O7NNevlFkIp8w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187193; c=relaxed/simple; bh=JppLoxTk2yQvMvgBV1u+uFFfNf8ouufYsTE5lNvHvvU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=bKDK7APkDI+qm7PvwBqJHeV3xyY6C9HIwLDhWeDVcWx8XI6NQ4gBeL9S+9jTbvP7f8gT8CFMa1omNZkJapeHsnT/Lb+LzrOW+xBGwu+CgWJD6RZH/mwNrVOD9SwDkxLWhxnVfLCuWL3Y4+8EeFfFI/cBy4t4vFT0Zb0kDQIdv2A= 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=X7ylM8ZD; 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="X7ylM8ZD" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id 32545C2B9DB; Tue, 19 May 2026 10:40:44 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 07FFA606E9; Tue, 19 May 2026 10:39:51 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 35DB2107E8AE7; Tue, 19 May 2026 12:39:44 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187189; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=6aQOHdSM3KvIpT5KF1eIyzfFSNvOiiuZnItO9Aa//vI=; b=X7ylM8ZDKA3RRWZIcuK3ejr+oZ7hgl2kFaPk5eT3Vp3IWIkOem9G2KiCWdenRAlrdnZ5ea faH1dnSGiUpm5uE2Py5z0l8cCUw81PwaNg+8tzdiol5NRR7iUWHUsKpnXCpe7Qno9FWB/8 23SK2tLNcNcrWg0wnxZvnbZB66VW0l3/pfMlorN9nLAV7U3p+FxBhmYL5X+p2o7ZosJxA9 cJJQHNEf7u2lPFVfamlG0c77CkV9tPJk6evHdmXKUs+B73AFsoHQgHxdMpc5O+wf1ZxZtz gSwcojU/S6Upt/ipIs/I5RZz6gKs+8FYf0C3DEJt736hIPVqrGQvzYHwiS2JjQ== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:41 +0200 Subject: [PATCH 24/37] drm/atomic: move drm_atomic_helper_disable_all() and drm_atomic_helper_shutdown() from drm_atomic_helper to drm_atomic 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: <20260519-drm-bridge-hotplug-v1-24-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 To support the upcoming DRM bridge hotplug, the drm_bridge.c code will need to call drm_atomic_helper_shutdown() to disable the pipeline when the tail bridges of the pipeline are removed without tearing down the card. However this would create a module dependency loop between the drm module (where drm_encoder is) and the drm_kms_helper module where drm_atomic_helper_shutdown() function currently is and which already depends on the drm module. Solve by moving drm_atomic_helper_shutdown(), along with its callee drm_atomic_helper_disable_all(), to drm_atomic which is in the drm module. Use identical names except for dropping the "_helper" infix, and make the original functions a deprecated wrapper to the new ones. No changes to the functions body. No functional changes except for moving the code to a different module. Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/drm_atomic.c | 115 ++++++++++++++++++++++++++++++++= ++++ drivers/gpu/drm/drm_atomic_helper.c | 76 ++---------------------- include/drm/drm_atomic.h | 3 + 3 files changed, 124 insertions(+), 70 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 9b2009262c97..7d12c062c16d 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1993,6 +1993,121 @@ int __drm_atomic_helper_set_config(struct drm_mode_= set *set, } EXPORT_SYMBOL(__drm_atomic_helper_set_config); =20 +/** + * drm_atomic_disable_all - disable all currently active outputs + * @dev: DRM device + * @ctx: lock acquisition context + * + * Loops through all connectors, finding those that aren't turned off and = then + * turns them off by setting their DPMS mode to OFF and deactivating the C= RTC + * that they are connected to. + * + * This is used for example in suspend/resume to disable all currently act= ive + * functions when suspending. If you just want to shut down everything at = e.g. + * driver unload, look at drm_atomic_helper_shutdown(). + * + * Note that if callers haven't already acquired all modeset locks this mi= ght + * return -EDEADLK, which must be handled by calling drm_modeset_backoff(). + * + * Returns: + * 0 on success or a negative error code on failure. + * + * See also: + * drm_atomic_helper_suspend(), drm_atomic_helper_resume() and + * drm_atomic_helper_shutdown(). + */ +int drm_atomic_disable_all(struct drm_device *dev, + struct drm_modeset_acquire_ctx *ctx) +{ + struct drm_atomic_commit *state; + struct drm_connector_state *conn_state; + struct drm_connector *conn; + struct drm_plane_state *plane_state; + struct drm_plane *plane; + struct drm_crtc_state *crtc_state; + struct drm_crtc *crtc; + int ret, i; + + state =3D drm_atomic_commit_alloc(dev); + if (!state) + return -ENOMEM; + + state->acquire_ctx =3D ctx; + + drm_for_each_crtc(crtc, dev) { + crtc_state =3D drm_atomic_get_crtc_state(state, crtc); + if (IS_ERR(crtc_state)) { + ret =3D PTR_ERR(crtc_state); + goto free; + } + + crtc_state->active =3D false; + + ret =3D drm_atomic_set_mode_prop_for_crtc(crtc_state, NULL); + if (ret < 0) + goto free; + + ret =3D drm_atomic_add_affected_planes(state, crtc); + if (ret < 0) + goto free; + + ret =3D drm_atomic_add_affected_connectors(state, crtc); + if (ret < 0) + goto free; + } + + for_each_new_connector_in_state(state, conn, conn_state, i) { + ret =3D drm_atomic_set_crtc_for_connector(conn_state, NULL); + if (ret < 0) + goto free; + } + + for_each_new_plane_in_state(state, plane, plane_state, i) { + ret =3D drm_atomic_set_crtc_for_plane(plane_state, NULL); + if (ret < 0) + goto free; + + drm_atomic_set_fb_for_plane(plane_state, NULL); + } + + ret =3D drm_atomic_commit(state); +free: + drm_atomic_commit_put(state); + return ret; +} +EXPORT_SYMBOL(drm_atomic_disable_all); + +/** + * drm_atomic_shutdown - shutdown all CRTC + * @dev: DRM device + * + * This shuts down all CRTC, which is useful for driver unloading. Shutdow= n on + * suspend should instead be handled with drm_atomic_helper_suspend(), sin= ce + * that also takes a snapshot of the modeset state to be restored on resum= e. + * + * This is just a convenience wrapper around drm_atomic_helper_disable_all= (), + * and it is the atomic version of drm_helper_force_disable_all(). + */ +void drm_atomic_shutdown(struct drm_device *dev) +{ + struct drm_modeset_acquire_ctx ctx; + int ret; + + if (dev =3D=3D NULL) + return; + + DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret); + + ret =3D drm_atomic_disable_all(dev, &ctx); + if (ret) + drm_err(dev, + "Disabling all crtc's during unload failed with %i\n", + ret); + + DRM_MODESET_LOCK_ALL_END(dev, ctx, ret); +} +EXPORT_SYMBOL(drm_atomic_shutdown); + static void drm_atomic_private_obj_print_state(struct drm_printer *p, const struct drm_private_state *state) { diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atom= ic_helper.c index 51f39edc31ed..afedfab9b568 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -3533,6 +3533,8 @@ EXPORT_SYMBOL(drm_atomic_helper_set_config); * @dev: DRM device * @ctx: lock acquisition context * + * Deprecated wrapper to drm_atomic_disable_all(). + * * Loops through all connectors, finding those that aren't turned off and = then * turns them off by setting their DPMS mode to OFF and deactivating the C= RTC * that they are connected to. @@ -3554,61 +3556,7 @@ EXPORT_SYMBOL(drm_atomic_helper_set_config); int drm_atomic_helper_disable_all(struct drm_device *dev, struct drm_modeset_acquire_ctx *ctx) { - struct drm_atomic_commit *state; - struct drm_connector_state *conn_state; - struct drm_connector *conn; - struct drm_plane_state *plane_state; - struct drm_plane *plane; - struct drm_crtc_state *crtc_state; - struct drm_crtc *crtc; - int ret, i; - - state =3D drm_atomic_commit_alloc(dev); - if (!state) - return -ENOMEM; - - state->acquire_ctx =3D ctx; - - drm_for_each_crtc(crtc, dev) { - crtc_state =3D drm_atomic_get_crtc_state(state, crtc); - if (IS_ERR(crtc_state)) { - ret =3D PTR_ERR(crtc_state); - goto free; - } - - crtc_state->active =3D false; - - ret =3D drm_atomic_set_mode_prop_for_crtc(crtc_state, NULL); - if (ret < 0) - goto free; - - ret =3D drm_atomic_add_affected_planes(state, crtc); - if (ret < 0) - goto free; - - ret =3D drm_atomic_add_affected_connectors(state, crtc); - if (ret < 0) - goto free; - } - - for_each_new_connector_in_state(state, conn, conn_state, i) { - ret =3D drm_atomic_set_crtc_for_connector(conn_state, NULL); - if (ret < 0) - goto free; - } - - for_each_new_plane_in_state(state, plane, plane_state, i) { - ret =3D drm_atomic_set_crtc_for_plane(plane_state, NULL); - if (ret < 0) - goto free; - - drm_atomic_set_fb_for_plane(plane_state, NULL); - } - - ret =3D drm_atomic_commit(state); -free: - drm_atomic_commit_put(state); - return ret; + return drm_atomic_disable_all(dev, ctx); } EXPORT_SYMBOL(drm_atomic_helper_disable_all); =20 @@ -3664,6 +3612,8 @@ EXPORT_SYMBOL(drm_atomic_helper_reset_crtc); * drm_atomic_helper_shutdown - shutdown all CRTC * @dev: DRM device * + * Deprecated wrapper to drm_atomic_shutdown(). + * * This shuts down all CRTC, which is useful for driver unloading. Shutdow= n on * suspend should instead be handled with drm_atomic_helper_suspend(), sin= ce * that also takes a snapshot of the modeset state to be restored on resum= e. @@ -3673,21 +3623,7 @@ EXPORT_SYMBOL(drm_atomic_helper_reset_crtc); */ void drm_atomic_helper_shutdown(struct drm_device *dev) { - struct drm_modeset_acquire_ctx ctx; - int ret; - - if (dev =3D=3D NULL) - return; - - DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret); - - ret =3D drm_atomic_helper_disable_all(dev, &ctx); - if (ret) - drm_err(dev, - "Disabling all crtc's during unload failed with %i\n", - ret); - - DRM_MODESET_LOCK_ALL_END(dev, ctx, ret); + return drm_atomic_shutdown(dev); } EXPORT_SYMBOL(drm_atomic_helper_shutdown); =20 diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index 1a80a8cdf269..9eb3d1bfa084 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -1373,5 +1373,8 @@ drm_atomic_get_old_bridge_state(const struct drm_atom= ic_commit *state, struct drm_bridge_state * drm_atomic_get_new_bridge_state(const struct drm_atomic_commit *state, struct drm_bridge *bridge); +int drm_atomic_disable_all(struct drm_device *dev, + struct drm_modeset_acquire_ctx *ctx); +void drm_atomic_shutdown(struct drm_device *dev); =20 #endif /* DRM_ATOMIC_H_ */ --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 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 07931370AF6 for ; Tue, 19 May 2026 10:39:56 +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=1779187197; cv=none; b=h7U+HeDKGpHgyctfttFe7z1AN+A2lfIep3SUYLawr/cZ8KZFrL2L8poS+l7xIWvljghPbtLbn4RaO1+7MJFZI9DCqiVY4lHiD07Y22v1m3BmNUdanTzw50DoSlVi8zUU3ai680zKXJRNqg/3ArytkeKzTvL5WCf8oc42k2+Y16Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187197; c=relaxed/simple; bh=DxoGKBQdlH13+gr2KRXmbGL++7F0/UIL4nz8bIKV1Ys=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qrk3RdES353vIbaWj8RlSBo7bsK6DuHhXdPjS7FVdlVOQsSLD4AbNKph1sOSC+wwnMQwnc0Tx2+zEfA/gbydQOzEiSdtvCR8qblaBY0ug0v65CtwkcoDRQaGRQK1hPQ8chLdXN6RUV0fjRT/licRqXcL+azCt5yNOnte1k3L/rg= 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=QLmUQNf7; 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="QLmUQNf7" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id 1F6E6C2B9E5; Tue, 19 May 2026 10:40:48 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id E9A7E606E9; Tue, 19 May 2026 10:39:54 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id BD79F107E8AF9; Tue, 19 May 2026 12:39:49 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187193; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=nrcKi47WYQp5yx8o26i5BI9HVOuq7uN7+XfvO362VYk=; b=QLmUQNf7MbkIWl1kuqlHzQfsuyJO71uIlJ1t92LXPPLZqQ0VmSYsUDG1xpnpTVaC8HBP1I mkQgOveyFqhCocgfdvpiHsk8KsXpGv+PcrxOkBBrwcNa5xyo3o5NWvgKGrSr1w6COOWuTk oriZI0xKXoiNN9rPWtlWkeYDCdtvwBd4dXK9vzO/vyYTwvuVr1ZN2zoA7d6SXFphbQVJFu Rwi5paf4tLAWI3RGp5ug1t++EZnlANi6YB+Wrvo24k4+T1SsErx2hx3JXkafeUT36dbkVG p8tjoLD3I67aS/5PK3wpXFUTegM3Aw7TB81/apSDm5ub/1+O/8lXr1EGDLqTRQ== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:42 +0200 Subject: [PATCH 25/37] drm/bridge: shutdown and cleanup on bridge unplug 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: <20260519-drm-bridge-hotplug-v1-25-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 With the upcoming support for DRM bridge hot(un)plugging, bridges can be removed at any time withotu tearing down the entire card. When this happens, shutdown the pipeline and detach from the encoder chain the bridge being removed along with all the following ones. Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/drm_bridge.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index 7f2d1a81d730..d45fb74ec8c2 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -462,9 +462,17 @@ EXPORT_SYMBOL(devm_drm_bridge_add); * it won't be found by users via of_drm_find_and_get_bridge(), and add it * to the lingering bridge list, to keep track of it until its allocated * memory is eventually freed. + * + * If the bridge is attached, also disable the active output and detach + * this bridge and the following ones. */ void drm_bridge_remove(struct drm_bridge *bridge) { + if (bridge->encoder) { + drm_atomic_shutdown(bridge->dev); + drm_encoder_cleanup_from(bridge->encoder, bridge); + } + mutex_lock(&bridge_lock); list_move_tail(&bridge->list, &bridge_lingering_list); mutex_unlock(&bridge_lock); --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 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 3DC05370AF6 for ; Tue, 19 May 2026 10:40:00 +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=1779187201; cv=none; b=RhfH8TAjlEZ8g2FP4Lw6Rsmq2P5qmmir2V9X2yrc4Dd1ugsKfdEiIfWdBFizdEZl/Zi9I8VasKXq6aX+4cCmujU+jywTIvnTIJ9L4WCzCzT2LAGeZ+Y+LOQ4T56rYLHs9lj0yb/HHJAtkC5Dvn/rouJzgbjs8ili/FtUfYpTcls= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187201; c=relaxed/simple; bh=EnwksouKb2n79HLISM0zHO0np6rY0xd5P8LG9KpTtZU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DSsNAxcw9by7ZrobQsREDAU1J5Tv9ZHToHxf1iBPWQkvqfleNJB4s1HFi69OKgaCEpLp2kQPCgqY94wIQy2PDfNc0Pl7nKMqhBr/vDsrxzGleIlPxR6PeDe3NIeE4jH0BPgHhuuF0iK+SlFkiNXdSRTJWbHFwD13hgXkTYTj/Qk= 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=fSmkf1oi; 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="fSmkf1oi" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 1BD601A3628; Tue, 19 May 2026 10:39:59 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id E3D7D606E9; Tue, 19 May 2026 10:39:58 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id E3D79107E8AF6; Tue, 19 May 2026 12:39:53 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187197; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=McH6p8MthUvLmKOOPwvHkRFvWdztoV3IgrOCuYLQkWE=; b=fSmkf1oiSZdbQU3PVujEtU4uMo3qJ2HIxlul9PlIS/+Y7uJaublMm25d50dr44nUMj9WSG lhMzBf2aM+XomUtkNCyo4oJrNOB1MRX97xYv2gtuPbpDVXkGHf8k0bFd/OmSa3dc6NSQ9v v9JKrs9lIoI6vaZZCWa4kKtakvZTM9AKp7s+1GnOeCl3sLlIBGwxAWPK90ZgTQPJPbQOmo iXgi35cF5j4AFsv6BtHMkVL0VeYmFjBquiNL5GeA+v6Oc3yFIPGYubGiuxRS/V4VgMS3Y8 yckuob23VPFmmBU12Pw+peqW+fxNXVd3Ps2/EzKRJt0VLAU6kdEZ1X6M63hNtg== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:43 +0200 Subject: [PATCH 26/37] drm: event-notifier: add mechanism to notify about hotplug events 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: <20260519-drm-bridge-hotplug-v1-26-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 In preparation for supporting DRM bridge hotplug, add an event notifier to allow interested parties to be notified about events they need to react to. For the initial implementation of bridge hotplug, two events are needed: bridge detach (happening in drm_bridge.c) and MIPI device attach to MIPI host (happening in drm_mipi_dsi.c). For this reason implement the event notifier in a new common file that event producers can easily use to send events. Signed-off-by: Luca Ceresoli --- A different approach I have considered is keeping the event notifier in drm_bridge.c (as in [0]) instead of a new centralized file. But then another notifier would be needed in drm_mipi_dsi.c for the DSI attach event. That would be particularly awkward because the designated component to implement hotplug is the drm_bridge_connector, which would then need to depend on DRM_MIPI_DSI even though it does nothing MIPI specific. [0] https://lore.kernel.org/lkml/20250206-hotplug-drm-bridge-v6-12-9d6f2c9c= 3058@bootlin.com/ --- drivers/gpu/drm/Kconfig | 3 ++ drivers/gpu/drm/Makefile | 2 ++ drivers/gpu/drm/drm_event_notifier.c | 58 ++++++++++++++++++++++++++++++++= ++++ include/drm/drm_event_notifier.h | 36 ++++++++++++++++++++++ 4 files changed, 99 insertions(+) diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 8f5a8d3012e4..18eb33e0e5a0 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -33,6 +33,9 @@ endmenu =20 if DRM =20 +config DRM_EVENT_NOTIFIER + tristate + config DRM_MIPI_DBI tristate depends on DRM diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index e97faabcd783..18c9cceacdaa 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -96,6 +96,8 @@ drm-$(CONFIG_DRM_PANIC_SCREEN_QR_CODE) +=3D drm_panic_qr.o drm-$(CONFIG_DRM_RAS) +=3D drm_ras.o drm_ras_nl.o drm_ras_genl_family.o obj-$(CONFIG_DRM) +=3D drm.o =20 +obj-$(CONFIG_DRM_EVENT_NOTIFIER) +=3D drm_event_notifier.o + obj-$(CONFIG_DRM_PANEL_ORIENTATION_QUIRKS) +=3D drm_panel_orientation_quir= ks.o obj-$(CONFIG_DRM_PANEL_BACKLIGHT_QUIRKS) +=3D drm_panel_backlight_quirks.o =20 diff --git a/drivers/gpu/drm/drm_event_notifier.c b/drivers/gpu/drm/drm_eve= nt_notifier.c new file mode 100644 index 000000000000..76af4dd4cdb0 --- /dev/null +++ b/drivers/gpu/drm/drm_event_notifier.c @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Internal event notifier for DRM drivers + * + * Copyright (C) 2026 GE HealthCare + * Author: Luca Ceresoli + */ + +#include +#include + +#include + +static BLOCKING_NOTIFIER_HEAD(drm_event_notifier); + +/** + * drm_event_notifier_register - Register to be notified of DRM events + * @nb: the notifier block to be registered + * + * @nb will be notified of events defined in &drm_event_notifier_event + * + * Returns 0 on success, %-EEXIST on error. + */ +int drm_event_notifier_register(struct notifier_block *nb) +{ + return blocking_notifier_chain_register(&drm_event_notifier, nb); +} +EXPORT_SYMBOL(drm_event_notifier_register); + +/** + * drm_event_notifier_unregister - Unregister from be notified of DRM even= ts + * @nb: the notifier block to be unregistered + * + * @nb will stop being notified of events defined in &drm_event_notifier_e= vent + * + * Returns zero on success or %-ENOENT on failure. + */ +int drm_event_notifier_unregister(struct notifier_block *nb) +{ + return blocking_notifier_chain_unregister(&drm_event_notifier, nb); +} +EXPORT_SYMBOL(drm_event_notifier_unregister); + +/** + * drm_event_notifier_notify - Emit an event to be notified to registered + * entities + * @event: event ID as defined in &drm_event_notifier_event + * @data: metadata associated to the event + */ +void drm_event_notifier_notify(unsigned long event, void *data) +{ + blocking_notifier_call_chain(&drm_event_notifier, event, data); +} +EXPORT_SYMBOL(drm_event_notifier_notify); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Luca Ceresoli "); +MODULE_DESCRIPTION("Notifier for DRM components addition/removal and attac= h/detach"); diff --git a/include/drm/drm_event_notifier.h b/include/drm/drm_event_notif= ier.h new file mode 100644 index 000000000000..78afc014ec9a --- /dev/null +++ b/include/drm/drm_event_notifier.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Internal event notifier for DRM drivers + * + * Copyright (C) 2026 GE HealthCare + * Author: Luca Ceresoli + */ + +#ifndef _DRM_EVENT_NOTIFIER_H_ +#define _DRM_EVENT_NOTIFIER_H_ + +/** + * enum drm_event_notifier_event - DRM bridge events + */ +enum drm_event_notifier_event { + /** + * @DRM_MIPI_DSI_ATTACHED: A MIPI DSI device has just been attached + * to its MIPI DSI host. @data is a pointer to the &struct + * mipi_dsi_device that has just attached. + */ + DRM_MIPI_DSI_ATTACHED, + /** + * @DRM_BRIDGE_NOTIFY_DETACHED: A bridge has just been detached + * from the encoder bridge chain. Emitted at the end of + * drm_bridge_detach(), after removing the bridge from the encoder + * chain. @data is a pointer to the &struct drm_bridge that has + * just been detached. + */ + DRM_BRIDGE_DETACHED, +}; + +int drm_event_notifier_register(struct notifier_block *nb); +int drm_event_notifier_unregister(struct notifier_block *nb); +void drm_event_notifier_notify(unsigned long event, void *data); + +#endif /* _DRM_EVENT_NOTIFIER_H_ */ --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 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 82B9C4EA363 for ; Tue, 19 May 2026 10:40:05 +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=1779187206; cv=none; b=VVD30hT7o9zAl/FVtfDilnqPqR+xP8Ot1wf5NVbTkWeK7WfLZvm2BNR+FzzVyq0JZ3ZV25xTWSLmjYtF3gPiaxp65KKCMzbwY1cQGJVDQ3hRsUCY05o7WYhR8dSLiA90L87N4j3NteZqfK9BD9QAMT4yeDMEJ2+O4jrya9EuT0g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187206; c=relaxed/simple; bh=PoYOaRghUOfWGLxaEbr2QA7/OZlcBeliMCvSSCN8B0I=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=I8OVcKVF/Gzxn/VzOYmDGQH9HoTlWVtjC0tozHwwRWf5oSg7wS7tq4KJYmg8QnrkpmdZcvTP6NxUlx8nVgXFKX4YFwdoIYrs5C/5H4JDlB2lRdRnVgET4sxvA1vVbK4OS29Vc0AGIZjFY1R3u7s6FmhEsI+gtnyzbmb5sFRRT0E= 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=gOj+U7Xa; 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="gOj+U7Xa" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 28EA21A3629; Tue, 19 May 2026 10:40:04 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id EBB4D606E9; Tue, 19 May 2026 10:40:03 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id E7FCA107E8AFA; Tue, 19 May 2026 12:39:57 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187201; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=eN6pL5kosuLFHDQOEEYHtqbm7sPqAq+GeT70rFRs0LQ=; b=gOj+U7XaOXqqhRiCtqoWTExaKf57PI5lsbopBhQnoItip50VmAyxc5ehIE2oflvHG9ssjM SY2QhjswtmJaiFlXE2fcoiAAFVRNt/bNNH9qvjYCh44CZ5RZLyZUKi9NB00u1U1O4nIpmD 3fstKXeQ+gjFJKnvVqHhY/oaMSlQLlZ2oBMbR4i7XqsAmmzQhUBr+pPcDGm51TZd7JkdjC CpDEeniTkrfzAnRnE1usFaMKGot0iD0zkjzV/t3LPdDRpBXqktYjQfa7VpDWAwu2tuUfDl K0WM4fjVBfEuLNN+5YCy564YQaejBvOokM+sigsyWrvjry5asQGLnJMiJazsuQ== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:44 +0200 Subject: [PATCH 27/37] drm/bridge: notify about detached 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: <20260519-drm-bridge-hotplug-v1-27-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 In preparation to support DRM bridge hotplug, let the drm_bridge code emit an event when a bridge is detached, so that this event can trigger the actions needed to deconfigure the pipeline and unregister the connector as appropriate. Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/Kconfig | 1 + drivers/gpu/drm/drm_bridge.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 18eb33e0e5a0..081660f3a0f2 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -17,6 +17,7 @@ menuconfig DRM # device and dmabuf fd. Let's make sure that is available for our userspac= e. select KCMP select VIDEO + select DRM_EVENT_NOTIFIER help Kernel-level support for the Direct Rendering Infrastructure (DRI) introduced in XFree86 4.0. If you say Y here, you need to select diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index d45fb74ec8c2..c62d17e84d4f 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -638,6 +639,9 @@ void drm_bridge_detach(struct drm_bridge *bridge) bridge->funcs->detach(bridge); =20 list_del_init(&bridge->chain_node); + + drm_event_notifier_notify(DRM_BRIDGE_DETACHED, bridge); + bridge->dev =3D NULL; drm_bridge_put(bridge); } --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (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 6F92F4C041F for ; Tue, 19 May 2026 10:40:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187211; cv=none; b=jmTyja1eGaaaPIKrlbBOKsAbxrlSj5zv4+az3w/8NEb21YM1hldBD60uSgdGOIWscI0z+qNU8rX9MqEGne03ex/g/gxzvRe0HWhekPY2x6tTAu8RfqSMOqEvL9QV/meCwfQLWnG8MbUXg5P97dqn5XlDMCxVj1oNk+D57YSBq+s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187211; c=relaxed/simple; bh=oWK/d/sfIYesmhsqKwdovnoj56fP2QT12deUkChfvd0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=kQ8tbafY5/YPV0T3PA5f3NEGqdmwJ2OeIGyRLkW6fs0O38ejOUknSaTiQTsbp0N2SWEyU5o7q7Gur8FU/LyE0FPN5TkAM8Ww5cMbKqGjvDiX1nohGfYd6QEOpuo64GRnQIUKzt7OE3SU8eBH6EYeAZSMb3wOcMo0jmVk+T5QqCg= 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=UOqU8kAK; arc=none smtp.client-ip=185.246.85.4 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="UOqU8kAK" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 190624E42CF2; Tue, 19 May 2026 10:40:09 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id E0E04606E9; Tue, 19 May 2026 10:40:08 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 743AB107E8AF0; Tue, 19 May 2026 12:40:02 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187206; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=OkkSgAlsYDBwnM9XbAsNnjeyIYKliFTEgCHfK5ghURg=; b=UOqU8kAK9WxaW6HsbFf7Iu6VMHr0gE6JJl8KL5x+H925gM5Qkoe2N35zaGxbWXcMmHpLNm oTzpgVU0Zli9HL3Vb9i8GGhHrnWBQ8UG0MW+4jcN96Cha8vogUrF7oEEL9jyMJMhGdIaYC zvpnpakc05AMeWd8EWVISs1q/7k96ytRPHfgeAldfdBXVUgD7nhpNuwhYDd/JhzJnAzHEP NQtcYPGW9hAcgTn2MioQuJo9k3fbz4Y0T/qjl2wfjmWVAmLRF1BmJ7hMK8vFWBhTfJPTb3 v4c64Op4MOy6+EKWEwt+5XpJ6DiOEyOWtAA1UPrlXPLABB9wGkbb2ZepDYWl1w== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:45 +0200 Subject: [PATCH 28/37] drm/mipi-dsi: turn DRM_MIPI_DSI into a tristate 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: <20260519-drm-bridge-hotplug-v1-28-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 DRM_MIPI_DSI is currently a bool, but there's no reason to not be allowed to build it as a loadable module. Moreover being a bool prevents DRM_MIPI_DSI to depend on a tristate module that is configured as 'm'. Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 081660f3a0f2..3093d5f30724 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -43,7 +43,7 @@ config DRM_MIPI_DBI select DRM_KMS_HELPER =20 config DRM_MIPI_DSI - bool + tristate depends on DRM =20 config DRM_KMS_HELPER --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 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 672784F7965 for ; Tue, 19 May 2026 10:40:14 +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=1779187215; cv=none; b=n9uELpfUQWroLkM7QZikad/Ola96CJ6g9vswDdv3DT+7G8xyigW7nkCtAXS7a0ju4NEO0L9WZXtX7iwsq0rS4B9FcOg8j3Jya9rziiv7bSj+jz9EclqWQAtc0eLHWsgfiloK+iC8S7toPGrSjml61e81C6VVu+aRbJQ3sLDMwwg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187215; c=relaxed/simple; bh=JUNAhhYd/MvLZ4MbTJMMM1aLkexb53DFHEsltMugqo8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=YJjpbjMeIxXWV29t9uieIEH3sn4ijtNB7VQYykv64QTHV2TRiYU+K+kgb2YsSxWwsXddX+V4znzsAa0uIggq9M5ruK7x0LkZ5MyFQar7xe9AXYqU4PoxO6IaG6SQJ1CbU3GaGaA2N5WuBUbTpzCktbCe+ZhxTzrzGWL20FB+KYs= 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=xIWpGSJc; 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="xIWpGSJc" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 1501E1A3629; Tue, 19 May 2026 10:40:13 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id D3401606E9; Tue, 19 May 2026 10:40:12 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 4AA2D107E8AE7; Tue, 19 May 2026 12:40:07 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187211; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=XPnXnL28rnew1q1eDqo7jc72bZYvB4PM1bXhy+LViR8=; b=xIWpGSJc3I8LET6EbkDG+Nla5ohZq8g8XGvlTlC07NzLdPwZGXhp1zST0RdzD0veUGtI4S swuJhpmqt27iNxEG9ucGtb3qbiUh+/+Q75tNRTdED/VgMgv16qHq8Wq2H703LS1W1euRFB jAx6EIvItpAPEFP+ZfGO2wvKcc6oahowivGxMUSWP1R6Zf96JcUO9fkUvnP54/vuiqCDDw xZkOCZx3yJrXJLK2zytWtiuN1keBO9My/He1vAIFhcMzEmIEo70kF7vtIQ/LRUM+Y6F1ZU Dha7WXg6MAOJozjGtVdjwVnUBqnJczTXe7jLji9m/SCxFpQivb2XeEVhle7kxQ== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:46 +0200 Subject: [PATCH 29/37] drm/mipi-dsi: notify about DSI attach 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: <20260519-drm-bridge-hotplug-v1-29-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 In preparation to support DRM bridge hotplug, let the drm_mipi_dsi code emit an event when a DSI device is attached to the corresponding DSI host, so that this event can trigger the actions needed to deconfigure the pipeline and unregister the connector as appropriate. Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/Kconfig | 1 + drivers/gpu/drm/drm_mipi_dsi.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 3093d5f30724..288845b6621b 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -45,6 +45,7 @@ config DRM_MIPI_DBI config DRM_MIPI_DSI tristate depends on DRM + select DRM_EVENT_NOTIFIER =20 config DRM_KMS_HELPER tristate diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index 3ac1dd5ad640..eaa474da4a51 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -34,6 +34,7 @@ #include =20 #include +#include #include #include =20 @@ -386,6 +387,8 @@ int mipi_dsi_attach(struct mipi_dsi_device *dsi) =20 dsi->attached =3D true; =20 + drm_event_notifier_notify(DRM_MIPI_DSI_ATTACHED, dsi); + return 0; } EXPORT_SYMBOL(mipi_dsi_attach); --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 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 841593A7F45 for ; Tue, 19 May 2026 10:40:18 +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=1779187220; cv=none; b=lUrQt1IwmEa7VyxxCU6JcHrm+WaeoVjOJN7ywRiZTefVIv1mxzBd9o12HB4rvUcBwLiQydrYnyjqQwUuRm8tySi3JyHg6jCjcoxhUvzHyCE42kwlTWsZLr2MbP1udW7S9un3Kz5BcxCqeMf+kS5P7k8tOD1VUqmpQkOPJIpINCQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187220; c=relaxed/simple; bh=Su/lbM8iIR/A6QqzlRnb4rm+4RtWUoxCR0Q3xfXBIfo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=gGFT+ba6z3Ng4ncIFL2TQcmbeHugLANJlNaQnL1xpd8s4MyjwjNbqlEwP9yFa1tSWbsHsm3XYCiILu94ZIFjztEvT+EKlQYC5vysym3P1xJUmQcsCmtMgpRAjvu0wDzW2+AYF6VDEmW9WqTy3ntTSz8QXj40k5dGE8+OP82lD9E= 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=JyGilfpW; 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="JyGilfpW" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 3391E1A3628; Tue, 19 May 2026 10:40:17 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 0734F606E9; Tue, 19 May 2026 10:40:17 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 259D8107E8AF0; Tue, 19 May 2026 12:40:11 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187215; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=QjEyGA9Kg8mSbftaYSZM9v+ClyMwRZd6xLu2RTl/IwY=; b=JyGilfpW6FF1WDd5YDkDrD/vjp5+5QLCqzdWjH565wNY7ZdIU4yqAWiMG3RVEiHoG6NIDH pnG04pxYIb7esTWPif0QLgtjb63//f7fyHW8SYSTPFHH8Es8ZL39TGeZMIcu76hamGFwtz YMcTus4OewSgxrY3/OeIr48MuO/M7t5MUXlvyOFjNsyPi4fMKNC7k8vrkdGB8kEVn8LZOT ZitG3yNOnFvL50kshS60cHBnvkRXlMbRa4TWGEo5UwoH6efMX1//UHDeAGfj6fpoR3wuH4 Xm7+S8pPdmQT5H5HQrUMymtpNFrU27vN2ktjMFgWxcJB6qQhMJS7Ys3w2Y3Hdw== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:47 +0200 Subject: [PATCH 30/37] drm/bridge: add drm_bridge_is_tail() to know whether a bridge completes the pipeline 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: <20260519-drm-bridge-hotplug-v1-30-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 For bridge hotplug we need to successfully probe a card with an incomplete bridge chain, i.e. a chain whose last bridge currently in bridge_chain needs a next_bridge to work. Such a card would have no connector, and be able to add one as soon as the followong bridges are added up to the tail bridge (e.g. a panel_bridge or a connector_bridge). Currently common DRM code is unable to tell whether the last bridge currently in the chain is the tail bridge (=3D the pipeline is complete) or not. Add drm_bridge_is_tail(), and a .is_tail func for it to rely on, so common code can know whether a bridge is a tail bridge or needs a next_bridge. Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/drm_bridge.c | 28 ++++++++++++++++++++++++++++ include/drm/drm_bridge.h | 19 +++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index c62d17e84d4f..2b539c9749a6 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -646,6 +646,34 @@ void drm_bridge_detach(struct drm_bridge *bridge) drm_bridge_put(bridge); } =20 +/** + * drm_bridge_is_tail - check whether the bridge is the last required to + * have a full pipeline + * @bridge: the bridge to check + * + * Tell whether this is a tail bridge, i.e. a bridge that does not need a + * next bridge to work. E.g. a panel_bridge is final, a DSI-to-LVDS bridge + * is not. + * + * In case of hotplug the last bridge currently in the chain (as in + * drm_bridge_chain_get_last_bridge()) might not be final, and be waiting + * for a pipeline tail to be connected. + * + * Return: true if this bridge does not need a next bridge to work, false + * otherwise + */ +bool drm_bridge_is_tail(struct drm_bridge *bridge) +{ + if (!(bridge->ops & DRM_BRIDGE_OP_IS_TAIL)) { + drm_warn_once(bridge->dev, "is_tail func not implemented by bridge %ps!", + bridge->funcs); + return false; + } + + return bridge->funcs->is_tail(bridge); +} +EXPORT_SYMBOL(drm_bridge_is_tail); + /** * DOC: bridge operations * diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index 4ba3a5deef9a..d783a6fb93a0 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -78,6 +78,19 @@ struct drm_bridge_funcs { int (*attach)(struct drm_bridge *bridge, struct drm_encoder *encoder, enum drm_bridge_attach_flags flags); =20 + /** + * @is_tail: + * + * Returns true if this is a tail bridge, i.e. it does not need a + * next bridge to work. E.g. a panel_bridge is a tail bridge, a + * DSI-to-LVDS bridge is not a tail bridge (no matter whether the + * next bridge is present or not). + * + * The @is_tail callback is optional but it is required if the + * bridge is part of a pipeline with hot-pluggable components. + */ + bool (*is_tail)(struct drm_bridge *bridge); + /** * @destroy: * @@ -1092,6 +1105,11 @@ enum drm_bridge_ops { * &drm_bridge_funcs->hdmi_clear_spd_infoframe callbacks. */ DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME =3D BIT(10), + /** + * @DRM_BRIDGE_OP_IS_TAIL: The bridge implements the + * &drm_bridge_funcs->is_tail callback. + */ + DRM_BRIDGE_OP_IS_TAIL =3D BIT(11), }; =20 /** @@ -1323,6 +1341,7 @@ void drm_bridge_remove(struct drm_bridge *bridge); int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *brid= ge, struct drm_bridge *previous, enum drm_bridge_attach_flags flags); +bool drm_bridge_is_tail(struct drm_bridge *bridge); =20 #ifdef CONFIG_OF struct drm_bridge *of_drm_find_and_get_bridge(struct device_node *np); --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 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 BDF5A32B122 for ; Tue, 19 May 2026 10:40:22 +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=1779187224; cv=none; b=ALlEy9Fy0ZbJ3G+8pi3s7a+B/hSasq86POtWWvgM1WOtWcfW/kE2ri6STrc6gCGaVVP8MLP52SIPvKbwPVTEhqqwbXlxRrxbx9cfyBoH1hccnlcznNZcBNG7lE4Ns3CwB8u5u6rZUB25HG3CTHwDLmQH8EX4SVWnZqYE+GnJv9k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187224; c=relaxed/simple; bh=ONLQc83h4Q903nt7lxQvcjnrVgTdM1Exq6bpKKvAAXs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=VwurqBUsNj9HAN9726meG9nVKJoMGEfK6e24EtJlLc13LrxTEDKQBHdubeSs0z3/6mTB7rK4Xzg00JoHatCD9wlhr8yioBg3poYvDg9tdDRRnGkERMZRHHIH3jGKnIHCLpZuikYWs2irCWEvJXtQ2LQkAs3FyIRvRMEtz19aK2Q= 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=WBwRoQB2; 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="WBwRoQB2" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id B5536C2B9DB; Tue, 19 May 2026 10:41:14 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 89DB0606E9; Tue, 19 May 2026 10:40:21 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 00428107E8AE7; Tue, 19 May 2026 12:40:15 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187219; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=+x/+hMZvd/mY+TDvxza1mQa1Krz1zW9d6N4aDdm3aVo=; b=WBwRoQB2t0CAFsznoKOix9Z+FB3ieKpmwoYJe2twTcy+zrteCXP0AgYjTvwyQ+qDJGu2wT L+fP1EFHkAMtjbPmdXt46zuZ4zim0qERMoM26egm1+ZR1WickXPEDb7WpmX5Y0osWAGXEA aciEyB09WzQnr72p76ZOvtoLlwBrEm+havQfRZotfkG8ZsG4e3W65g78XPYvujZfM1Crmh ATBR9qXlaUAQzz/RVbLkX1fslGsbSyFntJRvKnyVmMMoK3aXEaAds3eP/f1aNFxrVTY/P5 I2yAzeW0APKtbE77qMXAugpfEEhtpa+DzGyyNjtLeqzheYIc+a3SyDHHfzkC1w== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:48 +0200 Subject: [PATCH 31/37] drm/bridge: panel: implement .is_tail 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: <20260519-drm-bridge-hotplug-v1-31-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 This bridge is always a tail bridge, i.e. it never needs a following bridge to complete the pipeline. Add a is_tail func to expose this. Signed-off-by: Luca Ceresoli Reviewed-by: Neil Armstrong --- drivers/gpu/drm/bridge/panel.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c index 4978ec98a082..102f987b1235 100644 --- a/drivers/gpu/drm/bridge/panel.c +++ b/drivers/gpu/drm/bridge/panel.c @@ -58,6 +58,11 @@ static const struct drm_connector_funcs panel_bridge_con= nector_funcs =3D { .atomic_destroy_state =3D drm_atomic_helper_connector_destroy_state, }; =20 +static bool panel_bridge_is_tail(struct drm_bridge *bridge) +{ + return true; +} + static int panel_bridge_attach(struct drm_bridge *bridge, struct drm_encoder *encoder, enum drm_bridge_attach_flags flags) @@ -206,6 +211,7 @@ static void panel_bridge_debugfs_init(struct drm_bridge= *bridge, } =20 static const struct drm_bridge_funcs panel_bridge_bridge_funcs =3D { + .is_tail =3D panel_bridge_is_tail, .attach =3D panel_bridge_attach, .detach =3D panel_bridge_detach, .atomic_pre_enable =3D panel_bridge_atomic_pre_enable, @@ -297,7 +303,7 @@ struct drm_bridge *drm_panel_bridge_add_typed(struct dr= m_panel *panel, panel_bridge->panel =3D panel; =20 panel_bridge->bridge.of_node =3D panel->dev->of_node; - panel_bridge->bridge.ops =3D DRM_BRIDGE_OP_MODES; + panel_bridge->bridge.ops =3D DRM_BRIDGE_OP_MODES | DRM_BRIDGE_OP_IS_TAIL; panel_bridge->bridge.type =3D connector_type; panel_bridge->bridge.pre_enable_prev_first =3D panel->prepare_prev_first; =20 --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 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 B1DD432B13F for ; Tue, 19 May 2026 10:40:27 +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=1779187229; cv=none; b=k2UGTuplzOL3wJSDfv8HNrxnKLILAumgf3A9hNjctnMWpBDx36YcZ8p1WsFBs60dKFjddyRSbCOrM9KMccJpEKHADh6drnrGPzqI8WoMP1YSdIBI2cUugJowT42GPA0/nA/65cfIoWJTz9NxWXLk2U6GACsd6eT+EJcB1IzChdw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187229; c=relaxed/simple; bh=lkjVZg9vpS4ljCAhd540O9Rhi31RLmW0pLx/SUaTQfM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=eA4+/a6C7+NchDjZDjJWt7fwid0HJYIvfHSO1oC4T2Fxh1W7GnFWG7izd9wNiZhQPL2rVOECMmKyQdkq9jCC8dF83iopALx294xeYyYVHngwswVu5JBA94ochdnQ/s0T76QRfkN4Zc1h4vOlgp0pZogm6Uz9PowEU6e2rKxuCZ4= 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=T2N7PCEV; 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="T2N7PCEV" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id A7445C2B9E5; Tue, 19 May 2026 10:41:19 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 7D843606E9; Tue, 19 May 2026 10:40:26 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 48445107E8B03; Tue, 19 May 2026 12:40:19 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187224; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=oaDZzNhhlsYfML//xOFG6wXWu65nBogs+zUTIz1RF5A=; b=T2N7PCEVTYuTIU/5aFtL7cpuaWtxZfffb3xfVtA1+0l/280seqzJHH8z3a/bdTY6qX2Phx oKG+/QhlBnQZfNJ5rX3rGKFbSn7vXUx8uBPdiqPsUIzfFuR65GWIaKc3hmcSTOnTBVeIRz xG9jrGkyD223AxSEW2TUMqu6WQ0Geb/xr4X6CLxuEg30pGGb8heXHi704vaN+dRhDREnGy x0KKbq7d/YONoI+Qan9EJ+f6kSQLIqfh55AxPUD7mqrRY8eCBQ0RkCLOZL2VoSJdRsQfXB xSFH5qg0P3s3x9Js61QcoCHSCkAataRa3DRieMQtzs1d/4s1hARFu47Y9jrYXA== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:49 +0200 Subject: [PATCH 32/37] drm/bridge: display-connector: implement .is_tail 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: <20260519-drm-bridge-hotplug-v1-32-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 This bridge is always a tail bridge, i.e. it never needs a following bridge to complete the pipeline. Add a is_tail func to expose this. Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/bridge/display-connector.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/bridge/display-connector.c b/drivers/gpu/drm/b= ridge/display-connector.c index 16c0631adeb1..1c8111bdc89e 100644 --- a/drivers/gpu/drm/bridge/display-connector.c +++ b/drivers/gpu/drm/bridge/display-connector.c @@ -33,6 +33,11 @@ to_display_connector(struct drm_bridge *bridge) return container_of(bridge, struct display_connector, bridge); } =20 +static bool display_connector_is_tail(struct drm_bridge *bridge) +{ + return true; +} + static int display_connector_attach(struct drm_bridge *bridge, struct drm_encoder *encoder, enum drm_bridge_attach_flags flags) @@ -176,6 +181,7 @@ static u32 *display_connector_get_input_bus_fmts(struct= drm_bridge *bridge, } =20 static const struct drm_bridge_funcs display_connector_bridge_funcs =3D { + .is_tail =3D display_connector_is_tail, .attach =3D display_connector_attach, .detect =3D display_connector_bridge_detect, .edid_read =3D display_connector_edid_read, @@ -370,6 +376,7 @@ static int display_connector_probe(struct platform_devi= ce *pdev) =20 conn->bridge.of_node =3D pdev->dev.of_node; =20 + conn->bridge.ops =3D DRM_BRIDGE_OP_IS_TAIL; if (conn->bridge.ddc) conn->bridge.ops |=3D DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_DETECT; --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 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 E66B73F1AC3 for ; Tue, 19 May 2026 10:40:31 +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=1779187233; cv=none; b=rgEhyNDLtX7krW/cHltsh9fUn31hHKQVH1sQO9nkoZyEXuD4RAtq1AxQTlOLHneC3YG06Pkw6R758Zwv2DJcHoODnYFw130MogIgnqsgM101qwvsZJeZMtIultfr70zVB7y3N2Me+rXwfZ2MDfwmTFF7H2oP4E23akNrPKfRBLo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187233; c=relaxed/simple; bh=5j43y7DFu3qB/mMWIPqHQC6IjsUzLol2f2RUaMpvjQE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=M81CaUKW+j53y2nJIeQK4Nd9HqTLjOXj2OZ45aha+CaIJMv1dPPgpjmwnIa8j1ajTyHVPuCWSnHE4if4b5+xXvvirH64OcOvkUYePk/y27DonKzQXD3TqFxeGs9dLcimceZfzsb5Lymcku49Fuqr/8/m0eG3Cm3A87hJDBUUz+4= 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=MWJTDn5r; 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="MWJTDn5r" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id EC8E1C2B9DB; Tue, 19 May 2026 10:41:23 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id C19AB606E9; Tue, 19 May 2026 10:40:30 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 5BEFB107E8AF0; Tue, 19 May 2026 12:40:25 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187229; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=31ncBWdHqHsdjEKSp4vtUwOjKggaE/FUwi7+sB64GTA=; b=MWJTDn5rArD4HU8/88qXnibhNRKlApYd92dhmLobr0VRJBSg9i4Nmt6jrwGXpugMvv5OmY TpUfO/dBOabgxWRFrU/10zDCAXFxbLEZqFMDOe9SMZ+IWfixPQSIzlnfZPdcq/IlO/VGIr dFET0eus81/DZyOLH05lag+6WmQfcgQnsk9qalj79k6mddr5R/6pKyUA6GZXb+BAR3V3S1 23cN1nXngjKQfI+YmsdZ5lezoxal0KuUEipbhLwhHbrw/NnM5TGhNO3cytPQaGQ/MYB3KT wOl5qttM4Y1u2RSkUny+veut8wkeTbVCYw/TqNDZb1xMDLD4atb2o1XR1eJ69A== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:50 +0200 Subject: [PATCH 33/37] drm/bridge: samsung-dsim: implement .is_tail 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: <20260519-drm-bridge-hotplug-v1-33-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 This bridge is never a tail bridge, i.e. it always needs a following bridge to complete the pipeline. Add a is_tail func to expose this. Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/bridge/samsung-dsim.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge= /samsung-dsim.c index 3c70a45c5dce..55f4b0f16ade 100644 --- a/drivers/gpu/drm/bridge/samsung-dsim.c +++ b/drivers/gpu/drm/bridge/samsung-dsim.c @@ -1716,6 +1716,11 @@ static const u32 samsung_dsim_pixel_output_fmts[] = =3D { MEDIA_BUS_FMT_RGB888_1X24, }; =20 +static bool samsung_dsim_is_tail(struct drm_bridge *bridge) +{ + return false; +} + static bool samsung_dsim_pixel_output_fmt_supported(u32 fmt) { int i; @@ -1836,6 +1841,7 @@ static int samsung_dsim_attach(struct drm_bridge *bri= dge, } =20 static const struct drm_bridge_funcs samsung_dsim_bridge_funcs =3D { + .is_tail =3D samsung_dsim_is_tail, .atomic_duplicate_state =3D drm_atomic_helper_bridge_duplicate_state, .atomic_destroy_state =3D drm_atomic_helper_bridge_destroy_state, .atomic_reset =3D drm_atomic_helper_bridge_reset, @@ -2225,6 +2231,7 @@ int samsung_dsim_probe(struct platform_device *pdev) =20 pm_runtime_enable(dev); =20 + dsi->bridge.ops =3D DRM_BRIDGE_OP_IS_TAIL; dsi->bridge.of_node =3D dev->of_node; dsi->bridge.type =3D DRM_MODE_CONNECTOR_DSI; =20 --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (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 BB85D3F4DCA for ; Tue, 19 May 2026 10:40:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187238; cv=none; b=hFCAAcGXT4vdyLOwegNjHAJtHWacLu/bg7l7/wYebUwXoz83dBPFM7+CvaXyVj+pea8NNUtHef4NlLsN7KR9q34HgZoPpUR4bc71+0Dr1eEdvCSALFm4Pyt9ZyrDQBVwHulvdy8B7xi7yGJ7d7xpoQU0bNfzMnUOLzIqASU39x8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187238; c=relaxed/simple; bh=QUuJhgNdmX36u2PudlO4XK1i7xfIVurX4c/zAXmuxP4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DbjvIqzvhMey4IAnZcQwa0Ht4oxPhfgyWy5crG6zj63iRpGafCBHZDxeAZy2uF8O1wEFvzZD0ZqUvsDHq9Em/DKvKIrt1Js1RSsJyA29A+LgPMzABauNgZuu7G0u3eZzm2diNEPHljbsrd56JGMAnrvhWa4regTPSSDHPMwR3Tk= 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=S3onPUPW; arc=none smtp.client-ip=185.246.85.4 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="S3onPUPW" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 249854E42CF5; Tue, 19 May 2026 10:40:35 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id EC8E8606E9; Tue, 19 May 2026 10:40:34 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 93ABC107E8A20; Tue, 19 May 2026 12:40:29 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187233; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=QTBgLfeJdbyLF0o3Uh3AuWsgdFoP94RbZ7q3dzi5n8w=; b=S3onPUPWiUkG14dSDJ/4D30iXq6YVZFYX5uox5ys0ms9npERtrayEyx+5AxFFEi7XkUOY0 MY44obR9CEebjZGxzRYJo9h/hsz7E8BWk6A8nHdyW7JPkF5eqg+qCB/+mOjMejoXa1GYnf hgcDq2iqtRrA2rUXqOvwOfQZm1y1v9vDb4HuCFn89tQvMBMB4o7a3E//dl5Ed+pHOYS/9w IQT8be670py57dEyhp8Rwn9wRLqhbkh0X3zMby2aAcAOYKs/GG7r56+PBGI7Wp6WOqBSUA ezYlvMiEHnIdL8dQG7V5CDzMKlFb1PPpzH4NnlJU4+6+j2zorAtN15yWFbXgjQ== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:51 +0200 Subject: [PATCH 34/37] drm/bridge: ti-sn65dsi83: implement .is_tail 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: <20260519-drm-bridge-hotplug-v1-34-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 This bridge is never a tail bridge, i.e. it always needs a following bridge to complete the pipeline. Add a is_tail func to expose this. Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/bridge/ti-sn65dsi83.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge= /ti-sn65dsi83.c index a4f2a86a09be..5613c8812318 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c @@ -293,6 +293,11 @@ static struct sn65dsi83 *bridge_to_sn65dsi83(struct dr= m_bridge *bridge) return container_of(bridge, struct sn65dsi83, bridge); } =20 +static bool sn65dsi83_is_tail(struct drm_bridge *bridge) +{ + return false; +} + static int sn65dsi83_attach(struct drm_bridge *bridge, struct drm_encoder *encoder, enum drm_bridge_attach_flags flags) @@ -792,6 +797,7 @@ sn65dsi83_atomic_get_input_bus_fmts(struct drm_bridge *= bridge, } =20 static const struct drm_bridge_funcs sn65dsi83_funcs =3D { + .is_tail =3D sn65dsi83_is_tail, .attach =3D sn65dsi83_attach, .detach =3D sn65dsi83_detach, .atomic_enable =3D sn65dsi83_atomic_enable, @@ -1066,6 +1072,7 @@ static int sn65dsi83_probe(struct i2c_client *client) dev_set_drvdata(dev, ctx); i2c_set_clientdata(client, ctx); =20 + ctx->bridge.ops =3D DRM_BRIDGE_OP_IS_TAIL; ctx->bridge.of_node =3D dev->of_node; ctx->bridge.pre_enable_prev_first =3D true; ctx->bridge.type =3D DRM_MODE_CONNECTOR_LVDS; --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 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 B0B143F1ACE for ; Tue, 19 May 2026 10:40:40 +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=1779187242; cv=none; b=QhjQpImtOdB1I4QtFjptEAAhBvf2KtoHMflvVeFsuDrULYDrJqwEI9aLi1+j+UGDwzg2arQ5sJCWBdaj1S6vDUk94tU8Nl7j1f3EkLv8ELxi/2XuzESbvGFRysOOhwTkk7jj6kDxoI8vp0UtqdS+au0w3c0NtrxUQlBHYiaMZzk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187242; c=relaxed/simple; bh=TNGJ9RazZrye2pjIVFclKZ8vlYSWHt771Fh/bs6soak=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=R6rOyWqQfcItchsVwv9V1iY9g+WQRXw8GMCfugNGQe0+E1X6nRXM2pJ3t0hY2uLGXEXHhfeL69eeMioIf5NXR8sNs8wubJgs4WD2fB+jKW8jfGda5z4vLUVCCVKCX9zBXQolJCZEpZU4p1PpBP4OrmdTfhq5Ki1IfFHhwgrInng= 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=Ca/rGiQg; 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="Ca/rGiQg" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 772C91A3629; Tue, 19 May 2026 10:40:39 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 457F5606E9; Tue, 19 May 2026 10:40:39 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 0FFE3107E8AF0; Tue, 19 May 2026 12:40:33 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187237; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=rgVp93a1hHl6rSGJFgiMk/ReFa5XUVMfUAt1b53bH5w=; b=Ca/rGiQg938bz1xHEi3N1mdoEG0gO/+dhsaW5WudwhKrLxZKtdJeh/FP46bPv06UUzPkZS vw6+d5tFKyw+v3v+BIuKiT6sWzeiR0caRTTKjlTPQar7QH7O90q4l1MSNyR9RdSnwQqkQv 4rjQB5aiqIWEb8loCgfKmXpxFV58zO0eMmlE0E2VZuKq3/LzS9qV50ID3fnfpBVMnFqyLl 52CdMOKuiEVQiKOmVLjMoiBvaFte2B0PvLDFy5sVb/8jknXtYuG68CefLmo+aAbnJrHSKo qCVuAq2tQVQfvX/Jcm5qdqgcAvInfOU3+zhviS4FEGDwJ5lw7bst0GD43jsSyg== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:52 +0200 Subject: [PATCH 35/37] drm/bridge: drm_bridge_attach(): don't fail on -EPROBE_DEFER 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: <20260519-drm-bridge-hotplug-v1-35-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 With bridge hotplug support, when a bridge attach func returns -EPROBE_DEFER it means the following bridge is not yet connected, but it could be later on. In this case don't fail the entire attach operation, so the card can probe (without a connector) and be ready to handle a future hotplug that completes the pipeline. Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/drm_bridge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index 2b539c9749a6..05702ece77c9 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -593,7 +593,7 @@ int drm_bridge_attach(struct drm_encoder *encoder, stru= ct drm_bridge *bridge, =20 if (bridge->funcs->attach) { ret =3D bridge->funcs->attach(bridge, encoder, flags); - if (ret < 0) + if (ret < 0 && ret !=3D -EPROBE_DEFER) goto err_reset_bridge; } =20 --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 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 0AE7A369D4E for ; Tue, 19 May 2026 10:40:44 +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=1779187247; cv=none; b=CZAEEln7LypmXV/rQly+szi3j/FHy2IU78dKIFzsuj/X/gvMNJlQTiREdRnLAWF9X7nH9IVuNj3XuuN1/TkaLWN/a95qXDndTAJEBF6m0/jpvVHbB9EnlQ9FvXp+Yae9WsdSrJcDrJbQ8Sore4arriZSuvlezPk2TkB2LBXdYuk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187247; c=relaxed/simple; bh=2BwG8GxLJyD4kz+B7W+iQmXzkF19sTYTT2QrEZuoE7c=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=auRoR/LbR0HcWRXKqhAc1ktGffUgVMFvfAQTqLD+T8UbAxOPEsrrpWMw4fIVqKgsndbuZsTHzbmzkjcLjDHPnqf3aAF5jKvIkYDRa5NVVs+EUTSPqyoGXwBdmitieYpta8jLcsX/iA0ar407B+A/I12DtapNnVnLEeu+StxWDE8= 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=yoXF7nFv; 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="yoXF7nFv" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id DB034C2B9E5; Tue, 19 May 2026 10:41:36 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id B014B606E9; Tue, 19 May 2026 10:40:43 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 4C3AF107E8A20; Tue, 19 May 2026 12:40:38 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187242; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=td7yo9XNS1lv1rXLaX8XcWtU3vhlD0VxXYz9PxW/V+o=; b=yoXF7nFvbpPJi1a+qgsb8Y5Du8LSUfy41GDr8QvcHAxISWnIX/ZkkfKjHvzyCIc4ZwI3AD XaCQD944dR8xIQP5vIlX6xYzD6G7Mxqz0EX9luiWXbwLlmGGTmSM8NMV+1sX+2IA7rD7Nr tHcdOS0wuDCH8vlxN1U3lFasNn8/Mn4a/IFMEE5aDHNprKYIHWxyz/NVXe1oQyChI4NdxC tM3BnpJYdIA1KUcgquVWYGanxcs8jXUQYIMXqdHlf/1yL4MmHhELy0Z+ijrtWXvnE5+5jZ h91bR6v2ibkfIbulGOfoD/Ot8nMo97kZuoDoAkF05rscBR1apCZZ3jDLh0vQOg== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:53 +0200 Subject: [PATCH 36/37] drm/display: bridge-connector: handle bridge hotplug 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: <20260519-drm-bridge-hotplug-v1-36-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 The drm_bridge_connector is nowadays the recommended way to implement DRM connectors when a chain of bridges is used, and as such it is the ideal component to implement DRM bridge hotplug. Thus, let the drm_bridge_connector be created once for the whole drm_encoder lifetime (as it is now), but make it able of creating and destroying the DRM connector reacting on bridge hot(un)plug events. Unfortunately the current drm_bridge_connector_init() API is unable to support DRM bridge hotplug because it returns a drm_connector, and with hotplug the connector might start existing only later, and also be destroyed and recreated multiple times. So add a new API which is similar but returns a pointer to the drm_bridge_connector, which is persistent, and supports bridge hotplug by creating and destroying the drm_connector based on hotplug events. Because drm_bridge_connector_init() is really a drmm function (it does only drmm allocations), but without a drmm_ prefix, take this as an opportunity to call the new function with the same name but a drmm_ prefix: drmm_bridge_connector_init(). The old API can be replaced over time when needed to support hotplug, and eventually be removed if unused. The new drmm_bridge_connector_init() API differs from the old one in a few aspects in order to support bridge hotplug: * if the bridge chain is not (yet) complete, returns successfully without adding a drm_connector (in this case the old API returns an error) * registers an event notifier block to be able of reacting to events related to bridge hotplug and create/destroy the drm_connector Signed-off-by: Luca Ceresoli --- I'm tempted to let drmm_bridge_connector_init() return int (0 or negative error) instead of a struct drm_bridge_connector *, but I'm not sure whether the drm_bridge_connector pointer may be useful in the future to invoke actions on the bridge_connector after its creation. Opnions about this would be welcome. --- drivers/gpu/drm/display/drm_bridge_connector.c | 157 +++++++++++++++++++++= ++++ include/drm/drm_bridge_connector.h | 2 + 2 files changed, 159 insertions(+) diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/d= rm/display/drm_bridge_connector.c index b83da529cc7a..2ce6c04e2fc7 100644 --- a/drivers/gpu/drm/display/drm_bridge_connector.c +++ b/drivers/gpu/drm/display/drm_bridge_connector.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -158,6 +159,10 @@ struct drm_bridge_connector { * destruction */ struct mutex dynconn_mutex; + /** + * @drm_event_nb: notifier to receive DRM hotplug-related events + */ + struct notifier_block drm_event_nb; }; =20 static struct drm_bridge_connector_dynconn * @@ -1037,6 +1042,19 @@ static int drm_bridge_connector_init_hdmi_audio_cec(= struct drm_bridge_connector_ return 0; } =20 +static bool drm_bridge_connector_pipeline_is_complete(struct drm_bridge_co= nnector *bridge_connector) +{ + struct drm_bridge *last_bridge __free(drm_bridge_put) =3D + drm_bridge_chain_get_last_bridge(bridge_connector->encoder); + + if (!last_bridge || !drm_bridge_is_tail(last_bridge)) { + drm_dbg_driver(bridge_connector->drm, "pipeline not (yet) fully connecte= d"); + return false; + } + + return true; +} + /** * drm_bridge_connector_add_connector - add the drm_connector * @bridge_connector: drm_bridge_connector to add the drm_connector to @@ -1153,6 +1171,79 @@ static int drm_bridge_connector_add_connector(struct= drm_bridge_connector *bridg return ret; } =20 +/* + * Propagate the attach chain and possibly add a drm_connector after a new + * drm_bridge is hot-plugged. + * + * The connector is added only if the pipeline is now complete. This could + * not be the case for various reasons: + * + * - the new bridge is just unrelated to our encoder + * - the new bridge is not be the next one in the pipeline + * - the new bridge is the next in the pipeline but the pipeline is not yet + * complete + * + * All these cases are normal, not an error. + */ +static void drm_bridge_connector_try_complete(struct drm_bridge_connector = *bridge_connector) +{ + int err; + + /* + * drm_connector already present, the new bridge must be for + * another card + */ + if (bridge_connector->dynconn) + return; + + /* Propagate the attach call chain to newly hotplugged bridge(s) */ + struct drm_bridge *last_bridge __free(drm_bridge_put) =3D + drm_bridge_chain_get_last_bridge(bridge_connector->encoder); + + /* Encoder chain empty? */ + if (!last_bridge) + return; + + err =3D last_bridge->funcs->attach(last_bridge, bridge_connector->encoder, + DRM_BRIDGE_ATTACH_NO_CONNECTOR); + if (err) + return; + + /* Add the connector if the pipeline is now complete */ + if (drm_bridge_connector_pipeline_is_complete(bridge_connector)) + drm_bridge_connector_add_connector(bridge_connector); +} + +static int drm_bridge_connector_handle_event(struct notifier_block *nb, + unsigned long event, void *data) +{ + struct drm_bridge_connector *bridge_connector =3D + container_of(nb, struct drm_bridge_connector, drm_event_nb); + + switch (event) { + case DRM_MIPI_DSI_ATTACHED: + /* One or more bridges hot-plugged, try adding the drm_connector */ + drm_bridge_connector_try_complete(bridge_connector); + break; + case DRM_BRIDGE_DETACHED: + { + /* + * A bridge was unplugged, remove the drm_connector if it's + * part of the same pipeline + */ + struct drm_bridge *bridge =3D (struct drm_bridge *)data; + + if (bridge_connector->dynconn && + bridge->encoder =3D=3D bridge_connector->encoder) + drm_bridge_connector_dynconn_release(bridge_connector); + break; + } + default: + } + + return NOTIFY_DONE; +} + static void drm_bridge_connector_fini(struct drm_device *dev, void *res) { struct drm_bridge_connector *bridge_connector =3D (struct drm_bridge_conn= ector *)res; @@ -1205,3 +1296,69 @@ struct drm_connector *drm_bridge_connector_init(stru= ct drm_device *drm, return &bridge_connector->dynconn->connector; } EXPORT_SYMBOL_GPL(drm_bridge_connector_init); + +static void drm_bridge_connector_notifier_unregister(struct drm_device *de= v, void *res) +{ + struct notifier_block *nb =3D (struct notifier_block *)res; + + drm_event_notifier_unregister(nb); +} + +/** + * drmm_bridge_connector_init - Initialise the bridge_connector for a chain + * of bridges, with bridge hotplug support + * @drm: the DRM device + * @encoder: the encoder where the bridge chain starts + * + * Allocate, initialise and register a &drm_bridge_connector with the @drm + * device. The connector is associated with a chain of bridges that starts= at + * the @encoder. All bridges in the chain shall report bridge operation fl= ags + * (&drm_bridge->ops) and bridge output type (&drm_bridge->type), and none= of + * them may create a DRM connector directly. + * + * Also adds a drm_connector if the bridge chain is complete, otherwise the + * &drm_bridge_connector will still be successfully created but without + * adding a drm_connector. In both cases the &drm_bridge_connector will + * receive events notifying bridge hot-plug and hot-unplug and add or + * destroy the drm_connector accordingly. + * + * Returns a pointer to the new &drm_bridge_connector on success, or a + * negative error pointer otherwise. + */ +struct drm_bridge_connector *drmm_bridge_connector_init(struct drm_device = *drm, + struct drm_encoder *encoder) +{ + struct drm_bridge_connector *bridge_connector; + int ret; + + bridge_connector =3D drmm_kzalloc(drm, sizeof(*bridge_connector), GFP_KER= NEL); + if (!bridge_connector) + return ERR_PTR(-ENOMEM); + + mutex_init(&bridge_connector->dynconn_mutex); + bridge_connector->drm =3D drm; + bridge_connector->encoder =3D encoder; + bridge_connector->drm_event_nb.notifier_call =3D drm_bridge_connector_han= dle_event; + + if (drm_bridge_connector_pipeline_is_complete(bridge_connector)) { + ret =3D drm_bridge_connector_add_connector(bridge_connector); + if (ret) + return ERR_PTR(ret); + } + + ret =3D drmm_add_action_or_reset(drm, drm_bridge_connector_fini, bridge_c= onnector); + if (ret) + return ERR_PTR(ret); + + ret =3D drm_event_notifier_register(&bridge_connector->drm_event_nb); + if (ret) + return ERR_PTR(ret); + + ret =3D drmm_add_action_or_reset(drm, drm_bridge_connector_notifier_unreg= ister, + &bridge_connector->drm_event_nb); + if (ret) + return ERR_PTR(ret); + + return 0; +} +EXPORT_SYMBOL_GPL(drmm_bridge_connector_init); diff --git a/include/drm/drm_bridge_connector.h b/include/drm/drm_bridge_co= nnector.h index 69630815fb09..1c78221c0857 100644 --- a/include/drm/drm_bridge_connector.h +++ b/include/drm/drm_bridge_connector.h @@ -10,6 +10,8 @@ struct drm_connector; struct drm_device; struct drm_encoder; =20 +struct drm_bridge_connector *drmm_bridge_connector_init(struct drm_device = *drm, + struct drm_encoder *encoder); struct drm_connector *drm_bridge_connector_init(struct drm_device *drm, struct drm_encoder *encoder); =20 --=20 2.54.0 From nobody Mon May 25 01:57:46 2026 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 14571369D51 for ; Tue, 19 May 2026 10:40:49 +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=1779187250; cv=none; b=ok9m20sOvJ+B1At23DGBUNr3IgqFYlcphO5zu6w4+US6eoU50RDpe3C1MJru0RQwmrvxU8KndjzNSlS8ngVNp7q79SKmsJ+rVIWj0iTyXH2u7n5Je9y96nOKfQMTGNIIOOrsz7ZIpPzCsXVGqDYVGdLTOelVc1ohn8HFqetvhTM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779187250; c=relaxed/simple; bh=M+hVvxnQejdHxo+UYdJvd5gFmRwFi2byDjqLlPnNc4s=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=cCQXq6oncxFW53LNC6jaIYe4vBmUWaZHG4VCtHdkKihvDl45XPcYQI8xVN0fGZPJh0DRq9Gnkdqjd2uKTeuEbpmzX6fdWQi+yUk7TTJpxAgvk6HBFNFgODWecOr8P4oAjwzcl2locIKSBeBmsxu6XB5HJFc5JEEUnxLDDq18ndY= 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=Z4gYPq7Q; 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="Z4gYPq7Q" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id E4BEA1A3629; Tue, 19 May 2026 10:40:47 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id B1F81606E9; Tue, 19 May 2026 10:40:47 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 765BF107E8B03; Tue, 19 May 2026 12:40:42 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1779187246; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=a85Cizij9kXPn9Kt9sHvek1PwQkqP3FwMIAwRQz/a8o=; b=Z4gYPq7Q2NDsQG86vprBtBK5lBZtFpPE0bbnPnYGs+sZFFnP+Mx3El6bvsqAlrqEDPrXvG Bc6deDtultuXkpkS+kJUU8sSQq/k+pG0sItxEciHnatzT1rMygUpHH1JVeKOaP0J1Wexc/ g/d4eNtw/H9oBJkG//mVXKZR/uVaCRtS8RAQ6qfLnFu5XaZyAtgT35XTgHuW9ibLocjq8R pLWk+i1KMpk9BL78GCZHLpZLA92njKTPr83cHZVLYHUtWgj2WPuCeG7b3LNkUMTb54/Jok 3p/XrWjvtJaaf8BMe3w6qRFOoMGtCEbNgAY6cjGIIP5pqupG/gqzbwNnvMRT4A== From: Luca Ceresoli Date: Tue, 19 May 2026 12:37:54 +0200 Subject: [PATCH 37/37] drm/mxsfb/lcdif: enable bridge hotplug 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: <20260519-drm-bridge-hotplug-v1-37-45e2bdb3dfb4@bootlin.com> References: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@bootlin.com> In-Reply-To: <20260519-drm-bridge-hotplug-v1-0-45e2bdb3dfb4@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 , Inki Dae , Jagan Teki , Marek Szyprowski , Marek Vasut , Stefan Agner , Frank Li , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam Cc: Hui Pu , Ian Ray , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, Luca Ceresoli X-Mailer: b4 0.15.2 X-Last-TLS-Session-Version: TLSv1.3 Switch to the new drmm_bridge_connector_init() so the drm_bridge_connector will handle bridge hotplugging. Signed-off-by: Luca Ceresoli --- drivers/gpu/drm/mxsfb/lcdif_drv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/mxsfb/lcdif_drv.c b/drivers/gpu/drm/mxsfb/lcdi= f_drv.c index e2173c4d6fc2..0a7c197dbc1e 100644 --- a/drivers/gpu/drm/mxsfb/lcdif_drv.c +++ b/drivers/gpu/drm/mxsfb/lcdif_drv.c @@ -58,7 +58,7 @@ static int lcdif_attach_bridge(struct lcdif_drm_private *= lcdif) struct of_endpoint of_ep; struct drm_bridge *bridge; struct drm_encoder *encoder; - struct drm_connector *connector; + struct drm_bridge_connector *bridge_connector; int ret; =20 if (!of_device_is_available(remote)) @@ -94,9 +94,9 @@ static int lcdif_attach_bridge(struct lcdif_drm_private *= lcdif) "Failed to attach bridge for endpoint%u\n", of_ep.id); =20 - connector =3D drm_bridge_connector_init(lcdif->drm, encoder); - if (IS_ERR(connector)) - return dev_err_probe(dev, PTR_ERR(connector), + bridge_connector =3D drmm_bridge_connector_init(lcdif->drm, encoder); + if (IS_ERR(bridge_connector)) + return dev_err_probe(dev, PTR_ERR(bridge_connector), "Failed to init bridge_connector for endpoint%u\n", of_ep.id); } --=20 2.54.0