From b4b7ff4b08e691656c9d77c758fc355833128ac0 Mon Sep 17 00:00:00 2001 From: André Fabian Silva Delgado Date: Wed, 20 Jan 2016 14:01:31 -0300 Subject: Linux-libre 4.4-gnu --- drivers/usb/dwc2/core_intr.c | 106 ++++++++++++++++++++++++------------------- 1 file changed, 60 insertions(+), 46 deletions(-) (limited to 'drivers/usb/dwc2/core_intr.c') diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index 927be1e8b..27daa4278 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -80,15 +80,15 @@ static const char *dwc2_op_state_str(struct dwc2_hsotg *hsotg) */ static void dwc2_handle_usb_port_intr(struct dwc2_hsotg *hsotg) { - u32 hprt0 = readl(hsotg->regs + HPRT0); + u32 hprt0 = dwc2_readl(hsotg->regs + HPRT0); if (hprt0 & HPRT0_ENACHG) { hprt0 &= ~HPRT0_ENA; - writel(hprt0, hsotg->regs + HPRT0); + dwc2_writel(hprt0, hsotg->regs + HPRT0); } /* Clear interrupt */ - writel(GINTSTS_PRTINT, hsotg->regs + GINTSTS); + dwc2_writel(GINTSTS_PRTINT, hsotg->regs + GINTSTS); } /** @@ -102,7 +102,7 @@ static void dwc2_handle_mode_mismatch_intr(struct dwc2_hsotg *hsotg) dwc2_is_host_mode(hsotg) ? "Host" : "Device"); /* Clear interrupt */ - writel(GINTSTS_MODEMIS, hsotg->regs + GINTSTS); + dwc2_writel(GINTSTS_MODEMIS, hsotg->regs + GINTSTS); } /** @@ -117,8 +117,8 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg) u32 gotgctl; u32 gintmsk; - gotgint = readl(hsotg->regs + GOTGINT); - gotgctl = readl(hsotg->regs + GOTGCTL); + gotgint = dwc2_readl(hsotg->regs + GOTGINT); + gotgctl = dwc2_readl(hsotg->regs + GOTGCTL); dev_dbg(hsotg->dev, "++OTG Interrupt gotgint=%0x [%s]\n", gotgint, dwc2_op_state_str(hsotg)); @@ -126,10 +126,10 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg) dev_dbg(hsotg->dev, " ++OTG Interrupt: Session End Detected++ (%s)\n", dwc2_op_state_str(hsotg)); - gotgctl = readl(hsotg->regs + GOTGCTL); + gotgctl = dwc2_readl(hsotg->regs + GOTGCTL); if (dwc2_is_device_mode(hsotg)) - s3c_hsotg_disconnect(hsotg); + dwc2_hsotg_disconnect(hsotg); if (hsotg->op_state == OTG_STATE_B_HOST) { hsotg->op_state = OTG_STATE_B_PERIPHERAL; @@ -152,15 +152,15 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg) hsotg->lx_state = DWC2_L0; } - gotgctl = readl(hsotg->regs + GOTGCTL); + gotgctl = dwc2_readl(hsotg->regs + GOTGCTL); gotgctl &= ~GOTGCTL_DEVHNPEN; - writel(gotgctl, hsotg->regs + GOTGCTL); + dwc2_writel(gotgctl, hsotg->regs + GOTGCTL); } if (gotgint & GOTGINT_SES_REQ_SUC_STS_CHNG) { dev_dbg(hsotg->dev, " ++OTG Interrupt: Session Request Success Status Change++\n"); - gotgctl = readl(hsotg->regs + GOTGCTL); + gotgctl = dwc2_readl(hsotg->regs + GOTGCTL); if (gotgctl & GOTGCTL_SESREQSCS) { if (hsotg->core_params->phy_type == DWC2_PHY_TYPE_PARAM_FS @@ -168,9 +168,9 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg) hsotg->srp_success = 1; } else { /* Clear Session Request */ - gotgctl = readl(hsotg->regs + GOTGCTL); + gotgctl = dwc2_readl(hsotg->regs + GOTGCTL); gotgctl &= ~GOTGCTL_SESREQ; - writel(gotgctl, hsotg->regs + GOTGCTL); + dwc2_writel(gotgctl, hsotg->regs + GOTGCTL); } } } @@ -180,7 +180,7 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg) * Print statements during the HNP interrupt handling * can cause it to fail */ - gotgctl = readl(hsotg->regs + GOTGCTL); + gotgctl = dwc2_readl(hsotg->regs + GOTGCTL); /* * WA for 3.00a- HW is not setting cur_mode, even sometimes * this does not help @@ -200,9 +200,9 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg) * interrupt does not get handled and Linux * complains loudly. */ - gintmsk = readl(hsotg->regs + GINTMSK); + gintmsk = dwc2_readl(hsotg->regs + GINTMSK); gintmsk &= ~GINTSTS_SOF; - writel(gintmsk, hsotg->regs + GINTMSK); + dwc2_writel(gintmsk, hsotg->regs + GINTMSK); /* * Call callback function with spin lock @@ -216,9 +216,9 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg) hsotg->op_state = OTG_STATE_B_HOST; } } else { - gotgctl = readl(hsotg->regs + GOTGCTL); + gotgctl = dwc2_readl(hsotg->regs + GOTGCTL); gotgctl &= ~(GOTGCTL_HNPREQ | GOTGCTL_DEVHNPEN); - writel(gotgctl, hsotg->regs + GOTGCTL); + dwc2_writel(gotgctl, hsotg->regs + GOTGCTL); dev_dbg(hsotg->dev, "HNP Failed\n"); dev_err(hsotg->dev, "Device Not Connected/Responding\n"); @@ -244,9 +244,9 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg) hsotg->op_state = OTG_STATE_A_PERIPHERAL; } else { /* Need to disable SOF interrupt immediately */ - gintmsk = readl(hsotg->regs + GINTMSK); + gintmsk = dwc2_readl(hsotg->regs + GINTMSK); gintmsk &= ~GINTSTS_SOF; - writel(gintmsk, hsotg->regs + GINTMSK); + dwc2_writel(gintmsk, hsotg->regs + GINTMSK); spin_unlock(&hsotg->lock); dwc2_hcd_start(hsotg); spin_lock(&hsotg->lock); @@ -261,7 +261,7 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg) dev_dbg(hsotg->dev, " ++OTG Interrupt: Debounce Done++\n"); /* Clear GOTGINT */ - writel(gotgint, hsotg->regs + GOTGINT); + dwc2_writel(gotgint, hsotg->regs + GOTGINT); } /** @@ -276,11 +276,11 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg) */ static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg) { - u32 gintmsk = readl(hsotg->regs + GINTMSK); + u32 gintmsk = dwc2_readl(hsotg->regs + GINTMSK); /* Need to disable SOF interrupt immediately */ gintmsk &= ~GINTSTS_SOF; - writel(gintmsk, hsotg->regs + GINTMSK); + dwc2_writel(gintmsk, hsotg->regs + GINTMSK); dev_dbg(hsotg->dev, " ++Connector ID Status Change Interrupt++ (%s)\n", dwc2_is_host_mode(hsotg) ? "Host" : "Device"); @@ -297,7 +297,7 @@ static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg) } /* Clear interrupt */ - writel(GINTSTS_CONIDSTSCHNG, hsotg->regs + GINTSTS); + dwc2_writel(GINTSTS_CONIDSTSCHNG, hsotg->regs + GINTSTS); } /** @@ -313,16 +313,28 @@ static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg) */ static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg) { - dev_dbg(hsotg->dev, "++Session Request Interrupt++\n"); + int ret; + + dev_dbg(hsotg->dev, "Session request interrupt - lx_state=%d\n", + hsotg->lx_state); /* Clear interrupt */ - writel(GINTSTS_SESSREQINT, hsotg->regs + GINTSTS); + dwc2_writel(GINTSTS_SESSREQINT, hsotg->regs + GINTSTS); - /* - * Report disconnect if there is any previous session established - */ - if (dwc2_is_device_mode(hsotg)) - s3c_hsotg_disconnect(hsotg); + if (dwc2_is_device_mode(hsotg)) { + if (hsotg->lx_state == DWC2_L2) { + ret = dwc2_exit_hibernation(hsotg, true); + if (ret && (ret != -ENOTSUPP)) + dev_err(hsotg->dev, + "exit hibernation failed\n"); + } + + /* + * Report disconnect if there is any previous session + * established + */ + dwc2_hsotg_disconnect(hsotg); + } } /* @@ -339,13 +351,14 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg) dev_dbg(hsotg->dev, "%s lxstate = %d\n", __func__, hsotg->lx_state); if (dwc2_is_device_mode(hsotg)) { - dev_dbg(hsotg->dev, "DSTS=0x%0x\n", readl(hsotg->regs + DSTS)); + dev_dbg(hsotg->dev, "DSTS=0x%0x\n", + dwc2_readl(hsotg->regs + DSTS)); if (hsotg->lx_state == DWC2_L2) { - u32 dctl = readl(hsotg->regs + DCTL); + u32 dctl = dwc2_readl(hsotg->regs + DCTL); /* Clear Remote Wakeup Signaling */ dctl &= ~DCTL_RMTWKUPSIG; - writel(dctl, hsotg->regs + DCTL); + dwc2_writel(dctl, hsotg->regs + DCTL); ret = dwc2_exit_hibernation(hsotg, true); if (ret && (ret != -ENOTSUPP)) dev_err(hsotg->dev, "exit hibernation failed\n"); @@ -355,12 +368,16 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg) /* Change to L0 state */ hsotg->lx_state = DWC2_L0; } else { + if (hsotg->core_params->hibernation) { + dwc2_writel(GINTSTS_WKUPINT, hsotg->regs + GINTSTS); + return; + } if (hsotg->lx_state != DWC2_L1) { - u32 pcgcctl = readl(hsotg->regs + PCGCTL); + u32 pcgcctl = dwc2_readl(hsotg->regs + PCGCTL); /* Restart the Phy Clock */ pcgcctl &= ~PCGCTL_STOPPCLK; - writel(pcgcctl, hsotg->regs + PCGCTL); + dwc2_writel(pcgcctl, hsotg->regs + PCGCTL); mod_timer(&hsotg->wkp_timer, jiffies + msecs_to_jiffies(71)); } else { @@ -370,7 +387,7 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg) } /* Clear interrupt */ - writel(GINTSTS_WKUPINT, hsotg->regs + GINTSTS); + dwc2_writel(GINTSTS_WKUPINT, hsotg->regs + GINTSTS); } /* @@ -386,10 +403,7 @@ static void dwc2_handle_disconnect_intr(struct dwc2_hsotg *hsotg) if (hsotg->op_state == OTG_STATE_A_HOST) dwc2_hcd_disconnect(hsotg); - /* Change to L3 (OFF) state */ - hsotg->lx_state = DWC2_L3; - - writel(GINTSTS_DISCONNINT, hsotg->regs + GINTSTS); + dwc2_writel(GINTSTS_DISCONNINT, hsotg->regs + GINTSTS); } /* @@ -412,7 +426,7 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg) * Check the Device status register to determine if the Suspend * state is active */ - dsts = readl(hsotg->regs + DSTS); + dsts = dwc2_readl(hsotg->regs + DSTS); dev_dbg(hsotg->dev, "DSTS=0x%0x\n", dsts); dev_dbg(hsotg->dev, "DSTS.Suspend Status=%d HWCFG4.Power Optimize=%d\n", @@ -465,7 +479,7 @@ skip_power_saving: clear_int: /* Clear interrupt */ - writel(GINTSTS_USBSUSP, hsotg->regs + GINTSTS); + dwc2_writel(GINTSTS_USBSUSP, hsotg->regs + GINTSTS); } #define GINTMSK_COMMON (GINTSTS_WKUPINT | GINTSTS_SESSREQINT | \ @@ -483,9 +497,9 @@ static u32 dwc2_read_common_intr(struct dwc2_hsotg *hsotg) u32 gahbcfg; u32 gintmsk_common = GINTMSK_COMMON; - gintsts = readl(hsotg->regs + GINTSTS); - gintmsk = readl(hsotg->regs + GINTMSK); - gahbcfg = readl(hsotg->regs + GAHBCFG); + gintsts = dwc2_readl(hsotg->regs + GINTSTS); + gintmsk = dwc2_readl(hsotg->regs + GINTMSK); + gahbcfg = dwc2_readl(hsotg->regs + GAHBCFG); /* If any common interrupts set */ if (gintsts & gintmsk_common) -- cgit v1.2.3-54-g00ecf