usb: dwc3: rockchip: fix connect fail when force host mode

The DWC3 rockchip driver provides a sysfs interface "dwc3_mode"
to force Peripheral mode or Host mode. It has a problem to force
to Host mode when the DWC3 works as Peripheral mode and connects
to Host (e.g. PC USB Port).

This issue can be reproduced on RK1808 EVB follow these steps:

1. Set dr_mode = "otg" in DTS dwc3 node;
2. Start the system, and connect the RK1808 USB 3.0 to PC USB.
3. Make sure that PC has recognized the USB device, and then
   force DWC3 to Host mode via "dwc3_mode".

   echo "host" > /sys/devices/platform/usb/dwc3_mode

   And plug in an USB 2.0 Device to RK1808 USB 3.0 Port, then
   we can see the following error log:

   rockchip-dwc3 usb: Peripheral disconnect timeout
   rockchip-dwc3 usb: USB unconnectedxhci-hcd
   xhci-hcd.3.auto: xHCI Host Controller
   xhci-hcd xhci-hcd.3.auto: new USB bus registered, assigned bus number 3
   xhci-hcd xhci-hcd.3.auto: hcc params 0x0220fe64 hci version 0x110 quirks 0x04010010
   ...
   hub 4-0:1.0: USB hub found
   hub 4-0:1.0: 1 port detected
   rockchip-dwc3 usb: USB HOST connected
   rockchip-dwc3 usb: set new mode successfully
   usb 3-1: new high-speed USB device number 2 using xhci-hcd
   usb 3-1: new high-speed USB device number 3 using xhci-hcd
   usb usb3-port1: attempt power cycle
   usb 3-1: new full-speed USB device number 4 using xhci-hcd
   usb 3-1: Device not responding to setup address
   usb 3-1: Device not responding to setup address
   usb 3-1: device not accepting address 4, error -71

It's because that in this test case, the dr_mode is original otg
mode, and the current code only call phy_set_mode() to disconnect
the peripheral from PC host if the dr_mode is peripheral mode.
This cause dwc3_rockchip_otg_extcon_evt_work() wait peripheral
disconnect timeout, and DWC3 fail to do runtime suspend and resume
to initialized the DWC3 core register again.

This patch call phy_set_mode() to disconnect the peripheral if
the current dr_mode is peripheral or otg when force to host mode.

Change-Id: I733d364046abcb616cf3d99ed57ab8604a87eef6
Signed-off-by: William Wu <william.wu@rock-chips.com>
This commit is contained in:
William Wu
2019-03-15 10:00:15 +08:00
committed by Tao Huang
parent afd36f1250
commit ef409c6d47

View File

@@ -128,7 +128,8 @@ static ssize_t dwc3_mode_store(struct device *device,
* detection function in usb2 phy, this can help to trigger
* the peripheral disconnect by software.
*/
if (dwc->dr_mode == USB_DR_MODE_PERIPHERAL)
if (dwc->dr_mode == USB_DR_MODE_PERIPHERAL ||
dwc->dr_mode == USB_DR_MODE_OTG)
phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_INVALID);
dwc->dr_mode = USB_DR_MODE_OTG;