[PATCH v3 07/21] drm/bridge: Make the bridge chain a double-linked list
Boris Brezillon
boris.brezillon at collabora.com
Sun Nov 24 07:48:48 UTC 2019
Hi Neil,
Sorry for the late reply.
On Tue, 5 Nov 2019 17:02:30 +0100
Neil Armstrong <narmstrong at 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.brezillon at 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
More information about the dri-devel
mailing list