[PATCH RFC 08/19] drm/bridge: Introduce drm_bridge_chain_get_{first, last, next}_bridge()

Boris Brezillon boris.brezillon at collabora.com
Thu Aug 8 15:11:39 UTC 2019


And use them in drivers accessing the encoder->bridge or bridge->next
fields directly. This is part of our attempt to make the bridge chain
a double-linked list based on the generic list helpers.

Signed-off-by: Boris Brezillon <boris.brezillon at collabora.com>
---
 drivers/gpu/drm/drm_bridge.c           | 52 ++++++++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_hdmi.c    |  2 +-
 drivers/gpu/drm/msm/edp/edp_bridge.c   |  2 +-
 drivers/gpu/drm/omapdrm/omap_drv.c     |  7 ++--
 drivers/gpu/drm/omapdrm/omap_encoder.c |  3 +-
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 10 +++--
 drivers/gpu/drm/vc4/vc4_dsi.c          |  4 +-
 include/drm/drm_bridge.h               |  6 +++
 8 files changed, 75 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index 2bf9a19e11bf..b96bbba05ba9 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -160,6 +160,58 @@ void drm_bridge_detach(struct drm_bridge *bridge)
 	bridge->dev = NULL;
 }
 
+/**
+ * drm_bridge_chain_get_first_bridge() - Get the first bridge in the chain
+ * @encoder: encoder object
+ *
+ * RETURNS:
+ * the first bridge in the encoder chain, or NULL if there's no bridge
+ * attached to this encoder.
+ */
+struct drm_bridge *
+drm_bridge_chain_get_first_bridge(struct drm_encoder *encoder)
+{
+	return encoder->bridge;
+}
+EXPORT_SYMBOL(drm_bridge_chain_get_first_bridge);
+
+/**
+ * drm_bridge_chain_get_last_bridge() - Get the last bridge in the chain
+ * @encoder: encoder object
+ *
+ * RETURNS:
+ * the last bridge in the encoder chain, or NULL if there's no bridge
+ * attached to this encoder.
+ */
+struct drm_bridge *
+drm_bridge_chain_get_last_bridge(struct drm_encoder *encoder)
+{
+	struct drm_bridge *bridge = encoder->bridge;
+
+	while(bridge && bridge->next)
+		bridge = bridge->next;
+
+	return bridge;
+}
+EXPORT_SYMBOL(drm_bridge_chain_get_last_bridge);
+
+/**
+ * drm_bridge_chain_get_next_bridge() - Get the next bridge in the chain
+ * @bridge: bridge object
+ *
+ * RETURNS:
+ * the next bridge in the chain, or NULL if there's @bridge is the last.
+ */
+struct drm_bridge *
+drm_bridge_chain_get_next_bridge(struct drm_bridge *bridge)
+{
+	if (!bridge || !bridge->encoder)
+		return NULL;
+
+	return bridge->next;
+}
+EXPORT_SYMBOL(drm_bridge_chain_get_next_bridge);
+
 /**
  * DOC: bridge callbacks
  *
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index 6ec3d2584539..17e6d79303e0 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -1243,7 +1243,7 @@ static int mtk_hdmi_conn_mode_valid(struct drm_connector *conn,
 		mode->hdisplay, mode->vdisplay, mode->vrefresh,
 		!!(mode->flags & DRM_MODE_FLAG_INTERLACE), mode->clock * 1000);
 
-	if (hdmi->bridge.next) {
+	if (drm_bridge_chain_get_next_bridge(&hdmi->bridge)) {
 		struct drm_display_mode adjusted_mode;
 
 		drm_mode_copy(&adjusted_mode, mode);
diff --git a/drivers/gpu/drm/msm/edp/edp_bridge.c b/drivers/gpu/drm/msm/edp/edp_bridge.c
index 2950bba4aca9..6d2d405580d2 100644
--- a/drivers/gpu/drm/msm/edp/edp_bridge.c
+++ b/drivers/gpu/drm/msm/edp/edp_bridge.c
@@ -56,7 +56,7 @@ static void edp_bridge_mode_set(struct drm_bridge *bridge,
 
 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 		if ((connector->encoder != NULL) &&
-			(connector->encoder->bridge == bridge)) {
+		    (drm_bridge_chain_get_first_bridge(connector->encoder) == bridge)) {
 			msm_edp_ctrl_timing_cfg(edp->ctrl,
 				adjusted_mode, &connector->display_info);
 			break;
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index 224ec6fdc800..41fb98a9141b 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -215,11 +215,10 @@ static int omap_display_id(struct omap_dss_device *output)
 		node = display->dev->of_node;
 		omapdss_device_put(display);
 	} else if (output->bridge) {
-		struct drm_bridge *bridge = output->bridge;
-
-		while (bridge->next)
-			bridge = bridge->next;
+		struct drm_encoder *encoder = output->bridge->encoder;
+		struct drm_bridge *bridge;
 
+		bridge = drm_bridge_chain_get_last_bridge(encoder);
 		node = bridge->of_node;
 	} else if (output->panel) {
 		node = output->panel->dev->of_node;
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c b/drivers/gpu/drm/omapdrm/omap_encoder.c
index 24bbe9f2a32e..727a6bea3807 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.c
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.c
@@ -126,7 +126,8 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder,
 	for (dssdev = output; dssdev; dssdev = dssdev->next)
 		omap_encoder_update_videomode_flags(&vm, dssdev->bus_flags);
 
-	for (bridge = output->bridge; bridge; bridge = bridge->next) {
+	for (bridge = drm_bridge_chain_get_first_bridge(encoder);
+	     bridge; bridge = drm_bridge_chain_get_next_bridge(bridge)) {
 		if (!bridge->timings)
 			continue;
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index 2da46e3dc4ae..f2ae4c410244 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -14,6 +14,7 @@
 
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
+#include <drm/drm_bridge.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_device.h>
 #include <drm/drm_fb_cma_helper.h>
@@ -680,9 +681,10 @@ static void rcar_du_crtc_atomic_enable(struct drm_crtc *crtc,
 			rcdu->encoders[RCAR_DU_OUTPUT_LVDS0 + rcrtc->index];
 		const struct drm_display_mode *mode =
 			&crtc->state->adjusted_mode;
+		struct drm_bridge *bridge;
 
-		rcar_lvds_clk_enable(encoder->base.bridge,
-				     mode->clock * 1000);
+		bridge = drm_bridge_chain_get_first_bridge(&encoder->base);
+		rcar_lvds_clk_enable(bridge, mode->clock * 1000);
 	}
 
 	rcar_du_crtc_start(rcrtc);
@@ -702,12 +704,14 @@ static void rcar_du_crtc_atomic_disable(struct drm_crtc *crtc,
 	    rstate->outputs == BIT(RCAR_DU_OUTPUT_DPAD0)) {
 		struct rcar_du_encoder *encoder =
 			rcdu->encoders[RCAR_DU_OUTPUT_LVDS0 + rcrtc->index];
+		struct drm_bridge *bridge;
 
 		/*
 		 * Disable the LVDS clock output, see
 		 * rcar_du_crtc_atomic_enable().
 		 */
