On Wed, May 17, 2023 at 1:01 PM Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> wrote: > > On Wed, May 17, 2023 at 10:19:25AM -0700, Badhri Jagan Sridharan wrote: > > On Wed, May 17, 2023 at 7:44 AM Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> wrote: > > > > > > On Wed, May 17, 2023 at 11:59:55AM +0000, Badhri Jagan Sridharan wrote: > > > > chipidea udc calls usb_udc_vbus_handler from udc_start gadget > > > > ops causing a deadlock. Avoid this by offloading usb_udc_vbus_handler > > > > processing. > > > > > > Surely that is the wrong approach. > > > > > > The real problem here is that usb_udc_vbus_handler() gets called from > > > within a udc_start routine. But this is totally unnecessary, because > > > the UDC core will call usb_udc_connect_control_locked() itself, later on > > > during gadget_bind_driver(). > > > > Hi Alan, > > > > usb_udc_vbus_handler sets the udc->vbus flag as well apart from > > calling usb_udc_connect_control_locked(). So, removing usb_udc_vbus_handler > > from chip specific start callback might prevent the controller from > > starting. > > > > void usb_udc_vbus_handler(struct usb_gadget *gadget, bool status) > > { > > struct usb_udc *udc = gadget->udc; > > > > mutex_lock(&udc->connect_lock); > > if (udc) { > > udc->vbus = status; > > usb_udc_connect_control_locked(udc); > > Then add "udc->vbus = true;" at the appropriate spot in > gadget_bind_driver(). Not sure if I am misunderstanding something. "udc->vbus = true" is set by usb_udc_vbus_handler based on invocation from the chip level gadget driver and gadget_bind_driver() does not seem to have the context for udc->vbus. Do you still think it makes sense to add "udc->vbus = true;" to gadget_bind_driver() ? > > > Alan Stern > > PS: I just noticed that in max3420_udc.c, the max_3420_vbus_handler() > function calls usb_udc_vbus_handler() from within an interrupt handler. > This won't work, since interrupt handlers aren't allowed to sleep and > therefore can't lock mutexes. Good point ! I didn't notice that usb_udc_vbus_handler() is invoked from interrupt context as well. I was looking at turning connect_lock into a spin lock. But looks like udc_lock which is acquired in usb_gadget_disconnect_locked is a mutex, So keeping connect_lock as mutex and changing vbus_events_lock into spin_lock is what that seems to be possible. Sending out V2 of this patch with these changes so that it's easier to see what I am referring to. Eager to know your thoughts ! Thanks, Badhri