All of lore.kernel.org
 help / color / mirror / Atom feed
From: AngeloGioacchino Del Regno  <angelogioacchino.delregno@collabora.com>
To: Chun-Kuang Hu <chunkuang.hu@kernel.org>
Cc: DRI Development <dri-devel@lists.freedesktop.org>,
	David Airlie <airlied@linux.ie>,
	linux-kernel <linux-kernel@vger.kernel.org>,
	andrzej.hajda@intel.com,
	"moderated list:ARM/Mediatek SoC support" 
	<linux-mediatek@lists.infradead.org>,
	Jagan Teki <jagan@amarulasolutions.com>,
	Matthias Brugger <matthias.bgg@gmail.com>,
	Collabora Kernel ML <kernel@collabora.com>,
	Linux ARM <linux-arm-kernel@lists.infradead.org>
Subject: Re: [PATCH v3] drm/mediatek: mtk_dsi: Avoid EPROBE_DEFER loop with external bridge
Date: Thu, 27 Jan 2022 16:46:19 +0100	[thread overview]
Message-ID: <b8911eab-1419-60ad-ef07-25a5de365a52@collabora.com> (raw)
In-Reply-To: <CAAOTY__yO6Cq8qt8RSh9AX68mJEv+wWvuhY0_p-PTJ=eJD_7aA@mail.gmail.com>

Il 27/01/22 16:21, Chun-Kuang Hu ha scritto:
> Hi, Angelo:
> 
> AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> 於
> 2022年1月27日 週四 下午10:36寫道:
>>
>> DRM bridge drivers are now attaching their DSI device at probe time,
>> which requires us to register our DSI host in order to let the bridge
>> to probe: this recently started producing an endless -EPROBE_DEFER
>> loop on some machines that are using external bridges, like the
>> parade-ps8640, found on the ACER Chromebook R13.
>>
>> Now that the DSI hosts/devices probe sequence is documented, we can
>> do adjustments to the mtk_dsi driver as to both fix now and make sure
>> to avoid this situation in the future: for this, following what is
>> documented in drm_bridge.c, move the mtk_dsi component_add() to the
>> mtk_dsi_ops.attach callback and delete it in the detach callback;
>> keeping in mind that we are registering a drm_bridge for our DSI,
>> which is only used/attached if the DSI Host is bound, it wouldn't
>> make sense to keep adding our bridge at probe time (as it would
>> be useless to have it if mtk_dsi_ops.attach() fails!), so also move
>> that one to the dsi host attach function (and remove it in detach).
>>
>> Fixes: 209264a85707 ("drm/bridge: Document the probe issue with MIPI-DSI bridges")
> 
> The fixed tag should indicate the patch which cause the bug, but why a
> patch just adding document would cause bug?
> So no any patch cause bug? This patch just want to prevent a possible bug?
> 

I think you've missed my previous message on v2, so I will paste it here:

unfortunately I couldn't find a valid commit for a Fixes tag. This
started being an issue at some point, when the DRM was changed to
adhere to the documented probe sequence: the MediaTek DSI driver was
not the only one that got broken/affected by these changes.

If you have any advice on which commit should be tagged, I'm open for
any kind of suggestion.


I tried to check on other drivers which got fixed for the same behavior,
for example drm/msm, but none of them had a Fixes tag.
When the DRM got changed to adhere to this sequence, some drm/bridge
drivers were also changed; this has created some incompatibilities with
some drm drivers, including drm/msm and drm/mediatek.

This commit is not fixing a latent bug that was introduced in drm/mediatek
but rather one that was induced by the new, fixed, probe flow that got
recently documented - and to which drivers should adhere; failing to adhere
to that will produce an endless -EPROBE_DEFER loop, due to other drivers
(as mentioned, for example drm/bridge drivers) having been changed to use
that probe sequence.


Regards,
Angelo

