drm: bridge: Link encoder and bridge in core code
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Mon, 28 Nov 2016 15:59:08 +0000 (17:59 +0200)
committerArchit Taneja <architt@codeaurora.org>
Sun, 18 Dec 2016 11:01:45 +0000 (16:31 +0530)
Instead of linking encoders and bridges in every driver (and getting it
wrong half of the time, as many drivers forget to set the drm_bridge
encoder pointer), do so in core code. The drm_bridge_attach() function
needs the encoder and optional previous bridge to perform that task,
update all the callers.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Acked-by: Stefan Agner <stefan@agner.ch> # For DCU
Acked-by: Boris Brezillon <boris.brezillon@free-electrons.com> # For atmel-hlcdc
Acked-by: Vincent Abriou <vincent.abriou@st.com> # For STI
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com> # For sun4i
Acked-by: Xinliang Liu <z.liuxinliang@hisilicon.com> # For hisilicon
Acked-by: Jyri Sarha <jsarha@ti.com> # For tilcdc
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Archit Taneja <architt@codeaurora.org>
Link: http://patchwork.freedesktop.org/patch/msgid/1481709550-29226-4-git-send-email-laurent.pinchart+renesas@ideasonboard.com
25 files changed:
drivers/gpu/drm/arc/arcpgu_hdmi.c
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c
drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
drivers/gpu/drm/bridge/dw-hdmi.c
drivers/gpu/drm/drm_bridge.c
drivers/gpu/drm/drm_simple_kms_helper.c
drivers/gpu/drm/exynos/exynos_dp.c
drivers/gpu/drm/exynos/exynos_drm_dsi.c
drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c
drivers/gpu/drm/imx/imx-ldb.c
drivers/gpu/drm/imx/parallel-display.c
drivers/gpu/drm/mediatek/mtk_dpi.c
drivers/gpu/drm/mediatek/mtk_dsi.c
drivers/gpu/drm/mediatek/mtk_hdmi.c
drivers/gpu/drm/msm/dsi/dsi_manager.c
drivers/gpu/drm/msm/edp/edp_bridge.c
drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c
drivers/gpu/drm/sti/sti_dvo.c
drivers/gpu/drm/sti/sti_hda.c
drivers/gpu/drm/sti/sti_hdmi.c
drivers/gpu/drm/sun4i/sun4i_rgb.c
drivers/gpu/drm/tilcdc/tilcdc_external.c
include/drm/drm_bridge.h

index b69c66b4897e46e2ea77890e39235f3d9e94b57d..0ce7f398bcff150fee7ff1b9d5b2e975b72b458f 100644 (file)
@@ -47,10 +47,7 @@ int arcpgu_drm_hdmi_init(struct drm_device *drm, struct device_node *np)
                return ret;
 
        /* Link drm_bridge to encoder */
-       bridge->encoder = encoder;
-       encoder->bridge = bridge;
-
-       ret = drm_bridge_attach(drm, bridge);
+       ret = drm_bridge_attach(encoder, bridge, NULL);
        if (ret)
                drm_encoder_cleanup(encoder);
 
