All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrzej Hajda <a.hajda@samsung.com>
To: Peter Rosin <peda@axentia.se>, Jyri Sarha <jsarha@ti.com>,
	dri-devel@lists.freedesktop.org
Cc: airlied@linux.ie, "Rafael J. Wysocki" <rjw@rjwysocki.net>,
	tomi.valkeinen@ti.com, thierry.reding@gmail.com,
	laurent.pinchart@ideasonboard.com
Subject: Re: [PATCH v4 2/2] drm/panel: Add device_link from panel device to drm device
Date: Mon, 21 May 2018 11:21:44 +0200	[thread overview]
Message-ID: <56b2c3ea-8d1d-2bae-b962-7ca5e6d00dba@samsung.com> (raw)
In-Reply-To: <8229ae74-4d1c-749b-c6ee-16c0d4389020@axentia.se>

On 21.05.2018 10:53, Peter Rosin wrote:
> On 2018-05-21 10:15, Andrzej Hajda wrote:
>> On 19.05.2018 18:48, Peter Rosin wrote:
>>> On 2018-05-18 13:51, Andrzej Hajda wrote:
>>>> On 26.04.2018 10:07, Jyri Sarha wrote:
>>>>> Add device_link from panel device (supplier) to drm device (consumer)
>>>>> when drm_panel_attach() is called. This patch should protect the
>>>>> master drm driver if an attached panel driver unbinds while it is in
>>>>> use. The device_link should make sure the drm device is unbound before
>>>>> the panel driver becomes unavailable.
>>>>>
>>>>> The device_link is removed when drm_panel_detach() is called. The
>>>>> drm_panel_detach() should be called by the consumer DRM driver, not the
>>>>> panel driver, otherwise both drivers are racing to delete the same link.
>>>>>
>>>>> Signed-off-by: Jyri Sarha <jsarha@ti.com>
>>>>> Reviewed-by: Eric Anholt <eric@anholt.net>
>>>> Hi Jyri,
>>>>
>>>> This patch breaks few platforms: tm2, tm2e, trats2 - ie all platforms
>>>> using exynos_drm_dsi and dsi panels.
>>>> Exynos-DSI properly handles panels unbind - ie references to panel are
>>>> properly removed on panels removal and respective drm_connector enters
>>>> disconnected state, without destroying whole drm device.
>>>> And again on panel driver re-bind drm_panel is properly attached to
>>>> exynos-dsi and panel pipeline is working again.
>>>> This patch will break this behavior, ie it will destroy whole drm device.
>>>>
>>>> Making device_links for panels optional seems to me the best solution,
>>>> what do you think?
>>>>
>>>> The funny thing is that due to bug in device link code, your patch has
>>>> no effect on these platforms. So it does not hurt these platform yet,
>>>> but the bug will be fixed sooner or later.
>>> Ah, that's a pretty strong hint that we are doing something unusual. So,
>>> I had a deeper look and I think that device-links (with state, i.e. not
>>> DL_FLAG_STATELESS links) are assumed to be created by the .probe function
>>> of either the consumer or the supplier. Then it seems to works as expected.
>>> And that makes some sense too, because a link indicates that there exist
>>> a dependency between the two and that the consumer cannot really exist
>>> without the supplier. This is also what happens for the drm devices
>>> (panel/bridge consumers) Jyri and I are working with; they call panel or
>>> bridge attach during their probe. But this is not the case for exynos,
>>> which calls panel/bridge attach at some later stage, and that obviously
>>> violates the assumption that the device-link consumer cannot exist w/o
>>> the supplier ("obviously" since the drm driver has managed to successfully
>>> probe without the supplier).
>>>
>>> So, when the panel/bridge supplier is probed after the consumer is
>>> bound, the link starts out as DL_STATE_DORMANT, and progresses to
>>> DL_STATE_AVAILABLE once the panel/bridge has finished the probe. This is
>>> not what *we* want.
>> And this is also incorrect from Documentation PoV:
>>  * @DL_STATE_DORMANT: None of the supplier/consumer drivers is present.
>>  * @DL_STATE_AVAILABLE: The supplier driver is present, but the consumer
>> is not.
>>
>>> So, one idea I have is to, on panel/bridge attach, verify if the
>>> consumer is in its probe, and only create the link if that is the
>>> case. So, the link would be optional, but it would all be automatic.
>> Making it automatic looks tempting, but also error prone. In case of
>> component framework bind callbacks can be called from probe of any
>> component, so sometimes it can be called also from exynos-dsi probe,
>> sometimes not (depending on order of probing, which we cannot rely on).
>> So in some cases we will end-up with links, sometimes without. Ie
>> following scenarios are possible in drm_panel_attach:
>> 1. exynos-dsi bound, panel during probe.
>> 2. exynos-dsi during probe, panel during probe.
> 2. exynos-dsi during probe, panel bound? Or is this case 3, and 2 happens
> when drivers probe in parallel?

