Hello Amelie, sorry for the late reply On Wed, Jul 8, 2020 at 6:00 PM Amelie DELAUNAY <amelie.delaunay@xxxxxx> wrote: [...] > Could you please test with: > > static int dwc2_drd_role_sw_set(struct device *dev, enum usb_role role) > { > struct dwc2_hsotg *hsotg = dev_get_drvdata(dev); > unsigned long flags; > int already = 0; > > /* Skip session not in line with dr_mode */ > if ((role == USB_ROLE_DEVICE && hsotg->dr_mode == USB_DR_MODE_HOST) || > (role == USB_ROLE_HOST && hsotg->dr_mode == USB_DR_MODE_PERIPHERAL)) > return -EINVAL; > > /* Skip session if core is in test mode */ > if (role == USB_ROLE_NONE && hsotg->test_mode) { > dev_dbg(hsotg->dev, "Core is in test mode\n"); > return -EBUSY; > } > > spin_lock_irqsave(&hsotg->lock, flags); > > if (role == USB_ROLE_HOST) { > already = dwc2_ovr_avalid(hsotg, true); > } else if (role == USB_ROLE_DEVICE) { > already = dwc2_ovr_bvalid(hsotg, true); > /* This clear DCTL.SFTDISCON bit */ > dwc2_hsotg_core_connect(hsotg); > } else { > if (dwc2_is_device_mode(hsotg)) { > if (!dwc2_ovr_bvalid(hsotg, false)) > /* This set DCTL.SFTDISCON bit */ > dwc2_hsotg_core_disconnect(hsotg); > } else { > dwc2_ovr_avalid(hsotg, false); > } > } > > spin_unlock_irqrestore(&hsotg->lock, flags); > > if (!already && > role != USB_ROLE_NONE && hsotg->dr_mode == USB_DR_MODE_OTG) > /* This will raise a Connector ID Status Change Interrupt */ > dwc2_force_mode(hsotg, role == USB_ROLE_HOST); > > dev_dbg(hsotg->dev, "%s-session valid\n", > role == USB_ROLE_NONE ? "No" : > role == USB_ROLE_HOST ? "A" : "B"); > > return 0; > } > > > dwc2_force_mode is called outside the spin_lock_irqsave so the kernel > should not complain. I've tested on my setup and the behavior seems the > same. this one is looking good - the previous kernel warnings are now gone! thank you very much Best regards, Martin