index 6119b50855013522880f4e725b9ac8eb06372b26..e7799b6ee8293d706252c07c79cc15c6e2c44811 100644 (file)
@@ -230,9 +230,7 @@ static int atmel_hlcdc_attach_endpoint(struct drm_device *dev,
        of_node_put(np);
 
        if (bridge) {
-               output->encoder.bridge = bridge;
-               bridge->encoder = &output->encoder;
-               ret = drm_bridge_attach(dev, bridge);
+               ret = drm_bridge_attach(&output->encoder, bridge, NULL);
                if (!ret)
                        return 0;
        }
index 134bd28337a9c0e263a3927c07f5f9f9d3fa0051..02b97bf64ee4ea962033ffd51714dc09600f289e 100644 (file)
@@ -1232,12 +1232,10 @@ static int analogix_dp_create_bridge(struct drm_device *drm_dev,
 
        dp->bridge = bridge;
 
-       dp->encoder->bridge = bridge;
        bridge->driver_private = dp;
-       bridge->encoder = dp->encoder;
        bridge->funcs = &analogix_dp_bridge_funcs;
 
-       ret = drm_bridge_attach(drm_dev, bridge);
+       ret = drm_bridge_attach(dp->encoder, bridge, NULL);
        if (ret) {
                DRM_ERROR("failed to attach drm bridge\n");
                return -EINVAL;
index 235ce7d1583d5f165bcd3c05afd2d1570fe6fff0..f5009ae39b8937147af0afdfd8d83acd0096e417 100644 (file)
@@ -1841,13 +1841,12 @@ static int dw_hdmi_register(struct drm_device *drm, struct dw_hdmi *hdmi)
        hdmi->bridge = bridge;
        bridge->driver_private = hdmi;
        bridge->funcs = &dw_hdmi_bridge_funcs;
-       ret = drm_bridge_attach(drm, bridge);
+       ret = drm_bridge_attach(encoder, bridge, NULL);
        if (ret) {
                DRM_ERROR("Failed to initialize bridge with drm\n");
                return -EINVAL;
        }
 
-       encoder->bridge = bridge;
        hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
 
        drm_connector_helper_add(&hdmi->connector,
index 0ee052b7c21af76f9e172075c4b5671af018d2f0..850bd6509ef1122d258dd2574f917833dcbeae6e 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/mutex.h>
 
 #include <drm/drm_bridge.h>
+#include <drm/drm_encoder.h>
 
 /**
  * DOC: overview
@@ -92,32 +93,53 @@ void drm_bridge_remove(struct drm_bridge *bridge)
 EXPORT_SYMBOL(drm_bridge_remove);
 
 /**
- * drm_bridge_attach - associate given bridge to our DRM device
+ * drm_bridge_attach - attach the bridge to an encoder's chain
  *
- * @dev: DRM device
- * @bridge: bridge control structure
+ * @encoder: DRM encoder
+ * @bridge: bridge to attach
+ * @previous: previous bridge in the chain (optional)
  *
- * Called by a kms driver to link one of our encoder/bridge to the given
- * bridge.
+ * Called by a kms driver to link the bridge to an encoder's chain. The previous
+ * argument specifies the previous bridge in the chain. If NULL, the bridge is
+ * linked directly at the encoder's output. Otherwise it is linked at the
+ * previous bridge's output.
  *
- * Note that setting up links between the bridge and our encoder/bridge
- * objects needs to be handled by the kms driver itself.
+ * If non-NULL the previous bridge must be already attached by a call to this
+ * function.
  *
  * RETURNS:
  * Zero on success, error code on failure
  */
-int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge)
+int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge,
+                     struct drm_bridge *previous)
 {
-       if (!dev || !bridge)
+       int ret;
+
+       if (!encoder || !bridge)
+               return -EINVAL;
+
+       if (previous && (!previous->dev || previous->encoder != encoder))
                return -EINVAL;
 
        if (bridge->dev)
                return -EBUSY;
 
-       bridge->dev = dev;
+       bridge->dev = encoder->dev;
+       bridge->encoder = encoder;
+
+       if (bridge->funcs->attach) {
+               ret = bridge->funcs->attach(bridge);
+               if (ret < 0) {
+                       bridge->dev = NULL;
+                       bridge->encoder = NULL;
+                       return ret;
+               }
+       }
 
-       if (bridge->funcs->attach)
-               return bridge->funcs->attach(bridge);
+       if (previous)
+               previous->next = bridge;
+       else
+               encoder->bridge = bridge;
 
        return 0;
 }
index 7bae08c2bf0a92b9c547550cf61c4b670130d90d..ba7be616933996a6588c45137810d38c640cff73 100644 (file)
@@ -182,9 +182,7 @@ static const struct drm_plane_funcs drm_simple_kms_plane_funcs = {
 int drm_simple_display_pipe_attach_bridge(struct drm_simple_display_pipe *pipe,
                                          struct drm_bridge *bridge)
 {
-       bridge->encoder = &pipe->encoder;
-       pipe->encoder.bridge = bridge;
-       return drm_bridge_attach(pipe->encoder.dev, bridge);
+       return drm_bridge_attach(&pipe->encoder, bridge, NULL);
 }
 EXPORT_SYMBOL(drm_simple_display_pipe_attach_bridge);
 
index 528229faffe4bf1a6ec223ad5983e09d860ba615..1ef0be338b856c7ce3e03539d2a83792668b70a4 100644 (file)
@@ -99,7 +99,6 @@ static int exynos_dp_bridge_attach(struct analogix_dp_plat_data *plat_data,
                                   struct drm_connector *connector)
 {
        struct exynos_dp_device *dp = to_dp(plat_data);
-       struct drm_encoder *encoder = &dp->encoder;
        int ret;
 
        drm_connector_register(connector);
@@ -107,9 +106,7 @@ static int exynos_dp_bridge_attach(struct analogix_dp_plat_data *plat_data,
 
        /* Pre-empt DP connector creation if there's a bridge */
        if (dp->ptn_bridge) {
-               bridge->next = dp->ptn_bridge;
-               dp->ptn_bridge->encoder = encoder;
-               ret = drm_bridge_attach(encoder->dev, dp->ptn_bridge);
+               ret = drm_bridge_attach(&dp->encoder, dp->ptn_bridge, bridge);
                if (ret) {
                        DRM_ERROR("Failed to attach bridge to drm\n");
                        bridge->next = NULL;
index e07cb1fe4860440596debe0636877afe968d4470..812e2ec0761d0b2b6ad17c71c99a37995e09ca51 100644 (file)
@@ -1718,10 +1718,8 @@ static int exynos_dsi_bind(struct device *dev, struct device *master,
        }
 
        bridge = of_drm_find_bridge(dsi->bridge_node);
-       if (bridge) {
-               encoder->bridge = bridge;
-               drm_bridge_attach(drm_dev, bridge);
-       }
+       if (bridge)
+               drm_bridge_attach(encoder, bridge, NULL);
 
        return mipi_dsi_host_register(&dsi->dsi_host);
 }
index 05a8ee10687967e323a1052545f0a4a4b89399e9..c3651456c963f4a87b47694e9085f4663d0b2965 100644 (file)
@@ -160,10 +160,7 @@ static int fsl_dcu_attach_endpoint(struct fsl_dcu_drm_device *fsl_dev,
        if (!bridge)
                return -ENODEV;
 
-       fsl_dev->encoder.bridge = bridge;
-       bridge->encoder = &fsl_dev->encoder;
-
-       return drm_bridge_attach(fsl_dev->drm, bridge);
+       return drm_bridge_attach(&fsl_dev->encoder, bridge, NULL);
 }
 
 int fsl_dcu_create_outputs(struct fsl_dcu_drm_device *fsl_dev)
index 998452ad0fcb992cbef4169c9b5073c7c999bcc3..1737e98bc10a26c499c466d386d0994938a6f92f 100644 (file)
@@ -709,10 +709,7 @@ static int dsi_bridge_init(struct drm_device *dev, struct dw_dsi *dsi)
        int ret;
 
        /* associate the bridge to dsi encoder */
-       encoder->bridge = bridge;
-       bridge->encoder = encoder;
-
-       ret = drm_bridge_attach(dev, bridge);
+       ret = drm_bridge_attach(encoder, bridge, NULL);
        if (ret) {
                DRM_ERROR("failed to attach external bridge\n");
                return ret;
index 516d06490465429561bb4923a77645d7626e525d..ec49ea3d8e4088b139f35f3c73facfe96a5e16f7 100644 (file)
@@ -454,10 +454,8 @@ static int imx_ldb_register(struct drm_device *drm,
                         DRM_MODE_ENCODER_LVDS, NULL);
 
        if (imx_ldb_ch->bridge) {
-               imx_ldb_ch->bridge->encoder = encoder;
-
-               imx_ldb_ch->encoder.bridge = imx_ldb_ch->bridge;
-               ret = drm_bridge_attach(drm, imx_ldb_ch->bridge);
+               ret = drm_bridge_attach(&imx_ldb_ch->encoder,
+                                       imx_ldb_ch->bridge, NULL);
                if (ret) {
                        DRM_ERROR("Failed to initialize bridge with drm\n");
                        return ret;
index 8582a83c0d9b27f8b65b904d704324e6997f02ae..51d9f735c35841bd1c3b168e56bccdd509a9da2d 100644 (file)
@@ -191,9 +191,7 @@ static int imx_pd_register(struct drm_device *drm,
                drm_panel_attach(imxpd->panel, &imxpd->connector);
 
        if (imxpd->bridge) {
-               imxpd->bridge->encoder = encoder;
-               encoder->bridge = imxpd->bridge;
-               ret = drm_bridge_attach(drm, imxpd->bridge);
+               ret = drm_bridge_attach(encoder, imxpd->bridge, NULL);
                if (ret < 0) {
                        dev_err(imxpd->dev, "failed to attach bridge: %d\n",
                                ret);
index 90fb831ef031b9794df4f1ef95609204bedce93a..3bd3bd688d1a4d8105359a5c8ab80fed52ea67bd 100644 (file)
@@ -63,6 +63,7 @@ enum mtk_dpi_out_color_format {
 struct mtk_dpi {
        struct mtk_ddp_comp ddp_comp;
        struct drm_encoder encoder;
+       struct drm_bridge *bridge;
        void __iomem *regs;
        struct device *dev;
        struct clk *engine_clk;
@@ -620,8 +621,7 @@ static int mtk_dpi_bind(struct device *dev, struct device *master, void *data)
        /* Currently DPI0 is fixed to be driven by OVL1 */
        dpi->encoder.possible_crtcs = BIT(1);
 
-       dpi->encoder.bridge->encoder = &dpi->encoder;
-       ret = drm_bridge_attach(dpi->encoder.dev, dpi->encoder.bridge);
+       ret = drm_bridge_attach(&dpi->encoder, dpi->bridge, NULL);
        if (ret) {
                dev_err(dev, "Failed to attach bridge: %d\n", ret);
                goto err_cleanup;
@@ -718,9 +718,9 @@ static int mtk_dpi_probe(struct platform_device *pdev)
 
        dev_info(dev, "Found bridge node: %s\n", bridge_node->full_name);
 
-       dpi->encoder.bridge = of_drm_find_bridge(bridge_node);
+       dpi->bridge = of_drm_find_bridge(bridge_node);
        of_node_put(bridge_node);
-       if (!dpi->encoder.bridge)
+       if (!dpi->bridge)
                return -EPROBE_DEFER;
 
        comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DPI);
index 2c42f90809d8843aadf1df26968374ddf754cdf2..dd71cbb1a62201908c6a76694fe5594c77bae0ae 100644 (file)
@@ -622,26 +622,6 @@ static const struct drm_connector_helper_funcs
        .get_modes = mtk_dsi_connector_get_modes,
 };
 
-static int mtk_drm_attach_bridge(struct drm_bridge *bridge,
-                                struct drm_encoder *encoder)
-{
-       int ret;
-
-       if (!bridge)
-               return -ENOENT;
-
-       encoder->bridge = bridge;
-       bridge->encoder = encoder;
-       ret = drm_bridge_attach(encoder->dev, bridge);
-       if (ret) {
-               DRM_ERROR("Failed to attach bridge to drm\n");
-               encoder->bridge = NULL;
-               bridge->encoder = NULL;
-       }
-
-       return ret;
-}
-
 static int mtk_dsi_create_connector(struct drm_device *drm, struct mtk_dsi *dsi)
 {
        int ret;
@@ -692,8 +672,10 @@ static int mtk_dsi_create_conn_enc(struct drm_device *drm, struct mtk_dsi *dsi)
        dsi->encoder.possible_crtcs = 1;
 
        /* If there's a bridge, attach to it and let it create the connector */
-       ret = mtk_drm_attach_bridge(dsi->bridge, &dsi->encoder);
+       ret = drm_bridge_attach(&dsi->encoder, dsi->bridge, NULL);
        if (ret) {
+               DRM_ERROR("Failed to attach bridge to drm\n");
+
                /* Otherwise create our own connector and attach to a panel */
                ret = mtk_dsi_create_connector(drm, dsi);
                if (ret)
index 0e8c4d9af34069f55e8784d8e43b6e4e56251cfa..c26251260b83363352a0d460f55b2cd62989b8c8 100644 (file)
@@ -149,6 +149,7 @@ struct hdmi_audio_param {
 
 struct mtk_hdmi {
        struct drm_bridge bridge;
+       struct drm_bridge *next_bridge;
        struct drm_connector conn;
        struct device *dev;
        struct phy *phy;
@@ -1314,9 +1315,9 @@ static int mtk_hdmi_bridge_attach(struct drm_bridge *bridge)
                return ret;
        }
 
-       if (bridge->next) {
-               bridge->next->encoder = bridge->encoder;
-               ret = drm_bridge_attach(bridge->encoder->dev, bridge->next);
+       if (hdmi->next_bridge) {
+               ret = drm_bridge_attach(bridge->encoder, hdmi->next_bridge,
+                                       bridge);
                if (ret) {
                        dev_err(hdmi->dev,
                                "Failed to attach external bridge: %d\n", ret);
@@ -1510,8 +1511,8 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
        of_node_put(ep);
 
        if (!of_device_is_compatible(remote, "hdmi-connector")) {
-               hdmi->bridge.next = of_drm_find_bridge(remote);
-               if (!hdmi->bridge.next) {
+               hdmi->next_bridge = of_drm_find_bridge(remote);
+               if (!hdmi->next_bridge) {
                        dev_err(dev, "Waiting for external bridge\n");
                        of_node_put(remote);
                        return -EPROBE_DEFER;
index c8d1f19c9a6d92c7a5ee9f642abec21dfdda20a0..2bd8dad761056ccec772883a0089fb4ef081c0a8 100644 (file)
@@ -579,6 +579,7 @@ struct drm_bridge *msm_dsi_manager_bridge_init(u8 id)
        struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
        struct drm_bridge *bridge = NULL;
        struct dsi_bridge *dsi_bridge;
+       struct drm_encoder *encoder;
        int ret;
 
        dsi_bridge = devm_kzalloc(msm_dsi->dev->dev,
@@ -590,10 +591,18 @@ struct drm_bridge *msm_dsi_manager_bridge_init(u8 id)
 
        dsi_bridge->id = id;
 
+       /*
+        * HACK: we may not know the external DSI bridge device's mode
+        * flags here. We'll get to know them only when the device
+        * attaches to the dsi host. For now, assume the bridge supports
+        * DSI video mode
+        */
+       encoder = msm_dsi->encoders[MSM_DSI_VIDEO_ENCODER_ID];
+
        bridge = &dsi_bridge->base;
        bridge->funcs = &dsi_mgr_bridge_funcs;
 
-       ret = drm_bridge_attach(msm_dsi->dev, bridge);
+       ret = drm_bridge_attach(encoder, bridge, NULL);
        if (ret)
                goto fail;
 
@@ -628,11 +637,7 @@ struct drm_connector *msm_dsi_manager_ext_bridge_init(u8 id)
        encoder = msm_dsi->encoders[MSM_DSI_VIDEO_ENCODER_ID];
 
        /* link the internal dsi bridge to the external bridge */
-       int_bridge->next = ext_bridge;
-       /* set the external bridge's encoder as dsi's encoder */
-       ext_bridge->encoder = encoder;
-
-       drm_bridge_attach(dev, ext_bridge);
+       drm_bridge_attach(encoder, ext_bridge, int_bridge);
 
        /*
         * we need the drm_connector created by the external bridge
index 2bc73f82f3f50e00124cbec05908a879850ac29b..931a5c97cccf6fc65066b4bf77a67a6e274cecaa 100644 (file)
@@ -106,7 +106,7 @@ struct drm_bridge *msm_edp_bridge_init(struct msm_edp *edp)
        bridge = &edp_bridge->base;
        bridge->funcs = &edp_bridge_funcs;
 
-       ret = drm_bridge_attach(edp->dev, bridge);
+       ret = drm_bridge_attach(edp->encoder, bridge, NULL);
        if (ret)
                goto fail;
 
index bacbd5d8df0ec21fe2000a6d1735e84a63e7329d..4e6d1bf27474dbe027cde9b9b3151995a39d9da3 100644 (file)
@@ -227,7 +227,7 @@ struct drm_bridge *msm_hdmi_bridge_init(struct hdmi *hdmi)
        bridge = &hdmi_bridge->base;
        bridge->funcs = &msm_hdmi_bridge_funcs;
 
-       ret = drm_bridge_attach(hdmi->dev, bridge);
+       ret = drm_bridge_attach(hdmi->encoder, bridge, NULL);
        if (ret)
                goto fail;
 
index f9515f53cc5b79635112e6bc2188df4415bc2b7b..c4c5d1abcff81e682df0bcd559f64343954599f7 100644 (file)
@@ -124,10 +124,7 @@ int rcar_du_hdmienc_init(struct rcar_du_device *rcdu,
        hdmienc->renc = renc;
 
        /* Link the bridge to the encoder. */
-       bridge->encoder = encoder;
-       encoder->bridge = bridge;
-
-       ret = drm_bridge_attach(rcdu->ddev, bridge);
+       ret = drm_bridge_attach(encoder, bridge, NULL);
        if (ret) {
                drm_encoder_cleanup(encoder);
                return ret;
index e8c1ed08a9f7eea0726347082a8f35c9e21c762e..411dc6ec976ecce8d45d79307a4f12c146a2fdfa 100644 (file)
@@ -478,14 +478,13 @@ static int sti_dvo_bind(struct device *dev, struct device *master, void *data)
                return err;
        }
 
-       err = drm_bridge_attach(drm_dev, bridge);
+       err = drm_bridge_attach(encoder, bridge, NULL);
        if (err) {
                DRM_ERROR("Failed to attach bridge\n");
                return err;
        }
 
        dvo->bridge = bridge;
-       encoder->bridge = bridge;
        connector->encoder = encoder;
        dvo->encoder = encoder;
 
index 96f336dd0e29642d6b90ed93b1e2958e6a472c0f..66d37d78152a48648f0f7fec5c4ce04867379e08 100644 (file)
@@ -707,9 +707,8 @@ static int sti_hda_bind(struct device *dev, struct device *master, void *data)
 
        bridge->driver_private = hda;
        bridge->funcs = &sti_hda_bridge_funcs;
-       drm_bridge_attach(drm_dev, bridge);
+       drm_bridge_attach(encoder, bridge, NULL);
 
-       encoder->bridge = bridge;
        connector->encoder = encoder;
 
        drm_connector = (struct drm_connector *)connector;
index 376b0763c874aaebb88d4bc90927470d20809ed9..f0af1ae82ee92e405d9c41a88940fef93607754c 100644 (file)
@@ -1308,9 +1308,8 @@ static int sti_hdmi_bind(struct device *dev, struct device *master, void *data)
 
        bridge->driver_private = hdmi;
        bridge->funcs = &sti_hdmi_bridge_funcs;
-       drm_bridge_attach(drm_dev, bridge);
+       drm_bridge_attach(encoder, bridge, NULL);
 
-       encoder->bridge = bridge;
        connector->encoder = encoder;
 
        drm_connector = (struct drm_connector *)connector;
index f5e86fe7750eee87b2e2a72cf9171cbb789572ee..757208f5173115a553653b2f93f4c1de116cca7f 100644 (file)
@@ -208,6 +208,7 @@ int sun4i_rgb_init(struct drm_device *drm)
        struct sun4i_drv *drv = drm->dev_private;
        struct sun4i_tcon *tcon = drv->tcon;
        struct drm_encoder *encoder;
+       struct drm_bridge *bridge;
        struct sun4i_rgb *rgb;
        int ret;
 
@@ -218,8 +219,8 @@ int sun4i_rgb_init(struct drm_device *drm)
        encoder = &rgb->encoder;
 
        tcon->panel = sun4i_tcon_find_panel(tcon->dev->of_node);
-       encoder->bridge = sun4i_tcon_find_bridge(tcon->dev->of_node);
-       if (IS_ERR(tcon->panel) && IS_ERR(encoder->bridge)) {
+       bridge = sun4i_tcon_find_bridge(tcon->dev->of_node);
+       if (IS_ERR(tcon->panel) && IS_ERR(bridge)) {
                dev_info(drm->dev, "No panel or bridge found... RGB output disabled\n");
                return 0;
        }
@@ -260,16 +261,12 @@ int sun4i_rgb_init(struct drm_device *drm)
                }
        }
 
-       if (!IS_ERR(encoder->bridge)) {
-               encoder->bridge->encoder = &rgb->encoder;
-
-               ret = drm_bridge_attach(drm, encoder->bridge);
+       if (!IS_ERR(bridge)) {
+               ret = drm_bridge_attach(encoder, bridge, NULL);
                if (ret) {
                        dev_err(drm->dev, "Couldn't attach our bridge\n");
                        goto err_cleanup_connector;
                }
-       } else {
-               encoder->bridge = NULL;
        }
 
        return 0;
index c67d7cd7d57e30870c76df04b90f35edd72a5eab..b0dd5e8634ae896f6a9f72a273917ef2c4535709 100644 (file)
@@ -167,10 +167,8 @@ int tilcdc_attach_bridge(struct drm_device *ddev, struct drm_bridge *bridge)
        int ret;
 
        priv->external_encoder->possible_crtcs = BIT(0);
-       priv->external_encoder->bridge = bridge;
-       bridge->encoder = priv->external_encoder;
 
-       ret = drm_bridge_attach(ddev, bridge);
+       ret = drm_bridge_attach(priv->external_encoder, bridge, NULL);
        if (ret) {
                dev_err(ddev->dev, "drm_bridge_attach() failed %d\n", ret);
                return ret;
index 530a1d6e8cdee50dc04be3026059b44c8a0bb904..94e5ee96b3b5acf82388a0ac5f1a6fadcc799aad 100644 (file)
@@ -201,7 +201,8 @@ struct drm_bridge {
 int drm_bridge_add(struct drm_bridge *bridge);
 void drm_bridge_remove(struct drm_bridge *bridge);
 struct drm_bridge *of_drm_find_bridge(struct device_node *np);
-int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge);
+int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge,
+                     struct drm_bridge *previous);
 void drm_bridge_detach(struct drm_bridge *bridge);
 
 bool drm_bridge_mode_fixup(struct drm_bridge *bridge,