diff options
| -rw-r--r-- | drivers/usb/musb/musb_gadget.c | 10 | ||||
| -rw-r--r-- | drivers/usb/phy/phy-tusb.c | 8 | ||||
| -rw-r--r-- | include/linux/usb/phy.h | 13 | 
3 files changed, 29 insertions, 2 deletions
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index c04b7fbb6b9..441eda17919 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1612,15 +1612,20 @@ static void musb_pullup(struct musb *musb, int is_on)  	u8 power;  	power = musb_readb(musb->mregs, MUSB_POWER); -	if (is_on) +	if (is_on) { +		usb_phy_reset(musb->xceiv, 0); +		mdelay(10); +		usb_phy_reset(musb->xceiv, 1);  		power |= MUSB_POWER_SOFTCONN; -	else +	} else {  		power &= ~MUSB_POWER_SOFTCONN; +	}  	/* FIXME if on, HdrcStart; if off, HdrcStop */  	dev_dbg(musb->controller, "gadget D+ pullup %s\n",  		is_on ? "on" : "off"); +  	musb_writeb(musb->mregs, MUSB_POWER, power);  } @@ -1663,6 +1668,7 @@ static int musb_gadget_pullup(struct usb_gadget *gadget, int is_on)  	if (is_on != musb->softconnect) {  		musb->softconnect = is_on; +		dev_dbg(musb->controller, "musb_gadget_pullup: %d", is_on);  		musb_pullup(musb, is_on);  	} diff --git a/drivers/usb/phy/phy-tusb.c b/drivers/usb/phy/phy-tusb.c index 25b081ce4a2..48f958510b3 100644 --- a/drivers/usb/phy/phy-tusb.c +++ b/drivers/usb/phy/phy-tusb.c @@ -148,6 +148,13 @@ static int tusb_enable(struct tusb_usb *tusb, bool enable)  	return 0;  } +static int tusb_phy_reset(struct usb_phy *x, int enable) +{ +	struct tusb_usb	*tusb = dev_get_drvdata(x->dev); + +	return tusb_enable(tusb, (bool)enable); +} +  static int tusb_usb_set_vbus(struct usb_otg *otg, bool enabled)  {  	return 0; @@ -325,6 +332,7 @@ static int  tusb_usb_probe(struct platform_device *pdev)  	tusb->phy.dev		= tusb->dev;  	tusb->phy.label		= "tusb";  	tusb->phy.set_suspend	= tusb_set_suspend; +	tusb->phy.hw_reset	= tusb_phy_reset;  	tusb->phy.otg		= otg;  	tusb->phy.type		= USB_PHY_TYPE_USB2;  	tusb->phy.last_event	= USB_EVENT_NONE; diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h index 6b5978f5763..586152a6829 100644 --- a/include/linux/usb/phy.h +++ b/include/linux/usb/phy.h @@ -94,6 +94,10 @@ struct usb_phy {  	/* enable/disable VBUS */  	int	(*set_vbus)(struct usb_phy *x, int on); +	/* hold/unhold usb controller in reset */ +	int	(*hw_reset)(struct usb_phy *x, +				int enable); +  	/* effective for B devices, ignored for A-peripheral */  	int	(*set_power)(struct usb_phy *x,  				unsigned mA); @@ -181,6 +185,15 @@ usb_phy_vbus_off(struct usb_phy *x)  	return x->set_vbus(x, false);  } +static inline int +usb_phy_reset(struct usb_phy *x, int enable) +{ +	if (!x->hw_reset) +		return 0; + +	return x->hw_reset(x, enable); +} +  /* for usb host and peripheral controller drivers */  #if IS_ENABLED(CONFIG_USB_PHY)  extern struct usb_phy *usb_get_phy(enum usb_phy_type type);  |