[PATCH v2] ACPI / PM: allow deeper wakeup power states with no _SxD nor _SxW

2018-03-19 Thread Daniel Drake
acpi_dev_pm_get_state() is used to determine the range of allowable
device power states when going into S3 suspend. This is implemented
by executing the _S3D and _S3W ACPI methods.

Linux follows the ACPI spec behaviour in that when _S3D is implemented
and _S3W is not, Linux will not go into a power state deeper than the one
returned by _S3D for a wakeup-enabled device.

However, this same logic is being applied to the case when neither
_S3D nor _S3W are present, and the result is that this function
decides that the device must stay in D0 (fully on) state.

This is breaking USB wakeups on Asus V222GA and Acer XC-830. _S3D and
_S3W are not present, so the USB controller is left in the D0 running
state during S3, and hence it is unable to generate a PME# wake event.

The ACPI spec is unclear on which power states are permissable for
wakeup-enabled devices when both _S3D and _S3W are missing.
However, USB wakeups work fine on these platforms under Windows, where
device manager shows that they are using D3 device state for the USB
controller in S3.

I assume that the "max = min" clamping done by the code here is
specifically written for the _S3D but no _S3W case. By making the
code true to those conditions, avoiding them on these platforms,
the controller will be put into D3 state and USB wakeups start working.

Additionally I feel that this change makes the code more directly
mirror the wording of the ACPI spec and it's associated lack of clarity.

Thanks to Mathias Nyman for pointing us in the right direction.

Signed-off-by: Daniel Drake <dr...@endlessm.com>
Link: 
http://lkml.kernel.org/r/CAB4CAwf_k-WsF3zL4epm9TKAOu0h=bv1xhxv_gy3bzioo_n...@mail.gmail.com

https://phabricator.endlessm.com/T21410
---

Notes:
This should be considered for Linux 4.17 to give it a decent amount
of testing time before release.

v2: fix unused variable warning

 drivers/acpi/device_pm.c | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index c4d0a1c912f0..3d96e4da2d98 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -543,6 +543,7 @@ static int acpi_dev_pm_get_state(struct device *dev, struct 
acpi_device *adev,
unsigned long long ret;
int d_min, d_max;
bool wakeup = false;
+   bool has_sxd = false;
acpi_status status;
 
/*
@@ -581,6 +582,10 @@ static int acpi_dev_pm_get_state(struct device *dev, 
struct acpi_device *adev,
else
return -ENODATA;
}
+
+   if (status == AE_OK)
+   has_sxd = true;
+
d_min = ret;
wakeup = device_may_wakeup(dev) && adev->wakeup.flags.valid
&& adev->wakeup.sleep_state >= target_state;
@@ -599,7 +604,11 @@ static int acpi_dev_pm_get_state(struct device *dev, 
struct acpi_device *adev,
method[3] = 'W';
status = acpi_evaluate_integer(handle, method, NULL, );
if (status == AE_NOT_FOUND) {
-   if (target_state > ACPI_STATE_S0)
+   /* No _SxW. In this case, the ACPI spec says that we
+* must not go into any power state deeper than the
+* value returned from _SxD.
+*/
+   if (has_sxd && target_state > ACPI_STATE_S0)
d_max = d_min;
} else if (ACPI_SUCCESS(status) && ret <= ACPI_STATE_D3_COLD) {
/* Fall back to D3cold if ret is not a valid state. */
-- 
2.14.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] ACPI / PM: allow deeper wakeup power states with no _SxD nor _SxW

2018-03-19 Thread Daniel Drake
acpi_dev_pm_get_state() is used to determine the range of allowable
device power states when going into S3 suspend. This is implemented
by executing the _S3D and _S3W ACPI methods.

Linux follows the ACPI spec behaviour in that when _S3D is implemented
and _S3W is not, Linux will not go into a power state deeper than the one
returned by _S3D for a wakeup-enabled device.

However, this same logic is being applied to the case when neither
_S3D nor _S3W are present, and the result is that this function
decides that the device must stay in D0 (fully on) state.

This is breaking USB wakeups on Asus V222GA and Acer XC-830. _S3D and
_S3W are not present, so the USB controller is left in the D0 running
state during S3, and hence it is unable to generate a PME# wake event.

The ACPI spec is unclear on which power states are permissable for
wakeup-enabled devices when both _S3D and _S3W are missing.
However, USB wakeups work fine on these platforms under Windows, where
device manager shows that they are using D3 device state for the USB
controller in S3.

I assume that the "max = min" clamping done by the code here is
specifically written for the _S3D but no _S3W case. By making the
code true to those conditions, avoiding them on these platforms,
the controller will be put into D3 state and USB wakeups start working.

Additionally I feel that this change makes the code more directly
mirror the wording of the ACPI spec and it's associated lack of clarity.

Thanks to Mathias Nyman for pointing us in the right direction.

