Skip to content

Commit

Permalink
usb: dwc2: gadget: Add functionality to exit from LPM L1 state
Browse files Browse the repository at this point in the history
Add a function which will be called if device is in L1 sleep state
and Resume/Remote Wakeup Detected interrupt is asserted.

Signed-off-by: Sevak Arakelyan <sevaka@synopsys.com>
Signed-off-by: Grigor Tovmasyan <tovmasya@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
  • Loading branch information
Sevak Arakelyan authored and Felipe Balbi committed Mar 13, 2018
1 parent 6f80b6d commit 273d576
Showing 1 changed file with 52 additions and 0 deletions.
52 changes: 52 additions & 0 deletions drivers/usb/dwc2/core_intr.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,53 @@ static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg)
}
}

/**
* dwc2_wakeup_from_lpm_l1 - Exit the device from LPM L1 state
*
* @hsotg: Programming view of DWC_otg controller
*
*/
static void dwc2_wakeup_from_lpm_l1(struct dwc2_hsotg *hsotg)
{
u32 glpmcfg;
u32 i = 0;

if (hsotg->lx_state != DWC2_L1) {
dev_err(hsotg->dev, "Core isn't in DWC2_L1 state\n");
return;
}

glpmcfg = dwc2_readl(hsotg->regs + GLPMCFG);
if (dwc2_is_device_mode(hsotg)) {
dev_dbg(hsotg->dev, "Exit from L1 state\n");
glpmcfg &= ~GLPMCFG_ENBLSLPM;
glpmcfg &= ~GLPMCFG_HIRD_THRES_EN;
dwc2_writel(glpmcfg, hsotg->regs + GLPMCFG);

do {
glpmcfg = dwc2_readl(hsotg->regs + GLPMCFG);

if (!(glpmcfg & (GLPMCFG_COREL1RES_MASK |
GLPMCFG_L1RESUMEOK | GLPMCFG_SLPSTS)))
break;

udelay(1);
} while (++i < 200);

if (i == 200) {
dev_err(hsotg->dev, "Failed to exit L1 sleep state in 200us.\n");
return;
}
} else {
/* TODO */
dev_err(hsotg->dev, "Host side LPM is not supported.\n");
return;
}

/* Change to L0 state */
hsotg->lx_state = DWC2_L0;
}

/*
* This interrupt indicates that the DWC_otg controller has detected a
* resume or remote wakeup sequence. If the DWC_otg controller is in
Expand All @@ -352,6 +399,11 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg)
dev_dbg(hsotg->dev, "++Resume or Remote Wakeup Detected Interrupt++\n");
dev_dbg(hsotg->dev, "%s lxstate = %d\n", __func__, hsotg->lx_state);

if (hsotg->lx_state == DWC2_L1) {
dwc2_wakeup_from_lpm_l1(hsotg);
return;
}

if (dwc2_is_device_mode(hsotg)) {
dev_dbg(hsotg->dev, "DSTS=0x%0x\n",
dwc2_readl(hsotg->regs + DSTS));
Expand Down

0 comments on commit 273d576

Please sign in to comment.