Re: [PATCH] usb: chipidea: udc: reject non-control requests while controller is suspended
From: Andreea.Popescu@xxxxxxxxxxx
Date: Wed Apr 01 2026 - 07:01:02 EST
On Tue, Mar 31, 2026 at 12:21:45PM +0000, Andreea.Popescu@xxxxxxxxxxx wrote:
>> When Linux runtime PM autosuspends a ChipIdea UDC that is still
>> enumerated by the host, the driver gates the PHY clocks and marks
>> the controller as suspended (ci->in_lpm = 1) but deliberately leaves
>> gadget.speed unchanged so upper-layer gadget drivers do not see a
>> spurious disconnect.
>
>It's strange that chipidea UDC will runtime suspend even it's already
>enumerated by the host. AFAIK, the udc driver will call pm_runtime_get_sync()
>in ci_hdrc_gadget_connect(is_active = true), so it will be in runtime active
>state all the time unless a explicit pm_runtime_put/_autosuspend() is called
>in somewhere.
>
>Would you share more details how device controller go to runtime suspended?
>Thanks,
>Xu Yang
Thank you very much for taking the time and pointing this. It made me realize a very important distinction. I am using an I.MX board, due to this I will split my answer, so you can decide if it's still worth what I am proposing or you can just reject it. Either way, I am most grateful.
Still applicable to 6.19 mainline:
ep_queue returning 0 for USB_SPEED_UNKNOWN: I believe there might be the following window: _gadget_stop_activity() sets gadget.speed = USB_SPEED_UNKNOWN, but ep_queue is called before that completes from a concurrent context. The return 0 is misleading and should be -ESHUTDOWN.
I.MX specific: On i.MX SoCs the chipidea controller sits inside a power domain managed by imx-blk-ctrl or the GPC. When that parent domain is shut down by the platform PM framework, pm_runtime_force_suspend() is called on the chipidea device, bypassing usage_count entirely and invoking ci_runtime_suspend → ci_controller_suspend → ci->in_lpm = true. This happens while VBUS is still present and the gadget is enumerated. This is the actual path I observed and it is platform-specific, not a general chipidea mainline issue. Due to this, please disregard the proposed change with _ep_queue guard on ci->in_lpm
________________________________________
De la: Xu Yang <xu.yang_2@xxxxxxx>
Trimis: miercuri, 1 aprilie 2026 11:22
Către: Popescu, Andreea
Cc: Peter Chen; Greg Kroah-Hartman; linux-usb@xxxxxxxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx
Subiect: Re: [PATCH] usb: chipidea: udc: reject non-control requests while controller is suspended
On Tue, Mar 31, 2026 at 12:21:45PM +0000, Andreea.Popescu@xxxxxxxxxxx wrote:
> When Linux runtime PM autosuspends a ChipIdea UDC that is still
> enumerated by the host, the driver gates the PHY clocks and marks
> the controller as suspended (ci->in_lpm = 1) but deliberately leaves
> gadget.speed unchanged so upper-layer gadget drivers do not see a
> spurious disconnect.
It's strange that chipidea UDC will runtime suspend even it's already
enumerated by the host. AFAIK, the udc driver will call pm_runtime_get_sync()
in ci_hdrc_gadget_connect(is_active = true), so it will be in runtime active
state all the time unless a explicit pm_runtime_put/_autosuspend() is called
in somewhere.
Would you share more details how device controller go to runtime suspended?
Thanks,
Xu Yang