> Regards,
> Chun-Kuang.
> 
>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
>> Reviewed-by: Andrzej Hajda <andrzej.hajda@intel.com>
>> Reviewed-by: Jagan Teki <jagan@amarulasolutions.com>
>>
>> ---
>>   drivers/gpu/drm/mediatek/mtk_dsi.c | 167 +++++++++++++++--------------
>>   1 file changed, 84 insertions(+), 83 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
>> index 5d90d2eb0019..bced4c7d668e 100644
>> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
>> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
>> @@ -786,18 +786,101 @@ void mtk_dsi_ddp_stop(struct device *dev)
>>          mtk_dsi_poweroff(dsi);
>>   }
>>
>> +static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
>> +{
>> +       int ret;
>> +
>> +       ret = drm_simple_encoder_init(drm, &dsi->encoder,
>> +                                     DRM_MODE_ENCODER_DSI);
>> +       if (ret) {
>> +               DRM_ERROR("Failed to encoder init to drm\n");
>> +               return ret;
>> +       }
>> +
>> +       dsi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm, dsi->host.dev);
>> +
>> +       ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
>> +                               DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>> +       if (ret)
>> +               goto err_cleanup_encoder;
>> +
>> +       dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder);
>> +       if (IS_ERR(dsi->connector)) {
>> +               DRM_ERROR("Unable to create bridge connector\n");
>> +               ret = PTR_ERR(dsi->connector);
>> +               goto err_cleanup_encoder;
>> +       }
>> +       drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
>> +
>> +       return 0;
>> +
>> +err_cleanup_encoder:
>> +       drm_encoder_cleanup(&dsi->encoder);
>> +       return ret;
>> +}
>> +
>> +static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
>> +{
>> +       int ret;
>> +       struct drm_device *drm = data;
>> +       struct mtk_dsi *dsi = dev_get_drvdata(dev);
>> +
>> +       ret = mtk_dsi_encoder_init(drm, dsi);
>> +       if (ret)
>> +               return ret;
>> +
>> +       return device_reset_optional(dev);
>> +}
>> +
>> +static void mtk_dsi_unbind(struct device *dev, struct device *master,
>> +                          void *data)
>> +{
>> +       struct mtk_dsi *dsi = dev_get_drvdata(dev);
>> +
>> +       drm_encoder_cleanup(&dsi->encoder);
>> +}
>> +
>> +static const struct component_ops mtk_dsi_component_ops = {
>> +       .bind = mtk_dsi_bind,
>> +       .unbind = mtk_dsi_unbind,
>> +};
>> +
>>   static int mtk_dsi_host_attach(struct mipi_dsi_host *host,
>>                                 struct mipi_dsi_device *device)
>>   {
>>          struct mtk_dsi *dsi = host_to_dsi(host);
>> +       struct device *dev = host->dev;
>> +       int ret;
>>
>>          dsi->lanes = device->lanes;
>>          dsi->format = device->format;
>>          dsi->mode_flags = device->mode_flags;
>> +       dsi->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 0, 0);
>> +       if (IS_ERR(dsi->next_bridge))
>> +               return PTR_ERR(dsi->next_bridge);
>> +
>> +       drm_bridge_add(&dsi->bridge);
>> +
>> +       ret = component_add(host->dev, &mtk_dsi_component_ops);
>> +       if (ret) {
>> +               DRM_ERROR("failed to add dsi_host component: %d\n", ret);
>> +               drm_bridge_remove(&dsi->bridge);
>> +               return ret;
>> +       }
>>
>>          return 0;
>>   }
>>
>> +static int mtk_dsi_host_detach(struct mipi_dsi_host *host,
>> +                              struct mipi_dsi_device *device)
>> +{
>> +       struct mtk_dsi *dsi = host_to_dsi(host);
>> +
>> +       component_del(host->dev, &mtk_dsi_component_ops);
>> +       drm_bridge_remove(&dsi->bridge);
>> +       return 0;
>> +}
>> +
>>   static void mtk_dsi_wait_for_idle(struct mtk_dsi *dsi)
>>   {
>>          int ret;
>> @@ -938,73 +1021,14 @@ static ssize_t mtk_dsi_host_transfer(struct mipi_dsi_host *host,
>>
>>   static const struct mipi_dsi_host_ops mtk_dsi_ops = {
>>          .attach = mtk_dsi_host_attach,
>> +       .detach = mtk_dsi_host_detach,
>>          .transfer = mtk_dsi_host_transfer,
>>   };
>>
>> -static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
>> -{
>> -       int ret;
>> -
>> -       ret = drm_simple_encoder_init(drm, &dsi->encoder,
>> -                                     DRM_MODE_ENCODER_DSI);
>> -       if (ret) {
>> -               DRM_ERROR("Failed to encoder init to drm\n");
>> -               return ret;
>> -       }
>> -
>> -       dsi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm, dsi->host.dev);
>> -
>> -       ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
>> -                               DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>> -       if (ret)
>> -               goto err_cleanup_encoder;
>> -
>> -       dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder);
>> -       if (IS_ERR(dsi->connector)) {
>> -               DRM_ERROR("Unable to create bridge connector\n");
>> -               ret = PTR_ERR(dsi->connector);
>> -               goto err_cleanup_encoder;
>> -       }
>> -       drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
>> -
>> -       return 0;
>> -
>> -err_cleanup_encoder:
>> -       drm_encoder_cleanup(&dsi->encoder);
>> -       return ret;
>> -}
>> -
>> -static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
>> -{
>> -       int ret;
>> -       struct drm_device *drm = data;
>> -       struct mtk_dsi *dsi = dev_get_drvdata(dev);
>> -
>> -       ret = mtk_dsi_encoder_init(drm, dsi);
>> -       if (ret)
>> -               return ret;
>> -
>> -       return device_reset_optional(dev);
>> -}
>> -
>> -static void mtk_dsi_unbind(struct device *dev, struct device *master,
>> -                          void *data)
>> -{
>> -       struct mtk_dsi *dsi = dev_get_drvdata(dev);
>> -
>> -       drm_encoder_cleanup(&dsi->encoder);
>> -}
>> -
>> -static const struct component_ops mtk_dsi_component_ops = {
>> -       .bind = mtk_dsi_bind,
>> -       .unbind = mtk_dsi_unbind,
>> -};
>> -
>>   static int mtk_dsi_probe(struct platform_device *pdev)
>>   {
>>          struct mtk_dsi *dsi;
>>          struct device *dev = &pdev->dev;
>> -       struct drm_panel *panel;
>>          struct resource *regs;
>>          int irq_num;
>>          int ret;
>> @@ -1021,19 +1045,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
>>                  return ret;
>>          }
>>
>> -       ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
>> -                                         &panel, &dsi->next_bridge);
>> -       if (ret)
>> -               goto err_unregister_host;
>> -
>> -       if (panel) {
>> -               dsi->next_bridge = devm_drm_panel_bridge_add(dev, panel);
>> -               if (IS_ERR(dsi->next_bridge)) {
>> -                       ret = PTR_ERR(dsi->next_bridge);
>> -                       goto err_unregister_host;
>> -               }
>> -       }
>> -
>>          dsi->driver_data = of_device_get_match_data(dev);
>>
>>          dsi->engine_clk = devm_clk_get(dev, "engine");
>> @@ -1098,14 +1109,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
>>          dsi->bridge.of_node = dev->of_node;
>>          dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
>>
>> -       drm_bridge_add(&dsi->bridge);
>> -
>> -       ret = component_add(&pdev->dev, &mtk_dsi_component_ops);
>> -       if (ret) {
>> -               dev_err(&pdev->dev, "failed to add component: %d\n", ret);
>> -               goto err_unregister_host;
>> -       }
>> -
>>          return 0;
>>
>>   err_unregister_host:
>> @@ -1118,8 +1121,6 @@ static int mtk_dsi_remove(struct platform_device *pdev)
>>          struct mtk_dsi *dsi = platform_get_drvdata(pdev);
>>
>>          mtk_output_dsi_disable(dsi);
>> -       drm_bridge_remove(&dsi->bridge);
>> -       component_del(&pdev->dev, &mtk_dsi_component_ops);
>>          mipi_dsi_host_unregister(&dsi->host);
>>
>>          return 0;
>> --
>> 2.33.1
>>


-- 
AngeloGioacchino Del Regno
Software Engineer

Collabora Ltd.
Platinum Building, St John's Innovation Park, Cambridge CB4 0DS, UK
Registered in England & Wales, no. 5513718

WARNING: multiple messages have this Message-ID (diff)
From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
To: Chun-Kuang Hu <chunkuang.hu@kernel.org>
Cc: David Airlie <airlied@linux.ie>,
	linux-kernel <linux-kernel@vger.kernel.org>,
	DRI Development <dri-devel@lists.freedesktop.org>,
	"moderated list:ARM/Mediatek SoC support"
	<linux-mediatek@lists.infradead.org>,
	Jagan Teki <jagan@amarulasolutions.com>,
	andrzej.hajda@intel.com,
	Matthias Brugger <matthias.bgg@gmail.com>,
	Collabora Kernel ML <kernel@collabora.com>,
	Linux ARM <linux-arm-kernel@lists.infradead.org>