Panel is always probed not earlier than the end of exynos-dsi bind, so
only scenarios 1 and 2 should be possible.

> Whichever, you are right, I naively thought that the bind happened
> after the probe of all devices, but naturally it happens as part of
> the last device to register its component, and that normally happens
> during its probe.
>
> Sigh. So, scratch that, I guess we need a flag...
>
>>> The function device_is_bound seems like a good candidate for that
>>> check?
>>>
>>> Maybe device_link_add should automatically create a DL_FLAG_STATELESS link
>>> if either consumer or supplier has "proven" (with a successful probe) that
>>> they can exist without the other end? That would also work for us, since
>>> a DL_FLAG_STATELESS link does no harm in our case...
>> What will be benefit of having stateless device_links, in case of
>> panels/bridges?
> To have device suspend/resume happen in a predictable order? But maybe that
> has no value whatsoever?

At the moment panels do not have linux pm code, so I guess their pm is
done entirely by drm framework.
I am not sure about bridges.

Regards
Andrzej

>
> Cheers,
> Peter
>
>> Regards
>> Andrzej
>>
>>
>>> Cheers,
>>> Peter
>>>
>>>> The trick in case of exynos-dsi is to use mipi_dsi attach/detach
>>>> callbacks to get notifications about drm_panel's
>>>> appearance/disappearance, I guess ultimately such callbacks should be a
>>>> part of drm_panel
>>>> framework.
>>>>
>>>> Below description how all the code works:
>>>> Initialization:
>>>> 1. exynos_dsi (component of exynos_drm) at the end of bind callback
>>>> registers mipi_dsi bus.
>>>> 2. during mipi_dsi bus registration or later (if panel driver was not
>>>> yet registered), panel driver is bound ie - its probe callback is called.
>>>> 3. during panel's probe drm_panel_add is called, and later mipi_dsi_attach.
>>>> 4. mipi_dsi_attach calls dsi .attach callback of exynos_dsi.
>>>> 5. exynos_dsi.attach callback looks for drm_panel, calls
>>>> drm_panel_attach and changes connector's status to connected.
>>>> ....
>>>> Panel's unbind:
>>>> 1. device_release_driver calls panel's remove callback.
>>>> 2. panel's remove callback calls mipi_dsi_detach.
>>>> 3. mipi_dsi_detach calls exynos_dsi.detach callback.
>>>> 4. exynos_dsi.detach calls drm_panel_detach and changes connector's
>>>> state to disconnected.
>>>>
>>>> Panel's rebind is equivalent of steps 2-4 of Initialization.
>>>>
>>>> I have wrote the code few years ago, and it seemed to me the only safe
>>>> way to handle dynamic panel bind/unbind.
>>>> For example please note that step 5 of initialization and steps 2-4 of
>>>> unbind are executed always under panel's device_lock so it makes it
>>>> safe. Otherwise you risk that between panel lookup and panel attach
>>>> panel's driver can be unbind and consumer is left with dangling panel's
>>>> pointer, so even with your patch most of the drivers are still buggy.
>>>>
>>>> And few words about the bug(?) in device_link code: If you call
>>>> device_link_add from probe of the supplier(as it is in this case) its
>>>> status is set to DL_STATE_DORMANT, and after successful bind it is
>>>> changed to DL_STATE_AVAILABLE, which is incorrect (it should be
>>>> DL_STATE_ACTIVE), as a result on supplier's unbind consumer is not unbound.
>>>>
>>>> Regards
>>>> Andrzej
>>>>
>>>>> ---
>>>>>  drivers/gpu/drm/drm_panel.c | 10 ++++++++++
>>>>>  include/drm/drm_panel.h     |  1 +
>>>>>  2 files changed, 11 insertions(+)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
>>>>> index 71e4075..965530a 100644
>>>>> --- a/drivers/gpu/drm/drm_panel.c
>>>>> +++ b/drivers/gpu/drm/drm_panel.c
>>>>> @@ -24,6 +24,7 @@
>>>>>  #include <linux/err.h>
>>>>>  #include <linux/module.h>
>>>>>  
>>>>> +#include <drm/drm_device.h>
>>>>>  #include <drm/drm_crtc.h>
>>>>>  #include <drm/drm_panel.h>
>>>>>  
>>>>> @@ -104,6 +105,13 @@ int drm_panel_attach(struct drm_panel *panel, struct drm_connector *connector)
>>>>>  	if (panel->connector)
>>>>>  		return -EBUSY;
>>>>>  
>>>>> +	panel->link = device_link_add(connector->dev->dev, panel->dev, 0);
>>>>> +	if (!panel->link) {
>>>>> +		dev_err(panel->dev, "failed to link panel to %s\n",
>>>>> +			dev_name(connector->dev->dev));
>>>>> +		return -EINVAL;
>>>>> +	}
>>>>> +
>>>>>  	panel->connector = connector;
>>>>>  	panel->drm = connector->dev;
>>>>>  
>>>>> @@ -125,6 +133,8 @@ EXPORT_SYMBOL(drm_panel_attach);
>>>>>   */
>>>>>  int drm_panel_detach(struct drm_panel *panel)
>>>>>  {
>>>>> +	device_link_del(panel->link);
>>>>> +
>>>>>  	panel->connector = NULL;
>>>>>  	panel->drm = NULL;
>>>>>  
>>>>> diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
>>>>> index 14ac240..26a1b5f 100644
>>>>> --- a/include/drm/drm_panel.h
>>>>> +++ b/include/drm/drm_panel.h
>>>>> @@ -89,6 +89,7 @@ struct drm_panel {
>>>>>  	struct drm_device *drm;
>>>>>  	struct drm_connector *connector;
>>>>>  	struct device *dev;
>>>>> +	struct device_link *link;
>>>>>  
>>>>>  	const struct drm_panel_funcs *funcs;
>>>>>  
>>>
>>>
>
>
>

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

  reply	other threads:[~2018-05-21  9:21 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-26  8:06 [PATCH v4 0/2] drm/panel: Add device link in drm_panel_attach() Jyri Sarha
2018-04-26  8:06 ` [PATCH v4 1/2] drm/panel: Remove drm_panel_detach() calls from all panel drives Jyri Sarha
2018-04-26  8:07 ` [PATCH v4 2/2] drm/panel: Add device_link from panel device to drm device Jyri Sarha
2018-05-18 11:51   ` Andrzej Hajda
2018-05-18 12:54     ` Jyri Sarha
2018-05-19 16:48     ` Peter Rosin
2018-05-19 18:01       ` Peter Rosin
2018-05-21  8:15       ` Andrzej Hajda
2018-05-21  8:53         ` Peter Rosin
2018-05-21  9:21           ` Andrzej Hajda [this message]
2018-05-21 21:56             ` Peter Rosin
2018-05-22  6:29               ` Andrzej Hajda
2018-05-22  7:36                 ` Peter Rosin
2018-05-22  8:37                   ` Peter Rosin
2018-05-22  9:45                   ` Andrzej Hajda
2018-05-22 15:03                     ` Peter Rosin
2018-05-23  8:29                       ` Peter Rosin
2018-05-23  9:39                         ` Andrzej Hajda
2018-05-23 10:46                           ` Peter Rosin
2018-05-23 12:38                             ` Andrzej Hajda
2018-05-23 14:34                               ` Peter Rosin
2019-10-22  8:44     ` Daniel Vetter
2018-08-09  8:56   ` Daniel Vetter
2018-08-30 12:32   ` Linus Walleij
2018-08-30 14:41     ` Andrzej Hajda
2018-08-31  8:56       ` Linus Walleij
2018-08-31 10:08         ` Andrzej Hajda
2018-04-26 12:49 ` [PATCH v4 0/2] drm/panel: Add device link in drm_panel_attach() Thierry Reding
2018-05-21  6:09   ` Peter Rosin

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=56b2c3ea-8d1d-2bae-b962-7ca5e6d00dba@samsung.com \
    --to=a.hajda@samsung.com \
    --cc=airlied@linux.ie \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=jsarha@ti.com \
    --cc=laurent.pinchart@ideasonboard.com \
    --cc=peda@axentia.se \
    --cc=rjw@rjwysocki.net \
    --cc=thierry.reding@gmail.com \
    --cc=tomi.valkeinen@ti.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.