Hi, I found a few problems with the PXA27x UDC. usb_function_activate() in drivers/usb/gadget/composite.c does spin_lock_irqsave() and then calls gadget->ops->pullup() in drivers/usb/gadget/udc/core.c which is set to pxa_udc_pullup(), which should be called not in interrupt /** * pxa_udc_pullup - Offer manual D+ pullup control * @_gadget: usb gadget using the control * @is_active: 0 if disconnect, else connect D+ pullup resistor * Context: !in_interrupt() * * Returns 0 if OK, -EOPNOTSUPP if udc driver doesn't handle D+ pullup */ This finally causes fail at udc_enable() in drivers/usb/gadget/udc/pxa27x_udc.c at code /* * Caller must be able to sleep in order to cope with startup transients */ msleep(100); with a following error (with CONFIG_DEBUG_PREEMPT on): BUG: scheduling while atomic: v4l_id/360/0x00000002 ... Preemption disabled at: [<bf43be34>] usb_function_activate+0x20/0xa4 [libcomposite] CPU: 0 PID: 360 Comm: v4l_id Not tainted 4.10.0-rc5-magician+ #2 Hardware name: HTC Magician [<c000f540>] (unwind_backtrace) from [<c000d3e0>] (show_stack+0x10/0x14) [<c000d3e0>] (show_stack) from [<c00363b8>] (__schedule_bug+0x98/0xcc) [<c00363b8>] (__schedule_bug) from [<c035d94c>] (__schedule+0x58/0x444) [<c035d94c>] (__schedule) from [<c035dde0>] (schedule+0xa8/0xc8) [<c035dde0>] (schedule) from [<c0361558>] (schedule_timeout+0x1c8/0x1ec) [<c0361558>] (schedule_timeout) from [<c005312c>] (msleep+0x1c/0x20) [<c005312c>] (msleep) from [<bf4322e4>] (udc_enable+0x170/0x1d4 [pxa27x_udc]) [<bf4322e4>] (udc_enable [pxa27x_udc]) from [<bf432560>] (pxa_udc_pullup+0x40/0x68 [pxa27x_udc]) [<bf432560>] (pxa_udc_pullup [pxa27x_udc]) from [<bf4271c8>] (usb_gadget_connect+0x3c/0x5c [udc_core]) [<bf4271c8>] (usb_gadget_connect [udc_core]) from [<bf43beac>] (usb_function_activate+0x98/0xa4 [libcomposite]) [<bf43beac>] (usb_function_activate [libcomposite]) from [<bf44df08>] (uvc_function_connect+0x14/0x38 [usb_f_uvc]) [<bf44df08>] (uvc_function_connect [usb_f_uvc]) from [<bf44e944>] (uvc_v4l2_open+0x4c/0x60 [usb_f_uvc]) [<bf44e944>] (uvc_v4l2_open [usb_f_uvc]) from [<bf156420>] (v4l2_open+0x7c/0xc0 [videodev]) [<bf156420>] (v4l2_open [videodev]) from [<c00b4010>] (chrdev_open+0x198/0x1b0) [<c00b4010>] (chrdev_open) from [<c00ad314>] (do_dentry_open.constprop.3+0x1b0/0x2ec) [<c00ad314>] (do_dentry_open.constprop.3) from [<c00bdbf0>] (path_openat+0xc10/0xdd4) [<c00bdbf0>] (path_openat) from [<c00bdde4>] (do_filp_open+0x30/0x78) [<c00bdde4>] (do_filp_open) from [<c00ae340>] (do_sys_open+0xf0/0x1b0) [<c00ae340>] (do_sys_open) from [<c000a320>] (ret_fast_syscall+0x0/0x38) With the msleep changed to mdelay, the code (specified as !in_interrupt()) seems to work fine (after torture reloads). Can the caller (udc core) be changed to be able to sleep? Second bug was discovered by Robert Jarzmik during discussion in [BUG] usb: gadget: Kernel oops with UVC USB gadget and configfs A call to usb_put_phy(udc->transceiver) in pxa_udc_remove() can be called with variable containing error pointer or NULL. So it should be moved to a previous call like this (modified original suggestion): if (!IS_ERR_OR_NULL(udc->transceiver)) { usb_unregister_notifier(udc->transceiver, &pxa27x_udc_phy); usb_put_phy(udc->transceiver); } And as we talking about it, is this return correct? if (of_have_populated_dt()) { udc->transceiver = devm_usb_get_phy_by_phandle(udc->dev, "phys", 0); if (IS_ERR(udc->transceiver)) return PTR_ERR(udc->transceiver); } else { udc->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); } One branch returns on error and second one is fine, udc->transceiver then can hold an error, but this is fine for the rest of driver (tested). Question is does it have to return from a first branch (e.g. my device does not have phy)? And finally it seems definitions from drivers/usb/gadget/udc/pxa27x_udc.c are duplicated: static void udc_enable(struct pxa_udc *udc); static void udc_disable(struct pxa_udc *udc); I will send patch series as soon as we agree on solutions. best regards, Petr -- 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