usb: gadget: dwc2: avoid reset core before devices connected
Theoretically, the UDC register need not reconfig when GINTSTS.USBRst is set, and only do core reset if the devices was connected before. This change adds _connected_ flag to check the devices was really connected or not. As an optimization, reset device address to zero while GINTSTS.USBRst is set. This patch fix usb connect failed when continuously perform the 'fastboot reboot-bootloader' command. Change-Id: I6a78228e147d2274329d922ac3f3ffef19492e7e Signed-off-by: Frank Wang <frank.wang@rock-chips.com>
This commit is contained in:
parent
d007e7964b
commit
a52e8dd4da
|
|
@ -169,6 +169,7 @@ static void udc_disable(struct dwc2_udc *dev)
|
|||
dev->ep0state = WAIT_FOR_SETUP;
|
||||
dev->gadget.speed = USB_SPEED_UNKNOWN;
|
||||
dev->usb_address = 0;
|
||||
dev->connected = 0;
|
||||
|
||||
otg_phy_off(dev);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ struct dwc2_udc {
|
|||
unsigned char usb_address;
|
||||
|
||||
unsigned req_pending:1, req_std:1;
|
||||
unsigned connected:1;
|
||||
};
|
||||
|
||||
#define ep_is_in(EP) (((EP)->bEndpointAddress&USB_DIR_IN) == USB_DIR_IN)
|
||||
|
|
|
|||
|
|
@ -238,6 +238,7 @@ struct dwc2_usbotg_reg {
|
|||
#define DEV_SPEED_FULL_SPEED_11 (0x3 << 0)
|
||||
#define EP_MISS_CNT(x) (x << 18)
|
||||
#define DEVICE_ADDRESS(x) (x << 4)
|
||||
#define DCFG_DEVADDR_MASK (0x7f << 4)
|
||||
|
||||
/* Core Reset Register (GRSTCTL) */
|
||||
#define TX_FIFO_FLUSH (0x1 << 5)
|
||||
|
|
|
|||
|
|
@ -544,6 +544,9 @@ static int dwc2_udc_irq(int irq, void *_dev)
|
|||
}
|
||||
|
||||
if (intr_status & INT_RESET) {
|
||||
u32 temp;
|
||||
u32 connected = dev->connected;
|
||||
|
||||
usb_status = readl(®->gotgctl);
|
||||
debug_cond(DEBUG_ISR,
|
||||
"\tReset interrupt - (GOTGCTL):0x%x\n", usb_status);
|
||||
|
|
@ -554,7 +557,15 @@ static int dwc2_udc_irq(int irq, void *_dev)
|
|||
debug_cond(DEBUG_ISR,
|
||||
"\t\tOTG core got reset (%d)!!\n",
|
||||
reset_available);
|
||||
reconfig_usbd(dev);
|
||||
/* Reset device address to zero */
|
||||
temp = readl(®->dcfg);
|
||||
temp &= ~DCFG_DEVADDR_MASK;
|
||||
writel(temp, ®->dcfg);
|
||||
|
||||
/* Soft reset the core if connected */
|
||||
if (connected)
|
||||
reconfig_usbd(dev);
|
||||
|
||||
dev->ep0state = WAIT_FOR_SETUP;
|
||||
reset_available = 0;
|
||||
dwc2_udc_pre_setup();
|
||||
|
|
@ -1348,7 +1359,7 @@ static void dwc2_ep0_setup(struct dwc2_udc *dev)
|
|||
if (usb_ctrl->bRequestType
|
||||
!= (USB_TYPE_STANDARD | USB_RECIP_DEVICE))
|
||||
break;
|
||||
|
||||
dev->connected = 1;
|
||||
udc_set_address(dev, usb_ctrl->wValue);
|
||||
return;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue