Skip to content

Commit

Permalink
usb: dwc2: gadget: LPM interrupt handler
Browse files Browse the repository at this point in the history
This interrupt indicates that an LPM transaction
was received on the USB bus. After getting this
interrupt we are going from L0 state to L1 state.

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 273d576 commit d252184
Showing 1 changed file with 63 additions and 0 deletions.
63 changes: 63 additions & 0 deletions drivers/usb/dwc2/core_intr.c
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,67 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg)
}
}

/**
* dwc2_handle_lpm_intr - GINTSTS_LPMTRANRCVD Interrupt handler
*
* @hsotg: Programming view of DWC_otg controller
*
*/
static void dwc2_handle_lpm_intr(struct dwc2_hsotg *hsotg)
{
u32 glpmcfg;
u32 pcgcctl;
u32 hird;
u32 hird_thres;
u32 hird_thres_en;
u32 enslpm;

/* Clear interrupt */
dwc2_writel(GINTSTS_LPMTRANRCVD, hsotg->regs + GINTSTS);

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

if (!(glpmcfg & GLPMCFG_LPMCAP)) {
dev_err(hsotg->dev, "Unexpected LPM interrupt\n");
return;
}

hird = (glpmcfg & GLPMCFG_HIRD_MASK) >> GLPMCFG_HIRD_SHIFT;
hird_thres = (glpmcfg & GLPMCFG_HIRD_THRES_MASK &
~GLPMCFG_HIRD_THRES_EN) >> GLPMCFG_HIRD_THRES_SHIFT;
hird_thres_en = glpmcfg & GLPMCFG_HIRD_THRES_EN;
enslpm = glpmcfg & GLPMCFG_SNDLPM;

if (dwc2_is_device_mode(hsotg)) {
dev_dbg(hsotg->dev, "HIRD_THRES_EN = %d\n", hird_thres_en);

if (hird_thres_en && hird >= hird_thres) {
dev_dbg(hsotg->dev, "L1 with utmi_l1_suspend_n\n");
} else if (enslpm) {
dev_dbg(hsotg->dev, "L1 with utmi_sleep_n\n");
} else {
dev_dbg(hsotg->dev, "Entering Sleep with L1 Gating\n");

pcgcctl = dwc2_readl(hsotg->regs + PCGCTL);
pcgcctl |= PCGCTL_ENBL_SLEEP_GATING;
dwc2_writel(pcgcctl, hsotg->regs + PCGCTL);
}
/**
* Examine prt_sleep_sts after TL1TokenTetry period max (10 us)
*/
udelay(10);

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

if (glpmcfg & GLPMCFG_SLPSTS) {
/* Save the current state */
hsotg->lx_state = DWC2_L1;
dev_dbg(hsotg->dev,
"Core is in L1 sleep glpmcfg=%08x\n", glpmcfg);
}
}
}

#define GINTMSK_COMMON (GINTSTS_WKUPINT | GINTSTS_SESSREQINT | \
GINTSTS_CONIDSTSCHNG | GINTSTS_OTGINT | \
GINTSTS_MODEMIS | GINTSTS_DISCONNINT | \
Expand Down Expand Up @@ -605,6 +666,8 @@ irqreturn_t dwc2_handle_common_intr(int irq, void *dev)
dwc2_handle_wakeup_detected_intr(hsotg);
if (gintsts & GINTSTS_USBSUSP)
dwc2_handle_usb_suspend_intr(hsotg);
if (gintsts & GINTSTS_LPMTRANRCVD)
dwc2_handle_lpm_intr(hsotg);

if (gintsts & GINTSTS_PRTINT) {
/*
Expand Down

0 comments on commit d252184

Please sign in to comment.