RE: [PATCH v1 02/32] usb: dwc2: host: create a function to handle port_resume

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> -----Original Message-----
> From: dianders@xxxxxxxxxx [mailto:dianders@xxxxxxxxxx] On Behalf Of
> Doug Anderson
> Sent: Thursday, September 17, 2015 9:42 PM
> To: Kaukab, Yousaf
> Cc: linux-usb@xxxxxxxxxxxxxxx; Felipe Balbi; John Youn; Herrero, Gregory; Heiko
> Stübner; r.baldyga@xxxxxxxxxxx; Dinh Nguyen; Zhangfei Gao;
> sergei.shtylyov@xxxxxxxxxxxxxxxxxx; david.a.cohen@xxxxxxxxxxxxxxx
> Subject: Re: [PATCH v1 02/32] usb: dwc2: host: create a function to handle
> port_resume
> 
> Hi,
> 
> On Wed, Sep 9, 2015 at 3:20 AM, Mian Yousaf Kaukab
> <yousaf.kaukab@xxxxxxxxx> wrote:
> > From: Gregory Herrero <gregory.herrero@xxxxxxxxx>
> >
> > port resume sequence may be used in different places. Create a
> > function to handle it. Moreover, make hprt0 read-modify-write atomic.
> >
> > Signed-off-by: Gregory Herrero <gregory.herrero@xxxxxxxxx>
> > Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@xxxxxxxxx>
> > Tested-by: Robert Baldyga <r.baldyga@xxxxxxxxxxx>
> > ---
> >  drivers/usb/dwc2/hcd.c | 30 ++++++++++++++++++++++--------
> >  1 file changed, 22 insertions(+), 8 deletions(-)
> >
> > diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index
> > 007a3d5..0cef770 100644
> > --- a/drivers/usb/dwc2/hcd.c
> > +++ b/drivers/usb/dwc2/hcd.c
> > @@ -1484,6 +1484,27 @@ static void dwc2_port_suspend(struct dwc2_hsotg
> *hsotg, u16 windex)
> >         }
> >  }
> >
> > +/* Must NOT be called with interrupt disabled or spinlock held */
> > +static void dwc2_port_resume(struct dwc2_hsotg *hsotg) {
> > +       unsigned long flags;
> > +       u32 hprt0;
> > +
> > +       spin_lock_irqsave(&hsotg->lock, flags);
> > +       hprt0 = dwc2_read_hprt0(hsotg);
> > +       hprt0 |= HPRT0_RES;
> > +       hprt0 &= ~HPRT0_SUSP;
> > +       writel(hprt0, hsotg->regs + HPRT0);
> 
> Just from a completely "what changed" point of view, you have made a non-
> obvious behavior change here.  Previously the code only masked out
> HPRT0_SUSP in the 2nd write, not the first.  Was that a bug in the old code, or
> does it just not matter?

It doesn't matter. I will add this to the change log anyway.
HPRT0_SUSP is "read, write-set, and self-clear (R_WS_SC)" Application
can only set it and writing 0 has no effect. Hardware should clear it
when we set HPRT0_RES. So it doesn't matter if it is set in the first
write. But since we are clearing it, it's better to  clear it for both
writes. So that there is no chance hardware can see this as another
assertion of this bit.

> 
> > +       spin_unlock_irqrestore(&hsotg->lock, flags);
> > +
> > +       msleep(USB_RESUME_TIMEOUT);
> > +
> > +       spin_lock_irqsave(&hsotg->lock, flags);
> > +       hprt0 &= ~HPRT0_RES;
> > +       writel(hprt0, hsotg->regs + HPRT0);
> 
> Just curious: since you released and re-grabbed the lock, shouldn't you re-read
> HPRT0?

Agree we should. I will update the patch.

> 
> Also: one thing that was added in my local tree here was to make things
> parallel to dwc2_port_suspend() and update "hsotg->lx_state"
> here.  I'm not sure if it was added it because there as a real issue or if it just
> seemed better...
> 
> > +       spin_unlock_irqrestore(&hsotg->lock, flags); }
> > +
> >  /* Handles hub class-specific requests */  static int
> > dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
> >                                 u16 wvalue, u16 windex, char *buf, u16
> > wlength) @@ -1532,14 +1553,7 @@ static int dwc2_hcd_hub_control(struct
> dwc2_hsotg *hsotg, u16 typereq,
> >                         writel(0, hsotg->regs + PCGCTL);
> >                         usleep_range(20000, 40000);
> 
> In my local tree we already had a dwc2_port_resume() function and it included
> the two lines above.  I presume you didn't include them in your patch because
> future callers of  dwc2_port_resume() don't want those lines.  That's fine, but I
> figured I'd mention it...

dwc2_exit_hibernation() is taking care of it for the other caller. It's better to 
move this to dwc2_port_resume() to keep it balanced with dwc2_port_suspend().
I will update " usb: dwc2: host: enter hibernation during bus suspend" to add the
core_params->hibernation check to this new part as well.
> 
> >
> > -                       hprt0 = dwc2_read_hprt0(hsotg);
> > -                       hprt0 |= HPRT0_RES;
> > -                       writel(hprt0, hsotg->regs + HPRT0);
> > -                       hprt0 &= ~HPRT0_SUSP;
> > -                       msleep(USB_RESUME_TIMEOUT);
> > -
> > -                       hprt0 &= ~HPRT0_RES;
> > -                       writel(hprt0, hsotg->regs + HPRT0);
> > +                       dwc2_port_resume(hsotg);
> >                         break;
> >
> >                 case USB_PORT_FEAT_POWER:
> 
> -Doug

BR,
Yousaf
��.n��������+%������w��{.n�����{���)��jg��������ݢj����G�������j:+v���w�m������w�������h�����٥




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux