Message ID | 8f99e3ceb45ede4526363bd9b44d417a6b6ff5cd.1555075928.git.arturp@synopsys.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | usb: dwc2: Fix and improve power saving modes. | expand |
Hi Artur, On Fri, Apr 12, 2019 at 01:38:56PM +0000, Artur Petrosyan wrote: > In host mode port power must be turned on when wakeup > detected or session request interrupt is detected. > Because, otherwise core wouldn't exit form partial > power down. > > - Turned on the port power by setting HPRT0_PWR bit. > > - Called dwc2_hcd_connect() function after enabling > the power of the port. > > Signed-off-by: Artur Petrosyan <arturp@synopsys.com> > --- > drivers/usb/dwc2/core_intr.c | 24 +++++++++++++++++++++--- > 1 file changed, 21 insertions(+), 3 deletions(-) > > diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c > index 19ae2595f1c3..ce523fd2b1b4 100644 > --- a/drivers/usb/dwc2/core_intr.c > +++ b/drivers/usb/dwc2/core_intr.c > @@ -312,6 +312,7 @@ static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg) > static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg) > { > int ret; > + u32 hprt0; > > /* Clear interrupt */ > dwc2_writel(hsotg, GINTSTS_SESSREQINT, GINTSTS); > @@ -320,7 +321,8 @@ static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg) > hsotg->lx_state); > > if (dwc2_is_device_mode(hsotg)) { > - if (hsotg->lx_state == DWC2_L2) { > + if (hsotg->lx_state == DWC2_L2 && > + hsotg->params.power_down == 1) { I think you can replace 1 with DWC2_POWER_DOWN_PARAM_PARTIAL. [snip] --- Best, Jules
Hi Jules, On 4/12/2019 18:21, Jules Maselbas wrote: > Hi Artur, > > On Fri, Apr 12, 2019 at 01:38:56PM +0000, Artur Petrosyan wrote: >> In host mode port power must be turned on when wakeup >> detected or session request interrupt is detected. >> Because, otherwise core wouldn't exit form partial >> power down. >> >> - Turned on the port power by setting HPRT0_PWR bit. >> >> - Called dwc2_hcd_connect() function after enabling >> the power of the port. >> >> Signed-off-by: Artur Petrosyan <arturp@synopsys.com> >> --- >> drivers/usb/dwc2/core_intr.c | 24 +++++++++++++++++++++--- >> 1 file changed, 21 insertions(+), 3 deletions(-) >> >> diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c >> index 19ae2595f1c3..ce523fd2b1b4 100644 >> --- a/drivers/usb/dwc2/core_intr.c >> +++ b/drivers/usb/dwc2/core_intr.c >> @@ -312,6 +312,7 @@ static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg) >> static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg) >> { >> int ret; >> + u32 hprt0; >> >> /* Clear interrupt */ >> dwc2_writel(hsotg, GINTSTS_SESSREQINT, GINTSTS); >> @@ -320,7 +321,8 @@ static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg) >> hsotg->lx_state); >> >> if (dwc2_is_device_mode(hsotg)) { >> - if (hsotg->lx_state == DWC2_L2) { >> + if (hsotg->lx_state == DWC2_L2 && >> + hsotg->params.power_down == 1) { > I think you can replace 1 with DWC2_POWER_DOWN_PARAM_PARTIAL. Thank you for the review. Yeah, you are right it should be updated. > > [snip] > > --- > Best, > Jules > >
diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index 19ae2595f1c3..ce523fd2b1b4 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -312,6 +312,7 @@ static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg) static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg) { int ret; + u32 hprt0; /* Clear interrupt */ dwc2_writel(hsotg, GINTSTS_SESSREQINT, GINTSTS); @@ -320,7 +321,8 @@ static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg) hsotg->lx_state); if (dwc2_is_device_mode(hsotg)) { - if (hsotg->lx_state == DWC2_L2) { + if (hsotg->lx_state == DWC2_L2 && + hsotg->params.power_down == 1) { ret = dwc2_exit_partial_power_down(hsotg, true); if (ret && (ret != -ENOTSUPP)) dev_err(hsotg->dev, @@ -332,6 +334,14 @@ static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg) * established */ dwc2_hsotg_disconnect(hsotg); + } else { + /* Turn on the port power bit. */ + hprt0 = dwc2_read_hprt0(hsotg); + hprt0 |= HPRT0_PWR; + dwc2_writel(hsotg, hprt0, HPRT0); + + /* Connect hcd after port power is set. */ + dwc2_hcd_connect(hsotg); } } @@ -396,6 +406,7 @@ static void dwc2_wakeup_from_lpm_l1(struct dwc2_hsotg *hsotg) static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg) { int ret; + u32 hprt0; /* Clear interrupt */ dwc2_writel(hsotg, GINTSTS_WKUPINT, GINTSTS); @@ -426,8 +437,6 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg) /* Change to L0 state */ hsotg->lx_state = DWC2_L0; } else { - if (hsotg->params.power_down) - return; if (hsotg->lx_state != DWC2_L1) { u32 pcgcctl = dwc2_readl(hsotg, PCGCTL); @@ -435,6 +444,15 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg) /* Restart the Phy Clock */ pcgcctl &= ~PCGCTL_STOPPCLK; dwc2_writel(hsotg, pcgcctl, PCGCTL); + + /* Turn on the port power bit. */ + hprt0 = dwc2_read_hprt0(hsotg); + hprt0 |= HPRT0_PWR; + dwc2_writel(hsotg, hprt0, HPRT0); + + /* Connect hcd. */ + dwc2_hcd_connect(hsotg); + mod_timer(&hsotg->wkp_timer, jiffies + msecs_to_jiffies(71)); } else {
In host mode port power must be turned on when wakeup detected or session request interrupt is detected. Because, otherwise core wouldn't exit form partial power down. - Turned on the port power by setting HPRT0_PWR bit. - Called dwc2_hcd_connect() function after enabling the power of the port. Signed-off-by: Artur Petrosyan <arturp@synopsys.com> --- drivers/usb/dwc2/core_intr.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-)