> > >> You can use a synchronous workqueue for setup and disconnect. This > makes > >> sure the setup request and disconnect are executed in the same order > as > >> it was seen by the UDC. So you enqueue the setup packet followed by > the > >> disconnect. First you process the setup packet after that notify the > >> disconnect and put your udc into suspend. > >> > > How udc knows the disconnect has finished? suspend need to be called > by udc. > > Well, if you enqueue worker item and call in process context disconnect > of the gadget then you know when it is done once the function returns. > I am really puzzled your answer, can we get the worker item has finished after we queue it? Usually, we call gadget->disconnect like below (when cable is plugged out from the pc): static irqreturn_t udc_irq() { if (vbus_failing_interrupt()) gadget->disconnect(); } when the gadget->disconnect routine has really finished, we can call put the controller to low power code, it can be done both in interrupt and process context. At your patch, I have seen below code: +static void composite_disconnect(struct usb_gadget *gadget) +{ + struct usb_composite_dev *cdev = get_gadget_data(gadget); + + cdev->disc_pend = 1; + queue_work(system_nrt_wq, &cdev->disc_work); } How do you know the something like ep->disable has been called after composite_disconnect returns? > Sebastian -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html