Hi, John Stultz writes: > From: Yu Chen > > The Type-C drivers use USB role switch API to inform the > system about the negotiated data role, so registering a role > switch in the DRD code in order to support platforms with > USB Type-C connectors. > > Cc: Greg Kroah-Hartman > Cc: Rob Herring > Cc: Mark Rutland > CC: ShuFan Lee > Cc: Heikki Krogerus > Cc: Suzuki K Poulose > Cc: Chunfeng Yun > Cc: Yu Chen > Cc: Felipe Balbi > Cc: Hans de Goede > Cc: Andy Shevchenko > Cc: Jun Li > Cc: Valentin Schneider > Cc: Jack Pham > Cc: linux-usb@vger.kernel.org > Cc: devicetree@vger.kernel.org > Suggested-by: Heikki Krogerus > Signed-off-by: Yu Chen > Signed-off-by: John Stultz > --- > v2: Fix role_sw and role_switch_default_mode descriptions as > reported by kbuild test robot > > v3: Split out the role-switch-default-host logic into its own > patch > --- > drivers/usb/dwc3/Kconfig | 1 + > drivers/usb/dwc3/core.h | 3 ++ > drivers/usb/dwc3/drd.c | 66 +++++++++++++++++++++++++++++++++++++++- > 3 files changed, 69 insertions(+), 1 deletion(-) > > diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig > index 89abc6078703..1104745c41a9 100644 > --- a/drivers/usb/dwc3/Kconfig > +++ b/drivers/usb/dwc3/Kconfig > @@ -44,6 +44,7 @@ config USB_DWC3_DUAL_ROLE > bool "Dual Role mode" > depends on ((USB=y || USB=USB_DWC3) && (USB_GADGET=y || USB_GADGET=USB_DWC3)) > depends on (EXTCON=y || EXTCON=USB_DWC3) > + select USB_ROLE_SWITCH so even those using DWC3 as a peripheral-only or host-only driver will need role switch? > diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h > index 1c8b349379af..6f19e9891767 100644 > --- a/drivers/usb/dwc3/core.h > +++ b/drivers/usb/dwc3/core.h > @@ -25,6 +25,7 @@ > #include > #include > #include > +#include > #include > > #include > @@ -951,6 +952,7 @@ struct dwc3_scratchpad_array { > * @hsphy_mode: UTMI phy mode, one of following: > * - USBPHY_INTERFACE_MODE_UTMI > * - USBPHY_INTERFACE_MODE_UTMIW > + * @role_sw: usb_role_switch handle > * @usb2_phy: pointer to USB2 PHY > * @usb3_phy: pointer to USB3 PHY > * @usb2_generic_phy: pointer to USB2 PHY > @@ -1084,6 +1086,7 @@ struct dwc3 { > struct extcon_dev *edev; > struct notifier_block edev_nb; > enum usb_phy_interface hsphy_mode; > + struct usb_role_switch *role_sw; > > u32 fladj; > u32 irq_gadget; > diff --git a/drivers/usb/dwc3/drd.c b/drivers/usb/dwc3/drd.c > index c946d64142ad..61d4fd8aead4 100644 > --- a/drivers/usb/dwc3/drd.c > +++ b/drivers/usb/dwc3/drd.c > @@ -476,6 +476,52 @@ static struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc) > return edev; > } > > +static int dwc3_usb_role_switch_set(struct device *dev, enum usb_role role) > +{ > + struct dwc3 *dwc = dev_get_drvdata(dev); > + u32 mode; > + > + switch (role) { > + case USB_ROLE_HOST: > + mode = DWC3_GCTL_PRTCAP_HOST; > + break; > + case USB_ROLE_DEVICE: > + mode = DWC3_GCTL_PRTCAP_DEVICE; > + break; > + default: > + mode = DWC3_GCTL_PRTCAP_DEVICE; > + break; > + } > + > + dwc3_set_mode(dwc, mode); > + return 0; > +} role switching is starting to get way too complicated in DWC3. We now have a function that queues a work on the system_freezable_wq that will configure PHY and change PRTCAP. Is there a way we can simplify some of this a little? -- balbi