[v2,8/8] drm: bridge: anx7625: Switch to devm_drm_of_get_bridge

Message ID 20220301141247.126911-8-jagan@amarulasolutions.com
State New
Headers show
Series
  • [v2,1/8] Revert "drm/bridge: dw-mipi-dsi: Find the possible DSI devices"
Related show

Commit Message

Jagan Teki March 1, 2022, 2:12 p.m. UTC
devm_drm_of_get_bridge is capable of looking up the downstream
bridge and panel and trying to add a panel bridge if the panel
is found.

Replace explicit finding calls with devm_drm_of_get_bridge.

Cc: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
---
Changes for v2:
- split the patch

 drivers/gpu/drm/mcde/mcde_dsi.c | 39 +++++----------------------------
 1 file changed, 5 insertions(+), 34 deletions(-)

Comments

Linus Walleij March 1, 2022, 11:12 p.m. UTC | #1
On Tue, Mar 1, 2022 at 3:13 PM Jagan Teki <jagan@amarulasolutions.com> wrote:

> devm_drm_of_get_bridge is capable of looking up the downstream
> bridge and panel and trying to add a panel bridge if the panel
> is found.
>
> Replace explicit finding calls with devm_drm_of_get_bridge.
>
> Cc: Linus Walleij <linus.walleij@linaro.org>
> Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
> ---
> Changes for v2:
> - split the patch

This will be nice code reduction when it works!

> -       struct drm_panel *panel = NULL;
> -       struct drm_bridge *bridge = NULL;
> +       struct drm_bridge *bridge;

OK... and then you delete the code that uses panel. But:

static void mcde_dsi_unbind(struct device *dev, struct device *master,
                            void *data)
{
        struct mcde_dsi *d = dev_get_drvdata(dev);

        if (d->panel)
                drm_panel_bridge_remove(d->bridge_out);
        regmap_update_bits(d->prcmu, PRCM_DSI_SW_RESET,
                           PRCM_DSI_SW_RESET_DSI0_SW_RESETN, 0);
}

So this will not even compile.

I suppose you have a solution for removing the panel bridge automatically
as well?

Yours,
Linus Walleij
Linus Walleij March 1, 2022, 11:20 p.m. UTC | #2
On Tue, Mar 1, 2022 at 3:13 PM Jagan Teki <jagan@amarulasolutions.com> wrote:

> +       bridge = devm_drm_of_get_bridge(dev, dev->of_node, 0, 0);
> +       if (IS_ERR(bridge)) {
> +               dev_err(dev, "error to get bridge\n");
> +               return PTR_ERR(bridge);
>         }
>
>         d->bridge_out = bridge;

Also notice how this bridge gets used in other places:

struct drm_connector *connector = drm_panel_bridge_connector(mcde->bridge);

Since you deleted:

