diff options
Diffstat (limited to 'drivers/usb/dwc2')
-rw-r--r-- | drivers/usb/dwc2/gadget.c | 31 | ||||
-rw-r--r-- | drivers/usb/dwc2/hcd.c | 1 | ||||
-rw-r--r-- | drivers/usb/dwc2/hcd.h | 1 | ||||
-rw-r--r-- | drivers/usb/dwc2/hcd_queue.c | 3 | ||||
-rw-r--r-- | drivers/usb/dwc2/platform.c | 2 |
5 files changed, 30 insertions, 8 deletions
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index e9940dd004e4..4c5e3005e1dc 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2254,6 +2254,7 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, { u32 intmsk; u32 val; + u32 usbcfg; /* Kill any ep0 requests as controller will be reinitialized */ kill_all_requests(hsotg, hsotg->eps_out[0], -ECONNRESET); @@ -2267,10 +2268,16 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, * set configuration. */ + /* keep other bits untouched (so e.g. forced modes are not lost) */ + usbcfg = dwc2_readl(hsotg->regs + GUSBCFG); + usbcfg &= ~(GUSBCFG_TOUTCAL_MASK | GUSBCFG_PHYIF16 | GUSBCFG_SRPCAP | + GUSBCFG_HNPCAP); + /* set the PLL on, remove the HNP/SRP and set the PHY */ val = (hsotg->phyif == GUSBCFG_PHYIF8) ? 9 : 5; - dwc2_writel(hsotg->phyif | GUSBCFG_TOUTCAL(7) | - (val << GUSBCFG_USBTRDTIM_SHIFT), hsotg->regs + GUSBCFG); + usbcfg |= hsotg->phyif | GUSBCFG_TOUTCAL(7) | + (val << GUSBCFG_USBTRDTIM_SHIFT); + dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); dwc2_hsotg_init_fifo(hsotg); @@ -2418,6 +2425,9 @@ static irqreturn_t dwc2_hsotg_irq(int irq, void *pw) u32 gintsts; u32 gintmsk; + if (!dwc2_is_device_mode(hsotg)) + return IRQ_NONE; + spin_lock(&hsotg->lock); irq_retry: gintsts = dwc2_readl(hsotg->regs + GINTSTS); @@ -2624,7 +2634,10 @@ static int dwc2_hsotg_ep_enable(struct usb_ep *ep, desc->wMaxPacketSize, desc->bInterval); /* not to be called for EP0 */ - WARN_ON(index == 0); + if (index == 0) { + dev_err(hsotg->dev, "%s: called for EP 0\n", __func__); + return -EINVAL; + } dir_in = (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) ? 1 : 0; if (dir_in != hs_ep->dir_in) { @@ -3031,6 +3044,7 @@ static struct usb_ep_ops dwc2_hsotg_ep_ops = { static void dwc2_hsotg_init(struct dwc2_hsotg *hsotg) { u32 trdtim; + u32 usbcfg; /* unmask subset of endpoint interrupts */ dwc2_writel(DIEPMSK_TIMEOUTMSK | DIEPMSK_AHBERRMSK | @@ -3054,11 +3068,16 @@ static void dwc2_hsotg_init(struct dwc2_hsotg *hsotg) dwc2_hsotg_init_fifo(hsotg); + /* keep other bits untouched (so e.g. forced modes are not lost) */ + usbcfg = dwc2_readl(hsotg->regs + GUSBCFG); + usbcfg &= ~(GUSBCFG_TOUTCAL_MASK | GUSBCFG_PHYIF16 | GUSBCFG_SRPCAP | + GUSBCFG_HNPCAP); + /* set the PLL on, remove the HNP/SRP and set the PHY */ trdtim = (hsotg->phyif == GUSBCFG_PHYIF8) ? 9 : 5; - dwc2_writel(hsotg->phyif | GUSBCFG_TOUTCAL(7) | - (trdtim << GUSBCFG_USBTRDTIM_SHIFT), - hsotg->regs + GUSBCFG); + usbcfg |= hsotg->phyif | GUSBCFG_TOUTCAL(7) | + (trdtim << GUSBCFG_USBTRDTIM_SHIFT); + dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); if (using_dma(hsotg)) __orr32(hsotg->regs + GAHBCFG, GAHBCFG_DMA_EN); diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 1f6255131857..2df3d04d26f5 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -4703,6 +4703,7 @@ fail2: spin_unlock_irqrestore(&hsotg->lock, flags); urb->hcpriv = NULL; kfree(qtd); + qtd = NULL; fail1: if (qh_allocated) { struct dwc2_qtd *qtd2, *qtd2_tmp; diff --git a/drivers/usb/dwc2/hcd.h b/drivers/usb/dwc2/hcd.h index 89fa26cb25f4..7758bfb644ff 100644 --- a/drivers/usb/dwc2/hcd.h +++ b/drivers/usb/dwc2/hcd.h @@ -552,6 +552,7 @@ static inline void dwc2_hcd_qtd_unlink_and_free(struct dwc2_hsotg *hsotg, { list_del(&qtd->qtd_list_entry); kfree(qtd); + qtd = NULL; } /* Descriptor DMA support functions */ diff --git a/drivers/usb/dwc2/hcd_queue.c b/drivers/usb/dwc2/hcd_queue.c index 7f634fd771c7..b5c7793a2df2 100644 --- a/drivers/usb/dwc2/hcd_queue.c +++ b/drivers/usb/dwc2/hcd_queue.c @@ -1709,7 +1709,8 @@ void dwc2_hcd_qh_unlink(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) dwc2_deschedule_periodic(hsotg, qh); hsotg->periodic_qh_count--; - if (!hsotg->periodic_qh_count) { + if (!hsotg->periodic_qh_count && + hsotg->core_params->dma_desc_enable <= 0) { intr_mask = dwc2_readl(hsotg->regs + GINTMSK); intr_mask &= ~GINTSTS_SOF; dwc2_writel(intr_mask, hsotg->regs + GINTMSK); diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 88629bed6614..fc6f5251de5d 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -562,7 +562,7 @@ static int dwc2_driver_probe(struct platform_device *dev) retval = dwc2_get_dr_mode(hsotg); if (retval) - return retval; + goto error; /* * Reset before dwc2_get_hwparams() then it could get power-on real |