Hi Neil,

Sorry for the late reply.

On Tue, 5 Nov 2019 17:02:30 +0100
Neil Armstrong <narmstr...@baylibre.com> wrote:

> Hi,
> 
> 
> On 25/10/2019 15:29, Neil Armstrong wrote:
> > On 23/10/2019 17:44, Boris Brezillon wrote:  
> >> So that each element in the chain can easily access its predecessor.
> >> This will be needed to support bus format negotiation between elements
> >> of the bridge chain.
> >>
> >> Signed-off-by: Boris Brezillon <boris.brezil...@collabora.com>
> >> ---
> >> Changes in v3:
> >> * None
> >>
> >> Changes in v2:
> >> * Adjust things to the "dummy encoder bridge" change (patch 2 in this
> >>   series)
> >> ---
> >>  drivers/gpu/drm/drm_bridge.c  | 171 ++++++++++++++++++++++------------
> >>  drivers/gpu/drm/drm_encoder.c |  16 +---
> >>  include/drm/drm_bridge.h      |  12 ++-
> >>  include/drm/drm_encoder.h     |   9 +-
> >>  4 files changed, 135 insertions(+), 73 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
> >> index 54c874493c57..c5cf8a9c4237 100644
> >> --- a/drivers/gpu/drm/drm_bridge.c
> >> +++ b/drivers/gpu/drm/drm_bridge.c  
> 
> [...]
> 
> >>  
> >> @@ -426,15 +471,23 @@ EXPORT_SYMBOL(drm_atomic_bridge_chain_post_disable);
> >>  void drm_atomic_bridge_chain_pre_enable(struct drm_bridge *bridge,
> >>                                    struct drm_atomic_state *state)
> >>  {
> >> +  struct drm_encoder *encoder;
> >> +  struct drm_bridge *iter;
> >> +
> >>    if (!bridge)
> >>            return;
> >>  
> >> -  drm_atomic_bridge_chain_pre_enable(bridge->next, state);
> >> +  encoder = bridge->encoder;
> >> +  list_for_each_entry_reverse(iter, &bridge->encoder->bridge_chain,
> >> +                              chain_node) {  
> 
> This should use the encoder local variable in list_for_each_entry_reverse()
> 
> >> +          if (iter->funcs->atomic_pre_enable)
> >> +                  iter->funcs->atomic_pre_enable(iter, state);
> >> +          else if (iter->funcs->pre_enable)
> >> +                  iter->funcs->pre_enable(iter);
> >>  
> >> -  if (bridge->funcs->atomic_pre_enable)
> >> -          bridge->funcs->atomic_pre_enable(bridge, state);
> >> -  else if (bridge->funcs->pre_enable)
> >> -          bridge->funcs->pre_enable(bridge);
> >> +          if (iter == bridge)
> >> +                  break;
> >> +  }
> >>  }
> >>  EXPORT_SYMBOL(drm_atomic_bridge_chain_pre_enable);
> >>  
> >> @@ -453,15 +506,19 @@ EXPORT_SYMBOL(drm_atomic_bridge_chain_pre_enable);
> >>  void drm_atomic_bridge_chain_enable(struct drm_bridge *bridge,
> >>                                struct drm_atomic_state *state)
> >>  {
> >> +  struct drm_encoder *encoder;
> >> +
> >>    if (!bridge)
> >>            return;
> >>  
> >> -  if (bridge->funcs->atomic_enable)
> >> -          bridge->funcs->atomic_enable(bridge, state);
> >> -  else if (bridge->funcs->enable)
> >> -          bridge->funcs->enable(bridge);
> >> -
> >> -  drm_atomic_bridge_chain_enable(bridge->next, state);
> >> +  encoder = bridge->encoder;
> >> +  list_for_each_entry_from(bridge, &bridge->encoder->bridge_chain,
> >> +                           chain_node) {  
> 
> This should use encoder instead of bridge->encoder otherwise bridge will
> change and bridge->encoder->bridge_chain won't be valid during the for_each 
> and
> cause the following :

Oops, indeed. I fixed the very same problem in another helper but
somehow missed those 2. Thanks for testing/reporting the bug.

Boris
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to