Signed-off-by: Daniel Drake <dr...@endlessm.com>
Link: 
http://lkml.kernel.org/r/CAB4CAwf_k-WsF3zL4epm9TKAOu0h=bv1xhxv_gy3bzioo_n...@mail.gmail.com
---
 drivers/acpi/device_pm.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index c4d0a1c912f0..b945e37bcac0 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -543,6 +543,7 @@ static int acpi_dev_pm_get_state(struct device *dev, struct 
acpi_device *adev,
unsigned long long ret;
int d_min, d_max;
bool wakeup = false;
+   acpi_status sxd_status;
acpi_status status;
 
/*
@@ -565,8 +566,8 @@ static int acpi_dev_pm_get_state(struct device *dev, struct 
acpi_device *adev,
 * provided if AE_NOT_FOUND is returned.
 */
ret = d_min;
-   status = acpi_evaluate_integer(handle, method, NULL, );
-   if ((ACPI_FAILURE(status) && status != AE_NOT_FOUND)
+   sxd_status = acpi_evaluate_integer(handle, method, NULL, );
+   if ((ACPI_FAILURE(sxd_status) && sxd_status != AE_NOT_FOUND)
|| ret > ACPI_STATE_D3_COLD)
return -ENODATA;
 
@@ -599,7 +600,11 @@ static int acpi_dev_pm_get_state(struct device *dev, 
struct acpi_device *adev,
method[3] = 'W';
status = acpi_evaluate_integer(handle, method, NULL, );
if (status == AE_NOT_FOUND) {
-   if (target_state > ACPI_STATE_S0)
+   /* No _SxW. In this case, the ACPI spec says that we
+* must not go into any power state deeper than the
+* value returned from _SxD.
+*/
+   if (sxd_status == AE_OK && target_state > ACPI_STATE_S0)
d_max = d_min;
} else if (ACPI_SUCCESS(status) && ret <= ACPI_STATE_D3_COLD) {
/* Fall back to D3cold if ret is not a valid state. */
-- 
2.14.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Intel GemniLake xHCI connected devices can never wake up the system from suspend

2018-03-18 Thread Daniel Drake
On Mon, Mar 19, 2018 at 6:36 AM, Rafael J. Wysocki  wrote:
> On Fri, Mar 16, 2018 at 10:06 AM, Mathias Nyman
>  wrote:
>> Adding Rafael directly to CC
>>
>> In short, if _S3D and _S3W are missing in DSDT then a PCI device
>> stays in D0 during suspend in Linux, but goes to D3 in Windows.
>>
>> USB wake doesn't work in Geminilake because of this.
>>
>> Should this be changed? reasoning below.
>
> It can be changed if that doesn't cause problems to happen.

I double checked that Windows 10 is going into S3 suspend and that USB
wakeup works fine on this platform - it works fine there.
Device manager for the XHCI controller clearly shows D3 being used for
S3 suspend: https://imgur.com/lF9U3V0

Current power state:
D0

Power capabilities:
0089
PDCAP_D0_SUPPORTED
PDCAP_D3_SUPPORTED
PDCAP_WAKE_FROM_D3_SUPPORTED

Power state mappings:
S0 -> D0
S1 -> Unspecified
S2 -> Unspecified
S3 -> D3
S4 -> D3
S5 -> D3

The biggest risk of my proposed change is that we would now end up
putting a wakeup-enabled device into a too low power state where it
can no longer wake up the system. On the other hand, it solves this
issue affecting 2 different vendors, and may even result in some power
savings in general.

Perhaps we can consider the change for inclusion in Linux-4.17, giving
2-3 months of testing time.

I'll submit the patch shortly.

Thanks
Daniel
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Intel GemniLake xHCI connected devices can never wake up the system from suspend

2018-03-16 Thread Daniel Drake
> I've studied the ACPI spec trying to understand better, but I'm
> struggling with the question:
> What is the maximum number (lowest power) permitted device power state
> for a device that is configured as able to wake the system from S3,
> **that does not implement the _S3W method**?

Actually the ACPI spec has an answer for the case when _S3D is present.
The lack of clarity is only over the situation when both _S3D and _S3W
are missing - like on the platforms being worked on here.

The _S3D docs say:
> If the device can wake the system from the S3 system sleeping state (see
> _PRW) then the device must support wake in the D-state returned by this
> object. However, OSPM cannot assume wake from the S3 system sleeping state
> is supported in any deeper D-state unless specified by a corresponding
> _S3W object

Looking at the design of the existing Linux code, it seems like this
"max = min" assignment that is causing us trouble originates directly
from an attempt to implement that logic: if we didn't get a response from
_S3W, then we must clamp ourselves to the data we got from _S3D.

If I modify the Linux code to be a little more specific in that logic
(only applying when we actually got something from _S3D) then the
problematic behaviour is avoided and USB wakeups work.

I feel that this change makes the Linux implementation more directly
mirror the wording in the ACPI spec and it's associated lack of clarity
for when both methods are missing. Thoughts?

---
 drivers/acpi/device_pm.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index a4c8ad98560d..44f12c5c75ee 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -543,6 +543,7 @@ static int acpi_dev_pm_get_state(struct device *dev, struct 
acpi_device *adev,
unsigned long long ret;
int d_min, d_max;
bool wakeup = false;
+   acpi_status sxd_status;
acpi_status status;
 
/*
@@ -565,8 +566,8 @@ static int acpi_dev_pm_get_state(struct device *dev, struct 
acpi_device *adev,
 * provided if AE_NOT_FOUND is returned.
 */
ret = d_min;
-   status = acpi_evaluate_integer(handle, method, NULL, );
-   if ((ACPI_FAILURE(status) && status != AE_NOT_FOUND)
+   sxd_status = acpi_evaluate_integer(handle, method, NULL, );
+   if ((ACPI_FAILURE(sxd_status) && sxd_status != AE_NOT_FOUND)
|| ret > ACPI_STATE_D3_COLD)
return -ENODATA;
 
@@ -599,7 +600,11 @@ static int acpi_dev_pm_get_state(struct device *dev, 
struct acpi_device *adev,
method[3] = 'W';
status = acpi_evaluate_integer(handle, method, NULL, );
if (status == AE_NOT_FOUND) {
-   if (target_state > ACPI_STATE_S0)
+   /* No _SxW. In this case, the ACPI spec says that we
+* must not go into any power state deeper than the
+* value returned from _SxD.
+*/
+   if (sxd_status == AE_OK && target_state > ACPI_STATE_S0)
d_max = d_min;
} else if (ACPI_SUCCESS(status) && ret <= ACPI_STATE_D3_COLD) {
/* Fall back to D3cold if ret is not a valid state. */
-- 
2.14.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Intel GemniLake xHCI connected devices can never wake up the system from suspend

2018-03-16 Thread Daniel Drake
Hi,

I'm working alongside Chris on this issue.

On Fri, Mar 16, 2018 at 12:11 AM, Mathias Nyman
 wrote:
> Scope (_SB.PCI0.XHC) has _PS0 method, so Linux will look for a _S3W to get
> the
> lowest possible D state in S3, but_S3W is missing, so Linux pci-acpi code
> will
> probably default to D0

Yes, _S3W is missing, and in this case, acpi_dev_pm_get_state() is
setting the maximum number permitted device power state to the minimum
value of D0.

So the XHCI controller is in D0 when you go into suspend.

I tried your hack to force it into D3hot. Now the system can wake up
from resume via the USB port. Thanks for finding that.

>> ASUS said the BIOS has no problem on USB wakeup under Windows so I don't
>> think
>> there's any update. Anything else could be cause for this?
>
> Linux and Windows probably check different DSDT values

I've studied the ACPI spec trying to understand better, but I'm
struggling with the question:
What is the maximum number (lowest power) permitted device power state
for a device that is configured as able to wake the system from S3,
**that does not implement the _S3W method**?

As far as I can see, the ACPI spec doesn't give an answer. It's clear
what the behaviour is when _S3W is present, but not unclear what
should happen when it is not there.

As noted above, Linux's interpretation is that in such case, the
device must remain fully on (D0) when going into S3. I am wondering if
Windows just has made an alternative assumption that all available
device power states can wake the system from suspend in such case.

This is working in Windows so hopefully we can find a way to match the
behaviour?

Thanks
Daniel
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] Revert "Bluetooth: btusb: fix QCA Rome suspend/resume"

2017-12-21 Thread Daniel Drake
On Wed, Dec 20, 2017 at 6:53 PM, Brian Norris  wrote:
>
> On Wed, Dec 20, 2017 at 07:00:07PM +0800, Kai-Heng Feng wrote:
> > This commit causes a regression on some QCA ROME chips. The USB device
> > reset happens in btusb_open(), hence firmware loading gets interrupted.
>
> Oh, did you really confirm that's the root of the problem? I was only
> hypothesizing, with some informed observation and code review; but I
> didn't fully convince myself. If so, that's interesting.

I have the same doubt. Can you explain how/why firmware uploading and
btusb_open() overlap, and how this is avoided with your patch?
If they do overlap, is that not a bug in the stack that should be fixed instead?
If the fix belongs in btusb and this BTUSB_RESET_RESUME thing really
is problematic, should it be totally removed instead?

Daniel
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3] USB: Force disconnect Huawei 4G modem during suspend

2017-10-23 Thread Daniel Drake
Hi Oliver,

On Wed, Oct 18, 2017 at 5:31 PM, Oliver Neukum <oneu...@suse.com> wrote:
> Am Mittwoch, den 18.10.2017, 15:15 +0800 schrieb Daniel Drake:
>> Notes:
>> v2:
>> - Handle quirk later in suspend, to avoid interfering with other parts
>>   of the suspend routine.
>> - Don't do the disconnect on runtime suspend, only for S3 suspend
>
> well, can we effectively runtime suspend these devices?

How can I test for effective runtime suspend?

> Furthermore, it seems to me that we indeed cannot do a runtime
> suspend on external devices needing this quirk, but what about
> internal devices?

In this case the modem is an internal device.

Daniel
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3] USB: Force disconnect Huawei 4G modem during suspend

2017-10-18 Thread Daniel Drake
When going into S3 suspend, the Acer TravelMate P648-M and P648-G3
laptops immediately wake up 3-4 seconds later for no obvious reason.

Unbinding the integrated Huawei 4G LTE modem before suspend avoids
the issue, even though we are not using the modem at all (checked
from rescue.target/runlevel1). The problem also occurs when the option
and cdc-ether modem drivers aren't loaded; it reproduces just with the
base usb driver. Under Windows the system can suspend fine.

Seeking a better fix, we've tried a lot of things, including:
 - Check that the device's power/wakeup is disabled
 - Check that remote wakeup is off at the USB level
 - All the quirks in drivers/usb/core/quirks.c e.g. USB_QUIRK_RESET_RESUME,
   USB_QUIRK_RESET, USB_QUIRK_IGNORE_REMOTE_WAKEUP, USB_QUIRK_NO_LPM.

but none of that makes any difference.

There are no errors in the logs showing any suspend/resume-related issues.
When the system wakes up due to the modem, log-wise it appears to be a
normal resume.

Introduce a quirk to disable the port during suspend when the modem is
detected.

The modem from the P648-G3 model is:
T:  Bus=01 Lev=01 Prnt=01 Port=08 Cnt=04 Dev#=  5 Spd=480  MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=ff MxPS=64 #Cfgs=  3
P:  Vendor=12d1 ProdID=15c3 Rev= 1.02
S:  Manufacturer=Huawei Technologies Co., Ltd.
S:  Product=HUAWEI Mobile
S:  SerialNumber=0123456789ABCDEF
C:  #Ifs= 5 Cfg#= 1 Atr=a0 MxPwr=  2mA
I:  If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=06 Prot=10 Driver=
E:  Ad=82(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
E:  Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=06 Prot=13 Driver=
E:  Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=06 Prot=12 Driver=
E:  Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 3 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=06 Prot=16 Driver=
E:  Ad=86(I) Atr=03(Int.) MxPS=  16 Ivl=2ms
I:  If#= 3 Alt= 1 #EPs= 3 Cls=ff(vend.) Sub=06 Prot=16 Driver=
E:  Ad=86(I) Atr=03(Int.) MxPS=  16 Ivl=2ms
E:  Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=06 Prot=1b Driver=
E:  Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
C:* #Ifs= 6 Cfg#= 2 Atr=a0 MxPwr=  2mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=06 Prot=00 Driver=cdc_ether
E:  Ad=82(I) Atr=03(Int.) MxPS=  16 Ivl=2ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=06 Prot=00 Driver=cdc_ether
E:  Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=06 Prot=10 Driver=option
E:  Ad=84(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
E:  Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=06 Prot=13 Driver=option
E:  Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=06 Prot=12 Driver=option
E:  Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 5 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=06 Prot=1b Driver=option
E:  Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
C:  #Ifs= 2 Cfg#= 3 Atr=a0 MxPwr=  2mA
A:  FirstIf#= 0 IfCount= 2 Cls=02(comm.) Sub=0e Prot=00
I:  If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=0e Prot=00 Driver=
E:  Ad=82(I) Atr=03(Int.) MxPS=  16 Ivl=2ms
I:  If#= 1 Alt= 0 #EPs= 0 Cls=0a(data ) Sub=00 Prot=02 Driver=
I:  If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=
E:  Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms

Based on an earlier patch by Chris Chiu.

Signed-off-by: Daniel Drake <dr...@endlessm.com>
---

Notes:
v2:
- Handle quirk later in suspend, to avoid interfering with other parts
  of the suspend routine.
- Don't do the disconnect on runtime suspend, only for S3 suspend

v3:
- Ignore return value from usb_port_disable()
- Correct kerneldoc Context information
- Don't mark device as disconnected

 drivers/usb/core/driver.c  | 10 +-
 drivers/usb/core/hub.c | 13 +
 drivers/usb/core/quirks.c  |  6 ++
 drivers/usb/core/usb.h |  1 +
 include/linux/usb/quirks.h |  6 ++
 5 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index eb87a259d55c..353993f983c8 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1461,6 +1461,7 @@ static void choose_wakeup(struct usb_device *udev, 
pm_message_t msg)
 int usb_suspend(struct device *dev, pm_message_t msg)
 {
struct usb_device   *udev = to_usb_device(dev);
+   int r;
 
unbind_no_pm_drivers_interfaces(udev);
 
@@ -1469,7 +1470,14 @@ int usb_suspend(struct device *dev, pm_mess

[PATCH v2] USB: Force disconnect Huawei 4G modem during suspend

2017-10-12 Thread Daniel Drake
When going into S3 suspend, the Acer TravelMate P648-M and P648-G3
laptops immediately wake up 3-4 seconds later for no obvious reason.

Unbinding the integrated Huawei 4G LTE modem before suspend avoids
the issue, even though we are not using the modem at all (checked
from rescue.target/runlevel1). The problem also occurs when the option
and cdc-ether modem drivers aren't loaded; it reproduces just with the
base usb driver. Under Windows the system can suspend fine.

Seeking a better fix, we've tried a lot of things, including:
 - Check that the device's power/wakeup is disabled
 - Check that remote wakeup is off at the USB level
 - All the quirks in drivers/usb/core/quirks.c e.g. USB_QUIRK_RESET_RESUME,
   USB_QUIRK_RESET, USB_QUIRK_IGNORE_REMOTE_WAKEUP, USB_QUIRK_NO_LPM.

but none of that makes any difference.

There are no errors in the logs showing any suspend/resume-related issues.
When the system wakes up due to the modem, log-wise it appears to be a
normal resume.

Introduce a quirk to disable the port during suspend when the modem is
detected.

The modem from the P648-G3 model is:
T:  Bus=01 Lev=01 Prnt=01 Port=08 Cnt=04 Dev#=  5 Spd=480  MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=ff MxPS=64 #Cfgs=  3
P:  Vendor=12d1 ProdID=15c3 Rev= 1.02
S:  Manufacturer=Huawei Technologies Co., Ltd.
S:  Product=HUAWEI Mobile
S:  SerialNumber=0123456789ABCDEF
C:  #Ifs= 5 Cfg#= 1 Atr=a0 MxPwr=  2mA
I:  If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=06 Prot=10 Driver=
E:  Ad=82(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
E:  Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=06 Prot=13 Driver=
E:  Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=06 Prot=12 Driver=
E:  Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 3 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=06 Prot=16 Driver=
E:  Ad=86(I) Atr=03(Int.) MxPS=  16 Ivl=2ms
I:  If#= 3 Alt= 1 #EPs= 3 Cls=ff(vend.) Sub=06 Prot=16 Driver=
E:  Ad=86(I) Atr=03(Int.) MxPS=  16 Ivl=2ms
E:  Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=06 Prot=1b Driver=
E:  Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
C:* #Ifs= 6 Cfg#= 2 Atr=a0 MxPwr=  2mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=06 Prot=00 Driver=cdc_ether
E:  Ad=82(I) Atr=03(Int.) MxPS=  16 Ivl=2ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=06 Prot=00 Driver=cdc_ether
E:  Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=06 Prot=10 Driver=option
E:  Ad=84(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
E:  Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=06 Prot=13 Driver=option
E:  Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=06 Prot=12 Driver=option
E:  Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 5 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=06 Prot=1b Driver=option
E:  Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
C:  #Ifs= 2 Cfg#= 3 Atr=a0 MxPwr=  2mA
A:  FirstIf#= 0 IfCount= 2 Cls=02(comm.) Sub=0e Prot=00
I:  If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=0e Prot=00 Driver=
E:  Ad=82(I) Atr=03(Int.) MxPS=  16 Ivl=2ms
I:  If#= 1 Alt= 0 #EPs= 0 Cls=0a(data ) Sub=00 Prot=02 Driver=
I:  If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=
E:  Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms

Based on an earlier patch by Chris Chiu.

Signed-off-by: Daniel Drake <dr...@endlessm.com>
---

Notes:
v2:
- Handle quirk later in suspend, to avoid interfering with other parts
  of the suspend routine.
- Don't do the disconnect on runtime suspend, only for S3 suspend

 drivers/usb/core/driver.c  | 10 +-
 drivers/usb/core/hub.c | 13 +
 drivers/usb/core/quirks.c  |  6 ++
 drivers/usb/core/usb.h |  1 +
 include/linux/usb/quirks.h |  6 ++
 5 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index eb87a259d55c..7c048afc9bfd 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1461,6 +1461,7 @@ static void choose_wakeup(struct usb_device *udev, 
pm_message_t msg)
 int usb_suspend(struct device *dev, pm_message_t msg)
 {
struct usb_device   *udev = to_usb_device(dev);
+   int r;
 
unbind_no_pm_drivers_interfaces(udev);
 
@@ -1469,7 +1470,14 @@ int usb_suspend(struct device *dev, pm_message_t msg)
 * so we may still need to unbind and rebind upon resume
 */
choose_wakeup(udev, msg);
-   return usb_suspend_both(

Re: [PATCH] USB: Force disconnect Huawei 4G modem during suspend

2017-10-12 Thread Daniel Drake
On Wed, Oct 11, 2017 at 11:04 PM, Alan Stern  wrote:
> Also, you should check whether this is for a runtime suspend or a
> system suspend.  You don't want to go around disconnecting a device
> whenever it gets runtime suspended!

Good point, I had not considered runtime suspend. It's not quite so
simple though.

I make your suggested change (testing PMSG_IS_AUTO in this codepath),
then enable autosuspend with:
 echo auto > /sys/bus/usb/devices/1-9/power/control

then the device gets suspended (no interface drivers are loaded)
without the port disconnect happening.

Now if I go into S3 suspend, the original problem returns: the system
wakes up immediately.

So that is an imperfection with this approach. Any suggestions for how
to proceed?

Daniel
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] USB: Force disconnect Huawei 4G modem during suspend

2017-10-11 Thread Daniel Drake
From: Chris Chiu <c...@endlessm.com>

When going into S3 suspend, the Acer TravelMate P648-M and P648-G3
laptops immediately wake up 3-4 seconds later for no obvious reason.

Unbinding the integrated Huawei 4G LTE modem before suspend avoids
the issue, even though we are not using the modem at all (checked
from rescue.target/runlevel1). The problem also occurs when the option
and cdc-ether modem drivers aren't loaded; it reproduces just with the
base usb driver. Under Windows the system can suspend fine.

Seeking a better fix, we've tried a lot of things, including:
 - Check that the device's power/wakeup is disabled
 - Check that remote wakeup is off at the USB level
 - All the quirks in drivers/usb/core/quirks.c e.g. USB_QUIRK_RESET_RESUME,
   USB_QUIRK_RESET, USB_QUIRK_IGNORE_REMOTE_WAKEUP, USB_QUIRK_NO_LPM.

but none of that makes any difference.

There are no errors in the logs showing any suspend/resume-related issues.
When the system wakes up due to the modem, log-wise it appears to be a
normal resume.

Introduce a quirk to disable the port during suspend when the modem is
detected.

The modem from the P648-G3 model is:
T:  Bus=01 Lev=01 Prnt=01 Port=08 Cnt=04 Dev#=  5 Spd=480  MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=ff MxPS=64 #Cfgs=  3
P:  Vendor=12d1 ProdID=15c3 Rev= 1.02
S:  Manufacturer=Huawei Technologies Co., Ltd.
S:  Product=HUAWEI Mobile
S:  SerialNumber=0123456789ABCDEF
C:  #Ifs= 5 Cfg#= 1 Atr=a0 MxPwr=  2mA
I:  If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=06 Prot=10 Driver=
E:  Ad=82(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
E:  Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=06 Prot=13 Driver=
E:  Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=06 Prot=12 Driver=
E:  Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 3 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=06 Prot=16 Driver=
E:  Ad=86(I) Atr=03(Int.) MxPS=  16 Ivl=2ms
I:  If#= 3 Alt= 1 #EPs= 3 Cls=ff(vend.) Sub=06 Prot=16 Driver=
E:  Ad=86(I) Atr=03(Int.) MxPS=  16 Ivl=2ms
E:  Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:  If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=06 Prot=1b Driver=
E:  Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
C:* #Ifs= 6 Cfg#= 2 Atr=a0 MxPwr=  2mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=06 Prot=00 Driver=cdc_ether
E:  Ad=82(I) Atr=03(Int.) MxPS=  16 Ivl=2ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=06 Prot=00 Driver=cdc_ether
E:  Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=06 Prot=10 Driver=option
E:  Ad=84(I) Atr=03(Int.) MxPS=  10 Ivl=32ms
E:  Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=06 Prot=13 Driver=option
E:  Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=06 Prot=12 Driver=option
E:  Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 5 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=06 Prot=1b Driver=option
E:  Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
C:  #Ifs= 2 Cfg#= 3 Atr=a0 MxPwr=  2mA
A:  FirstIf#= 0 IfCount= 2 Cls=02(comm.) Sub=0e Prot=00
I:  If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=0e Prot=00 Driver=
E:  Ad=82(I) Atr=03(Int.) MxPS=  16 Ivl=2ms
I:  If#= 1 Alt= 0 #EPs= 0 Cls=0a(data ) Sub=00 Prot=02 Driver=
I:  If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=
E:  Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms

Signed-off-by: Chris Chiu <c...@endlessm.com>
Signed-off-by: Daniel Drake <dr...@endlessm.com>
---
 drivers/usb/core/hub.c | 3 +++
 drivers/usb/core/quirks.c  | 6 ++
 include/linux/usb/quirks.h | 6 ++
 3 files changed, 15 insertions(+)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index b5c733613823..0eb3d8191a26 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -3160,6 +3160,9 @@ int usb_port_suspend(struct usb_device *udev, 
pm_message_t msg)
goto err_ltm;
}
 
+   if (udev->quirks & USB_QUIRK_DISCONNECT_SUSPEND)
+   usb_clear_port_feature(hub->hdev, port1, USB_PORT_FEAT_ENABLE);
+
/* see 7.1.7.6 */
if (hub_is_superspeed(hub->hdev))
status = hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_U3);
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 82806e311202..746d2b19109c 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -203,6 +203,12 @@ static const struct usb_device_id usb_quirk_list[] = {
{ USB_DEVICE(0x10d6, 0x2200), .driver_info =

Re: Huawei integrated modem causes instant resume from suspend on Acer P648-G3

2017-10-01 Thread Daniel Drake
On Wed, Sep 27, 2017 at 3:12 PM, Oliver Neukum  wrote:
> 1) kernel version?

Currently testing 4.14.0-rc2 but reproduced on multiple older versions
too going back to 4.8. (Have not found a working kernel version)

> 2) driver used?

The problem is reproducible just with the base usb driver, without any
USB modem drivers loaded. (It would ordinarily load option and
cdc-ether)

> 3) device descriptors (lsusb)

Bus 001 Device 005: ID 12d1:15c3 Huawei Technologies Co., Ltd.
Device Descriptor:
  bLength18
  bDescriptorType 1
  bcdUSB   2.00
  bDeviceClass0 (Defined at Interface level)
  bDeviceSubClass 0
  bDeviceProtocol   255
  bMaxPacketSize064
  idVendor   0x12d1 Huawei Technologies Co., Ltd.
  idProduct  0x15c3
  bcdDevice1.02
  iManufacturer   1 Huawei Technologies Co., Ltd.
  iProduct2 HUAWEI Mobile
  iSerial 3 0123456789ABCDEF
  bNumConfigurations  3
  Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength  259
bNumInterfaces  5
bConfigurationValue 1
iConfiguration  0
bmAttributes 0xa0
  (Bus Powered)
  Remote Wakeup
MaxPower2mA
Interface Descriptor:
  bLength 9
  bDescriptorType 4
  bInterfaceNumber0
  bAlternateSetting   0
  bNumEndpoints   3
  bInterfaceClass   255 Vendor Specific Class
  bInterfaceSubClass  6
  bInterfaceProtocol 16
  iInterface  0
  ** UNRECOGNIZED:  05 24 00 10 01
  ** UNRECOGNIZED:  04 24 02 02
  ** UNRECOGNIZED:  05 24 01 00 00
  ** UNRECOGNIZED:  05 24 06 00 00
  Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82  EP 2 IN
bmAttributes3
  Transfer TypeInterrupt
  Synch Type   None
  Usage Type   Data
wMaxPacketSize 0x000a  1x 10 bytes
bInterval   9
  Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81  EP 1 IN
bmAttributes2
  Transfer TypeBulk
  Synch Type   None
  Usage Type   Data
wMaxPacketSize 0x0200  1x 512 bytes
bInterval   0
  Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01  EP 1 OUT
bmAttributes2
  Transfer TypeBulk
  Synch Type   None
  Usage Type   Data
wMaxPacketSize 0x0200  1x 512 bytes
bInterval   0
Interface Descriptor:
  bLength 9
  bDescriptorType 4
  bInterfaceNumber1
  bAlternateSetting   0
  bNumEndpoints   2
  bInterfaceClass   255 Vendor Specific Class
  bInterfaceSubClass  6
  bInterfaceProtocol 19
  iInterface  0
  ** UNRECOGNIZED:  05 24 00 10 01
  ** UNRECOGNIZED:  04 24 02 02
  ** UNRECOGNIZED:  05 24 01 00 01
  ** UNRECOGNIZED:  05 24 06 00 00
  Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83  EP 3 IN
bmAttributes2
  Transfer TypeBulk
  Synch Type   None
  Usage Type   Data
wMaxPacketSize 0x0200  1x 512 bytes
bInterval   0
  Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02  EP 2 OUT
bmAttributes2
  Transfer TypeBulk
  Synch Type   None
  Usage Type   Data
wMaxPacketSize 0x0200  1x 512 bytes
bInterval   0
Interface Descriptor:
  bLength 9
  bDescriptorType 4
  bInterfaceNumber2
  bAlternateSetting   0
  bNumEndpoints   2
  bInterfaceClass   255 Vendor Specific Class
  bInterfaceSubClass  6
  bInterfaceProtocol 18
  iInterface  0
  ** UNRECOGNIZED:  05 24 00 10 01
  ** UNRECOGNIZED:  04 24 02 02
  ** UNRECOGNIZED:  05 24 01 00 02
  ** UNRECOGNIZED:  05 24 06 00 00
  Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x84  EP 4 IN
bmAttributes2
  Transfer TypeBulk
  Synch Type   None
  Usage Type   Data
wMaxPacketSize 

Huawei integrated modem causes instant resume from suspend on Acer P648-G3

2017-09-27 Thread Daniel Drake
Hi,

The Acer TravelMate P648-G3 laptop includes this integrated Huawei 4G modem
on the USB bus:

T:  Bus=01 Lev=01 Prnt=01 Port=08 Cnt=04 Dev#=  5 Spd=480  MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=ff MxPS=64 #Cfgs=  3
P:  Vendor=12d1 ProdID=15c3 Rev= 1.02
S:  Manufacturer=Huawei Technologies Co., Ltd.
S:  Product=HUAWEI Mobile
S:  SerialNumber=0123456789ABCDEF
C:  #Ifs= 5 Cfg#= 1 Atr=a0 MxPwr=  2mA

Under Linux, this system has an issue where it will automatically resume
3-4 seconds after going into suspend. After some experimentation we realised
that it is related to this 4G modem.

The problem can be worked around with:

  echo 1-9 > /sys/bus/usb/drivers/usb/unbind

or the attached hacky patch which does something similar. Now the system
goes into suspend and stays asleep.

The problem happens even though we are not using the modem at all (checked
from rescue.target/runlevel1). Under Windows the system can suspend fine.

Seeking a better fix, we've tried a lot of things, including:
 - Unbind usb serial interface(ttyUSB0-3) and cdc-eth interface (instead of
the whole port)
 - Check that the device's power/wakeup is disabled
 - All the quirks in drivers/usb/core/quirks.c e.g. USB_QUIRK_RESET_RESUME,
   USB_QUIRK_RESET, USB_QUIRK_IGNORE_REMOTE_WAKEUP, USB_QUIRK_NO_LPM.
 - Check usb_port_suspend() to see if the do_remote_wakeup path is followed
   (it's not)

but none of that makes any difference.

There are no errors in the logs showing any suspend/resume-related issues.
When the system wakes up due to the modem, log-wise it appears to be a
normal resume.

Does anyone have any suggestions for how we can investigate further, or how
we should workaround this issue in upstreamable form?

Thanks
Daniel

---
 drivers/usb/core/hub.c | 4 
 drivers/usb/core/quirks.c  | 4 
 include/linux/usb/quirks.h | 5 +
 3 files changed, 13 insertions(+)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 822f8c50e423..ac9ceacdc76c 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -3160,6 +3160,10 @@ int usb_port_suspend(struct usb_device *udev, 
pm_message_t msg)
goto err_ltm;
}
 
+   if (udev->quirks & USB_QUIRK_DISCONNECT_SUSPEND) {
+   usb_clear_port_feature(hub->hdev, port1, USB_PORT_FEAT_ENABLE);
+   }
+
/* see 7.1.7.6 */
if (hub_is_superspeed(hub->hdev))
status = hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_U3);
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 82806e311202..9325be88bb02 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -203,6 +203,10 @@ static const struct usb_device_id usb_quirk_list[] = {
{ USB_DEVICE(0x10d6, 0x2200), .driver_info =
USB_QUIRK_STRING_FETCH_255 },
 
+   /* Huawei 4G LTE module */
+   { USB_DEVICE(0x12d1, 0x15c3), .driver_info = 
USB_QUIRK_DISCONNECT_SUSPEND},
+   { USB_DEVICE(0x12d1, 0x15bb), .driver_info = 
USB_QUIRK_DISCONNECT_SUSPEND},
+
/* SKYMEDI USB_DRIVE */
{ USB_DEVICE(0x1516, 0x8628), .driver_info = USB_QUIRK_RESET_RESUME },
 
diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h
index de2a722fe3cf..45ad360dfa21 100644
--- a/include/linux/usb/quirks.h
+++ b/include/linux/usb/quirks.h
@@ -56,4 +56,9 @@
  */
 #define USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL  BIT(11)
 
+/* device need to be disconnect before suspend to prevent from unexpected
+ * wakeup.
+ */
+#define USB_QUIRK_DISCONNECT_SUSPEND   BIT(12)
+
 #endif /* __LINUX_USB_QUIRKS_H */
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] Bluetooth: btusb: match generic class code in interface descriptor

2015-07-17 Thread Daniel Drake
btusb currently has a generic match on USB device descriptors:
{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) },

However, http://www.usb.org/developers/defined_class states:

  Base Class E0h (Wireless Controller)
  This base class is defined for devices that are Wireless controllers.
  Values not shown in the table below are reserved. These class codes are
  to be used in Interface Descriptors, with the exception of the Bluetooth
  class code which can also be used in a Device Descriptor.

Add a match on the interface descriptors accordingly.

This fixes compatibility with the RTL8723AU device shown below.
This device conforms to the USB Interface Association Descriptor
specification, which requires the device to have class ef/02/01.
The extra IAD descriptor then specifies that interfaces 0 and 1
belong to the same function/driver, which is true. Provided that
the Bluetooth device class spec accepts use of the IAD, I imagine that
technically, all btusb devices should be configured like this.

T:  Bus=01 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#=  3 Spd=480  MxCh= 0
D:  Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=0bda ProdID=0724 Rev= 2.00
S:  Manufacturer=Realtek
S:  Product=802.11n WLAN Adapter
S:  SerialNumber=00e04c01
C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=500mA
A:  FirstIf#= 0 IfCount= 2 Cls=e0(wlcon) Sub=01 Prot=01
I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=81(I) Atr=03(Int.) MxPS=  16 Ivl=1ms
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=03(O) Atr=01(Isoc) MxPS=   0 Ivl=1ms
E:  Ad=83(I) Atr=01(Isoc) MxPS=   0 Ivl=1ms
I:  If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=03(O) Atr=01(Isoc) MxPS=   9 Ivl=1ms
E:  Ad=83(I) Atr=01(Isoc) MxPS=   9 Ivl=1ms
I:  If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=03(O) Atr=01(Isoc) MxPS=  17 Ivl=1ms
E:  Ad=83(I) Atr=01(Isoc) MxPS=  17 Ivl=1ms
I:  If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=03(O) Atr=01(Isoc) MxPS=  25 Ivl=1ms
E:  Ad=83(I) Atr=01(Isoc) MxPS=  25 Ivl=1ms
I:  If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=03(O) Atr=01(Isoc) MxPS=  33 Ivl=1ms
E:  Ad=83(I) Atr=01(Isoc) MxPS=  33 Ivl=1ms
I:  If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=03(O) Atr=01(Isoc) MxPS=  49 Ivl=1ms
E:  Ad=83(I) Atr=01(Isoc) MxPS=  49 Ivl=1ms
I:* If#= 2 Alt= 0 #EPs= 4 Cls=ff(vend.) Sub=ff Prot=ff Driver=rtl8723au
E:  Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=87(I) Atr=03(Int.) MxPS=  64 Ivl=500us

Signed-off-by: Daniel Drake dr...@endlessm.com
---
 drivers/bluetooth/btusb.c | 1 +
 1 file changed, 1 insertion(+)

This replaces/obsoletes:
  [PATCH] Bluetooth: btusb: Recognize Realtek shared wifi/bluetooth devices
  [PATCH] Bluetooth: btusb: Add Realtek devices into module device table

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 93339a4..9874aac 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -64,6 +64,7 @@ static struct usb_driver btusb_driver;
 static const struct usb_device_id btusb_table[] = {
/* Generic Bluetooth USB device */
{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
+   { USB_INTERFACE_INFO(0xe0, 0x01, 0x01) },
 
/* Generic Bluetooth AMP device */
{ USB_DEVICE_INFO(0xe0, 0x01, 0x04), .driver_info = BTUSB_AMP },
-- 
2.1.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: 3.17-rc6 on ODROID: ERROR: Bad of_node_put() on /ehci@12580000/port@1

2014-10-01 Thread Daniel Drake
On Wed, Oct 1, 2014 at 12:36 AM, Vivek Gautam gautam.vi...@samsung.com wrote:
 One reason i doubt why it could be coming is because we are
 specifically putting the
 child after doing everything with it.

 When we are getting the child node using for_each_available_child_of_node(),
 which calls for of_get_next_available_child(). So 
 of_get_next_available_child()
 does a of_node_put() on the prev node, in case we have siblings to the 
 child.

 Can you see if the below change helps ?

 
 diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c
 index 7189f2e..1b726bf 100644
 --- a/drivers/usb/host/ehci-exynos.c
 +++ b/drivers/usb/host/ehci-exynos.c
 @@ -74,7 +74,6 @@ static int exynos_ehci_get_phy(struct device *dev,

 phy = devm_of_phy_get(dev, child, NULL);
 exynos_ehci-phy[phy_number] = phy;
 -   of_node_put(child);
 if (IS_ERR(phy)) {
 ret = PTR_ERR(phy);
 if (ret == -EPROBE_DEFER) {
 


 This is on top of usb-next.
 If you are testing on rc6 only, then probably you will have to cherrypick two
 patches each for ehci-exynos and ohci-exynos:
 usb: host: ehci-exynos: Remove unnecessary usb-phy support
 usb: host: ohci-exynos: Remove unnecessary usb-phy support

I made the equivalent change to 3.17-rc7 (right now 3.17 is my main
interest), i.e. removed all of_node_put calls from
exynos_ehci_get_phy(). Same change is needed in exynos_ohci_get_phy().
Now the warnings are gone.
BTW, I think the warning only appeared when CONFIG_OF_SELFTEST=y

I didn't check the implementation details like you did, but I looked
at a few other users of for_each_available_child_of_node and it looks
like indeed you do not need to call of_node_put() on the children in
the normal case, or at least, nobody else does.

Thanks,
Daniel
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] phy: phy-samsung-usb2: Change phy power on/power off sequence

2014-07-07 Thread Daniel Drake
On Tue, Jul 1, 2014 at 4:15 PM, Kamil Debski k.deb...@samsung.com wrote:
 The Exynos4412 USB 2.0 PHY hardware differs from the description provided
 in the documentation. Some register bits have different function. This
 patch fixes the defines of register bits and changes the way how phys are
 powered on and off.

 Signed-off-by: Kamil Debski k.deb...@samsung.com

Tested on ODROID-U2 with the internal LAN (which is a USB device), and
an external USB mouse connected via the internal USB hub.

Tested-by: Daniel Drake dr...@endlessm.com
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] phy: phy-samsung-usb2: Change phy power on/power off sequence

2014-06-25 Thread Daniel Drake
On Tue, Jun 24, 2014 at 4:35 PM, Kamil Debski k.deb...@samsung.com wrote:
 By reboot I guess that you mean typing reboot or by using SysRq magic
 and not power cycling?

 If so, I had experienced the same symptoms. I guess that the Ethernet
 chip is not reset properly and fails to enumerate without power cycling
 (it's nRESET pin is connected to P3V3).

 I found that removing regulator-always-on from buck8_reg: BUCK8 in the
 dts file fixes this problem.

Yes, that fixes the problem. Thanks!

Tested-by: Daniel Drake dr...@endlessm.com
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] phy: phy-samsung-usb2: Change phy power on/power off sequence

2014-06-24 Thread Daniel Drake
On Tue, Jun 24, 2014 at 1:54 PM, Kamil Debski k.deb...@samsung.com wrote:
 The Exynos4412 USB 2.0 PHY hardware differs from the description provided
 in the documentation. Some register bits have different function. This
 patch fixes the defines of register bits and changes the way how phys are
 powered on and off.

I guess this replaces the patch titled drivers: phy: exynos4x12-phy:
fix HSIC1 power on/off sequence

Tested on ODROID-U2. Seems to be working as well as the previous patch:
- Internal SMSC hub works on boot and after reboot, tested with USB mouse
- Internal SMSC ethernet device works on boot, but disappears upon
reboot. (same as previous patch, also reproduced by Marek)

Thanks,
Daniel
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html