Subject: Re: [PATCH v3] drm/mediatek: mtk_dsi: Avoid EPROBE_DEFER loop with external bridge
Date: Thu, 27 Jan 2022 16:46:19 +0100	[thread overview]
Message-ID: <b8911eab-1419-60ad-ef07-25a5de365a52@collabora.com> (raw)
In-Reply-To: <CAAOTY__yO6Cq8qt8RSh9AX68mJEv+wWvuhY0_p-PTJ=eJD_7aA@mail.gmail.com>

Il 27/01/22 16:21, Chun-Kuang Hu ha scritto:
> Hi, Angelo:
> 
> AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> 於
> 2022年1月27日 週四 下午10:36寫道:
>>
>> DRM bridge drivers are now attaching their DSI device at probe time,
>> which requires us to register our DSI host in order to let the bridge
>> to probe: this recently started producing an endless -EPROBE_DEFER
>> loop on some machines that are using external bridges, like the
>> parade-ps8640, found on the ACER Chromebook R13.
>>
>> Now that the DSI hosts/devices probe sequence is documented, we can
>> do adjustments to the mtk_dsi driver as to both fix now and make sure
>> to avoid this situation in the future: for this, following what is
>> documented in drm_bridge.c, move the mtk_dsi component_add() to the
>> mtk_dsi_ops.attach callback and delete it in the detach callback;
>> keeping in mind that we are registering a drm_bridge for our DSI,
>> which is only used/attached if the DSI Host is bound, it wouldn't
>> make sense to keep adding our bridge at probe time (as it would
>> be useless to have it if mtk_dsi_ops.attach() fails!), so also move
>> that one to the dsi host attach function (and remove it in detach).
>>
>> Fixes: 209264a85707 ("drm/bridge: Document the probe issue with MIPI-DSI bridges")
> 
> The fixed tag should indicate the patch which cause the bug, but why a
> patch just adding document would cause bug?
> So no any patch cause bug? This patch just want to prevent a possible bug?
> 

I think you've missed my previous message on v2, so I will paste it here:

unfortunately I couldn't find a valid commit for a Fixes tag. This
started being an issue at some point, when the DRM was changed to
adhere to the documented probe sequence: the MediaTek DSI driver was
not the only one that got broken/affected by these changes.

If you have any advice on which commit should be tagged, I'm open for
any kind of suggestion.


I tried to check on other drivers which got fixed for the same behavior,
for example drm/msm, but none of them had a Fixes tag.
When the DRM got changed to adhere to this sequence, some drm/bridge
drivers were also changed; this has created some incompatibilities with
some drm drivers, including drm/msm and drm/mediatek.

This commit is not fixing a latent bug that was introduced in drm/mediatek
but rather one that was induced by the new, fixed, probe flow that got
recently documented - and to which drivers should adhere; failing to adhere
to that will produce an endless -EPROBE_DEFER loop, due to other drivers
(as mentioned, for example drm/bridge drivers) having been changed to use
that probe sequence.


Regards,
Angelo

