usb: dwc2: make otg manage lowlevel hw on its own

According to the design guide of dwc2, the application must flush
all FIFOs after reallocating the FIFO data RAM and the phy is
required to keep power on when flush FIFO. But on some rockchip
platforms, the usb phy will be powered off when the usb otg/gadget
disconnect, in this case if the application call the function
dwc2_hsotg_udc_start() to start udc, it will result in the error
as below:

dwc2_hsotg_init_fifo: timeout flushing fifos (GRSTCTL=80000430)
dwc2_core_reset() HANG! Soft Reset GRSTCTL=80000001
bound driver configfs-gadget
dwc2_core_reset() HANG! Soft Reset GRSTCTL=80000001

This patch make the dwc2 driver to manage the power of phy in
udc start and stop function both in otg and peripheral mode. Make
sure that the usb phy is powered on when udc start, and then the
usb phy driver can manage the phy power dynamically.

Change-Id: I15d3cb5313fc157b58a37c9e15f191d7cb966217
Signed-off-by: Meng Dongyang <daniel.meng@rock-chips.com>
This commit is contained in:
Meng Dongyang
2017-11-21 17:57:03 +08:00
committed by Tao Huang
parent 0f3895a77d
commit dc71e51944
2 changed files with 7 additions and 4 deletions

View File

@@ -3465,7 +3465,8 @@ static int dwc2_hsotg_udc_start(struct usb_gadget *gadget,
hsotg->gadget.dev.of_node = hsotg->dev->of_node;
hsotg->gadget.speed = USB_SPEED_UNKNOWN;
if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) {
if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL ||
hsotg->dr_mode == USB_DR_MODE_OTG) {
ret = dwc2_lowlevel_hw_enable(hsotg);
if (ret)
goto err;
@@ -3524,7 +3525,8 @@ static int dwc2_hsotg_udc_stop(struct usb_gadget *gadget)
if (!IS_ERR_OR_NULL(hsotg->uphy))
otg_set_peripheral(hsotg->uphy->otg, NULL);
if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL)
if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL ||
hsotg->dr_mode == USB_DR_MODE_OTG)
dwc2_lowlevel_hw_disable(hsotg);
return 0;

View File

@@ -622,8 +622,9 @@ static int dwc2_driver_probe(struct platform_device *dev)
dwc2_debugfs_init(hsotg);
/* Gadget code manages lowlevel hw on its own */
if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL)
/* Gadget and otg code manages lowlevel hw on its own */
if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL ||
hsotg->dr_mode == USB_DR_MODE_OTG)
dwc2_lowlevel_hw_disable(hsotg);
return 0;