On 11/29/2016 10:04 AM, Laurent Pinchart wrote:
> 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+rene...@ideasonboard.com>
> ---
>  drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c   |  4 +-
>  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c |  4 +-
>  drivers/gpu/drm/bridge/dw-hdmi.c                   |  3 +-
>  drivers/gpu/drm/drm_bridge.c                       | 46 
> ++++++++++++++++------
>  drivers/gpu/drm/drm_simple_kms_helper.c            |  4 +-
>  drivers/gpu/drm/exynos/exynos_dp.c                 |  5 +--
>  drivers/gpu/drm/exynos/exynos_drm_dsi.c            |  6 +--
>  drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c          |  5 +--
>  drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c       |  5 +--
>  drivers/gpu/drm/imx/imx-ldb.c                      |  6 +--
>  drivers/gpu/drm/imx/parallel-display.c             |  4 +-
>  drivers/gpu/drm/mediatek/mtk_dpi.c                 |  8 ++--
>  drivers/gpu/drm/mediatek/mtk_dsi.c                 | 24 ++---------
>  drivers/gpu/drm/mediatek/mtk_hdmi.c                | 11 +++---
>  drivers/gpu/drm/msm/dsi/dsi_manager.c              | 17 +++++---
>  drivers/gpu/drm/msm/edp/edp_bridge.c               |  2 +-
>  drivers/gpu/drm/msm/hdmi/hdmi_bridge.c             |  2 +-
>  drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c          |  5 +--
>  drivers/gpu/drm/sti/sti_dvo.c                      |  3 +-
>  drivers/gpu/drm/sti/sti_hda.c                      |  3 +-
>  drivers/gpu/drm/sti/sti_hdmi.c                     |  3 +-

Hi Laurent,

For sti dvo, hda and hdmi:
Acked-by: Vincent Abriou <vincent.abr...@st.com>

Vincent

>  drivers/gpu/drm/sun4i/sun4i_rgb.c                  | 13 +++---
>  include/drm/drm_bridge.h                           |  3 +-
>  23 files changed, 83 insertions(+), 103 deletions(-)
>
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c 
> b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c
> index 6119b5085501..e7799b6ee829 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c
> @@ -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;
>         }
> diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
> b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
> index 6e0447f329a2..1835f1fdad19 100644
> --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
> +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
> @@ -1227,12 +1227,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;
> diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c 
> b/drivers/gpu/drm/bridge/dw-hdmi.c
> index b71088dab268..432e0e3fff72 100644
> --- a/drivers/gpu/drm/bridge/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/dw-hdmi.c
> @@ -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,
> diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
> index 0ee052b7c21a..850bd6509ef1 100644
> --- a/drivers/gpu/drm/drm_bridge.c
> +++ b/drivers/gpu/drm/drm_bridge.c
> @@ -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;
>  }
> diff --git a/drivers/gpu/drm/drm_simple_kms_helper.c 
> b/drivers/gpu/drm/drm_simple_kms_helper.c
> index 7bae08c2bf0a..ba7be6169339 100644
> --- a/drivers/gpu/drm/drm_simple_kms_helper.c
> +++ b/drivers/gpu/drm/drm_simple_kms_helper.c
> @@ -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);
>
> diff --git a/drivers/gpu/drm/exynos/exynos_dp.c 
> b/drivers/gpu/drm/exynos/exynos_dp.c
> index 528229faffe4..1ef0be338b85 100644
> --- a/drivers/gpu/drm/exynos/exynos_dp.c
> +++ b/drivers/gpu/drm/exynos/exynos_dp.c
> @@ -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;
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
> b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> index e07cb1fe4860..812e2ec0761d 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> @@ -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);
>  }
> diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c 
> b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
> index e1dd75b18118..3ad76423c60d 100644
> --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
> +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
> @@ -167,10 +167,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)
> diff --git a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c 
> b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c
> index 998452ad0fcb..1737e98bc10a 100644
> --- a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c
> +++ b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c
> @@ -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;
> diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
> index b300998dce7d..2fcb579f5489 100644
> --- a/drivers/gpu/drm/imx/imx-ldb.c
> +++ b/drivers/gpu/drm/imx/imx-ldb.c
> @@ -461,10 +461,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;
> diff --git a/drivers/gpu/drm/imx/parallel-display.c 
> b/drivers/gpu/drm/imx/parallel-display.c
> index d796ada2a47a..2d80c769f56b 100644
> --- a/drivers/gpu/drm/imx/parallel-display.c
> +++ b/drivers/gpu/drm/imx/parallel-display.c
> @@ -198,9 +198,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);
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c 
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 0186e500d2a5..3cced1c522fd 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -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;
> @@ -615,8 +616,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;
> @@ -713,9 +713,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);
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index 28b2044ed9f2..2ac0f1abba86 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -597,26 +597,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;
> @@ -667,8 +647,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)
> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c 
> b/drivers/gpu/drm/mediatek/mtk_hdmi.c
> index 71227deef21b..5ca1b0fbf937 100644
> --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
> @@ -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;
> @@ -1320,9 +1321,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);
> @@ -1505,8 +1506,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;
> diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c 
> b/drivers/gpu/drm/msm/dsi/dsi_manager.c
> index c8d1f19c9a6d..2bd8dad76105 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
> +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
> @@ -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
> diff --git a/drivers/gpu/drm/msm/edp/edp_bridge.c 
> b/drivers/gpu/drm/msm/edp/edp_bridge.c
> index 2bc73f82f3f5..931a5c97cccf 100644
> --- a/drivers/gpu/drm/msm/edp/edp_bridge.c
> +++ b/drivers/gpu/drm/msm/edp/edp_bridge.c
> @@ -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;
>
> diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c 
> b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
> index bacbd5d8df0e..4e6d1bf27474 100644
> --- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
> +++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
> @@ -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;
>
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c 
> b/drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c
> index a1a2c5e7822c..933a2547798e 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c
> @@ -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;
> diff --git a/drivers/gpu/drm/sti/sti_dvo.c b/drivers/gpu/drm/sti/sti_dvo.c
> index e8c1ed08a9f7..411dc6ec976e 100644
> --- a/drivers/gpu/drm/sti/sti_dvo.c
> +++ b/drivers/gpu/drm/sti/sti_dvo.c
> @@ -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;
>
> diff --git a/drivers/gpu/drm/sti/sti_hda.c b/drivers/gpu/drm/sti/sti_hda.c
> index e7c243f70870..5b1855e44f87 100644
> --- a/drivers/gpu/drm/sti/sti_hda.c
> +++ b/drivers/gpu/drm/sti/sti_hda.c
> @@ -714,9 +714,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;
> diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
> index 376b0763c874..f0af1ae82ee9 100644
> --- a/drivers/gpu/drm/sti/sti_hdmi.c
> +++ b/drivers/gpu/drm/sti/sti_hdmi.c
> @@ -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;
> diff --git a/drivers/gpu/drm/sun4i/sun4i_rgb.c 
> b/drivers/gpu/drm/sun4i/sun4i_rgb.c
> index c3ff10f559cc..ce071c17134b 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_rgb.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_rgb.c
> @@ -219,6 +219,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;
>
> @@ -229,8 +230,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;
>         }
> @@ -271,16 +272,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;
> diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
> index 530a1d6e8cde..94e5ee96b3b5 100644
> --- a/include/drm/drm_bridge.h
> +++ b/include/drm/drm_bridge.h
> @@ -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,
> --
> Regards,
>
> Laurent Pinchart
>

Reply via email to