> Regards,
> Chun-Kuang.
> 
>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
>> Reviewed-by: Andrzej Hajda <andrzej.hajda@intel.com>
>> Reviewed-by: Jagan Teki <jagan@amarulasolutions.com>
>>
>> ---
>>   drivers/gpu/drm/mediatek/mtk_dsi.c | 167 +++++++++++++++--------------
>>   1 file changed, 84 insertions(+), 83 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
>> index 5d90d2eb0019..bced4c7d668e 100644
>> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
>> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
>> @@ -786,18 +786,101 @@ void mtk_dsi_ddp_stop(struct device *dev)
>>          mtk_dsi_poweroff(dsi);
>>   }
>>
>> +static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
>> +{
>> +       int ret;
>> +
>> +       ret = drm_simple_encoder_init(drm, &dsi->encoder,
>> +                                     DRM_MODE_ENCODER_DSI);
>> +       if (ret) {
>> +               DRM_ERROR("Failed to encoder init to drm\n");
>> +               return ret;
>> +       }
>> +
>> +       dsi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm, dsi->host.dev);
>> +
>> +       ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
>> +                               DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>> +       if (ret)
>> +               goto err_cleanup_encoder;
>> +
>> +       dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder);
>> +       if (IS_ERR(dsi->connector)) {
>> +               DRM_ERROR("Unable to create bridge connector\n");
>> +               ret = PTR_ERR(dsi->connector);
>> +               goto err_cleanup_encoder;
>> +       }
>> +       drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
>> +
>> +       return 0;
>> +
>> +err_cleanup_encoder:
>> +       drm_encoder_cleanup(&dsi->encoder);
>> +       return ret;
>> +}
>> +
>> +static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
>> +{
>> +       int ret;
>> +       struct drm_device *drm = data;
>> +       struct mtk_dsi *dsi = dev_get_drvdata(dev);
>> +
>> +       ret = mtk_dsi_encoder_init(drm, dsi);
>> +       if (ret)
>> +               return ret;
>> +
>> +       return device_reset_optional(dev);
>> +}
>> +
>> +static void mtk_dsi_unbind(struct device *dev, struct device *master,
>> +                          void *data)
>> +{
>> +       struct mtk_dsi *dsi = dev_get_drvdata(dev);
>> +
>> +       drm_encoder_cleanup(&dsi->encoder);
>> +}
>> +
>> +static const struct component_ops mtk_dsi_component_ops = {
>> +       .bind = mtk_dsi_bind,
>> +       .unbind = mtk_dsi_unbind,
>> +};
>> +
>>   static int mtk_dsi_host_attach(struct mipi_dsi_host *host,
>>                                 struct mipi_dsi_device *device)
>>   {
>>          struct mtk_dsi *dsi = host_to_dsi(host);
>> +       struct device *dev = host->dev;
>> +       int ret;
>>
>>          dsi->lanes = device->lanes;
>>          dsi->format = device->format;
>>          dsi->mode_flags = device->mode_flags;
>> +       dsi->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 0, 0);
>> +       if (IS_ERR(dsi->next_bridge))
>> +               return PTR_ERR(dsi->next_bridge);
>> +
>> +       drm_bridge_add(&dsi->bridge);
>> +
>> +       ret = component_add(host->dev, &mtk_dsi_component_ops);
>> +       if (ret) {
>> +               DRM_ERROR("failed to add dsi_host component: %d\n", ret);
>> +               drm_bridge_remove(&dsi->bridge);
>> +               return ret;
>> +       }
>>
>>          return 0;
>>   }
>>
>> +static int mtk_dsi_host_detach(struct mipi_dsi_host *host,
>> +                              struct mipi_dsi_device *device)
>> +{
>> +       struct mtk_dsi *dsi = host_to_dsi(host);
>> +
>> +       component_del(host->dev, &mtk_dsi_component_ops);
>> +       drm_bridge_remove(&dsi->bridge);
>> +       return 0;
>> +}
>> +
>>   static void mtk_dsi_wait_for_idle(struct mtk_dsi *dsi)
>>   {
>>          int ret;
>> @@ -938,73 +1021,14 @@ static ssize_t mtk_dsi_host_transfer(struct mipi_dsi_host *host,
>>
>>   static const struct mipi_dsi_host_ops mtk_dsi_ops = {
>>          .attach = mtk_dsi_host_attach,
>> +       .detach = mtk_dsi_host_detach,
>>          .transfer = mtk_dsi_host_transfer,
>>   };
>>
>> -static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
>> -{
>> -       int ret;
>> -
>> -       ret = drm_simple_encoder_init(drm, &dsi->encoder,
>> -                                     DRM_MODE_ENCODER_DSI);
>> -       if (ret) {
>> -               DRM_ERROR("Failed to encoder init to drm\n");
>> -               return ret;
>> -       }
>> -
>> -       dsi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm, dsi->host.dev);
>> -
>> -       ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
>> -                               DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>> -       if (ret)
>> -               goto err_cleanup_encoder;
>> -
>> -       dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder);
>> -       if (IS_ERR(dsi->connector)) {
>> -               DRM_ERROR("Unable to create bridge connector\n");
>> -               ret = PTR_ERR(dsi->connector);
>> -               goto err_cleanup_encoder;
>> -       }
>> -       drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
>> -
>> -       return 0;
>> -
>> -err_cleanup_encoder:
>> -       drm_encoder_cleanup(&dsi->encoder);
>> -       return ret;
>> -}
>> -
>> -static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
>> -{
>> -       int ret;
>> -       struct drm_device *drm = data;
>> -       struct mtk_dsi *dsi = dev_get_drvdata(dev);
>> -
>> -       ret = mtk_dsi_encoder_init(drm, dsi);
>> -       if (ret)
>> -               return ret;
>> -
>> -       return device_reset_optional(dev);
>> -}
>> -
>> -static void mtk_dsi_unbind(struct device *dev, struct device *master,
>> -                          void *data)
>> -{
>> -       struct mtk_dsi *dsi = dev_get_drvdata(dev);
>> -
>> -       drm_encoder_cleanup(&dsi->encoder);
>> -}
>> -
>> -static const struct component_ops mtk_dsi_component_ops = {
>> -       .bind = mtk_dsi_bind,
>> -       .unbind = mtk_dsi_unbind,
>> -};
>> -
>>   static int mtk_dsi_probe(struct platform_device *pdev)
>>   {
>>          struct mtk_dsi *dsi;
>>          struct device *dev = &pdev->dev;
>> -       struct drm_panel *panel;
>>          struct resource *regs;
>>          int irq_num;
>>          int ret;
>> @@ -1021,19 +1045,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
>>                  return ret;
>>          }
>>
>> -       ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
>> -                                         &panel, &dsi->next_bridge);
>> -       if (ret)
>> -               goto err_unregister_host;
>> -
>> -       if (panel) {
>> -               dsi->next_bridge = devm_drm_panel_bridge_add(dev, panel);
>> -               if (IS_ERR(dsi->next_bridge)) {
>> -                       ret = PTR_ERR(dsi->next_bridge);
>> -                       goto err_unregister_host;
>> -               }
>> -       }
>> -
>>          dsi->driver_data = of_device_get_match_data(dev);
>>
>>          dsi->engine_clk = devm_clk_get(dev, "engine");
>> @@ -1098,14 +1109,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
>>          dsi->bridge.of_node = dev->of_node;
>>          dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
>>
>> -       drm_bridge_add(&dsi->bridge);
>> -
>> -       ret = component_add(&pdev->dev, &mtk_dsi_component_ops);
>> -       if (ret) {
>> -               dev_err(&pdev->dev, "failed to add component: %d\n", ret);
>> -               goto err_unregister_host;
>> -       }
>> -
>>          return 0;
>>
>>   err_unregister_host:
>> @@ -1118,8 +1121,6 @@ static int mtk_dsi_remove(struct platform_device *pdev)
>>          struct mtk_dsi *dsi = platform_get_drvdata(pdev);
>>
>>          mtk_output_dsi_disable(dsi);
>> -       drm_bridge_remove(&dsi->bridge);
>> -       component_del(&pdev->dev, &mtk_dsi_component_ops);
>>          mipi_dsi_host_unregister(&dsi->host);
>>
>>          return 0;
>> --
>> 2.33.1
>>


-- 
AngeloGioacchino Del Regno
Software Engineer

Collabora Ltd.
Platinum Building, St John's Innovation Park, Cambridge CB4 0DS, UK
Registered in England & Wales, no. 5513718

WARNING: multiple messages have this Message-ID (diff)
From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
To: Chun-Kuang Hu <chunkuang.hu@kernel.org>
Cc: DRI Development <dri-devel@lists.freedesktop.org>,
	David Airlie <airlied@linux.ie>,
	linux-kernel <linux-kernel@vger.kernel.org>,
	andrzej.hajda@intel.com,
	"moderated list:ARM/Mediatek SoC support"
	<linux-mediatek@lists.infradead.org>,
	Jagan Teki <jagan@amarulasolutions.com>,
	Matthias Brugger <matthias.bgg@gmail.com>,
	Collabora Kernel ML <kernel@collabora.com>,
	Linux ARM <linux-arm-kernel@lists.infradead.org>