-       } else if (bridge) {
-               /* TODO: AV8100 HDMI encoder goes here for example */
-               dev_info(dev, "connected to non-panel bridge (unsupported)\n");
-               return -ENODEV;

This will now have "interesting" effects. I think.

I don't know if there is a way to solve this though?

Yours,
Linus Walleij
Jagan Teki March 2, 2022, 4:23 a.m. UTC | #3
On Wed, Mar 2, 2022 at 4:43 AM Linus Walleij <linus.walleij@linaro.org> wrote:
>
> On Tue, Mar 1, 2022 at 3:13 PM Jagan Teki <jagan@amarulasolutions.com> wrote:
>
> > devm_drm_of_get_bridge is capable of looking up the downstream
> > bridge and panel and trying to add a panel bridge if the panel
> > is found.
> >
> > Replace explicit finding calls with devm_drm_of_get_bridge.
> >
> > Cc: Linus Walleij <linus.walleij@linaro.org>
> > Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
> > ---
> > Changes for v2:
> > - split the patch
>
> This will be nice code reduction when it works!
>
> > -       struct drm_panel *panel = NULL;
> > -       struct drm_bridge *bridge = NULL;
> > +       struct drm_bridge *bridge;
>
> OK... and then you delete the code that uses panel. But:
>
> static void mcde_dsi_unbind(struct device *dev, struct device *master,
>                             void *data)
> {
>         struct mcde_dsi *d = dev_get_drvdata(dev);
>
>         if (d->panel)
>                 drm_panel_bridge_remove(d->bridge_out);

I think using drm_bridge_remove(d->bridge_out); will directly remove
the bridge whether it is the next bridge or panel bridge as bridge_out
is already found the relevant downstream.

Jagan.
Jagan Teki March 2, 2022, 4:37 a.m. UTC | #4
On Wed, Mar 2, 2022 at 4:50 AM Linus Walleij <linus.walleij@linaro.org> wrote:
>
> On Tue, Mar 1, 2022 at 3:13 PM Jagan Teki <jagan@amarulasolutions.com> wrote:
>
> > +       bridge = devm_drm_of_get_bridge(dev, dev->of_node, 0, 0);
> > +       if (IS_ERR(bridge)) {
> > +               dev_err(dev, "error to get bridge\n");
> > +               return PTR_ERR(bridge);
> >         }
> >
> >         d->bridge_out = bridge;
>
> Also notice how this bridge gets used in other places:
>
> struct drm_connector *connector = drm_panel_bridge_connector(mcde->bridge);

mcde->bridge bridge is the current bridge pointer it cannot affect
this change. d->bridge_out is what we are finding of the downstream
bridge.

>
> Since you deleted:
>
> -       } else if (bridge) {
> -               /* TODO: AV8100 HDMI encoder goes here for example */
> -               dev_info(dev, "connected to non-panel bridge (unsupported)\n");
> -               return -ENODEV;

So, this means mcde dsi can support if the downstream bridge is the
panel not if the downstream bridge is the next bridge. With
devm_drm_of_get_bridge we cannot find that diff. Identifying the
panel-bridge with some name pointer during panel_bridge_add might
solve this, not sure that is proper way to do that?

Thanks,
Jagan.
Linus Walleij March 2, 2022, 11:57 a.m. UTC | #5
On Wed, Mar 2, 2022 at 5:37 AM Jagan Teki <jagan@amarulasolutions.com> wrote:
> On Wed, Mar 2, 2022 at 4:50 AM Linus Walleij <linus.walleij@linaro.org> wrote:
> >
> > On Tue, Mar 1, 2022 at 3:13 PM Jagan Teki <jagan@amarulasolutions.com> wrote:
> >
> > > +       bridge = devm_drm_of_get_bridge(dev, dev->of_node, 0, 0);
> > > +       if (IS_ERR(bridge)) {
> > > +               dev_err(dev, "error to get bridge\n");
> > > +               return PTR_ERR(bridge);
> > >         }
> > >
> > >         d->bridge_out = bridge;
> >
> > Also notice how this bridge gets used in other places:
> >
> > struct drm_connector *connector = drm_panel_bridge_connector(mcde->bridge);
>
> mcde->bridge bridge is the current bridge pointer it cannot affect
> this change. d->bridge_out is what we are finding of the downstream
> bridge.

Sorry I confused things.

Got lost in my own code :/

The bridge in the other file is for DPI obviously...
I should rename it dpi_panel_bridge.

> > Since you deleted:
> >
> > -       } else if (bridge) {
> > -               /* TODO: AV8100 HDMI encoder goes here for example */
> > -               dev_info(dev, "connected to non-panel bridge (unsupported)\n");
> > -               return -ENODEV;
>
> So, this means mcde dsi can support if the downstream bridge is the
> panel not if the downstream bridge is the next bridge. With
> devm_drm_of_get_bridge we cannot find that diff. Identifying the
> panel-bridge with some name pointer during panel_bridge_add might
> solve this, not sure that is proper way to do that?

I'd say leave it, as the DSI bridge (bridge_out) doesn't really care
about this being a panel or not. A further bridge down the chain
should "just work" (famous last words).

Just make sure we properly remove bridge_out in unbind call.

Yours,
Linus Walleij

Patch

diff --git a/drivers/gpu/drm/mcde/mcde_dsi.c b/drivers/gpu/drm/mcde/mcde_dsi.c
index 5651734ce977..9371349b8b25 100644
--- a/drivers/gpu/drm/mcde/mcde_dsi.c
+++ b/drivers/gpu/drm/mcde/mcde_dsi.c
@@ -1073,9 +1073,7 @@  static int mcde_dsi_bind(struct device *dev, struct device *master,
 	struct drm_device *drm = data;
 	struct mcde *mcde = to_mcde(drm);
 	struct mcde_dsi *d = dev_get_drvdata(dev);
-	struct device_node *child;
-	struct drm_panel *panel = NULL;
-	struct drm_bridge *bridge = NULL;
+	struct drm_bridge *bridge;
 
 	if (!of_get_available_child_count(dev->of_node)) {
 		dev_info(dev, "unused DSI interface\n");
@@ -1100,37 +1098,10 @@  static int mcde_dsi_bind(struct device *dev, struct device *master,
 		return PTR_ERR(d->lp_clk);
 	}
 
-	/* Look for a panel as a child to this node */
-	for_each_available_child_of_node(dev->of_node, child) {
-		panel = of_drm_find_panel(child);
-		if (IS_ERR(panel)) {
-			dev_err(dev, "failed to find panel try bridge (%ld)\n",
-				PTR_ERR(panel));
-			panel = NULL;
-
-			bridge = of_drm_find_bridge(child);
-			if (!bridge) {
-				dev_err(dev, "failed to find bridge\n");
-				return -EINVAL;
-			}
-		}
-	}
-	if (panel) {
-		bridge = drm_panel_bridge_add_typed(panel,
-						    DRM_MODE_CONNECTOR_DSI);
-		if (IS_ERR(bridge)) {
-			dev_err(dev, "error adding panel bridge\n");
-			return PTR_ERR(bridge);
-		}
-		dev_info(dev, "connected to panel\n");
-		d->panel = panel;
-	} else if (bridge) {
-		/* TODO: AV8100 HDMI encoder goes here for example */
-		dev_info(dev, "connected to non-panel bridge (unsupported)\n");
-		return -ENODEV;
-	} else {
-		dev_err(dev, "no panel or bridge\n");
-		return -ENODEV;
+	bridge = devm_drm_of_get_bridge(dev, dev->of_node, 0, 0);
+	if (IS_ERR(bridge)) {
+		dev_err(dev, "error to get bridge\n");
+		return PTR_ERR(bridge);
 	}
 
 	d->bridge_out = bridge;