Re: dwc3 gadget breaks on system suspend/resume

Felipe Balbi
2017-01-30T13:47:58Z

[-- Attachment #1: Type: text/plain, Size: 2611 bytes --]

Hi,

Felipe Balbi <balbi-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> writes:
> Roger Quadros <rogerq-l0cyMroinI0@public.gmane.org> writes:
>>> Roger Quadros <rogerq-l0cyMroinI0@public.gmane.org> writes:
>>>>> (hmm, I didn't receive your reply in my intel inbox, only
>>>>> gmail. Odd. Replying to myself here, but it should be on your reply,
>>>>> rater).
>>>>>
>>>>> Felipe Balbi <balbi-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> writes:
>>>>>>> The previous commit c499ff71ff2a281366c6ec7a904c547d806cbcd1 is fine.
>>>>>>
>>>>>> okay. Then let's try to figure out what's going on. A diff of regdump
>>>>>> before and after suspend/resume might start to give some clue about
>>>>>> what's going on. DWC3 tracepoints should help too. Care to get those?
>>>>>> BTW, is this dwc3 as host or peripheral?
>>>>>
>>>>> You don't have any endpoints enabled:
>>>>>
>>>>> -DALEPENA = 0x0000000f
>>>>> +DALEPENA = 0x00000000
>>>>
>>>> Thanks for the hints.
>>>>
>>>> This problem is because reason dwc3_gadget_run_stop() is timing out
>>>> during the suspend sequence and so dwc3_disconnect_gadget() and
>>>> __dwc3_gadget_stop() are not being called.
>>>
>>> I see
>>>
>>>> dwc3_suspend() does not consider dwc3_gadget_suspend()'s return value
>>>> and happily continues suspending the machine.
>>>>
>>>> If I force dwc3_gadget_run_stop() to return 0 then everything works fine.
>>>>
>>>> Any ideas why DWC3_DSTS_DEVCTRLHLT is not getting set?
>>>
>>> no idea. It should always get set when run_stop is cleared. Can you
>>> check if suspending with cable detached has any difference?
>>
>> After cable detach, it still timed out the next suspend. But on
>> subsequent suspends there were no timeouts. (I didn't plug the cable
>> back at all)
>>
>> This behaviour is on dra7. I will test the behaviour on am43x as well.
>
> wonder if there's something odd with 2.02a. AM437x is 2.40a IIRC,
> testing that is, indeed, a good idea.

What if your platform just takes longer to halt?

Can you try below?

diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 4db97ecae885..d2e405793b1f 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1586,7 +1586,7 @@ static int dwc3_gadget_set_selfpowered(struct usb_gadget *g,
static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend)
{
u32 reg;
- u32 timeout = 500;
+ u32 timeout = 500000;

if (pm_runtime_suspended(dwc->dev))
return 0;

--
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]