Subject: Re: [PATCH v3] drm/mediatek: mtk_dsi: Avoid EPROBE_DEFER loop with external bridge
Date: Thu, 27 Jan 2022 16:46:19 +0100	[thread overview]
Message-ID: <b8911eab-1419-60ad-ef07-25a5de365a52@collabora.com> (raw)
In-Reply-To: <CAAOTY__yO6Cq8qt8RSh9AX68mJEv+wWvuhY0_p-PTJ=eJD_7aA@mail.gmail.com>

Il 27/01/22 16:21, Chun-Kuang Hu ha scritto:
> Hi, Angelo:
> 
> AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> 於
> 2022年1月27日 週四 下午10:36寫道:
>>
>> DRM bridge drivers are now attaching their DSI device at probe time,
>> which requires us to register our DSI host in order to let the bridge
>> to probe: this recently started producing an endless -EPROBE_DEFER
>> loop on some machines that are using external bridges, like the
>> parade-ps8640, found on the ACER Chromebook R13.
>>
>> Now that the DSI hosts/devices probe sequence is documented, we can
>> do adjustments to the mtk_dsi driver as to both fix now and make sure
>> to avoid this situation in the future: for this, following what is
>> documented in drm_bridge.c, move the mtk_dsi component_add() to the
>> mtk_dsi_ops.attach callback and delete it in the detach callback;
>> keeping in mind that we are registering a drm_bridge for our DSI,
>> which is only used/attached if the DSI Host is bound, it wouldn't
>> make sense to keep adding our bridge at probe time (as it would
>> be useless to have it if mtk_dsi_ops.attach() fails!), so also move
>> that one to the dsi host attach function (and remove it in detach).
>>
>> Fixes: 209264a85707 ("drm/bridge: Document the probe issue with MIPI-DSI bridges")
> 
> The fixed tag should indicate the patch which cause the bug, but why a
> patch just adding document would cause bug?
> So no any patch cause bug? This patch just want to prevent a possible bug?
> 

I think you've missed my previous message on v2, so I will paste it here:

unfortunately I couldn't find a valid commit for a Fixes tag. This
started being an issue at some point, when the DRM was changed to
adhere to the documented probe sequence: the MediaTek DSI driver was
not the only one that got broken/affected by these changes.

If you have any advice on which commit should be tagged, I'm open for
any kind of suggestion.


I tried to check on other drivers which got fixed for the same behavior,
for example drm/msm, but none of them had a Fixes tag.
When the DRM got changed to adhere to this sequence, some drm/bridge
drivers were also changed; this has created some incompatibilities with
some drm drivers, including drm/msm and drm/mediatek.

This commit is not fixing a latent bug that was introduced in drm/mediatek
but rather one that was induced by the new, fixed, probe flow that got
recently documented - and to which drivers should adhere; failing to adhere
to that will produce an endless -EPROBE_DEFER loop, due to other drivers
(as mentioned, for example drm/bridge drivers) having been changed to use
that probe sequence.


Regards,
Angelo

