diff options
Diffstat (limited to 'drivers/usb/dwc2')
-rw-r--r-- | drivers/usb/dwc2/core_intr.c | 25 | ||||
-rw-r--r-- | drivers/usb/dwc2/hcd_intr.c | 14 |
2 files changed, 31 insertions, 8 deletions
diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index 8205799e6db..c93918b70d0 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -72,6 +72,26 @@ static const char *dwc2_op_state_str(struct dwc2_hsotg *hsotg) } /** + * dwc2_handle_usb_port_intr - handles OTG PRTINT interrupts. + * When the PRTINT interrupt fires, there are certain status bits in the Host + * Port that needs to get cleared. + * + * @hsotg: Programming view of DWC_otg controller + */ +static void dwc2_handle_usb_port_intr(struct dwc2_hsotg *hsotg) +{ + u32 hprt0 = readl(hsotg->regs + HPRT0); + + if (hprt0 & HPRT0_ENACHG) { + hprt0 &= ~HPRT0_ENA; + writel(hprt0, hsotg->regs + HPRT0); + } + + /* Clear interrupt */ + writel(GINTSTS_PRTINT, hsotg->regs + GINTSTS); +} + +/** * dwc2_handle_mode_mismatch_intr() - Logs a mode mismatch warning message * * @hsotg: Programming view of DWC_otg controller @@ -479,9 +499,8 @@ irqreturn_t dwc2_handle_common_intr(int irq, void *dev) if (dwc2_is_device_mode(hsotg)) { dev_dbg(hsotg->dev, " --Port interrupt received in Device mode--\n"); - gintsts = GINTSTS_PRTINT; - writel(gintsts, hsotg->regs + GINTSTS); - retval = 1; + dwc2_handle_usb_port_intr(hsotg); + retval = IRQ_HANDLED; } } diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c index 012f17ec1a3..47b9eb5389b 100644 --- a/drivers/usb/dwc2/hcd_intr.c +++ b/drivers/usb/dwc2/hcd_intr.c @@ -975,8 +975,8 @@ static void dwc2_hc_xfercomp_intr(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd) { struct dwc2_hcd_urb *urb = qtd->urb; - int pipe_type = dwc2_hcd_get_pipe_type(&urb->pipe_info); enum dwc2_halt_status halt_status = DWC2_HC_XFER_COMPLETE; + int pipe_type; int urb_xfer_done; if (dbg_hc(chan)) @@ -984,6 +984,11 @@ static void dwc2_hc_xfercomp_intr(struct dwc2_hsotg *hsotg, "--Host Channel %d Interrupt: Transfer Complete--\n", chnum); + if (!urb) + goto handle_xfercomp_done; + + pipe_type = dwc2_hcd_get_pipe_type(&urb->pipe_info); + if (hsotg->core_params->dma_desc_enable > 0) { dwc2_hcd_complete_xfer_ddma(hsotg, chan, chnum, halt_status); if (pipe_type == USB_ENDPOINT_XFER_ISOC) @@ -1005,9 +1010,6 @@ static void dwc2_hc_xfercomp_intr(struct dwc2_hsotg *hsotg, } } - if (!urb) - goto handle_xfercomp_done; - /* Update the QTD and URB states */ switch (pipe_type) { case USB_ENDPOINT_XFER_CONTROL: @@ -1105,7 +1107,7 @@ static void dwc2_hc_stall_intr(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd) { struct dwc2_hcd_urb *urb = qtd->urb; - int pipe_type = dwc2_hcd_get_pipe_type(&urb->pipe_info); + int pipe_type; dev_dbg(hsotg->dev, "--Host Channel %d Interrupt: STALL Received--\n", chnum); @@ -1119,6 +1121,8 @@ static void dwc2_hc_stall_intr(struct dwc2_hsotg *hsotg, if (!urb) goto handle_stall_halt; + pipe_type = dwc2_hcd_get_pipe_type(&urb->pipe_info); + if (pipe_type == USB_ENDPOINT_XFER_CONTROL) dwc2_host_complete(hsotg, qtd, -EPIPE); |