All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stephen Warren <swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
To: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>,
	Thierry Reding
	<thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Cc: Alan Stern
	<stern-nwvwT67g6+6dFdvTe/nMLpVzexx5G7lz@public.gmane.org>,
	Greg Kroah-Hartman
	<gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org>,
	Alexandre Courbot
	<gnurou-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Jon Hunter <jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>,
	linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Philipp Zabel <p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
Subject: Re: [PATCH v3 2/2] usb: host: ehci-tegra: Avoid getting the same reset twice
Date: Thu, 5 May 2016 10:00:27 -0600	[thread overview]
Message-ID: <572B6E1B.3060901@wwwdotorg.org> (raw)
In-Reply-To: <fdf3583d-636e-5619-5df6-17b6ae331ac9-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

On 05/05/2016 02:05 AM, Hans de Goede wrote:
> Hi,
>
> On 04-05-16 22:25, Thierry Reding wrote:
>> On Wed, May 04, 2016 at 11:23:20AM -0600, Stephen Warren wrote:
>>> On 05/04/2016 08:40 AM, Thierry Reding wrote:
>>>> From: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
>>>>
>>>> Starting with commit 0b52297f2288 ("reset: Add support for shared reset
>>>> controls") there is a reference count for reset control assertions. The
>>>> goal is to allow resets to be shared by multiple devices and an assert
>>>> will take effect only when all instances have asserted the reset.
>>>>
>>>> In order to preserve backwards-compatibility, all reset controls become
>>>> exclusive by default. This is to ensure that reset_control_assert() can
>>>> immediately assert in hardware.
>>>>
>>>> However, this new behaviour triggers the following warning in the EHCI
>>>> driver for Tegra:
>>> ...
>>>> The reason is that Tegra SoCs have three EHCI controllers, each with a
>>>> separate reset line. However the first controller contains UTMI pads
>>>> configuration registers that are shared with its siblings and that are
>>>> reset as part of the first controller's reset. There is special code in
>>>> the driver to assert and deassert this shared reset at probe time, and
>>>> it does so irrespective of which controller is probed first to ensure
>>>> that these shared registers are reset before any of the controllers are
>>>> initialized. Unfortunately this means that if the first controller gets
>>>> probed first, it will request its own reset line and will subsequently
>>>> request the same reset line again (temporarily) to perform the reset.
>>>> This used to work fine before the above-mentioned commit, but now
>>>> triggers the new WARN.
>>>>
>>>> Work around this by making sure we reuse the controller's reset if the
>>>> controller happens to be the first controller.
>>>
>>>> diff --git a/drivers/usb/host/ehci-tegra.c
>>>> b/drivers/usb/host/ehci-tegra.c
>>>
>>>> @@ -81,15 +81,23 @@ static int tegra_reset_usb_controller(struct
>>>> platform_device *pdev)
>>>
>>>> +    bool has_utmi_pad_registers = false;
>>>>
>>>>       phy_np = of_parse_phandle(pdev->dev.of_node, "nvidia,phy", 0);
>>>>       if (!phy_np)
>>>>           return -ENOENT;
>>>>
>>>> +    if (of_property_read_bool(phy_np,
>>>> "nvidia,has-utmi-pad-registers"))
>>>> +        has_utmi_pad_registers = true;
>>>
>>> Isn't that just:
>>>
>>> has_utmi_pad_registers = of_property_read_bool(phy_np,
>>>     "nvidia,has-utmi-pad-registers");
>>>
>>> ... and then you can remove " = false" from the declaration too?
>>
>> Yes. This is really only for aesthetics. The direct assignment doesn't
>> fit within 80 columns, and wrapping it looks ugly whichever way you do
>> it.
>>
>>>>       if (!usb1_reset_attempted) {
>>>>           struct reset_control *usb1_reset;
>>>>
>>>> -        usb1_reset = of_reset_control_get(phy_np, "utmi-pads");
>>>> +        if (!has_utmi_pad_registers)
>>>> +            usb1_reset = of_reset_control_get(phy_np, "utmi-pads");
>>>> +        else
>>>> +            usb1_reset = tegra->rst;
>>> ...
>>>>           usb1_reset_attempted = true;
>>>>       }
>>>
>>> This is a pre-existing issue, but what happens if the probes for two USB
>>> controllers run in parallel; there seems to be missing locking
>>> related to
>>> testing/setting usb1_reset_attempted, which could cause multiple
>>> parallel
>>> attempts to get the "utmi-pads" reset object, which would presumably
>>> cause
>>> essentially the same issue this patch is solving in other cases?
>>
>> Hah! Interestingly my initial attempt at fixing this was to introduce a
>> lock to serialize these, because I thought that was what was going on. I
>> don't think this function can ever run concurrently for different
>> devices because the driver core already serializes probes (unless a
>> driver specifically requests asynchronous probing, which this one
>> doesn't).
>
> Why not just use the new shared reset functionality ? It is easy to use,
> that way you can drop some of the special handling in the driver and
> you're code actually reflects the hardware (which IMHO has a shared reset).

Judging purely by the descriptions of the shared reset functionality in 
this thread, I doubt that will work. A varying number of USB controllers 
will be enabled in DT on a board-by-board basis, so anything that 
attempts to wait for "all devices to assert reset" can't be implemented, 
since it won't be known ahead of time how many reset assertions to wait 
for. Equally, if device probes are serialized, the reset will not happen 
at the right time since it can't happen until the nth probe (when each 
device has asserted reset) but we want it to happen during the 1st probe.

WARNING: multiple messages have this Message-ID (diff)
From: Stephen Warren <swarren@wwwdotorg.org>
To: Hans de Goede <hdegoede@redhat.com>,
	Thierry Reding <thierry.reding@gmail.com>
Cc: Alan Stern <stern@rowland.harvard.edu>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Alexandre Courbot <gnurou@gmail.com>,
	Jon Hunter <jonathanh@nvidia.com>,
	linux-usb@vger.kernel.org, linux-tegra@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	Philipp Zabel <p.zabel@pengutronix.de>
Subject: Re: [PATCH v3 2/2] usb: host: ehci-tegra: Avoid getting the same reset twice
Date: Thu, 5 May 2016 10:00:27 -0600	[thread overview]
Message-ID: <572B6E1B.3060901@wwwdotorg.org> (raw)
In-Reply-To: <fdf3583d-636e-5619-5df6-17b6ae331ac9@redhat.com>

On 05/05/2016 02:05 AM, Hans de Goede wrote:
> Hi,
>
> On 04-05-16 22:25, Thierry Reding wrote:
>> On Wed, May 04, 2016 at 11:23:20AM -0600, Stephen Warren wrote:
>>> On 05/04/2016 08:40 AM, Thierry Reding wrote:
>>>> From: Thierry Reding <treding@nvidia.com>
>>>>
>>>> Starting with commit 0b52297f2288 ("reset: Add support for shared reset
>>>> controls") there is a reference count for reset control assertions. The
>>>> goal is to allow resets to be shared by multiple devices and an assert
>>>> will take effect only when all instances have asserted the reset.
>>>>
>>>> In order to preserve backwards-compatibility, all reset controls become
>>>> exclusive by default. This is to ensure that reset_control_assert() can
>>>> immediately assert in hardware.
>>>>
>>>> However, this new behaviour triggers the following warning in the EHCI
>>>> driver for Tegra:
>>> ...
>>>> The reason is that Tegra SoCs have three EHCI controllers, each with a
>>>> separate reset line. However the first controller contains UTMI pads
>>>> configuration registers that are shared with its siblings and that are
>>>> reset as part of the first controller's reset. There is special code in
>>>> the driver to assert and deassert this shared reset at probe time, and
>>>> it does so irrespective of which controller is probed first to ensure
>>>> that these shared registers are reset before any of the controllers are
>>>> initialized. Unfortunately this means that if the first controller gets
>>>> probed first, it will request its own reset line and will subsequently
>>>> request the same reset line again (temporarily) to perform the reset.
>>>> This used to work fine before the above-mentioned commit, but now
>>>> triggers the new WARN.
>>>>
>>>> Work around this by making sure we reuse the controller's reset if the
>>>> controller happens to be the first controller.
>>>
>>>> diff --git a/drivers/usb/host/ehci-tegra.c
>>>> b/drivers/usb/host/ehci-tegra.c
>>>
>>>> @@ -81,15 +81,23 @@ static int tegra_reset_usb_controller(struct
>>>> platform_device *pdev)
>>>
>>>> +    bool has_utmi_pad_registers = false;
>>>>
>>>>       phy_np = of_parse_phandle(pdev->dev.of_node, "nvidia,phy", 0);
>>>>       if (!phy_np)
>>>>           return -ENOENT;
>>>>
>>>> +    if (of_property_read_bool(phy_np,
>>>> "nvidia,has-utmi-pad-registers"))
>>>> +        has_utmi_pad_registers = true;
>>>
>>> Isn't that just:
>>>
>>> has_utmi_pad_registers = of_property_read_bool(phy_np,
>>>     "nvidia,has-utmi-pad-registers");
>>>
>>> ... and then you can remove " = false" from the declaration too?
>>
>> Yes. This is really only for aesthetics. The direct assignment doesn't
>> fit within 80 columns, and wrapping it looks ugly whichever way you do
>> it.
>>
>>>>       if (!usb1_reset_attempted) {
>>>>           struct reset_control *usb1_reset;
>>>>
>>>> -        usb1_reset = of_reset_control_get(phy_np, "utmi-pads");
>>>> +        if (!has_utmi_pad_registers)
>>>> +            usb1_reset = of_reset_control_get(phy_np, "utmi-pads");
>>>> +        else
>>>> +            usb1_reset = tegra->rst;
>>> ...
>>>>           usb1_reset_attempted = true;
>>>>       }
>>>
>>> This is a pre-existing issue, but what happens if the probes for two USB
>>> controllers run in parallel; there seems to be missing locking
>>> related to
>>> testing/setting usb1_reset_attempted, which could cause multiple
>>> parallel
>>> attempts to get the "utmi-pads" reset object, which would presumably
>>> cause
>>> essentially the same issue this patch is solving in other cases?
>>
>> Hah! Interestingly my initial attempt at fixing this was to introduce a
>> lock to serialize these, because I thought that was what was going on. I
>> don't think this function can ever run concurrently for different
>> devices because the driver core already serializes probes (unless a
>> driver specifically requests asynchronous probing, which this one
>> doesn't).
>
> Why not just use the new shared reset functionality ? It is easy to use,
> that way you can drop some of the special handling in the driver and
> you're code actually reflects the hardware (which IMHO has a shared reset).

Judging purely by the descriptions of the shared reset functionality in 
this thread, I doubt that will work. A varying number of USB controllers 
will be enabled in DT on a board-by-board basis, so anything that 
attempts to wait for "all devices to assert reset" can't be implemented, 
since it won't be known ahead of time how many reset assertions to wait 
for. Equally, if device probes are serialized, the reset will not happen 
at the right time since it can't happen until the nth probe (when each 
device has asserted reset) but we want it to happen during the 1st probe.

  parent reply	other threads:[~2016-05-05 16:00 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-05-04 14:39 [PATCH v3 1/2] usb: host: ehci-tegra: Grab the correct UTMI pads reset Thierry Reding
     [not found] ` <1462372800-30900-1-git-send-email-thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-05-04 14:40   ` [PATCH v3 2/2] usb: host: ehci-tegra: Avoid getting the same reset twice Thierry Reding
2016-05-04 14:40     ` Thierry Reding
     [not found]     ` <1462372800-30900-2-git-send-email-thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-05-04 17:22       ` Philipp Zabel
2016-05-04 17:22         ` Philipp Zabel
2016-05-04 20:16         ` Thierry Reding
2016-05-04 17:23       ` Stephen Warren
2016-05-04 17:23         ` Stephen Warren
     [not found]         ` <572A3008.4020602-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2016-05-04 20:25           ` Thierry Reding
2016-05-04 20:25             ` Thierry Reding
2016-05-05  8:05             ` Hans de Goede
     [not found]               ` <fdf3583d-636e-5619-5df6-17b6ae331ac9-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-05-05 16:00                 ` Stephen Warren [this message]
2016-05-05 16:00                   ` Stephen Warren
     [not found]                   ` <572B6E1B.3060901-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2016-05-05 17:12                     ` Hans de Goede
2016-05-05 17:12                       ` Hans de Goede
2016-05-05 17:05       ` Jon Hunter
2016-05-05 17:05         ` Jon Hunter
     [not found]         ` <572B7D48.6010807-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2016-05-05 17:10           ` Jon Hunter
2016-05-05 17:10             ` Jon Hunter
2016-05-04 14:57   ` [PATCH v3 1/2] usb: host: ehci-tegra: Grab the correct UTMI pads reset Greg Kroah-Hartman
2016-05-04 14:57     ` Greg Kroah-Hartman
     [not found]     ` <20160504145710.GA14708-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org>
2016-05-04 15:26       ` Thierry Reding
2016-05-04 15:26         ` Thierry Reding
     [not found]         ` <20160504152648.GA31420-EkSeR96xj6Pcmrwk2tT4+A@public.gmane.org>
2016-05-05 16:05           ` Tuomas Tynkkynen
2016-05-05 16:05             ` Tuomas Tynkkynen
2016-05-04 17:14   ` Stephen Warren
2016-05-04 17:14     ` Stephen Warren
     [not found]     ` <572A2E0A.8040408-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2016-05-04 20:30       ` Thierry Reding
2016-05-04 20:30         ` Thierry Reding
2016-05-05  7:39   ` Jon Hunter
2016-05-05  7:39     ` Jon Hunter

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=572B6E1B.3060901@wwwdotorg.org \
    --to=swarren-3lzwwm7+weoh9zmkesr00q@public.gmane.org \
    --cc=gnurou-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org \
    --cc=hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
    --cc=jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org \
    --cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org \
    --cc=stern-nwvwT67g6+6dFdvTe/nMLpVzexx5G7lz@public.gmane.org \
    --cc=thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    /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.