> Regards,
> Chun-Kuang.
> 
>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
>> Reviewed-by: Andrzej Hajda <andrzej.hajda@intel.com>
>> Reviewed-by: Jagan Teki <jagan@amarulasolutions.com>
>>
>> ---
>>   drivers/gpu/drm/mediatek/mtk_dsi.c | 167 +++++++++++++++--------------
>>   1 file changed, 84 insertions(+), 83 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
>> index 5d90d2eb0019..bced4c7d668e 100644
>> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
>> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
>> @@ -786,18 +786,101 @@ void mtk_dsi_ddp_stop(struct device *dev)
>>          mtk_dsi_poweroff(dsi);
>>   }
>>
>> +static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
>> +{
>> +       int ret;
>> +
>> +       ret = drm_simple_encoder_init(drm, &dsi->encoder,
>> +                                     DRM_MODE_ENCODER_DSI);
>> +       if (ret) {
>> +               DRM_ERROR("Failed to encoder init to drm\n");
>> +               return ret;
>> +       }
>> +
>> +       dsi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm, dsi->host.dev);
>> +
>> +       ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
>> +                               DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>> +       if (ret)
>> +               goto err_cleanup_encoder;
>> +
>> +       dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder);
>> +       if (IS_ERR(dsi->connector)) {
>> +               DRM_ERROR("Unable to create bridge connector\n");
>> +               ret = PTR_ERR(dsi->connector);
>> +               goto err_cleanup_encoder;
>> +       }
>> +       drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
>> +
>> +       return 0;
>> +
>> +err_cleanup_encoder:
>> +       drm_encoder_cleanup(&dsi->encoder);
>> +       return ret;
>> +}
>> +
>> +static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
>> +{
>> +       int ret;
>> +       struct drm_device *drm = data;
>> +       struct mtk_dsi *dsi = dev_get_drvdata(dev);
>> +
>> +       ret = mtk_dsi_encoder_init(drm, dsi);
>> +       if (ret)
>> +               return ret;
>> +
>> +       return device_reset_optional(dev);
>> +}
>> +
>> +static void mtk_dsi_unbind(struct device *dev, struct device *master,
>> +                          void *data)
>> +{
>> +       struct mtk_dsi *dsi = dev_get_drvdata(dev);
>> +
>> +       drm_encoder_cleanup(&dsi->encoder);
>> +}
>> +
>> +static const struct component_ops mtk_dsi_component_ops = {
>> +       .bind = mtk_dsi_bind,
>> +       .unbind = mtk_dsi_unbind,
>> +};
>> +
>>   static int mtk_dsi_host_attach(struct mipi_dsi_host *host,
>>                                 struct mipi_dsi_device *device)
>>   {
>>          struct mtk_dsi *dsi = host_to_dsi(host);
>> +       struct device *dev = host->dev;
>> +       int ret;
>>
>>          dsi->lanes = device->lanes;
>>          dsi->format = device->format;
>>          dsi->mode_flags = device->mode_flags;
>> +       dsi->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 0, 0);
>> +       if (IS_ERR(dsi->next_bridge))
>> +               return PTR_ERR(dsi->next_bridge);
>> +
>> +       drm_bridge_add(&dsi->bridge);
>> +
>> +       ret = component_add(host->dev, &mtk_dsi_component_ops);
>> +       if (ret) {
>> +               DRM_ERROR("failed to add dsi_host component: %d\n", ret);
>> +               drm_bridge_remove(&dsi->bridge);
>> +               return ret;
>> +       }
>>
>>          return 0;
>>   }
>>
>> +static int mtk_dsi_host_detach(struct mipi_dsi_host *host,
>> +                              struct mipi_dsi_device *device)
>> +{
>> +       struct mtk_dsi *dsi = host_to_dsi(host);
>> +
>> +       component_del(host->dev, &mtk_dsi_component_ops);
>> +       drm_bridge_remove(&dsi->bridge);
>> +       return 0;
>> +}
>> +
>>   static void mtk_dsi_wait_for_idle(struct mtk_dsi *dsi)
>>   {
>>          int ret;
>> @@ -938,73 +1021,14 @@ static ssize_t mtk_dsi_host_transfer(struct mipi_dsi_host *host,
>>
>>   static const struct mipi_dsi_host_ops mtk_dsi_ops = {
>>          .attach = mtk_dsi_host_attach,
>> +       .detach = mtk_dsi_host_detach,
>>          .transfer = mtk_dsi_host_transfer,
>>   };
>>
>> -static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
>> -{
>> -       int ret;
>> -
>> -       ret = drm_simple_encoder_init(drm, &dsi->encoder,
>> -                                     DRM_MODE_ENCODER_DSI);
>> -       if (ret) {
>> -               DRM_ERROR("Failed to encoder init to drm\n");
>> -               return ret;
>> -       }
>> -
>> -       dsi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm, dsi->host.dev);
>> -
>> -       ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
>> -                               DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>> -       if (ret)
>> -               goto err_cleanup_encoder;
>> -
>> -       dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder);
>> -       if (IS_ERR(dsi->connector)) {
>> -               DRM_ERROR("Unable to create bridge connector\n");
>> -               ret = PTR_ERR(dsi->connector);
>> -               goto err_cleanup_encoder;
>> -       }
>> -       drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
>> -
>> -       return 0;
>> -
>> -err_cleanup_encoder:
>> -       drm_encoder_cleanup(&dsi->encoder);
>> -       return ret;
>> -}
>> -
>> -static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
>> -{
>> -       int ret;
>> -       struct drm_device *drm = data;
>> -       struct mtk_dsi *dsi = dev_get_drvdata(dev);
>> -
>> -       ret = mtk_dsi_encoder_init(drm, dsi);
>> -       if (ret)
>> -               return ret;
>> -
>> -       return device_reset_optional(dev);
>> -}
>> -
>> -static void mtk_dsi_unbind(struct device *dev, struct device *master,
>> -                          void *data)
>> -{
>> -       struct mtk_dsi *dsi = dev_get_drvdata(dev);
>> -
>> -       drm_encoder_cleanup(&dsi->encoder);
>> -}
>> -
>> -static const struct component_ops mtk_dsi_component_ops = {
>> -       .bind = mtk_dsi_bind,
>> -       .unbind = mtk_dsi_unbind,
>> -};
>> -
>>   static int mtk_dsi_probe(struct platform_device *pdev)
>>   {
>>          struct mtk_dsi *dsi;
>>          struct device *dev = &pdev->dev;
>> -       struct drm_panel *panel;
>>          struct resource *regs;
>>          int irq_num;
>>          int ret;
>> @@ -1021,19 +1045,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
>>                  return ret;
>>          }
>>
>> -       ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
>> -                                         &panel, &dsi->next_bridge);
>> -       if (ret)
>> -               goto err_unregister_host;
>> -
>> -       if (panel) {
>> -               dsi->next_bridge = devm_drm_panel_bridge_add(dev, panel);
>> -               if (IS_ERR(dsi->next_bridge)) {
>> -                       ret = PTR_ERR(dsi->next_bridge);
>> -                       goto err_unregister_host;
>> -               }
>> -       }
>> -
>>          dsi->driver_data = of_device_get_match_data(dev);
>>
>>          dsi->engine_clk = devm_clk_get(dev, "engine");
>> @@ -1098,14 +1109,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
>>          dsi->bridge.of_node = dev->of_node;
>>          dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
>>
>> -       drm_bridge_add(&dsi->bridge);
>> -
>> -       ret = component_add(&pdev->dev, &mtk_dsi_component_ops);
>> -       if (ret) {
>> -               dev_err(&pdev->dev, "failed to add component: %d\n", ret);
>> -               goto err_unregister_host;
>> -       }
>> -
>>          return 0;
>>
>>   err_unregister_host:
>> @@ -1118,8 +1121,6 @@ static int mtk_dsi_remove(struct platform_device *pdev)
>>          struct mtk_dsi *dsi = platform_get_drvdata(pdev);
>>
>>          mtk_output_dsi_disable(dsi);
>> -       drm_bridge_remove(&dsi->bridge);
>> -       component_del(&pdev->dev, &mtk_dsi_component_ops);
>>          mipi_dsi_host_unregister(&dsi->host);
>>
>>          return 0;
>> --
>> 2.33.1
>>


-- 
AngeloGioacchino Del Regno
Software Engineer

Collabora Ltd.
Platinum Building, St John's Innovation Park, Cambridge CB4 0DS, UK
Registered in England & Wales, no. 5513718

_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

WARNING: multiple messages have this Message-ID (diff)
From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
To: Chun-Kuang Hu <chunkuang.hu@kernel.org>
Cc: DRI Development <dri-devel@lists.freedesktop.org>,
	David Airlie <airlied@linux.ie>,
	linux-kernel <linux-kernel@vger.kernel.org>,
	andrzej.hajda@intel.com,
	"moderated list:ARM/Mediatek SoC support"
	<linux-mediatek@lists.infradead.org>,
	Jagan Teki <jagan@amarulasolutions.com>,
	Matthias Brugger <matthias.bgg@gmail.com>,
	Collabora Kernel ML <kernel@collabora.com>,
	Linux ARM <linux-arm-kernel@lists.infradead.org>
Subject: Re: [PATCH v3] drm/mediatek: mtk_dsi: Avoid EPROBE_DEFER loop with external bridge
Date: Thu, 27 Jan 2022 16:46:19 +0100	[thread overview]
Message-ID: <b8911eab-1419-60ad-ef07-25a5de365a52@collabora.com> (raw)
In-Reply-To: <CAAOTY__yO6Cq8qt8RSh9AX68mJEv+wWvuhY0_p-PTJ=eJD_7aA@mail.gmail.com>

