> --- a/drivers/usb/chipidea/Kconfig > +++ b/drivers/usb/chipidea/Kconfig > @@ -3,6 +3,8 @@ config USB_CHIPIDEA > depends on ((USB_EHCI_HCD && USB_GADGET) || (USB_EHCI_HCD > && !USB_GADGET) || (!USB_EHCI_HCD && USB_GADGET)) && HAS_DMA > select EXTCON > select RESET_CONTROLLER > + select MULTIPLEXER > + select MUX_GPIO The above two configurations are only used at your specific platforms, please add them at either your platform defconfig or the related hardware driver's Kconfig. > help > Say Y here if your system has a dual role high speed USB > controller based on ChipIdea silicon IP. It supports: > diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index > 33ae87f..8fa0991 100644 > --- a/drivers/usb/chipidea/core.c > +++ b/drivers/usb/chipidea/core.c > @@ -61,6 +61,7 @@ > #include <linux/of.h> > #include <linux/regulator/consumer.h> > #include <linux/usb/ehci_def.h> > +#include <linux/mux/consumer.h> > > #include "ci.h" > #include "udc.h" > @@ -687,6 +688,10 @@ static int ci_get_platdata(struct device *dev, > if (of_find_property(dev->of_node, "non-zero-ttctrl-ttha", NULL)) > platdata->flags |= CI_HDRC_SET_NON_ZERO_TTHA; > > + platdata->usb_switch = devm_mux_control_get_optional(dev, "usb_switch"); > + if (IS_ERR(platdata->usb_switch)) > + return PTR_ERR(platdata->usb_switch); > + > ext_id = ERR_PTR(-ENODEV); > ext_vbus = ERR_PTR(-ENODEV); > if (of_property_read_bool(dev->of_node, "extcon")) { diff --git > a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index af45aa32..d9d2d00 > 100644 > --- a/drivers/usb/chipidea/host.c > +++ b/drivers/usb/chipidea/host.c > @@ -13,6 +13,7 @@ > #include <linux/usb/hcd.h> > #include <linux/usb/chipidea.h> > #include <linux/regulator/consumer.h> > +#include <linux/mux/consumer.h> > > #include "../host/ehci.h" > > @@ -161,6 +162,10 @@ static int host_start(struct ci_hdrc *ci) > if (ci_otg_is_fsm_mode(ci)) { > otg->host = &hcd->self; > hcd->self.otg_port = 1; > + } else { > + ret = mux_control_select(ci->platdata->usb_switch, 1); > + if (ret) > + goto disable_reg; What will happen if ci->platdata->usb_switch is NULL? > } > } > > @@ -181,6 +186,8 @@ static void host_stop(struct ci_hdrc *ci) > struct usb_hcd *hcd = ci->hcd; > > if (hcd) { > + if (!ci_otg_is_fsm_mode(ci)) > + mux_control_deselect(ci->platdata->usb_switch); Ditto. > if (ci->platdata->notify_event) > ci->platdata->notify_event(ci, > CI_HDRC_CONTROLLER_STOPPED_EVENT); > diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index > 9852ec5..209d3f6 100644 > --- a/drivers/usb/chipidea/udc.c > +++ b/drivers/usb/chipidea/udc.c > @@ -19,6 +19,7 @@ > #include <linux/usb/gadget.h> > #include <linux/usb/otg-fsm.h> > #include <linux/usb/chipidea.h> > +#include <linux/mux/consumer.h> > > #include "ci.h" > #include "udc.h" > @@ -1965,16 +1966,26 @@ void ci_hdrc_gadget_destroy(struct ci_hdrc *ci) > > static int udc_id_switch_for_device(struct ci_hdrc *ci) { > + int ret = 0; > + > if (ci->is_otg) > /* Clear and enable BSV irq */ > hw_write_otgsc(ci, OTGSC_BSVIS | OTGSC_BSVIE, > OTGSC_BSVIS | OTGSC_BSVIE); > > - return 0; > + if (!ci_otg_is_fsm_mode(ci)) > + ret = mux_control_select(ci->platdata->usb_switch, 0); > + Ditto > + if (ci->is_otg && ret) > + hw_write_otgsc(ci, OTGSC_BSVIE | OTGSC_BSVIS, > OTGSC_BSVIS); > + > + return ret; > } > > static void udc_id_switch_for_host(struct ci_hdrc *ci) { > + mux_control_deselect(ci->platdata->usb_switch); > + > /* > * host doesn't care B_SESSION_VALID event > * so clear and disbale BSV irq > diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h index > 07f9936..9ea55a1 100644 > --- a/include/linux/usb/chipidea.h > +++ b/include/linux/usb/chipidea.h > @@ -10,6 +10,7 @@ > #include <linux/usb/otg.h> > > struct ci_hdrc; > +struct mux_control; > > /** > * struct ci_hdrc_cable - structure for external connector cable state tracking @@ - > 76,6 +77,7 @@ struct ci_hdrc_platform_data { > /* VBUS and ID signal state tracking, using extcon framework */ > struct ci_hdrc_cable vbus_extcon; > struct ci_hdrc_cable id_extcon; > + struct mux_control *usb_switch; > u32 phy_clkgate_delay_us; If CONFIG_USB_CHIPIDEA_HOST is not defined, it may cause build error Peter -- 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