All of lore.kernel.org
 help / color / mirror / Atom feed
From: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
To: Doug Anderson <dianders@chromium.org>
Cc: Felipe Balbi <balbi@kernel.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>,
	"linux-usb@vger.kernel.org" <linux-usb@vger.kernel.org>,
	John Youn <John.Youn@synopsys.com>
Subject: [v1,14/14] usb: dwc2: Add enter/exit hibernation from system issued suspend/resume
Date: Mon, 29 Apr 2019 12:01:16 +0000	[thread overview]
Message-ID: <SN1PR12MB24313212A9F1574A4D00C3B3A7390@SN1PR12MB2431.namprd12.prod.outlook.com> (raw)

Hi,

On 4/27/2019 01:01, Doug Anderson wrote:
> Hi,
> 
> On Fri, Apr 19, 2019 at 1:05 PM Artur Petrosyan
> <Arthur.Petrosyan@synopsys.com> wrote:
>>
>> Added a new flow of entering and exiting hibernation when PC is
>> hibernated or suspended.
>>
>> Signed-off-by: Artur Petrosyan <arturp@synopsys.com>
>> ---
>>   drivers/usb/dwc2/hcd.c | 128 +++++++++++++++++++++++++++++++------------------
>>   1 file changed, 81 insertions(+), 47 deletions(-)
>>
>> diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
>> index 45d4a3e1ebd2..f1e92a287cb1 100644
>> --- a/drivers/usb/dwc2/hcd.c
>> +++ b/drivers/usb/dwc2/hcd.c
>> @@ -4510,35 +4510,54 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd)
>>          if (hsotg->op_state == OTG_STATE_B_PERIPHERAL)
>>                  goto unlock;
>>
>> -       if (hsotg->params.power_down != DWC2_POWER_DOWN_PARAM_PARTIAL ||
>> +       if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_NONE ||
>>              hsotg->flags.b.port_connect_status == 0)
>>                  goto skip_power_saving;
>>
>> -       /*
>> -        * Drive USB suspend and disable port Power
>> -        * if usb bus is not suspended.
>> -        */
>> -       if (!hsotg->bus_suspended) {
>> -               hprt0 = dwc2_read_hprt0(hsotg);
>> -               hprt0 |= HPRT0_SUSP;
>> -               hprt0 &= ~HPRT0_PWR;
>> -               dwc2_writel(hsotg, hprt0, HPRT0);
>> -               spin_unlock_irqrestore(&hsotg->lock, flags);
>> -               dwc2_vbus_supply_exit(hsotg);
>> -               spin_lock_irqsave(&hsotg->lock, flags);
>> -       }
>> +       switch (hsotg->params.power_down) {
>> +       case DWC2_POWER_DOWN_PARAM_PARTIAL:
>> +               /*
>> +                * Drive USB suspend and disable port Power
>> +                * if usb bus is not suspended.
>> +                */
>> +               if (!hsotg->bus_suspended) {
>> +                       hprt0 = dwc2_read_hprt0(hsotg);
>> +                       hprt0 |= HPRT0_SUSP;
>> +                       hprt0 &= ~HPRT0_PWR;
>> +                       dwc2_writel(hsotg, hprt0, HPRT0);
>> +                       spin_unlock_irqrestore(&hsotg->lock, flags);
>> +                       dwc2_vbus_supply_exit(hsotg);
>> +                       spin_lock_irqsave(&hsotg->lock, flags);
>> +               }
>>
>> -       /* Enter partial_power_down */
>> -       ret = dwc2_enter_partial_power_down(hsotg);
>> -       if (ret) {
>> -               if (ret != -ENOTSUPP)
>> -                       dev_err(hsotg->dev,
>> -                               "enter partial_power_down failed\n");
>> +               /* Enter partial_power_down */
>> +               ret = dwc2_enter_partial_power_down(hsotg);
>> +               if (ret) {
>> +                       if (ret != -ENOTSUPP)
>> +                               dev_err(hsotg->dev,
>> +                                       "enter partial_power_down failed\n");
>> +                       goto skip_power_saving;
>> +               }
>> +               hsotg->bus_suspended = true;
>> +               break;
>> +       case DWC2_POWER_DOWN_PARAM_HIBERNATION:
>> +               if (!hsotg->bus_suspended) {
> 
> Do you have any idea why for DWC2_POWER_DOWN_PARAM_PARTIAL we still
> call dwc2_enter_partial_power_down() even if bus_suspended is true,
> but for hibernate you don't call dwc2_enter_hibernation()?
For Hibernation I do call dwc2_enter_hibernation().

> 
> 
>> +                       /* Enter hibernation */
>> +                       spin_unlock_irqrestore(&hsotg->lock, flags);
>> +                       ret = dwc2_enter_hibernation(hsotg, 1);
>> +                       spin_lock_irqsave(&hsotg->lock, flags);
>> +                       if (ret && ret != -ENOTSUPP)
>> +                               dev_err(hsotg->dev,
>> +                                       "%s: enter hibernation failed\n",
>> +                                       __func__);
> 
> nit: no __func__ in dev_xxx() error messages.  The device plus the
> message should be enough.  Only resort to __func__ if you're forced to
> do an error message without a "struct device *".
This code comes form previous implementations I have not touched it not 
to back anything.

> 
> nit: as per my comments in an earlier patch, remove special case for -ENOTSUPP
> 
> Also, presumably you want to match the error handling in
> DWC2_POWER_DOWN_PARAM_PARTIAL and do a "goto skip_power_saving" when
> you see an error?
When there is an error power_saving should be skipped.

> 
> 
>> +               } else {
>> +                       goto skip_power_saving;
>> +               }
>> +               break;
>> +       default:
>>                  goto skip_power_saving;
>>          }
>>
>> -       hsotg->bus_suspended = true;
>> -
> 
> It's a bit weird to remove this, but I guess it just got moved to the
> partial power down case?  ...and in the hibernate case you're relying
> on the hibernate function to set this?  Yet another frustratingly
> asymmetric code structure...Enter hibernation implements setting bus_suspend so I don't touch this.
Actually this patch set fixes issues it doesn't clean up everything 
related to hibernation or partial power down.

> 
> 
>>          /* Ask phy to be suspended */
>>          if (!IS_ERR_OR_NULL(hsotg->uphy)) {
>>                  spin_unlock_irqrestore(&hsotg->lock, flags);
>> @@ -4564,17 +4583,17 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd)
>>          int ret = 0;
>>          u32 hprt0;
>>
>> -       hprt0 = dwc2_read_hprt0(hsotg);
>> -
>>          spin_lock_irqsave(&hsotg->lock, flags);
>>
>> -       if (dwc2_is_device_mode(hsotg))
>> +       if (!hsotg->bus_suspended)
> 
> As per my comments above I don't have a good grasp on what
> "bus_suspended" is for.  ...that being said, if your change here is
> actually correct then you probably (?) want to remove the "if
> (hsotg->bus_suspended)" check later in this same function.
> 
> Said another way, you've now got code that looks like:
> 
> if (!hsotg->bus_suspended)
>    goto exit;
> 
> /* code that I think doesn't touch bus_suspended */
> 
> if (hsotg->bus_suspended) {
>    /* do something */
> } else {
>    /* do something else */
> }
> 
> Presumably the "do something" is now dead code?
> 
That part is not dad because if hsotg->bus_suspended is true 
resuming/exiting from suspend/partial power down/hibernation should be 
performed.
On the other hand if hsotg->bus_suspended is false there is no need to 
resume.

So of course if core is not suspended the code responsible for resuming 
should not be called. In that sense the code can be called dead.

> 
>>                  goto unlock;
>>
>>          if (hsotg->lx_state != DWC2_L2)
>>                  goto unlock;
>>
>> -       if (hsotg->params.power_down != DWC2_POWER_DOWN_PARAM_PARTIAL ||
>> +       hprt0 = dwc2_read_hprt0(hsotg);
>> +
>> +       if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_NONE ||
>>              hprt0 & HPRT0_CONNSTS) {
>>                  hsotg->lx_state = DWC2_L0;
>>                  goto unlock;
>> @@ -4597,36 +4616,51 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd)
>>                  spin_lock_irqsave(&hsotg->lock, flags);
>>          }
>>
>> -       /* Exit partial_power_down */
>> -       ret = dwc2_exit_partial_power_down(hsotg, true);
>> -       if (ret && (ret != -ENOTSUPP))
>> -               dev_err(hsotg->dev, "exit partial_power_down failed\n");
>> +       switch (hsotg->params.power_down) {
>> +       case DWC2_POWER_DOWN_PARAM_PARTIAL:
>>
>> -       hsotg->lx_state = DWC2_L0;
>> +               /* Exit partial_power_down */
>> +               ret = dwc2_exit_partial_power_down(hsotg, true);
>> +               if (ret && (ret != -ENOTSUPP))
>> +                       dev_err(hsotg->dev, "exit partial_power_down failed\n");
>>
>> -       spin_unlock_irqrestore(&hsotg->lock, flags);
>> +               hsotg->lx_state = DWC2_L0;
>>
>> -       if (hsotg->bus_suspended) {
>> -               spin_lock_irqsave(&hsotg->lock, flags);
>> -               hsotg->flags.b.port_suspend_change = 1;
>>                  spin_unlock_irqrestore(&hsotg->lock, flags);
>> -               dwc2_port_resume(hsotg);
>> -       } else {
>> -               dwc2_vbus_supply_init(hsotg);
>>
>> -               /* Wait for controller to correctly update D+/D- level */
>> -               usleep_range(3000, 5000);
>> +               if (hsotg->bus_suspended) {
>> +                       spin_lock_irqsave(&hsotg->lock, flags);
>> +                       hsotg->flags.b.port_suspend_change = 1;
>> +                       spin_unlock_irqrestore(&hsotg->lock, flags);
>> +                       dwc2_port_resume(hsotg);
>> +               } else {
>> +                       dwc2_vbus_supply_init(hsotg);
>>
>> -               /*
>> -                * Clear Port Enable and Port Status changes.
>> -                * Enable Port Power.
>> -                */
>> -               dwc2_writel(hsotg, HPRT0_PWR | HPRT0_CONNDET |
>> +                       /* Wait for controller to correctly update D+/D- level */
>> +                       usleep_range(3000, 5000);
>> +
>> +                       /*
>> +                        * Clear Port Enable and Port Status changes.
>> +                        * Enable Port Power.
>> +                        */
>> +                       dwc2_writel(hsotg, HPRT0_PWR | HPRT0_CONNDET |
>>                                  HPRT0_ENACHG, HPRT0);
>> -               /* Wait for controller to detect Port Connect */
>> -               usleep_range(5000, 7000);
>> +                       /* Wait for controller to detect Port Connect */
>> +                       usleep_range(5000, 7000);
>> +               }
>> +               break;
>> +       case DWC2_POWER_DOWN_PARAM_HIBERNATION:
>> +
>> +               /* Exit host hibernation. */
>> +               if (hsotg->hibernated)
>> +                       dwc2_exit_hibernation(hsotg, 0, 0, 1);
>> +               break;
>> +       default:
>> +               goto unlock;
>>          }
>>
>> +       spin_unlock_irqrestore(&hsotg->lock, flags);
>> +
> 
> I'm pretty curious if you tested DWC2_POWER_DOWN_PARAM_PARTIAL after
> applying your patch series.  As far as I can tell your switch
> statement for DWC2_POWER_DOWN_PARAM_PARTIAL will "break" with the
> spinlock already unlocked.  ...so you'll run spin_unlock_irqrestore
> twice.  Is that really legit?
I have tested the patches on HAPS-DX and Linaro HiKey 960 boards.

> 
> 
> 
> NOTE: in case it helps you, I've attempted to rebase this atop my
> series.  Please double-check that I didn't mess anything up, though
> 
> https://urldefense.proofpoint.com/v2/url?u=https-3A__chromium.googlesource.com_chromiumos_third-5Fparty_kernel_-2Blog_refs_sandbox_dianders_190426-2Ddwc2-2Dstuff&d=DwIBaQ&c=DPL6_X_6JkXFx7AXWqB0tg&r=9hPBFKCJ_nBjJhGVrrlYOeOQjP_HlVzYqrC_D7niMJI&m=2xJPvFyQhKsjBCMYd6_Kpb7_r7HPUAoeJHcQmBH80Gc&s=wEgbdpKgC9t9CfXpI8awXLos9GuRcsNEkpW09dgMxiw&e=
> 
> 
> ...with that a quick test seems to show that partial power down is
> sorta working on rk3288 now.  I _think_ I saw one case where hotplug
> failed but I've seen several where it works.  ...unfortunately it
> seems to break when I do hotplug on the port where I have
> "snps,reset-phy-on-wake" set.
You can provide debug logs for that scenario I will try to help you fix 
issues with that.

> 
> -Doug
>

WARNING: multiple messages have this Message-ID (diff)
From: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
To: Doug Anderson <dianders@chromium.org>
Cc: Felipe Balbi <balbi@kernel.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>,
	"linux-usb@vger.kernel.org" <linux-usb@vger.kernel.org>,
	John Youn <John.Youn@synopsys.com>
Subject: Re: [PATCH v1 14/14] usb: dwc2: Add enter/exit hibernation from system issued suspend/resume
Date: Mon, 29 Apr 2019 12:01:16 +0000	[thread overview]
Message-ID: <SN1PR12MB24313212A9F1574A4D00C3B3A7390@SN1PR12MB2431.namprd12.prod.outlook.com> (raw)
Message-ID: <20190429120116.t3-pytzAMORGRyleNKxmKtTqmPwZCz5wCFPx7vaWVvs@z> (raw)
In-Reply-To: CAD=FV=VDVhA0qzBN13=3C44mAzhDaQBUia_QADqyggSSFwKXqQ@mail.gmail.com

Hi,

On 4/27/2019 01:01, Doug Anderson wrote:
> Hi,
> 
> On Fri, Apr 19, 2019 at 1:05 PM Artur Petrosyan
> <Arthur.Petrosyan@synopsys.com> wrote:
>>
>> Added a new flow of entering and exiting hibernation when PC is
>> hibernated or suspended.
>>
>> Signed-off-by: Artur Petrosyan <arturp@synopsys.com>
>> ---
>>   drivers/usb/dwc2/hcd.c | 128 +++++++++++++++++++++++++++++++------------------
>>   1 file changed, 81 insertions(+), 47 deletions(-)
>>
>> diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
>> index 45d4a3e1ebd2..f1e92a287cb1 100644
>> --- a/drivers/usb/dwc2/hcd.c
>> +++ b/drivers/usb/dwc2/hcd.c
>> @@ -4510,35 +4510,54 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd)
>>          if (hsotg->op_state == OTG_STATE_B_PERIPHERAL)
>>                  goto unlock;
>>
>> -       if (hsotg->params.power_down != DWC2_POWER_DOWN_PARAM_PARTIAL ||
>> +       if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_NONE ||
>>              hsotg->flags.b.port_connect_status == 0)
>>                  goto skip_power_saving;
>>
>> -       /*
>> -        * Drive USB suspend and disable port Power
>> -        * if usb bus is not suspended.
>> -        */
>> -       if (!hsotg->bus_suspended) {
>> -               hprt0 = dwc2_read_hprt0(hsotg);
>> -               hprt0 |= HPRT0_SUSP;
>> -               hprt0 &= ~HPRT0_PWR;
>> -               dwc2_writel(hsotg, hprt0, HPRT0);
>> -               spin_unlock_irqrestore(&hsotg->lock, flags);
>> -               dwc2_vbus_supply_exit(hsotg);
>> -               spin_lock_irqsave(&hsotg->lock, flags);
>> -       }
>> +       switch (hsotg->params.power_down) {
>> +       case DWC2_POWER_DOWN_PARAM_PARTIAL:
>> +               /*
>> +                * Drive USB suspend and disable port Power
>> +                * if usb bus is not suspended.
>> +                */
>> +               if (!hsotg->bus_suspended) {
>> +                       hprt0 = dwc2_read_hprt0(hsotg);
>> +                       hprt0 |= HPRT0_SUSP;
>> +                       hprt0 &= ~HPRT0_PWR;
>> +                       dwc2_writel(hsotg, hprt0, HPRT0);
>> +                       spin_unlock_irqrestore(&hsotg->lock, flags);
>> +                       dwc2_vbus_supply_exit(hsotg);
>> +                       spin_lock_irqsave(&hsotg->lock, flags);
>> +               }
>>
>> -       /* Enter partial_power_down */
>> -       ret = dwc2_enter_partial_power_down(hsotg);
>> -       if (ret) {
>> -               if (ret != -ENOTSUPP)
>> -                       dev_err(hsotg->dev,
>> -                               "enter partial_power_down failed\n");
>> +               /* Enter partial_power_down */
>> +               ret = dwc2_enter_partial_power_down(hsotg);
>> +               if (ret) {
>> +                       if (ret != -ENOTSUPP)
>> +                               dev_err(hsotg->dev,
>> +                                       "enter partial_power_down failed\n");
>> +                       goto skip_power_saving;
>> +               }
>> +               hsotg->bus_suspended = true;
>> +               break;
>> +       case DWC2_POWER_DOWN_PARAM_HIBERNATION:
>> +               if (!hsotg->bus_suspended) {
> 
> Do you have any idea why for DWC2_POWER_DOWN_PARAM_PARTIAL we still
> call dwc2_enter_partial_power_down() even if bus_suspended is true,
> but for hibernate you don't call dwc2_enter_hibernation()?
For Hibernation I do call dwc2_enter_hibernation().

> 
> 
>> +                       /* Enter hibernation */
>> +                       spin_unlock_irqrestore(&hsotg->lock, flags);
>> +                       ret = dwc2_enter_hibernation(hsotg, 1);
>> +                       spin_lock_irqsave(&hsotg->lock, flags);
>> +                       if (ret && ret != -ENOTSUPP)
>> +                               dev_err(hsotg->dev,
>> +                                       "%s: enter hibernation failed\n",
>> +                                       __func__);
> 
> nit: no __func__ in dev_xxx() error messages.  The device plus the
> message should be enough.  Only resort to __func__ if you're forced to
> do an error message without a "struct device *".
This code comes form previous implementations I have not touched it not 
to back anything.

> 
> nit: as per my comments in an earlier patch, remove special case for -ENOTSUPP
> 
> Also, presumably you want to match the error handling in
> DWC2_POWER_DOWN_PARAM_PARTIAL and do a "goto skip_power_saving" when
> you see an error?
When there is an error power_saving should be skipped.

> 
> 
>> +               } else {
>> +                       goto skip_power_saving;
>> +               }
>> +               break;
>> +       default:
>>                  goto skip_power_saving;
>>          }
>>
>> -       hsotg->bus_suspended = true;
>> -
> 
> It's a bit weird to remove this, but I guess it just got moved to the
> partial power down case?  ...and in the hibernate case you're relying
> on the hibernate function to set this?  Yet another frustratingly
> asymmetric code structure...Enter hibernation implements setting bus_suspend so I don't touch this.
Actually this patch set fixes issues it doesn't clean up everything 
related to hibernation or partial power down.

> 
> 
>>          /* Ask phy to be suspended */
>>          if (!IS_ERR_OR_NULL(hsotg->uphy)) {
>>                  spin_unlock_irqrestore(&hsotg->lock, flags);
>> @@ -4564,17 +4583,17 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd)
>>          int ret = 0;
>>          u32 hprt0;
>>
>> -       hprt0 = dwc2_read_hprt0(hsotg);
>> -
>>          spin_lock_irqsave(&hsotg->lock, flags);
>>
>> -       if (dwc2_is_device_mode(hsotg))
>> +       if (!hsotg->bus_suspended)
> 
> As per my comments above I don't have a good grasp on what
> "bus_suspended" is for.  ...that being said, if your change here is
> actually correct then you probably (?) want to remove the "if
> (hsotg->bus_suspended)" check later in this same function.
> 
> Said another way, you've now got code that looks like:
> 
> if (!hsotg->bus_suspended)
>    goto exit;
> 
> /* code that I think doesn't touch bus_suspended */
> 
> if (hsotg->bus_suspended) {
>    /* do something */
> } else {
>    /* do something else */
> }
> 
> Presumably the "do something" is now dead code?
> 
That part is not dad because if hsotg->bus_suspended is true 
resuming/exiting from suspend/partial power down/hibernation should be 
performed.
On the other hand if hsotg->bus_suspended is false there is no need to 
resume.

So of course if core is not suspended the code responsible for resuming 
should not be called. In that sense the code can be called dead.

> 
>>                  goto unlock;
>>
>>          if (hsotg->lx_state != DWC2_L2)
>>                  goto unlock;
>>
>> -       if (hsotg->params.power_down != DWC2_POWER_DOWN_PARAM_PARTIAL ||
>> +       hprt0 = dwc2_read_hprt0(hsotg);
>> +
>> +       if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_NONE ||
>>              hprt0 & HPRT0_CONNSTS) {
>>                  hsotg->lx_state = DWC2_L0;
>>                  goto unlock;
>> @@ -4597,36 +4616,51 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd)
>>                  spin_lock_irqsave(&hsotg->lock, flags);
>>          }
>>
>> -       /* Exit partial_power_down */
>> -       ret = dwc2_exit_partial_power_down(hsotg, true);
>> -       if (ret && (ret != -ENOTSUPP))
>> -               dev_err(hsotg->dev, "exit partial_power_down failed\n");
>> +       switch (hsotg->params.power_down) {
>> +       case DWC2_POWER_DOWN_PARAM_PARTIAL:
>>
>> -       hsotg->lx_state = DWC2_L0;
>> +               /* Exit partial_power_down */
>> +               ret = dwc2_exit_partial_power_down(hsotg, true);
>> +               if (ret && (ret != -ENOTSUPP))
>> +                       dev_err(hsotg->dev, "exit partial_power_down failed\n");
>>
>> -       spin_unlock_irqrestore(&hsotg->lock, flags);
>> +               hsotg->lx_state = DWC2_L0;
>>
>> -       if (hsotg->bus_suspended) {
>> -               spin_lock_irqsave(&hsotg->lock, flags);
>> -               hsotg->flags.b.port_suspend_change = 1;
>>                  spin_unlock_irqrestore(&hsotg->lock, flags);
>> -               dwc2_port_resume(hsotg);
>> -       } else {
>> -               dwc2_vbus_supply_init(hsotg);
>>
>> -               /* Wait for controller to correctly update D+/D- level */
>> -               usleep_range(3000, 5000);
>> +               if (hsotg->bus_suspended) {
>> +                       spin_lock_irqsave(&hsotg->lock, flags);
>> +                       hsotg->flags.b.port_suspend_change = 1;
>> +                       spin_unlock_irqrestore(&hsotg->lock, flags);
>> +                       dwc2_port_resume(hsotg);
>> +               } else {
>> +                       dwc2_vbus_supply_init(hsotg);
>>
>> -               /*
>> -                * Clear Port Enable and Port Status changes.
>> -                * Enable Port Power.
>> -                */
>> -               dwc2_writel(hsotg, HPRT0_PWR | HPRT0_CONNDET |
>> +                       /* Wait for controller to correctly update D+/D- level */
>> +                       usleep_range(3000, 5000);
>> +
>> +                       /*
>> +                        * Clear Port Enable and Port Status changes.
>> +                        * Enable Port Power.
>> +                        */
>> +                       dwc2_writel(hsotg, HPRT0_PWR | HPRT0_CONNDET |
>>                                  HPRT0_ENACHG, HPRT0);
>> -               /* Wait for controller to detect Port Connect */
>> -               usleep_range(5000, 7000);
>> +                       /* Wait for controller to detect Port Connect */
>> +                       usleep_range(5000, 7000);
>> +               }
>> +               break;
>> +       case DWC2_POWER_DOWN_PARAM_HIBERNATION:
>> +
>> +               /* Exit host hibernation. */
>> +               if (hsotg->hibernated)
>> +                       dwc2_exit_hibernation(hsotg, 0, 0, 1);
>> +               break;
>> +       default:
>> +               goto unlock;
>>          }
>>
>> +       spin_unlock_irqrestore(&hsotg->lock, flags);
>> +
> 
> I'm pretty curious if you tested DWC2_POWER_DOWN_PARAM_PARTIAL after
> applying your patch series.  As far as I can tell your switch
> statement for DWC2_POWER_DOWN_PARAM_PARTIAL will "break" with the
> spinlock already unlocked.  ...so you'll run spin_unlock_irqrestore
> twice.  Is that really legit?
I have tested the patches on HAPS-DX and Linaro HiKey 960 boards.

> 
> 
> 
> NOTE: in case it helps you, I've attempted to rebase this atop my
> series.  Please double-check that I didn't mess anything up, though
> 
> https://urldefense.proofpoint.com/v2/url?u=https-3A__chromium.googlesource.com_chromiumos_third-5Fparty_kernel_-2Blog_refs_sandbox_dianders_190426-2Ddwc2-2Dstuff&d=DwIBaQ&c=DPL6_X_6JkXFx7AXWqB0tg&r=9hPBFKCJ_nBjJhGVrrlYOeOQjP_HlVzYqrC_D7niMJI&m=2xJPvFyQhKsjBCMYd6_Kpb7_r7HPUAoeJHcQmBH80Gc&s=wEgbdpKgC9t9CfXpI8awXLos9GuRcsNEkpW09dgMxiw&e=
> 
> 
> ...with that a quick test seems to show that partial power down is
> sorta working on rk3288 now.  I _think_ I saw one case where hotplug
> failed but I've seen several where it works.  ...unfortunately it
> seems to break when I do hotplug on the port where I have
> "snps,reset-phy-on-wake" set.
You can provide debug logs for that scenario I will try to help you fix 
issues with that.

> 
> -Doug
> 


-- 
Regards,
Artur

             reply	other threads:[~2019-04-29 12:01 UTC|newest]

Thread overview: 84+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-04-29 12:01 Artur Petrosyan [this message]
2019-04-29 12:01 ` [PATCH v1 14/14] usb: dwc2: Add enter/exit hibernation from system issued suspend/resume Artur Petrosyan
  -- strict thread matches above, loose matches on Subject: below --
2019-05-03  8:13 [v1,04/14] usb: dwc2: Fix suspend state in host mode for partial power down Artur Petrosyan
2019-05-03  8:13 ` [PATCH v1 04/14] " Artur Petrosyan
2019-05-03  7:58 [v1,08/14] usb: dwc2: Add default param to control power optimization Artur Petrosyan
2019-05-03  7:58 ` [PATCH v1 08/14] " Artur Petrosyan
2019-05-01  1:54 [v1,04/14] usb: dwc2: Fix suspend state in host mode for partial power down Doug Anderson
2019-05-01  1:54 ` [PATCH v1 04/14] " Doug Anderson
2019-04-30 15:23 [v1,08/14] usb: dwc2: Add default param to control power optimization Doug Anderson
2019-04-30 15:23 ` [PATCH v1 08/14] " Doug Anderson
2019-04-30 13:06 [v1,14/14] usb: dwc2: Add enter/exit hibernation from system issued suspend/resume Artur Petrosyan
2019-04-30 13:06 ` [PATCH v1 14/14] " Artur Petrosyan
2019-04-30 12:45 [v1,08/14] usb: dwc2: Add default param to control power optimization Artur Petrosyan
2019-04-30 12:45 ` [PATCH v1 08/14] " Artur Petrosyan
2019-04-30  7:10 [v1,04/14] usb: dwc2: Fix suspend state in host mode for partial power down Artur Petrosyan
2019-04-30  7:10 ` [PATCH v1 04/14] " Artur Petrosyan
2019-04-29 17:42 [v1,14/14] usb: dwc2: Add enter/exit hibernation from system issued suspend/resume Doug Anderson
2019-04-29 17:42 ` [PATCH v1 14/14] " Doug Anderson
2019-04-29 17:40 [v1,08/14] usb: dwc2: Add default param to control power optimization Doug Anderson
2019-04-29 17:40 ` [PATCH v1 08/14] " Doug Anderson
2019-04-29 17:35 [v1,04/14] usb: dwc2: Fix suspend state in host mode for partial power down Doug Anderson
2019-04-29 17:35 ` [PATCH v1 04/14] " Doug Anderson
2019-04-29 11:35 [v1,09/14] usb: dwc2: Update dwc2_handle_usb_suspend_intr function Artur Petrosyan
2019-04-29 11:35 ` [PATCH v1 09/14] " Artur Petrosyan
2019-04-29 11:29 [v1,08/14] usb: dwc2: Add default param to control power optimization Artur Petrosyan
2019-04-29 11:29 ` [PATCH v1 08/14] " Artur Petrosyan
2019-04-29 11:03 [v1,04/14] usb: dwc2: Fix suspend state in host mode for partial power down Artur Petrosyan
2019-04-29 11:03 ` [PATCH v1 04/14] " Artur Petrosyan
2019-04-29 10:54 [v1,03/14] usb: dwc2: Fix wakeup detected and session request interrupt handlers Artur Petrosyan
2019-04-29 10:54 ` [PATCH v1 03/14] " Artur Petrosyan
2019-04-26 21:00 [v1,14/14] usb: dwc2: Add enter/exit hibernation from system issued suspend/resume Doug Anderson
2019-04-26 21:00 ` [PATCH v1 14/14] " Doug Anderson
2019-04-26 20:51 [v1,12/14] usb: dwc2: Clear fifo_map when resetting core Doug Anderson
2019-04-26 20:51 ` [PATCH v1 12/14] " Doug Anderson
2019-04-26 20:51 [v1,09/14] usb: dwc2: Update dwc2_handle_usb_suspend_intr function Doug Anderson
2019-04-26 20:51 ` [PATCH v1 09/14] " Doug Anderson
2019-04-26 20:46 [v1,08/14] usb: dwc2: Add default param to control power optimization Doug Anderson
2019-04-26 20:46 ` [PATCH v1 08/14] " Doug Anderson
2019-04-26 20:45 [v1,06/14] usb: dwc2: Add part. power down exit from dwc2_conn_id_status_change() Doug Anderson
2019-04-26 20:45 ` [PATCH v1 06/14] " Doug Anderson
2019-04-26 20:45 [v1,05/14] usb: dwc2: Add port conn. sts. checking in _dwc2_hcd_resume() function Doug Anderson
2019-04-26 20:45 ` [PATCH v1 05/14] " Doug Anderson
2019-04-26 20:44 [v1,04/14] usb: dwc2: Fix suspend state in host mode for partial power down Doug Anderson
2019-04-26 20:44 ` [PATCH v1 04/14] " Doug Anderson
2019-04-26 20:44 [v1,03/14] usb: dwc2: Fix wakeup detected and session request interrupt handlers Doug Anderson
2019-04-26 20:44 ` [PATCH v1 03/14] " Doug Anderson
2019-04-19 11:25 [v1,14/14] usb: dwc2: Add enter/exit hibernation from system issued suspend/resume Artur Petrosyan
2019-04-19 11:25 ` [PATCH v1 14/14] " Artur Petrosyan
2019-04-19 11:25 [v1,13/14] usb: dwc2: Clear GINTSTS_RESTOREDONE bit after restore is generated Artur Petrosyan
2019-04-19 11:25 ` [PATCH v1 13/14] " Artur Petrosyan
2019-04-19 11:25 [v1,12/14] usb: dwc2: Clear fifo_map when resetting core Artur Petrosyan
2019-04-19 11:25 ` [PATCH v1 12/14] " Artur Petrosyan
2019-04-19 11:25 [v1,11/14] usb: dwc2: Allow exiting hibernation from gpwrdn rst detect Artur Petrosyan
2019-04-19 11:25 ` [PATCH v1 11/14] " Artur Petrosyan
2019-04-19 11:25 [v1,10/14] usb: dwc2: Fix hibernation between host and device modes Artur Petrosyan
2019-04-19 11:25 ` [PATCH v1 10/14] " Artur Petrosyan
2019-04-19 11:24 [v1,09/14] usb: dwc2: Update dwc2_handle_usb_suspend_intr function Artur Petrosyan
2019-04-19 11:24 ` [PATCH v1 09/14] " Artur Petrosyan
2019-04-19 11:24 [v1,08/14] usb: dwc2: Add default param to control power optimization Artur Petrosyan
2019-04-19 11:24 ` [PATCH v1 08/14] " Artur Petrosyan
2019-04-19 11:24 [v1,07/14] usb: dwc2: Reset DEVADDR after exiting gadget hibernation Artur Petrosyan
2019-04-19 11:24 ` [PATCH v1 07/14] " Artur Petrosyan
2019-04-19 11:24 [v1,06/14] usb: dwc2: Add part. power down exit from dwc2_conn_id_status_change() Artur Petrosyan
2019-04-19 11:24 ` [PATCH v1 06/14] " Artur Petrosyan
2019-04-19 11:24 [v1,05/14] usb: dwc2: Add port conn. sts. checking in _dwc2_hcd_resume() function Artur Petrosyan
2019-04-19 11:24 ` [PATCH v1 05/14] " Artur Petrosyan
2019-04-19 11:24 [v1,04/14] usb: dwc2: Fix suspend state in host mode for partial power down Artur Petrosyan
2019-04-19 11:24 ` [PATCH v1 04/14] " Artur Petrosyan
2019-04-19 11:23 [v1,03/14] usb: dwc2: Fix wakeup detected and session request interrupt handlers Artur Petrosyan
2019-04-19 11:23 ` [PATCH v1 03/14] " Artur Petrosyan
2019-04-19 11:23 [v1,02/14] usb: dwc2: Add descriptive debug messages for Partial Power Down mode Artur Petrosyan
2019-04-19 11:23 ` [PATCH v1 02/14] " Artur Petrosyan
2019-04-19 11:23 [v1,01/14] usb: dwc2: Fix dwc2_restore_device_registers() function Artur Petrosyan
2019-04-19 11:23 ` [PATCH v1 01/14] " Artur Petrosyan
2019-04-19 11:23 [PATCH v1 00/14] usb: dwc2: Fix and improve power saving modes Artur Petrosyan
2019-04-25 12:43 ` Felipe Balbi
2019-04-25 14:00   ` Artur Petrosyan
2019-04-25 20:12     ` Doug Anderson
2019-04-26  7:10       ` Artur Petrosyan
2019-04-26 16:01         ` Doug Anderson
2019-04-26 21:06           ` Doug Anderson
2019-04-29 12:05             ` Artur Petrosyan
2019-04-29 17:43               ` Doug Anderson
2019-04-29  8:44           ` Artur Petrosyan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=SN1PR12MB24313212A9F1574A4D00C3B3A7390@SN1PR12MB2431.namprd12.prod.outlook.com \
    --to=arthur.petrosyan@synopsys.com \
    --cc=John.Youn@synopsys.com \
    --cc=Minas.Harutyunyan@synopsys.com \
    --cc=balbi@kernel.org \
    --cc=dianders@chromium.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-usb@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.