Il 27/01/22 16:21, Chun-Kuang Hu ha scritto:
> Hi, Angelo:
> 
> AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> 於
> 2022年1月27日 週四 下午10:36寫道:
>>
>> DRM bridge drivers are now attaching their DSI device at probe time,
>> which requires us to register our DSI host in order to let the bridge
>> to probe: this recently started producing an endless -EPROBE_DEFER
>> loop on some machines that are using external bridges, like the
>> parade-ps8640, found on the ACER Chromebook R13.
>>
>> Now that the DSI hosts/devices probe sequence is documented, we can
>> do adjustments to the mtk_dsi driver as to both fix now and make sure
>> to avoid this situation in the future: for this, following what is
>> documented in drm_bridge.c, move the mtk_dsi component_add() to the
>> mtk_dsi_ops.attach callback and delete it in the detach callback;
>> keeping in mind that we are registering a drm_bridge for our DSI,
>> which is only used/attached if the DSI Host is bound, it wouldn't
>> make sense to keep adding our bridge at probe time (as it would
>> be useless to have it if mtk_dsi_ops.attach() fails!), so also move
>> that one to the dsi host attach function (and remove it in detach).
>>
>> Fixes: 209264a85707 ("drm/bridge: Document the probe issue with MIPI-DSI bridges")
> 
> The fixed tag should indicate the patch which cause the bug, but why a
> patch just adding document would cause bug?
> So no any patch cause bug? This patch just want to prevent a possible bug?
> 

I think you've missed my previous message on v2, so I will paste it here:

unfortunately I couldn't find a valid commit for a Fixes tag. This
started being an issue at some point, when the DRM was changed to
adhere to the documented probe sequence: the MediaTek DSI driver was
not the only one that got broken/affected by these changes.

If you have any advice on which commit should be tagged, I'm open for
any kind of suggestion.


I tried to check on other drivers which got fixed for the same behavior,
for example drm/msm, but none of them had a Fixes tag.
When the DRM got changed to adhere to this sequence, some drm/bridge
drivers were also changed; this has created some incompatibilities with
some drm drivers, including drm/msm and drm/mediatek.

This commit is not fixing a latent bug that was introduced in drm/mediatek
but rather one that was induced by the new, fixed, probe flow that got
recently documented - and to which drivers should adhere; failing to adhere
to that will produce an endless -EPROBE_DEFER loop, due to other drivers
(as mentioned, for example drm/bridge drivers) having been changed to use
that probe sequence.


Regards,
Angelo

