From: Luca Ceresoli <luca.ceresoli@bootlin.com>
To: Andrzej Hajda <andrzej.hajda@intel.com>,
Neil Armstrong <neil.armstrong@linaro.org>,
Robert Foss <rfoss@kernel.org>,
Laurent Pinchart <Laurent.pinchart@ideasonboard.com>,
Jonas Karlman <jonas@kwiboo.se>,
Jernej Skrabec <jernej.skrabec@gmail.com>,
Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
Maxime Ripard <mripard@kernel.org>,
Thomas Zimmermann <tzimmermann@suse.de>,
David Airlie <airlied@gmail.com>,
Simona Vetter <simona@ffwll.ch>, Miguel Ojeda <ojeda@kernel.org>,
Nathan Chancellor <nathan@kernel.org>,
Nick Desaulniers <nick.desaulniers+lkml@gmail.com>,
Bill Wendling <morbo@google.com>,
Justin Stitt <justinstitt@google.com>,
Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Cc: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>,
Chaoyi Chen <chaoyi.chen@rock-chips.com>,
Hui Pu <Hui.Pu@gehealthcare.com>,
Thomas Petazzoni <thomas.petazzoni@bootlin.com>,
dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
llvm@lists.linux.dev, Luca Ceresoli <luca.ceresoli@bootlin.com>
Subject: [PATCH 3/9] drm/bridge: add drm_for_each_bridge_in_chain_scoped()
Date: Wed, 23 Jul 2025 11:54:10 +0200 [thread overview]
Message-ID: <20250723-drm-bridge-alloc-getput-for_each_bridge-v1-3-be8f4ae006e9@bootlin.com> (raw)
In-Reply-To: <20250723-drm-bridge-alloc-getput-for_each_bridge-v1-0-be8f4ae006e9@bootlin.com>
Add variant of drm_for_each_bridge_in_chain() that gets/puts the bridge
reference at the beginning/end of each iteration, and puts it if breaking
ot of the loop.
Note that this requires adding a new drm_bridge_get_next_bridge_and_put()
function because, unlike similar functions as __of_get_next_child(),
drm_bridge_get_next_bridge() gets the "next" pointer but does not put the
"prev" pointer, and some of its users rely on this.
Also deprecate drm_for_each_bridge_in_chain(), in preparation for removing
it after converting all users to the scoped version.
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
---
Note 1: drm_for_each_bridge_in_chain_scoped() could be renamed removing the
_scoped suffix after removing all the users of the current macro
and eventually the current macro itself. Even though this series is
converting all users, I'd at least wait one kernel release before
renaming, to minimize issues with existing patches which would fail
building.
Note 2: Yes, the drm_bridge_get_next_bridge_and_put() name is ugly, but we
do need a "next_bridge" function that does not put the "prev"
bridge and one that does. Any proposal for a better name or a
different implementation is welcome.
---
.clang-format | 1 +
include/drm/drm_bridge.h | 41 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 42 insertions(+)
diff --git a/.clang-format b/.clang-format
index 48405c54ef271e9546da08893d200a4cf48f3a55..1cac7d4976644c8f083f801e98f619782c2e23cc 100644
--- a/.clang-format
+++ b/.clang-format
@@ -168,6 +168,7 @@ ForEachMacros:
- 'drm_exec_for_each_locked_object'
- 'drm_exec_for_each_locked_object_reverse'
- 'drm_for_each_bridge_in_chain'
+ - 'drm_for_each_bridge_in_chain_scoped'
- 'drm_for_each_connector_iter'
- 'drm_for_each_crtc'
- 'drm_for_each_crtc_reverse'
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 717171d0e58725ed854209c3355260e415b4c5d7..990ef98011c96619b269787ebe01a2ad3b225c42 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -1358,10 +1358,51 @@ drm_bridge_chain_get_first_bridge(struct drm_encoder *encoder)
* iteration
*
* Iterate over all bridges present in the bridge chain attached to @encoder.
+ *
+ * This is deprecated, do not use!
+ * New drivers shall use drm_for_each_bridge_in_chain_scoped().
*/
#define drm_for_each_bridge_in_chain(encoder, bridge) \
list_for_each_entry(bridge, &(encoder)->bridge_chain, chain_node)
+/**
+ * drm_bridge_get_next_bridge_and_put - Get the next bridge in the chain
+ * and put the previous
+ * @bridge: bridge object
+ *
+ * Same as drm_bridge_get_next_bridge() but additionally puts the @bridge.
+ *
+ * RETURNS:
+ * the next bridge in the chain after @bridge, or NULL if @bridge is the last.
+ */
+static inline struct drm_bridge *
+drm_bridge_get_next_bridge_and_put(struct drm_bridge *bridge)
+{
+ struct drm_bridge *next = drm_bridge_get_next_bridge(bridge);
+
+ drm_bridge_put(bridge);
+
+ return next;
+}
+
+/**
+ * drm_for_each_bridge_in_chain_scoped - iterate over all bridges attached
+ * to an encoder
+ * @encoder: the encoder to iterate bridges on
+ * @bridge: a bridge pointer updated to point to the current bridge at each
+ * iteration
+ *
+ * Iterate over all bridges present in the bridge chain attached to @encoder.
+ *
+ * Automatically gets/puts the bridge reference while iterating, and puts
+ * the reference even if returning or breaking in the middle of the loop.
+ */
+#define drm_for_each_bridge_in_chain_scoped(encoder, bridge) \
+ for (struct drm_bridge *bridge __free(drm_bridge_put) = \
+ drm_bridge_chain_get_first_bridge(encoder); \
+ bridge; \
+ bridge = drm_bridge_get_next_bridge_and_put(bridge))
+
enum drm_mode_status
drm_bridge_chain_mode_valid(struct drm_bridge *bridge,
const struct drm_display_info *info,
--
2.50.1
next prev parent reply other threads:[~2025-07-23 9:54 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-23 9:54 [PATCH 0/9] drm/bridge: get/put the bridge when looping over the encoder chain Luca Ceresoli
2025-07-23 9:54 ` [PATCH 1/9] drm/display: bridge-connector: use scope-specific variable for the bridge pointer Luca Ceresoli
2025-07-23 9:54 ` [PATCH 2/9] drm/display: bridge-connector: remove unused variable assignment Luca Ceresoli
2025-07-23 9:54 ` Luca Ceresoli [this message]
2025-07-23 9:54 ` [PATCH 4/9] drm/display: bridge-connector: use drm_for_each_bridge_in_chain_scoped() Luca Ceresoli
2025-07-23 9:54 ` [PATCH 5/9] drm/atomic: " Luca Ceresoli
2025-07-23 9:54 ` [PATCH 6/9] drm/bridge: " Luca Ceresoli
2025-07-23 9:54 ` [PATCH 7/9] drm/bridge: remove drm_for_each_bridge_in_chain() Luca Ceresoli
2025-07-23 9:54 ` [PATCH 8/9] drm/bridge: add drm_for_each_bridge_in_chain_from() Luca Ceresoli
2025-07-23 9:54 ` [PATCH 9/9] drm/omap: use drm_for_each_bridge_in_chain_from() Luca Ceresoli
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250723-drm-bridge-alloc-getput-for_each_bridge-v1-3-be8f4ae006e9@bootlin.com \
--to=luca.ceresoli@bootlin.com \
--cc=Hui.Pu@gehealthcare.com \
--cc=Laurent.pinchart@ideasonboard.com \
--cc=airlied@gmail.com \
--cc=andrzej.hajda@intel.com \
--cc=chaoyi.chen@rock-chips.com \
--cc=dmitry.baryshkov@oss.qualcomm.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=jernej.skrabec@gmail.com \
--cc=jonas@kwiboo.se \
--cc=justinstitt@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=llvm@lists.linux.dev \
--cc=maarten.lankhorst@linux.intel.com \
--cc=morbo@google.com \
--cc=mripard@kernel.org \
--cc=nathan@kernel.org \
--cc=neil.armstrong@linaro.org \
--cc=nick.desaulniers+lkml@gmail.com \
--cc=ojeda@kernel.org \
--cc=rfoss@kernel.org \
--cc=simona@ffwll.ch \
--cc=thomas.petazzoni@bootlin.com \
--cc=tomi.valkeinen@ideasonboard.com \
--cc=tzimmermann@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).