-		rcar_lvds_clk_disable(encoder->base.bridge);
+		bridge = drm_bridge_chain_get_first_bridge(&encoder->base);
+		rcar_lvds_clk_disable(bridge);
 	}
 
 	spin_lock_irq(&crtc->dev->event_lock);
diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
index d7cd720c4efa..a1698417927d 100644
--- a/drivers/gpu/drm/vc4/vc4_dsi.c
+++ b/drivers/gpu/drm/vc4/vc4_dsi.c
@@ -1629,8 +1629,10 @@ static void vc4_dsi_unbind(struct device *dev, struct device *master,
 	struct drm_device *drm = dev_get_drvdata(master);
 	struct vc4_dev *vc4 = to_vc4_dev(drm);
 	struct vc4_dsi *dsi = dev_get_drvdata(dev);
+	struct drm_bridge *bridge;
 
-	if (dsi->encoder->bridge)
+	bridge = drm_bridge_chain_get_first_bridge(dsi->encoder);
+	if (bridge)
 		pm_runtime_disable(dev);
 
 	vc4_dsi_encoder_destroy(dsi->encoder);
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 3057e2153f62..d429bd1c00f9 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -409,6 +409,12 @@ struct drm_bridge *of_drm_find_bridge(struct device_node *np);
 int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge,
 		      struct drm_bridge *previous);
 
+struct drm_bridge *
+drm_bridge_chain_get_first_bridge(struct drm_encoder *encoder);
+struct drm_bridge *
+drm_bridge_chain_get_last_bridge(struct drm_encoder *encoder);
+struct drm_bridge *
+drm_bridge_chain_get_next_bridge(struct drm_bridge *bridge);
 bool drm_bridge_chain_mode_fixup(struct drm_encoder *encoder,
 				 const struct drm_display_mode *mode,
 				 struct drm_display_mode *adjusted_mode);
-- 
2.21.0



More information about the dri-devel mailing list