> Regards,
> Chun-Kuang.
> 
>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
>> Reviewed-by: Andrzej Hajda <andrzej.hajda@intel.com>
>> Reviewed-by: Jagan Teki <jagan@amarulasolutions.com>
>>
>> ---
>>   drivers/gpu/drm/mediatek/mtk_dsi.c | 167 +++++++++++++++--------------
>>   1 file changed, 84 insertions(+), 83 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
>> index 5d90d2eb0019..bced4c7d668e 100644
>> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
>> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
>> @@ -786,18 +786,101 @@ void mtk_dsi_ddp_stop(struct device *dev)
>>          mtk_dsi_poweroff(dsi);
>>   }
>>
>> +static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
>> +{
>> +       int ret;
>> +
>> +       ret = drm_simple_encoder_init(drm, &dsi->encoder,
>> +                                     DRM_MODE_ENCODER_DSI);
>> +       if (ret) {
>> +               DRM_ERROR("Failed to encoder init to drm\n");
>> +               return ret;
>> +       }
>> +
>> +       dsi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm, dsi->host.dev);
>> +
>> +       ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
>> +                               DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>> +       if (ret)
>> +               goto err_cleanup_encoder;
>> +
>> +       dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder);
>> +       if (IS_ERR(dsi->connector)) {
>> +               DRM_ERROR("Unable to create bridge connector\n");
>> +               ret = PTR_ERR(dsi->connector);
>> +               goto err_cleanup_encoder;
>> +       }
>> +       drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
>> +
>> +       return 0;
>> +
>> +err_cleanup_encoder:
>> +       drm_encoder_cleanup(&dsi->encoder);
>> +       return ret;
>> +}
>> +
>> +static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
>> +{
>> +       int ret;
>> +       struct drm_device *drm = data;
>> +       struct mtk_dsi *dsi = dev_get_drvdata(dev);
>> +
>> +       ret = mtk_dsi_encoder_init(drm, dsi);
>> +       if (ret)
>> +               return ret;
>> +
>> +       return device_reset_optional(dev);
>> +}
>> +
>> +static void mtk_dsi_unbind(struct device *dev, struct device *master,
>> +                          void *data)
>> +{
>> +       struct mtk_dsi *dsi = dev_get_drvdata(dev);
>> +
>> +       drm_encoder_cleanup(&dsi->encoder);
>> +}
>> +
>> +static const struct component_ops mtk_dsi_component_ops = {
>> +       .bind = mtk_dsi_bind,
>> +       .unbind = mtk_dsi_unbind,
>> +};
>> +
>>   static int mtk_dsi_host_attach(struct mipi_dsi_host *host,
>>                                 struct mipi_dsi_device *device)
>>   {
>>          struct mtk_dsi *dsi = host_to_dsi(host);
>> +       struct device *dev = host->dev;
>> +       int ret;
>>
>>          dsi->lanes = device->lanes;
>>          dsi->format = device->format;
>>          dsi->mode_flags = device->mode_flags;
>> +       dsi->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 0, 0);
>> +       if (IS_ERR(dsi->next_bridge))
>> +               return PTR_ERR(dsi->next_bridge);
>> +
>> +       drm_bridge_add(&dsi->bridge);
>> +
>> +       ret = component_add(host->dev, &mtk_dsi_component_ops);
>> +       if (ret) {
>> +               DRM_ERROR("failed to add dsi_host component: %d\n", ret);
>> +               drm_bridge_remove(&dsi->bridge);
>> +               return ret;
>> +       }
>>
>>          return 0;
>>   }
>>
>> +static int mtk_dsi_host_detach(struct mipi_dsi_host *host,
>> +                              struct mipi_dsi_device *device)
>> +{
>> +       struct mtk_dsi *dsi = host_to_dsi(host);
>> +
>> +       component_del(host->dev, &mtk_dsi_component_ops);
>> +       drm_bridge_remove(&dsi->bridge);
>> +       return 0;
>> +}
>> +
>>   static void mtk_dsi_wait_for_idle(struct mtk_dsi *dsi)
>>   {
>>          int ret;
>> @@ -938,73 +1021,14 @@ static ssize_t mtk_dsi_host_transfer(struct mipi_dsi_host *host,
>>
>>   static const struct mipi_dsi_host_ops mtk_dsi_ops = {
>>          .attach = mtk_dsi_host_attach,
>> +       .detach = mtk_dsi_host_detach,
>>          .transfer = mtk_dsi_host_transfer,
>>   };
>>
>> -static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
>> -{
>> -       int ret;
>> -
>> -       ret = drm_simple_encoder_init(drm, &dsi->encoder,
>> -                                     DRM_MODE_ENCODER_DSI);
>> -       if (ret) {
>> -               DRM_ERROR("Failed to encoder init to drm\n");
>> -               return ret;
>> -       }
>> -
>> -       dsi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm, dsi->host.dev);
>> -
>> -       ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
>> -                               DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>> -       if (ret)
>> -               goto err_cleanup_encoder;
>> -
>> -       dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder);
>> -       if (IS_ERR(dsi->connector)) {
>> -               DRM_ERROR("Unable to create bridge connector\n");
>> -               ret = PTR_ERR(dsi->connector);
>> -               goto err_cleanup_encoder;
>> -       }
>> -       drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
>> -
>> -       return 0;
>> -
>> -err_cleanup_encoder:
>> -       drm_encoder_cleanup(&dsi->encoder);
>> -       return ret;
>> -}
>> -
>> -static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
>> -{
>> -       int ret;
>> -       struct drm_device *drm = data;
>> -       struct mtk_dsi *dsi = dev_get_drvdata(dev);
>> -
>> -       ret = mtk_dsi_encoder_init(drm, dsi);
>> -       if (ret)
>> -               return ret;
>> -
>> -       return device_reset_optional(dev);
>> -}
>> -
>> -static void mtk_dsi_unbind(struct device *dev, struct device *master,
>> -                          void *data)
>> -{
>> -       struct mtk_dsi *dsi = dev_get_drvdata(dev);
>> -
>> -       drm_encoder_cleanup(&dsi->encoder);
>> -}
>> -
>> -static const struct component_ops mtk_dsi_component_ops = {
>> -       .bind = mtk_dsi_bind,
>> -       .unbind = mtk_dsi_unbind,
>> -};
>> -
>>   static int mtk_dsi_probe(struct platform_device *pdev)
>>   {
>>          struct mtk_dsi *dsi;
>>          struct device *dev = &pdev->dev;
>> -       struct drm_panel *panel;
>>          struct resource *regs;
>>          int irq_num;
>>          int ret;
>> @@ -1021,19 +1045,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
>>                  return ret;
>>          }
>>
>> -       ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
>> -                                         &panel, &dsi->next_bridge);
>> -       if (ret)
>> -               goto err_unregister_host;
>> -
>> -       if (panel) {
>> -               dsi->next_bridge = devm_drm_panel_bridge_add(dev, panel);
>> -               if (IS_ERR(dsi->next_bridge)) {
>> -                       ret = PTR_ERR(dsi->next_bridge);
>> -                       goto err_unregister_host;
>> -               }
>> -       }
>> -
>>          dsi->driver_data = of_device_get_match_data(dev);
>>
>>          dsi->engine_clk = devm_clk_get(dev, "engine");
>> @@ -1098,14 +1109,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
>>          dsi->bridge.of_node = dev->of_node;
>>          dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
>>
>> -       drm_bridge_add(&dsi->bridge);
>> -
>> -       ret = component_add(&pdev->dev, &mtk_dsi_component_ops);
>> -       if (ret) {
>> -               dev_err(&pdev->dev, "failed to add component: %d\n", ret);
>> -               goto err_unregister_host;
>> -       }
>> -
>>          return 0;
>>
>>   err_unregister_host:
>> @@ -1118,8 +1121,6 @@ static int mtk_dsi_remove(struct platform_device *pdev)
>>          struct mtk_dsi *dsi = platform_get_drvdata(pdev);
>>
>>          mtk_output_dsi_disable(dsi);
>> -       drm_bridge_remove(&dsi->bridge);
>> -       component_del(&pdev->dev, &mtk_dsi_component_ops);
>>          mipi_dsi_host_unregister(&dsi->host);
>>
>>          return 0;
>> --
>> 2.33.1
>>


-- 
AngeloGioacchino Del Regno
Software Engineer

Collabora Ltd.
Platinum Building, St John's Innovation Park, Cambridge CB4 0DS, UK
Registered in England & Wales, no. 5513718

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2022-01-27 15:46 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-27 14:36 [PATCH v3] drm/mediatek: mtk_dsi: Avoid EPROBE_DEFER loop with external bridge AngeloGioacchino Del Regno
2022-01-27 14:36 ` AngeloGioacchino Del Regno
2022-01-27 14:36 ` AngeloGioacchino Del Regno
2022-01-27 14:36 ` AngeloGioacchino Del Regno
2022-01-27 15:21 ` Chun-Kuang Hu
2022-01-27 15:21   ` Chun-Kuang Hu
2022-01-27 15:21   ` Chun-Kuang Hu
2022-01-27 15:21   ` Chun-Kuang Hu
2022-01-27 15:46   ` AngeloGioacchino Del Regno [this message]
2022-01-27 15:46     ` AngeloGioacchino Del Regno
2022-01-27 15:46     ` AngeloGioacchino Del Regno
2022-01-27 15:46     ` AngeloGioacchino Del Regno
2022-01-28  9:13     ` AngeloGioacchino Del Regno
2022-01-28  9:13       ` AngeloGioacchino Del Regno
2022-01-28  9:13       ` AngeloGioacchino Del Regno
2022-01-28  9:13       ` AngeloGioacchino Del Regno
2022-01-28 15:57       ` Chun-Kuang Hu
2022-01-28 15:57         ` Chun-Kuang Hu
2022-01-28 15:57         ` Chun-Kuang Hu
2022-01-28 15:57         ` Chun-Kuang Hu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=b8911eab-1419-60ad-ef07-25a5de365a52@collabora.com \
    --to=angelogioacchino.delregno@collabora.com \
    --cc=airlied@linux.ie \
    --cc=andrzej.hajda@intel.com \
    --cc=chunkuang.hu@kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=jagan@amarulasolutions.com \
    --cc=kernel@collabora.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mediatek@lists.infradead.org \
    --cc=matthias.bgg@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.