[asus-nb-wmi] thermal device detected by asus-nb-wmi platform driver

2014-03-20 Thread Lu, Baolu

Hi,

I booted Ubuntu13.10 onto ASUS T100 Tablet and upgraded it with upstream
kernel (3.14.0-rc7+). There is a thermal device under
/sys/devices/platform/asus-nb-wmi.

root@t100:~/linux# tree /sys/class/hwmon/
/sys/class/hwmon/
├── hwmon0 - ../../devices/platform/coretemp.0/hwmon/hwmon0
└── hwmon1 - ../../devices/platform/asus-nb-wmi/hwmon/hwmon1

root@t100:/sys/devices/platform/asus-nb-wmi# ls
cpufv driver hwmon input modalias power subsystem uevent

root@t100:~/linux# sensors
coretemp-isa-
Adapter: ISA adapter
Core 0: +38.0°C (high = +90.0°C, crit = +90.0°C)
Core 1: +38.0°C (high = +90.0°C, crit = +90.0°C)
Core 2: +39.0°C (high = +90.0°C, crit = +90.0°C)
Core 3: +38.0°C (high = +90.0°C, crit = +90.0°C)

asus-isa-
Adapter: ISA adapter
temp1: +6280.0°C

I didn't get any information about thermal interface in
Documentation/ABI/testing/sysfs-platform-asus-wmi. Is this a thermal
sensor? If it's the fact, how can I change the environment so that this
sensor gives me variable data?

Thanks,
baolu

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


[PATCH 1/1] xhci: clear root port wake on bits if controller isn't wake-up capable

2014-06-11 Thread Lu Baolu
When the xHCI PCI host is suspended, if do_wakeup is false in xhci_pci_suspend,
xhci_bus_suspend needs to clear all root port wake on bits. Otherwise some Intel
platform may get a spurious wakeup, even if PCI PME# is disabled.

http://marc.info/?l=linux-usbm=138194006009255w=2

Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
 drivers/usb/host/xhci-hub.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 6231ce6..fb771bd 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -22,6 +22,7 @@
 
 
 #include linux/slab.h
+#include linux/device.h
 #include asm/unaligned.h
 
 #include xhci.h
@@ -1139,7 +1140,9 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
 * including the USB 3.0 roothub, but only if CONFIG_PM_RUNTIME
 * is enabled, so also enable remote wake here.
 */
-   if (hcd-self.root_hub-do_remote_wakeup) {
+   if (hcd-self.root_hub-do_remote_wakeup
+device_may_wakeup(hcd-self.controller)) {
+
if (t1  PORT_CONNECT) {
t2 |= PORT_WKOC_E | PORT_WKDISC_E;
t2 = ~PORT_WKCONN_E;
-- 
1.9.1

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


[PATCH v2 1/1] xhci: clear root port wake on bits if controller isn't wake-up capable

2014-06-12 Thread Lu Baolu
When xHCI PCI host is suspended, if do_wakeup is false in xhci_pci_suspend,
xhci_bus_suspend needs to clear all root port wake on bits. Otherwise some Intel
platforms may get a spurious wakeup, even if PCI PME# is disabled.

This patch should be back-ported to kernels as old as 2.6.37, that
contains the commit 9777e3ce907d4cb5a513902a87ecd03b52499569
USB: xHCI: bus power management implementation. 

Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
 drivers/usb/host/xhci-hub.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 6231ce6..fb771bd 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -22,6 +22,7 @@
 
 
 #include linux/slab.h
+#include linux/device.h
 #include asm/unaligned.h
 
 #include xhci.h
@@ -1139,7 +1140,9 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
 * including the USB 3.0 roothub, but only if CONFIG_PM_RUNTIME
 * is enabled, so also enable remote wake here.
 */
-   if (hcd-self.root_hub-do_remote_wakeup) {
+   if (hcd-self.root_hub-do_remote_wakeup
+device_may_wakeup(hcd-self.controller)) {
+
if (t1  PORT_CONNECT) {
t2 |= PORT_WKOC_E | PORT_WKDISC_E;
t2 = ~PORT_WKCONN_E;
-- 
1.9.1

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


[PATCH 1/1] USB: Add device quirk for ASUS T100 Base Station keyboard

2014-08-28 Thread Lu Baolu
This full-speed USB device generates spurious remote wakeup event
as soon as USB_DEVICE_REMOTE_WAKEUP feature is set. As the result,
Linux can't enter system suspend and S0ix power saving modes once
this keyboard is used.

This patch tries to introduce USB_QUIRK_IGNOR_REMOTE_WAKEUP quirk.
With this quirk set, wakeup capability will be ignored during
device configure.

This patch could be back-ported to kernels as old as 2.6.39.

Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
 drivers/usb/core/hub.c | 6 --
 drivers/usb/core/quirks.c  | 4 
 include/linux/usb/quirks.h | 3 +++
 3 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 8a4dcbc..5df1457 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1977,8 +1977,10 @@ void usb_set_device_state(struct usb_device *udev,
|| new_state == USB_STATE_SUSPENDED)
;   /* No change to wakeup settings */
else if (new_state == USB_STATE_CONFIGURED)
-   wakeup = udev-actconfig-desc.bmAttributes
- USB_CONFIG_ATT_WAKEUP;
+   wakeup = (udev-quirks 
+   USB_QUIRK_IGNOR_REMOTE_WAKEUP) ? 0 :
+   udev-actconfig-desc.bmAttributes 
+   USB_CONFIG_ATT_WAKEUP;
else
wakeup = 0;
}
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index bae636e..e7d1e3c 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -159,6 +159,10 @@ static const struct usb_device_id usb_quirk_list[] = {
/* USB3503 */
{ USB_DEVICE(0x0424, 0x3503), .driver_info = USB_QUIRK_RESET_RESUME },
 
+   /* ASUS Base Station(T100) */
+   { USB_DEVICE(0x0b05, 0x17e0), .driver_info =
+   USB_QUIRK_IGNOR_REMOTE_WAKEUP },
+
{ }  /* terminating entry must be last */
 };
 
diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h
index 55a17b1..0f784c3 100644
--- a/include/linux/usb/quirks.h
+++ b/include/linux/usb/quirks.h
@@ -41,4 +41,7 @@
  */
 #define USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL 0x0080
 
+/* device generates spurious wakeup, ignore remote wakeup capability */
+#define USB_QUIRK_IGNOR_REMOTE_WAKEUP  0x0100
+
 #endif /* __LINUX_USB_QUIRKS_H */
-- 
1.9.1

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


Re: [PATCH 1/1] USB: Add device quirk for ASUS T100 Base Station keyboard

2014-08-29 Thread Lu, Baolu


On 8/29/2014 7:59 PM, Sergei Shtylyov wrote:

Hello.

On 8/29/2014 8:26 AM, Lu Baolu wrote:


This full-speed USB device generates spurious remote wakeup event
as soon as USB_DEVICE_REMOTE_WAKEUP feature is set. As the result,
Linux can't enter system suspend and S0ix power saving modes once
this keyboard is used.



This patch tries to introduce USB_QUIRK_IGNOR_REMOTE_WAKEUP quirk.


   Why not IGNORE? This doesn't look like a big save...


Sure, will change it.




With this quirk set, wakeup capability will be ignored during
device configure.



This patch could be back-ported to kernels as old as 2.6.39.



Signed-off-by: Lu Baolu baolu...@linux.intel.com


WBR, Sergei



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


[PATCH v2 1/1] USB: Add device quirk for ASUS T100 Base Station keyboard

2014-08-31 Thread Lu Baolu
This full-speed USB device generates spurious remote wakeup event
as soon as USB_DEVICE_REMOTE_WAKEUP feature is set. As the result,
Linux can't enter system suspend and S0ix power saving modes once
this keyboard is used.

This patch tries to introduce USB_QUIRK_IGNORE_REMOTE_WAKEUP quirk.
With this quirk set, wakeup capability will be ignored during
device configure.

This patch could be back-ported to kernels as old as 2.6.39.

Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
 drivers/usb/core/hub.c | 6 --
 drivers/usb/core/quirks.c  | 4 
 include/linux/usb/quirks.h | 3 +++
 3 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 8a4dcbc..5df1457 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1977,8 +1977,10 @@ void usb_set_device_state(struct usb_device *udev,
|| new_state == USB_STATE_SUSPENDED)
;   /* No change to wakeup settings */
else if (new_state == USB_STATE_CONFIGURED)
-   wakeup = udev-actconfig-desc.bmAttributes
- USB_CONFIG_ATT_WAKEUP;
+   wakeup = (udev-quirks 
+   USB_QUIRK_IGNORE_REMOTE_WAKEUP) ? 0 :
+   udev-actconfig-desc.bmAttributes 
+   USB_CONFIG_ATT_WAKEUP;
else
wakeup = 0;
}
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index bae636e..e7d1e3c 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -159,6 +159,10 @@ static const struct usb_device_id usb_quirk_list[] = {
/* USB3503 */
{ USB_DEVICE(0x0424, 0x3503), .driver_info = USB_QUIRK_RESET_RESUME },
 
+   /* ASUS Base Station(T100) */
+   { USB_DEVICE(0x0b05, 0x17e0), .driver_info =
+   USB_QUIRK_IGNORE_REMOTE_WAKEUP },
+
{ }  /* terminating entry must be last */
 };
 
diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h
index 55a17b1..0f784c3 100644
--- a/include/linux/usb/quirks.h
+++ b/include/linux/usb/quirks.h
@@ -41,4 +41,7 @@
  */
 #define USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL 0x0080
 
+/* device generates spurious wakeup, ignore remote wakeup capability */
+#define USB_QUIRK_IGNORE_REMOTE_WAKEUP 0x0100
+
 #endif /* __LINUX_USB_QUIRKS_H */
-- 
1.9.1

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


[PATCH 0/3] Rework xhci: clear root port wake on bits if controller isn't wake-up capable

2014-10-30 Thread Lu Baolu
This serie of patch reworks commit ff8cbf250b448aac35589f6075082c3fcad8a8fe.
This has been discussed at http://www.spinics.net/lists/linux-usb/msg114986.html
It also includes a patch to fix a comment in drivers/usb/host/xhci.h.

Lu Baolu (3):
  usb: xhci: Revert xhci: clear root port wake on bits if controller
isn't wake-up capable
  usb: xhci: This reworks ff8cbf250b448aac35589f6075082c3fcad8a8fe
  usb: xhci: fix comment for PORT_DEV_REMOVE

 drivers/usb/host/xhci-hub.c |  5 +
 drivers/usb/host/xhci-pci.c | 42 ++
 drivers/usb/host/xhci.h |  8 +++-
 3 files changed, 50 insertions(+), 5 deletions(-)

-- 
1.9.1

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


[PATCH 3/3] usb: xhci: fix comment for PORT_DEV_REMOVE

2014-10-30 Thread Lu Baolu
According to xHCI specification, PORT_DEV_REMOVE(bit 30) in PORTSC
true means Device is non-removable.

Reported-by: Juro Bystricky jurobystri...@hotmail.com
Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
 drivers/usb/host/xhci.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 2f6131b..4e160db 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -358,7 +358,7 @@ struct xhci_op_regs {
 /* wake on over-current (enable) */
 #define PORT_WKOC_E(1  27)
 /* bits 28:29 reserved */
-/* true: device is removable - for USB 3.0 roothub emulation */
+/* true: device is non-removable - for USB 3.0 roothub emulation */
 #define PORT_DEV_REMOVE(1  30)
 /* Initiate a warm port reset - complete when PORT_WRC is '1' */
 #define PORT_WR(1  31)
-- 
1.9.1

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


[PATCH 2/3] usb: xhci: This reworks ff8cbf250b448aac35589f6075082c3fcad8a8fe

2014-10-30 Thread Lu Baolu
xhci: clear root port wake on bits if controller isn't wake-up capable

When xHCI PCI host is suspended, if do_wakeup is false in xhci_pci_suspend,
xhci_pci_suspend needs to clear all root port wake on bits. Otherwise some Intel
platforms may get a spurious wakeup, even if PCI PME# is disabled.

Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
 drivers/usb/host/xhci-pci.c | 42 ++
 drivers/usb/host/xhci.h |  6 ++
 2 files changed, 48 insertions(+)

diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 280dde9..3e7441a 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -27,6 +27,8 @@
 #include xhci.h
 #include xhci-trace.h
 
+#definePORT_WAKE_BITS  (PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E)
+
 /* Device for a quirk */
 #define PCI_VENDOR_ID_FRESCO_LOGIC 0x1b73
 #define PCI_DEVICE_ID_FRESCO_LOGIC_PDK 0x1000
@@ -126,6 +128,7 @@ static void xhci_pci_quirks(struct device *dev, struct 
xhci_hcd *xhci)
 */
xhci-quirks |= XHCI_SPURIOUS_REBOOT;
xhci-quirks |= XHCI_AVOID_BEI;
+   xhci-quirks |= XHCI_DISABLE_PORT_WOB;
}
if (pdev-vendor == PCI_VENDOR_ID_INTEL 
(pdev-device == PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI ||
@@ -279,6 +282,42 @@ static void xhci_pci_remove(struct pci_dev *dev)
 }
 
 #ifdef CONFIG_PM
+static void xhci_disable_port_wake_bits(struct xhci_hcd *xhci)
+{
+   int port_index;
+   __le32 __iomem **port_array;
+   unsigned long flags;
+   u32 t1, t2;
+
+   spin_lock_irqsave(xhci-lock, flags);
+
+   /* disble usb3 ports Wake bits*/
+   port_index = xhci-num_usb3_ports;
+   port_array = xhci-usb3_ports;
+   while (port_index--) {
+   t1 = readl(port_array[port_index]);
+   t2 = xhci_port_state_to_neutral(t1);
+   t2 = ~PORT_WAKE_BITS;
+   t1 = xhci_port_state_to_neutral(t1);
+   if (t1 != t2)
+   writel(t2, port_array[port_index]);
+   }
+
+   /* disble usb2 ports Wake bits*/
+   port_index = xhci-num_usb2_ports;
+   port_array = xhci-usb2_ports;
+   while (port_index--) {
+   t1 = readl(port_array[port_index]);
+   t2 = xhci_port_state_to_neutral(t1);
+   t2 = ~PORT_WAKE_BITS;
+   t1 = xhci_port_state_to_neutral(t1);
+   if (t1 != t2)
+   writel(t2, port_array[port_index]);
+   }
+
+   spin_unlock_irqrestore(xhci-lock, flags);
+}
+
 static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
 {
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
@@ -291,6 +330,9 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool 
do_wakeup)
if (xhci-quirks  XHCI_COMP_MODE_QUIRK)
pdev-no_d3cold = true;
 
+   if (xhci-quirks  XHCI_DISABLE_PORT_WOB  !do_wakeup)
+   xhci_disable_port_wake_bits(xhci);
+
return xhci_suspend(xhci);
 }
 
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index df76d64..2f6131b 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1560,6 +1560,12 @@ struct xhci_hcd {
 #define XHCI_SPURIOUS_WAKEUP   (1  18)
 /* For controllers with a broken beyond repair streams implementation */
 #define XHCI_BROKEN_STREAMS(1  19)
+/*
+ * Some Intel platforms may get a spurious wakeup after entering system
+ * suspend with PCI PME# disabled. Software can workaround this by dis-
+ * abling the wake on bits of all root ports.
+ */
+#define XHCI_DISABLE_PORT_WOB  (1  20)
unsigned intnum_active_eps;
unsigned intlimit_active_eps;
/* There are two roothubs to keep track of bus suspend info for */
-- 
1.9.1

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


[PATCH 1/3] usb: xhci: Revert xhci: clear root port wake on bits if controller isn't wake-up capable

2014-10-30 Thread Lu Baolu
This reverts commit ff8cbf250b448aac35589f6075082c3fcad8a8fe.

Commit ff8cbf250b448aac35589f6075082c3fcad8a8fe triggers the bug logged at

https://bugzilla.kernel.org/show_bug.cgi?id=85701

Reported-by: Dmitry Nezhevenko d...@inhex.net
Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
 drivers/usb/host/xhci-hub.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 696160d..388cfd8 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -22,7 +22,6 @@
 
 
 #include linux/slab.h
-#include linux/device.h
 #include asm/unaligned.h
 
 #include xhci.h
@@ -1149,9 +1148,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
 * including the USB 3.0 roothub, but only if CONFIG_PM_RUNTIME
 * is enabled, so also enable remote wake here.
 */
-   if (hcd-self.root_hub-do_remote_wakeup
-device_may_wakeup(hcd-self.controller)) {
-
+   if (hcd-self.root_hub-do_remote_wakeup) {
if (t1  PORT_CONNECT) {
t2 |= PORT_WKOC_E | PORT_WKDISC_E;
t2 = ~PORT_WKCONN_E;
-- 
1.9.1

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


[PATCH 1/1] usb: xhci: fix comment for PORT_DEV_REMOVE

2014-09-16 Thread Lu Baolu
According to xHCI specification, PORT_DEV_REMOVE(bit 30) in PORTSC
true means Device is non-removable.

Reported-by: Juro Bystricky jurobystri...@hotmail.com
Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
 drivers/usb/host/xhci.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index dace515..2682f18 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -358,7 +358,7 @@ struct xhci_op_regs {
 /* wake on over-current (enable) */
 #define PORT_WKOC_E(1  27)
 /* bits 28:29 reserved */
-/* true: device is removable - for USB 3.0 roothub emulation */
+/* true: device is non-removable - for USB 3.0 roothub emulation */
 #define PORT_DEV_REMOVE(1  30)
 /* Initiate a warm port reset - complete when PORT_WRC is '1' */
 #define PORT_WR(1  31)
-- 
1.9.1

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


Re: [PATCH v4 0/3] Rework xhci: clear root port wake on bits if controller isn't wake-up capable

2014-11-13 Thread Lu, Baolu

Hi Mathias,

This patch series has been acked by Alan Stern. There seems no further 
comments from others. Can you please pull in it?


Thanks,
-baolu

On 2014年11月06日 10:50, Lu Baolu wrote:

This serie of patch reworks commit ff8cbf250b448aac35589f6075082c3fcad8a8fe.
This has been discussed at http://www.spinics.net/lists/linux-usb/msg114986.html
It also includes a patch to fix a comment in drivers/usb/host/xhci.h.

Changes in v4:
- Refine xhci_disable_port_wake_on_bits().
- Add Acked-by: Alan Stern

Changes in v3:
- Need to consider run-time suspend as well.
- Change wake-up capable to allowed to do wakeup
in both comments and patch description.
- Add Suggested-by: Alan Stern

Changes in v2:
- Should not be a quirk.
- Should be applied to all xhci controllers.

Lu Baolu (3):
   usb: xhci: Revert xhci: clear root port wake on bits if controller
 isn't wake-up capable
   usb: xhci: This reworks ff8cbf250b448aac35589f6075082c3fcad8a8fe
   usb: xhci: fix comment for PORT_DEV_REMOVE

  drivers/usb/host/xhci-hub.c  |  5 +
  drivers/usb/host/xhci-pci.c  |  2 +-
  drivers/usb/host/xhci-plat.c | 10 +-
  drivers/usb/host/xhci.c  | 42 +-
  drivers/usb/host/xhci.h  |  4 ++--
  5 files changed, 54 insertions(+), 9 deletions(-)



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


Re: [PATCH 06/19] usb: dwc3: host: Pass the XHCI_DRD_SUPPORT and XHCI_NEEDS_LHC_RESET quirk

2014-11-26 Thread Lu, Baolu


On 2014年11月25日 21:11, George Cherian wrote:

Pass the quir flag XHCI_DRD_SUPPORT from DWC3 host to xhci platform driver.

quir to quirk

Regards,
Baolu


This enables xhci driver to handle deallocation's differently while in DRD mode.
Pass the quirk flag XHCI_NEEDS_LHC_RESET from DWC3 host to xhci platform
driver. This enables to do LHRESET during xhci_reset().

Signed-off-by: George Cherian george.cher...@ti.com
---
  drivers/usb/dwc3/host.c | 2 ++
  1 file changed, 2 insertions(+)

diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c
index dcb8ca0..257b5b5 100644
--- a/drivers/usb/dwc3/host.c
+++ b/drivers/usb/dwc3/host.c
@@ -53,6 +53,8 @@ int dwc3_host_init(struct dwc3 *dwc)
  #ifdef CONFIG_DWC3_HOST_USB3_LPM_ENABLE
pdata.usb3_lpm_capable = 1;
  #endif
+   pdata.usb_drd_support = 1;
+   pdata.usb_needs_lhc_reset = 1;
  
  	ret = platform_device_add_data(xhci, pdata, sizeof(pdata));

if (ret) {


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


Re: [PATCH 2/3] usb: xhci: This reworks ff8cbf250b448aac35589f6075082c3fcad8a8fe

2014-11-03 Thread Lu, Baolu


On 10/31/2014 10:28 PM, Alan Stern wrote:

On Fri, 31 Oct 2014, Lu Baolu wrote:


xhci: clear root port wake on bits if controller isn't wake-up capable

When xHCI PCI host is suspended, if do_wakeup is false in xhci_pci_suspend,
xhci_pci_suspend needs to clear all root port wake on bits. Otherwise some Intel
platforms may get a spurious wakeup, even if PCI PME# is disabled.

Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
  drivers/usb/host/xhci-pci.c | 42 ++
  drivers/usb/host/xhci.h |  6 ++
  2 files changed, 48 insertions(+)

diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 280dde9..3e7441a 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -27,6 +27,8 @@
  #include xhci.h
  #include xhci-trace.h
  
+#define	PORT_WAKE_BITS	(PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E)

+
  /* Device for a quirk */
  #define PCI_VENDOR_ID_FRESCO_LOGIC0x1b73
  #define PCI_DEVICE_ID_FRESCO_LOGIC_PDK0x1000
@@ -126,6 +128,7 @@ static void xhci_pci_quirks(struct device *dev, struct 
xhci_hcd *xhci)
 */
xhci-quirks |= XHCI_SPURIOUS_REBOOT;
xhci-quirks |= XHCI_AVOID_BEI;
+   xhci-quirks |= XHCI_DISABLE_PORT_WOB;
}
if (pdev-vendor == PCI_VENDOR_ID_INTEL 
(pdev-device == PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI ||
@@ -279,6 +282,42 @@ static void xhci_pci_remove(struct pci_dev *dev)
  }
  
  #ifdef CONFIG_PM

+static void xhci_disable_port_wake_bits(struct xhci_hcd *xhci)
+{
+   int port_index;
+   __le32 __iomem **port_array;
+   unsigned long flags;
+   u32 t1, t2;
+
+   spin_lock_irqsave(xhci-lock, flags);
+
+   /* disble usb3 ports Wake bits*/
+   port_index = xhci-num_usb3_ports;
+   port_array = xhci-usb3_ports;
+   while (port_index--) {
+   t1 = readl(port_array[port_index]);
+   t2 = xhci_port_state_to_neutral(t1);
+   t2 = ~PORT_WAKE_BITS;
+   t1 = xhci_port_state_to_neutral(t1);
+   if (t1 != t2)
+   writel(t2, port_array[port_index]);
+   }
+
+   /* disble usb2 ports Wake bits*/
+   port_index = xhci-num_usb2_ports;
+   port_array = xhci-usb2_ports;
+   while (port_index--) {
+   t1 = readl(port_array[port_index]);
+   t2 = xhci_port_state_to_neutral(t1);
+   t2 = ~PORT_WAKE_BITS;
+   t1 = xhci_port_state_to_neutral(t1);
+   if (t1 != t2)
+   writel(t2, port_array[port_index]);
+   }
+
+   spin_unlock_irqrestore(xhci-lock, flags);
+}
+
  static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
  {
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
@@ -291,6 +330,9 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool 
do_wakeup)
if (xhci-quirks  XHCI_COMP_MODE_QUIRK)
pdev-no_d3cold = true;
  
+	if (xhci-quirks  XHCI_DISABLE_PORT_WOB  !do_wakeup)

+   xhci_disable_port_wake_bits(xhci);
+
return xhci_suspend(xhci);
  }

There are two things wrong here.  First, this should not be a quirk.
The Wake-On bits should be disabled whenever they aren't needed, on
every controller.

Second, this code (or something like it) belongs in xhci.c or
xhci-hub.c, not xhci-pci.c.  This is because it should apply to all
xHCI controllers, not just the PCI-based ones.

Hi Alan,

I agree with you. I will resubmit my patches.

BR,
baolu



(In fact, instead of disabling the Wake-On bits when the controller is
suspended and do_wakeup is 0, it probably would be better to leave them
disabled normally and then _enable_ them if do_wakeup is 1.)

Alan Stern



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


[PATCH v2 3/3] usb: xhci: fix comment for PORT_DEV_REMOVE

2014-11-04 Thread Lu Baolu
According to xHCI specification, PORT_DEV_REMOVE(bit 30) in PORTSC
true means Device is non-removable.

Reported-by: Juro Bystricky jurobystri...@hotmail.com
Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
 drivers/usb/host/xhci.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index df76d64..66c168a9 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -358,7 +358,7 @@ struct xhci_op_regs {
 /* wake on over-current (enable) */
 #define PORT_WKOC_E(1  27)
 /* bits 28:29 reserved */
-/* true: device is removable - for USB 3.0 roothub emulation */
+/* true: device is non-removable - for USB 3.0 roothub emulation */
 #define PORT_DEV_REMOVE(1  30)
 /* Initiate a warm port reset - complete when PORT_WRC is '1' */
 #define PORT_WR(1  31)
-- 
1.9.1

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


[PATCH v2 0/3] Rework xhci: clear root port wake on bits if controller isn't wake-up capable

2014-11-04 Thread Lu Baolu
This serie of patch reworks commit ff8cbf250b448aac35589f6075082c3fcad8a8fe.
This has been discussed at http://www.spinics.net/lists/linux-usb/msg114986.html
It also includes a patch to fix a comment in drivers/usb/host/xhci.h.

Changes in v2:
* Should not be a quirk.
* Should be applied to all xhci controllers.

Lu Baolu (3):
  usb: xhci: Revert xhci: clear root port wake on bits if controller
isn't wake-up capable
  usb: xhci: This reworks ff8cbf250b448aac35589f6075082c3fcad8a8fe
  usb: xhci: fix comment for PORT_DEV_REMOVE

 drivers/usb/host/xhci-hub.c |  5 +
 drivers/usb/host/xhci-pci.c | 42 ++
 drivers/usb/host/xhci.h |  8 +++-
 3 files changed, 50 insertions(+), 5 deletions(-)

-- 
1.9.1

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


[PATCH v2 1/3] usb: xhci: Revert xhci: clear root port wake on bits if controller isn't wake-up capable

2014-11-04 Thread Lu Baolu
This reverts commit ff8cbf250b448aac35589f6075082c3fcad8a8fe.

Commit ff8cbf250b448aac35589f6075082c3fcad8a8fe triggers the bug logged at

https://bugzilla.kernel.org/show_bug.cgi?id=85701

Reported-by: Dmitry Nezhevenko d...@inhex.net
Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
 drivers/usb/host/xhci-hub.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 696160d..388cfd8 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -22,7 +22,6 @@
 
 
 #include linux/slab.h
-#include linux/device.h
 #include asm/unaligned.h
 
 #include xhci.h
@@ -1149,9 +1148,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
 * including the USB 3.0 roothub, but only if CONFIG_PM_RUNTIME
 * is enabled, so also enable remote wake here.
 */
-   if (hcd-self.root_hub-do_remote_wakeup
-device_may_wakeup(hcd-self.controller)) {
-
+   if (hcd-self.root_hub-do_remote_wakeup) {
if (t1  PORT_CONNECT) {
t2 |= PORT_WKOC_E | PORT_WKDISC_E;
t2 = ~PORT_WKCONN_E;
-- 
1.9.1

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


[PATCH v2 2/3] usb: xhci: This reworks ff8cbf250b448aac35589f6075082c3fcad8a8fe

2014-11-04 Thread Lu Baolu
xhci: clear root port wake on bits if controller isn't wake-up capable

When system is being suspended, if host device is not wakeup capable,
xhci_suspend() needs to clear all root port wake on bits.  Otherwise,
some platforms may generate spurious wakeup, even if PCI PME# is dis-
abled.

Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
 drivers/usb/host/xhci.c | 42 ++
 1 file changed, 42 insertions(+)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 2a5d45b..cd57aae 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -35,6 +35,8 @@
 #define DRIVER_AUTHOR Sarah Sharp
 #define DRIVER_DESC 'eXtensible' Host Controller (xHC) Driver
 
+#definePORT_WAKE_BITS  (PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E)
+
 /* Some 0.95 hardware can't handle the chain bit on a Link TRB being cleared */
 static int link_quirk;
 module_param(link_quirk, int, S_IRUGO | S_IWUSR);
@@ -851,6 +853,42 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci)
xhci_set_cmd_ring_deq(xhci);
 }
 
+static void xhci_disable_port_wake_on_bits(struct xhci_hcd *xhci)
+{
+   int port_index;
+   __le32 __iomem **port_array;
+   unsigned long flags;
+   u32 t1, t2;
+
+   spin_lock_irqsave(xhci-lock, flags);
+
+   /* disble usb3 ports Wake bits*/
+   port_index = xhci-num_usb3_ports;
+   port_array = xhci-usb3_ports;
+   while (port_index--) {
+   t1 = readl(port_array[port_index]);
+   t2 = xhci_port_state_to_neutral(t1);
+   t2 = ~PORT_WAKE_BITS;
+   t1 = xhci_port_state_to_neutral(t1);
+   if (t1 != t2)
+   writel(t2, port_array[port_index]);
+   }
+
+   /* disble usb2 ports Wake bits*/
+   port_index = xhci-num_usb2_ports;
+   port_array = xhci-usb2_ports;
+   while (port_index--) {
+   t1 = readl(port_array[port_index]);
+   t2 = xhci_port_state_to_neutral(t1);
+   t2 = ~PORT_WAKE_BITS;
+   t1 = xhci_port_state_to_neutral(t1);
+   if (t1 != t2)
+   writel(t2, port_array[port_index]);
+   }
+
+   spin_unlock_irqrestore(xhci-lock, flags);
+}
+
 /*
  * Stop HC (not bus-specific)
  *
@@ -868,6 +906,10 @@ int xhci_suspend(struct xhci_hcd *xhci)
xhci-shared_hcd-state != HC_STATE_SUSPENDED)
return -EINVAL;
 
+   /* Clear root port wake on bits if not wakeup capable. */
+   if (!device_may_wakeup(hcd-self.controller))
+   xhci_disable_port_wake_on_bits(xhci);
+
/* Don't poll the roothubs on bus suspend. */
xhci_dbg(xhci, %s: stopping port polling.\n, __func__);
clear_bit(HCD_FLAG_POLL_RH, hcd-flags);
-- 
1.9.1

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


Re: [PATCH v2 2/3] usb: xhci: This reworks ff8cbf250b448aac35589f6075082c3fcad8a8fe

2014-11-04 Thread Lu, Baolu


On 11/5/2014 12:58 AM, Alan Stern wrote:

On Tue, 4 Nov 2014, Lu Baolu wrote:


xhci: clear root port wake on bits if controller isn't wake-up capable

When system is being suspended, if host device is not wakeup capable,
xhci_suspend() needs to clear all root port wake on bits.  Otherwise,
some platforms may generate spurious wakeup, even if PCI PME# is dis-
abled.

Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
  drivers/usb/host/xhci.c | 42 ++
  1 file changed, 42 insertions(+)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 2a5d45b..cd57aae 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -35,6 +35,8 @@
  #define DRIVER_AUTHOR Sarah Sharp
  #define DRIVER_DESC 'eXtensible' Host Controller (xHC) Driver
  
+#define	PORT_WAKE_BITS	(PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E)

+
  /* Some 0.95 hardware can't handle the chain bit on a Link TRB being cleared 
*/
  static int link_quirk;
  module_param(link_quirk, int, S_IRUGO | S_IWUSR);
@@ -851,6 +853,42 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci)
xhci_set_cmd_ring_deq(xhci);
  }
  
+static void xhci_disable_port_wake_on_bits(struct xhci_hcd *xhci)

+{
+   int port_index;
+   __le32 __iomem **port_array;
+   unsigned long flags;
+   u32 t1, t2;
+
+   spin_lock_irqsave(xhci-lock, flags);
+
+   /* disble usb3 ports Wake bits*/
+   port_index = xhci-num_usb3_ports;
+   port_array = xhci-usb3_ports;
+   while (port_index--) {
+   t1 = readl(port_array[port_index]);
+   t2 = xhci_port_state_to_neutral(t1);
+   t2 = ~PORT_WAKE_BITS;
+   t1 = xhci_port_state_to_neutral(t1);
+   if (t1 != t2)
+   writel(t2, port_array[port_index]);
+   }
+
+   /* disble usb2 ports Wake bits*/
+   port_index = xhci-num_usb2_ports;
+   port_array = xhci-usb2_ports;
+   while (port_index--) {
+   t1 = readl(port_array[port_index]);
+   t2 = xhci_port_state_to_neutral(t1);
+   t2 = ~PORT_WAKE_BITS;
+   t1 = xhci_port_state_to_neutral(t1);
+   if (t1 != t2)
+   writel(t2, port_array[port_index]);
+   }
+
+   spin_unlock_irqrestore(xhci-lock, flags);
+}
+
  /*
   * Stop HC (not bus-specific)
   *
@@ -868,6 +906,10 @@ int xhci_suspend(struct xhci_hcd *xhci)
xhci-shared_hcd-state != HC_STATE_SUSPENDED)
return -EINVAL;
  
+	/* Clear root port wake on bits if not wakeup capable. */

+   if (!device_may_wakeup(hcd-self.controller))
+   xhci_disable_port_wake_on_bits(xhci);
+
/* Don't poll the roothubs on bus suspend. */
xhci_dbg(xhci, %s: stopping port polling.\n, __func__);
clear_bit(HCD_FLAG_POLL_RH, hcd-flags);

This is better but still wrong.  Remember, this same code gets called
for system suspend _and_ for runtime suspend.  During runtime suspend,
wakeup is always supposed to be turned on, even if device_may_wakeup()
is false.  That's because device_may_wakeup() refers only to system
suspend.  What you need to test is the do_wakeup flag, which should be
passed into xhci_suspend() by xhci_pci_suspend() and
xhci_plat_suspend().
Yes, it should cover runtime suspend as well. Thanks for the comments. I 
will resend the patch.



Another problem is in the patch description and the comments.  If
device_may_wakeup() returns false, it doesn't mean the controller isn't
wakeup-capable -- it means the controller isn't _allowed_ to wake up
the system.  Those are two different things.


Accept, I will change this in new patch version.


Finally, the code in xhci_disable_port_wake_on_bits() looks a little
peculiar -- I'm not sure about all those calls to
xhci_port_state_to_neutral().  But I'm not an expert on that; Mathias
will have to advise on it.

This part of code was written with reference to code in xhci-hub.c.

Comments of xhci_port_state_to_neutral():
/*
 * Given a port state, this function returns a value that would result 
in the
 * port being in the same state, if the value was written to the port 
status

 * control register.
 * Save Read Only (RO) bits and save read/write bits where
 * writing a 0 clears the bit and writing a 1 sets the bit (RWS).
 * For all other types (RW1S, RW1CS, RW, and RZ), writing a '0' has no 
effect.

 */

This calculation is used to avoid side effect of changing other bit fields.

Thanks,
-baolu



Alan Stern



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


[PATCH v3 0/3] Rework xhci: clear root port wake on bits if controller isn't wake-up capable

2014-11-04 Thread Lu Baolu
This serie of patch reworks commit ff8cbf250b448aac35589f6075082c3fcad8a8fe.
This has been discussed at http://www.spinics.net/lists/linux-usb/msg114986.html
It also includes a patch to fix a comment in drivers/usb/host/xhci.h.

Changes in v3:
* Need to consider run-time suspend as well.
* Change wake-up capable to allowed to do wakeup
in both comments and patch description.
* Add Suggested-by: Alan Stern

Changes in v2:
* Should not be a quirk.
* Should be applied to all xhci controllers.

Lu Baolu (3):
  usb: xhci: Revert xhci: clear root port wake on bits if controller
isn't wake-up capable
  usb: xhci: This reworks ff8cbf250b448aac35589f6075082c3fcad8a8fe
  usb: xhci: fix comment for PORT_DEV_REMOVE

 drivers/usb/host/xhci-hub.c  |  5 +
 drivers/usb/host/xhci-pci.c  |  2 +-
 drivers/usb/host/xhci-plat.c | 10 +-
 drivers/usb/host/xhci.c  | 44 +++-
 drivers/usb/host/xhci.h  |  4 ++--
 5 files changed, 56 insertions(+), 9 deletions(-)

-- 
1.9.1

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


[PATCH v3 3/3] usb: xhci: fix comment for PORT_DEV_REMOVE

2014-11-04 Thread Lu Baolu
According to xHCI specification, PORT_DEV_REMOVE(bit 30) in PORTSC
true means Device is non-removable.

Signed-off-by: Lu Baolu baolu...@linux.intel.com
Reported-by: Juro Bystricky jurobystri...@hotmail.com
---
 drivers/usb/host/xhci.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index d745715..ab36bbb 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -358,7 +358,7 @@ struct xhci_op_regs {
 /* wake on over-current (enable) */
 #define PORT_WKOC_E(1  27)
 /* bits 28:29 reserved */
-/* true: device is removable - for USB 3.0 roothub emulation */
+/* true: device is non-removable - for USB 3.0 roothub emulation */
 #define PORT_DEV_REMOVE(1  30)
 /* Initiate a warm port reset - complete when PORT_WRC is '1' */
 #define PORT_WR(1  31)
-- 
1.9.1

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


[PATCH v3 2/3] usb: xhci: This reworks ff8cbf250b448aac35589f6075082c3fcad8a8fe

2014-11-04 Thread Lu Baolu
xhci: clear root port wake on bits if controller isn't allowed to do wakeup

When system is being suspended, if host device is not allowed to do wakeup,
xhci_suspend() needs to clear all root port wake on bits. Otherwise, some
platforms may generate spurious wakeup, even if PCI PME# is disabled.

Signed-off-by: Lu Baolu baolu...@linux.intel.com
Suggested-by: Alan Stern st...@rowland.harvard.edu
---
 drivers/usb/host/xhci-pci.c  |  2 +-
 drivers/usb/host/xhci-plat.c | 10 +-
 drivers/usb/host/xhci.c  | 44 +++-
 drivers/usb/host/xhci.h  |  2 +-
 4 files changed, 54 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 280dde9..d3fa3c2 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -291,7 +291,7 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool 
do_wakeup)
if (xhci-quirks  XHCI_COMP_MODE_QUIRK)
pdev-no_d3cold = true;
 
-   return xhci_suspend(xhci);
+   return xhci_suspend(xhci, do_wakeup);
 }
 
 static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated)
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 3d78b0c..646300c 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -204,7 +204,15 @@ static int xhci_plat_suspend(struct device *dev)
struct usb_hcd  *hcd = dev_get_drvdata(dev);
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
 
-   return xhci_suspend(xhci);
+   /*
+* xhci_suspend() needs `do_wakeup` to know whether host is allowed
+* to do wakeup during suspend. Since xhci_plat_suspend is currently
+* only designed for system suspend, device_may_wakeup() is enough
+* to dertermine whether host is allowed to do wakeup. Need to
+* reconsider this when xhci_plat_suspend enlarges its scope, e.g.,
+* also applies to runtime suspend.
+*/
+   return xhci_suspend(xhci, device_may_wakeup(dev));
 }
 
 static int xhci_plat_resume(struct device *dev)
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 2a5d45b..70d607b 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -35,6 +35,8 @@
 #define DRIVER_AUTHOR Sarah Sharp
 #define DRIVER_DESC 'eXtensible' Host Controller (xHC) Driver
 
+#definePORT_WAKE_BITS  (PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E)
+
 /* Some 0.95 hardware can't handle the chain bit on a Link TRB being cleared */
 static int link_quirk;
 module_param(link_quirk, int, S_IRUGO | S_IWUSR);
@@ -851,13 +853,49 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci)
xhci_set_cmd_ring_deq(xhci);
 }
 
+static void xhci_disable_port_wake_on_bits(struct xhci_hcd *xhci)
+{
+   int port_index;
+   __le32 __iomem **port_array;
+   unsigned long flags;
+   u32 t1, t2;
+
+   spin_lock_irqsave(xhci-lock, flags);
+
+   /* disble usb3 ports Wake bits*/
+   port_index = xhci-num_usb3_ports;
+   port_array = xhci-usb3_ports;
+   while (port_index--) {
+   t1 = readl(port_array[port_index]);
+   t2 = xhci_port_state_to_neutral(t1);
+   t2 = ~PORT_WAKE_BITS;
+   t1 = xhci_port_state_to_neutral(t1);
+   if (t1 != t2)
+   writel(t2, port_array[port_index]);
+   }
+
+   /* disble usb2 ports Wake bits*/
+   port_index = xhci-num_usb2_ports;
+   port_array = xhci-usb2_ports;
+   while (port_index--) {
+   t1 = readl(port_array[port_index]);
+   t2 = xhci_port_state_to_neutral(t1);
+   t2 = ~PORT_WAKE_BITS;
+   t1 = xhci_port_state_to_neutral(t1);
+   if (t1 != t2)
+   writel(t2, port_array[port_index]);
+   }
+
+   spin_unlock_irqrestore(xhci-lock, flags);
+}
+
 /*
  * Stop HC (not bus-specific)
  *
  * This is called when the machine transition into S3/S4 mode.
  *
  */
-int xhci_suspend(struct xhci_hcd *xhci)
+int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
 {
int rc = 0;
unsigned intdelay = XHCI_MAX_HALT_USEC;
@@ -868,6 +906,10 @@ int xhci_suspend(struct xhci_hcd *xhci)
xhci-shared_hcd-state != HC_STATE_SUSPENDED)
return -EINVAL;
 
+   /* Clear root port wake on bits if wakeup not allowed. */
+   if (!do_wakeup)
+   xhci_disable_port_wake_on_bits(xhci);
+
/* Don't poll the roothubs on bus suspend. */
xhci_dbg(xhci, %s: stopping port polling.\n, __func__);
clear_bit(HCD_FLAG_POLL_RH, hcd-flags);
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index df76d64..d745715 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1746,7 +1746,7 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t 
get_quirks);
 void xhci_init_driver(struct hc_driver *drv, int

[PATCH v3 1/3] usb: xhci: Revert xhci: clear root port wake on bits if controller isn't wake-up capable

2014-11-04 Thread Lu Baolu
This reverts commit ff8cbf250b448aac35589f6075082c3fcad8a8fe.

Commit ff8cbf250b448aac35589f6075082c3fcad8a8fe triggers the bug logged at

https://bugzilla.kernel.org/show_bug.cgi?id=85701

Signed-off-by: Lu Baolu baolu...@linux.intel.com
Reported-by: Dmitry Nezhevenko d...@inhex.net
---
 drivers/usb/host/xhci-hub.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 696160d..388cfd8 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -22,7 +22,6 @@
 
 
 #include linux/slab.h
-#include linux/device.h
 #include asm/unaligned.h
 
 #include xhci.h
@@ -1149,9 +1148,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
 * including the USB 3.0 roothub, but only if CONFIG_PM_RUNTIME
 * is enabled, so also enable remote wake here.
 */
-   if (hcd-self.root_hub-do_remote_wakeup
-device_may_wakeup(hcd-self.controller)) {
-
+   if (hcd-self.root_hub-do_remote_wakeup) {
if (t1  PORT_CONNECT) {
t2 |= PORT_WKOC_E | PORT_WKDISC_E;
t2 = ~PORT_WKCONN_E;
-- 
1.9.1

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


Re: [PATCH v3 2/3] usb: xhci: This reworks ff8cbf250b448aac35589f6075082c3fcad8a8fe

2014-11-05 Thread Lu, Baolu


On 11/6/2014 5:24 AM, Alan Stern wrote:

On Wed, 5 Nov 2014, Lu Baolu wrote:


xhci: clear root port wake on bits if controller isn't allowed to do wakeup

When system is being suspended, if host device is not allowed to do wakeup,
xhci_suspend() needs to clear all root port wake on bits. Otherwise, some
platforms may generate spurious wakeup, even if PCI PME# is disabled.

Signed-off-by: Lu Baolu baolu...@linux.intel.com
Suggested-by: Alan Stern st...@rowland.harvard.edu

This looks pretty good now.


+static void xhci_disable_port_wake_on_bits(struct xhci_hcd *xhci)
+{
+   int port_index;
+   __le32 __iomem **port_array;
+   unsigned long flags;
+   u32 t1, t2;
+
+   spin_lock_irqsave(xhci-lock, flags);
+
+   /* disble usb3 ports Wake bits*/
+   port_index = xhci-num_usb3_ports;
+   port_array = xhci-usb3_ports;
+   while (port_index--) {
+   t1 = readl(port_array[port_index]);
+   t2 = xhci_port_state_to_neutral(t1);
+   t2 = ~PORT_WAKE_BITS;
+   t1 = xhci_port_state_to_neutral(t1);
+   if (t1 != t2)
+   writel(t2, port_array[port_index]);

Why not just do:

t1 = readl(port_array[port_index]);
t1 = xhci_port_state_to_neutral(t1);
t2 = t1  ~PORT_WAKE_BITS;
if (t1 != t2) ...
Right, this looks better. I will test and resend the patches with this 
change.




Apart from that minor point,

Acked-by: Alan Stern st...@rowland.harvard.edu

Alan Stern

--
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


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


[PATCH v4 2/3] usb: xhci: This reworks ff8cbf250b448aac35589f6075082c3fcad8a8fe

2014-11-05 Thread Lu Baolu
xhci: clear root port wake on bits if controller isn't allowed to do wakeup

When system is being suspended, if host device is not allowed to do wakeup,
xhci_suspend() needs to clear all root port wake on bits. Otherwise, some
platforms may generate spurious wakeup, even if PCI PME# is disabled.

Signed-off-by: Lu Baolu baolu...@linux.intel.com
Suggested-by: Alan Stern st...@rowland.harvard.edu
Acked-by: Alan Stern st...@rowland.harvard.edu
---
 drivers/usb/host/xhci-pci.c  |  2 +-
 drivers/usb/host/xhci-plat.c | 10 +-
 drivers/usb/host/xhci.c  | 42 +-
 drivers/usb/host/xhci.h  |  2 +-
 4 files changed, 52 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 280dde9..d3fa3c2 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -291,7 +291,7 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool 
do_wakeup)
if (xhci-quirks  XHCI_COMP_MODE_QUIRK)
pdev-no_d3cold = true;
 
-   return xhci_suspend(xhci);
+   return xhci_suspend(xhci, do_wakeup);
 }
 
 static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated)
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 3d78b0c..646300c 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -204,7 +204,15 @@ static int xhci_plat_suspend(struct device *dev)
struct usb_hcd  *hcd = dev_get_drvdata(dev);
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
 
-   return xhci_suspend(xhci);
+   /*
+* xhci_suspend() needs `do_wakeup` to know whether host is allowed
+* to do wakeup during suspend. Since xhci_plat_suspend is currently
+* only designed for system suspend, device_may_wakeup() is enough
+* to dertermine whether host is allowed to do wakeup. Need to
+* reconsider this when xhci_plat_suspend enlarges its scope, e.g.,
+* also applies to runtime suspend.
+*/
+   return xhci_suspend(xhci, device_may_wakeup(dev));
 }
 
 static int xhci_plat_resume(struct device *dev)
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 2a5d45b..b832841 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -35,6 +35,8 @@
 #define DRIVER_AUTHOR Sarah Sharp
 #define DRIVER_DESC 'eXtensible' Host Controller (xHC) Driver
 
+#definePORT_WAKE_BITS  (PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E)
+
 /* Some 0.95 hardware can't handle the chain bit on a Link TRB being cleared */
 static int link_quirk;
 module_param(link_quirk, int, S_IRUGO | S_IWUSR);
@@ -851,13 +853,47 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci)
xhci_set_cmd_ring_deq(xhci);
 }
 
+static void xhci_disable_port_wake_on_bits(struct xhci_hcd *xhci)
+{
+   int port_index;
+   __le32 __iomem **port_array;
+   unsigned long flags;
+   u32 t1, t2;
+
+   spin_lock_irqsave(xhci-lock, flags);
+
+   /* disble usb3 ports Wake bits*/
+   port_index = xhci-num_usb3_ports;
+   port_array = xhci-usb3_ports;
+   while (port_index--) {
+   t1 = readl(port_array[port_index]);
+   t1 = xhci_port_state_to_neutral(t1);
+   t2 = t1  ~PORT_WAKE_BITS;
+   if (t1 != t2)
+   writel(t2, port_array[port_index]);
+   }
+
+   /* disble usb2 ports Wake bits*/
+   port_index = xhci-num_usb2_ports;
+   port_array = xhci-usb2_ports;
+   while (port_index--) {
+   t1 = readl(port_array[port_index]);
+   t1 = xhci_port_state_to_neutral(t1);
+   t2 = t1  ~PORT_WAKE_BITS;
+   if (t1 != t2)
+   writel(t2, port_array[port_index]);
+   }
+
+   spin_unlock_irqrestore(xhci-lock, flags);
+}
+
 /*
  * Stop HC (not bus-specific)
  *
  * This is called when the machine transition into S3/S4 mode.
  *
  */
-int xhci_suspend(struct xhci_hcd *xhci)
+int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
 {
int rc = 0;
unsigned intdelay = XHCI_MAX_HALT_USEC;
@@ -868,6 +904,10 @@ int xhci_suspend(struct xhci_hcd *xhci)
xhci-shared_hcd-state != HC_STATE_SUSPENDED)
return -EINVAL;
 
+   /* Clear root port wake on bits if wakeup not allowed. */
+   if (!do_wakeup)
+   xhci_disable_port_wake_on_bits(xhci);
+
/* Don't poll the roothubs on bus suspend. */
xhci_dbg(xhci, %s: stopping port polling.\n, __func__);
clear_bit(HCD_FLAG_POLL_RH, hcd-flags);
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index df76d64..d745715 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1746,7 +1746,7 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t 
get_quirks);
 void xhci_init_driver(struct hc_driver *drv, int (*setup_fn)(struct usb_hcd 
*));
 
 #ifdef CONFIG_PM
-int

[PATCH v4 3/3] usb: xhci: fix comment for PORT_DEV_REMOVE

2014-11-05 Thread Lu Baolu
According to xHCI specification, PORT_DEV_REMOVE(bit 30) in PORTSC
true means Device is non-removable.

Signed-off-by: Lu Baolu baolu...@linux.intel.com
Reported-by: Juro Bystricky jurobystri...@hotmail.com
---
 drivers/usb/host/xhci.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index d745715..ab36bbb 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -358,7 +358,7 @@ struct xhci_op_regs {
 /* wake on over-current (enable) */
 #define PORT_WKOC_E(1  27)
 /* bits 28:29 reserved */
-/* true: device is removable - for USB 3.0 roothub emulation */
+/* true: device is non-removable - for USB 3.0 roothub emulation */
 #define PORT_DEV_REMOVE(1  30)
 /* Initiate a warm port reset - complete when PORT_WRC is '1' */
 #define PORT_WR(1  31)
-- 
1.9.1

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


[PATCH v4 0/3] Rework xhci: clear root port wake on bits if controller isn't wake-up capable

2014-11-05 Thread Lu Baolu
This serie of patch reworks commit ff8cbf250b448aac35589f6075082c3fcad8a8fe.
This has been discussed at http://www.spinics.net/lists/linux-usb/msg114986.html
It also includes a patch to fix a comment in drivers/usb/host/xhci.h.

Changes in v4:
- Refine xhci_disable_port_wake_on_bits().
- Add Acked-by: Alan Stern

Changes in v3:
- Need to consider run-time suspend as well.
- Change wake-up capable to allowed to do wakeup
in both comments and patch description.
- Add Suggested-by: Alan Stern

Changes in v2:
- Should not be a quirk.
- Should be applied to all xhci controllers.

Lu Baolu (3):
  usb: xhci: Revert xhci: clear root port wake on bits if controller
isn't wake-up capable
  usb: xhci: This reworks ff8cbf250b448aac35589f6075082c3fcad8a8fe
  usb: xhci: fix comment for PORT_DEV_REMOVE

 drivers/usb/host/xhci-hub.c  |  5 +
 drivers/usb/host/xhci-pci.c  |  2 +-
 drivers/usb/host/xhci-plat.c | 10 +-
 drivers/usb/host/xhci.c  | 42 +-
 drivers/usb/host/xhci.h  |  4 ++--
 5 files changed, 54 insertions(+), 9 deletions(-)

-- 
1.9.1

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


[PATCH v4 1/3] usb: xhci: Revert xhci: clear root port wake on bits if controller isn't wake-up capable

2014-11-05 Thread Lu Baolu
This reverts commit ff8cbf250b448aac35589f6075082c3fcad8a8fe.

Commit ff8cbf250b448aac35589f6075082c3fcad8a8fe triggers the bug logged at

https://bugzilla.kernel.org/show_bug.cgi?id=85701

Signed-off-by: Lu Baolu baolu...@linux.intel.com
Reported-by: Dmitry Nezhevenko d...@inhex.net
---
 drivers/usb/host/xhci-hub.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 696160d..388cfd8 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -22,7 +22,6 @@
 
 
 #include linux/slab.h
-#include linux/device.h
 #include asm/unaligned.h
 
 #include xhci.h
@@ -1149,9 +1148,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
 * including the USB 3.0 roothub, but only if CONFIG_PM_RUNTIME
 * is enabled, so also enable remote wake here.
 */
-   if (hcd-self.root_hub-do_remote_wakeup
-device_may_wakeup(hcd-self.controller)) {
-
+   if (hcd-self.root_hub-do_remote_wakeup) {
if (t1  PORT_CONNECT) {
t2 |= PORT_WKOC_E | PORT_WKDISC_E;
t2 = ~PORT_WKCONN_E;
-- 
1.9.1

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


Re: [PATCH 1/1] usb: xhci: apply XHCI_AVOID_BEI quirk to Intel ValleyView and LynxPoint LP

2015-03-12 Thread Lu, Baolu



On 03/12/2015 04:46 PM, Mathias Nyman wrote:

On 12.03.2015 03:39, Lu Baolu wrote:

When a device with an isochronous endpoint is plugged into the Intel
xHCI host controller, and the driver submits multiple frames per URB,
the xHCI driver will set the Block Event Interrupt (BEI) flag on all
but the last TD for the URB. This causes the host controller to place
an event on the event ring, but not send an interrupt. When the last
TD for the URB completes, BEI is cleared, and we get an interrupt for
the whole URB.

However,  under some Intel xHCI host controllers like ValleyView and
Lynx Point LP, if the event ring is full of events from transfers with
BEI set, a Event Ring is Full event will be posted to the last entry
of the event ring, but no interrupt is generated. Host will cease all
transfer and command executions  and  wait until software completes
handling the pending events in event ring. That means xHC stops but
event of event ring is full is not notified. As the result, the xHC
looks like dead to user.

The patch is to apply XHCI_AVOID_BEI to Intel VallyView and Lynx Point
LP devices. And it should be backported to kernels as old as 3.0, that
contains the commit 69e848c2090a (Intel xhci: Support EHCI/xHCI port
switching.)


Maybe we should set the quirk for all Intel xHCI controllers.
So far the list includes Pantherpoint, Lynxpoint and valleyview.

I bet it concerns most Intel platforms.


Yes, I agree with you.

I will send out a new patch for this.



-Mathias



--
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




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


Re: [PATCH 1/1] usb: xhci: apply XHCI_AVOID_BEI quirk to Intel ValleyView and LynxPoint LP

2015-03-12 Thread Lu, Baolu



On 03/12/2015 03:54 PM, Greg Kroah-Hartman wrote:

On Thu, Mar 12, 2015 at 09:39:06AM +0800, Lu Baolu wrote:

When a device with an isochronous endpoint is plugged into the Intel
xHCI host controller, and the driver submits multiple frames per URB,
the xHCI driver will set the Block Event Interrupt (BEI) flag on all
but the last TD for the URB. This causes the host controller to place
an event on the event ring, but not send an interrupt. When the last
TD for the URB completes, BEI is cleared, and we get an interrupt for
the whole URB.

However,  under some Intel xHCI host controllers like ValleyView and
Lynx Point LP, if the event ring is full of events from transfers with
BEI set, a Event Ring is Full event will be posted to the last entry
of the event ring, but no interrupt is generated. Host will cease all
transfer and command executions  and  wait until software completes
handling the pending events in event ring. That means xHC stops but
event of event ring is full is not notified. As the result, the xHC
looks like dead to user.

The patch is to apply XHCI_AVOID_BEI to Intel VallyView and Lynx Point
LP devices. And it should be backported to kernels as old as 3.0, that
contains the commit 69e848c2090a (Intel xhci: Support EHCI/xHCI port
switching.)

Signed-off-by: Lu Baolu baolu...@linux.intel.com
Cc: sta...@vger.kernel.org
---
  drivers/usb/host/xhci-pci.c | 5 +
  1 file changed, 5 insertions(+)

diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index fd53c9e..5aa4893 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -40,6 +40,7 @@
  #define PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI   0x22b5
  #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI   0xa12f
  #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI  0x9d2f
+#definePCI_DEVICE_ID_INTEL_VALLEYVIEW_XHCI 0x0f35

Minor nit, you added a tab where the rest of the file was using a space
:(


Yes, thanks for reminding.


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




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


[PATCH v2 1/1] usb: xhci: apply XHCI_AVOID_BEI quirk to all Intel xHCI controllers

2015-03-12 Thread Lu Baolu
When a device with an isochronous endpoint is plugged into the Intel
xHCI host controller, and the driver submits multiple frames per URB,
the xHCI driver will set the Block Event Interrupt (BEI) flag on all
but the last TD for the URB. This causes the host controller to place
an event on the event ring, but not send an interrupt. When the last
TD for the URB completes, BEI is cleared, and we get an interrupt for
the whole URB.

However, under Intel xHCI host controllers, if the event ring is full
of events from transfers with BEI set,  an Event Ring is Full event
will be posted to the last entry of the event ring,  but no interrupt
is generated. Host will cease all transfer and command executions and
wait until software completes handling the pending events in the event
ring.  That means xHC stops, but event of event ring is full is not
notified. As the result, the xHC looks like dead to user.

This patch is to apply XHCI_AVOID_BEI quirk to Intel xHC devices. And
it should be backported to kernels as old as 3.0, that contains the
commit 69e848c2090a (Intel xhci: Support EHCI/xHCI port switching.).

Signed-off-by: Lu Baolu baolu...@linux.intel.com
Cc: sta...@vger.kernel.org
---
 drivers/usb/host/xhci-pci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index fd53c9e..2af32e2 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -115,6 +115,7 @@ static void xhci_pci_quirks(struct device *dev, struct 
xhci_hcd *xhci)
if (pdev-vendor == PCI_VENDOR_ID_INTEL) {
xhci-quirks |= XHCI_LPM_SUPPORT;
xhci-quirks |= XHCI_INTEL_HOST;
+   xhci-quirks |= XHCI_AVOID_BEI;
}
if (pdev-vendor == PCI_VENDOR_ID_INTEL 
pdev-device == PCI_DEVICE_ID_INTEL_PANTHERPOINT_XHCI) {
@@ -130,7 +131,6 @@ static void xhci_pci_quirks(struct device *dev, struct 
xhci_hcd *xhci)
 * PPT chipsets.
 */
xhci-quirks |= XHCI_SPURIOUS_REBOOT;
-   xhci-quirks |= XHCI_AVOID_BEI;
}
if (pdev-vendor == PCI_VENDOR_ID_INTEL 
pdev-device == PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI) {
-- 
2.1.0

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


Re: [PATCH 1/1] usb: xhci: handle Config Error Change (CEC) in xhci driver

2015-03-08 Thread Lu, Baolu

Hi Alan,

Do you have any comments for this patch?

Thanks,
 Baolu

On 03/06/2015 04:12 PM, Lu Baolu wrote:

Linux xHCI driver doesn't report and handle port cofig error change.
If Port Configure Error for root hub port occurs, CEC bit in PORTSC
would be set by xHC and remains 1. This happends when the root port
fails to configure its link partner, e.g. the port fails to exchange
port capabilities information using Port Capability LMPs.

Then the Port Status Change Events will be blocked until all status
change bits(CEC is one of the change bits) are cleared('0') (refer to
xHCI spec 4.19.2). Otherwise, the port status change event for this
root port will not be generated anymore, then root port would look
like dead for user and can't be recovered until a Host Controller
Reset(HCRST).

This patch is to check CEC bit in PORTSC in xhci_get_port_status()
and set a Config Error in the return status if CEC is set. This will
cause a ClearPortFeature request, where CEC bit is cleared in
xhci_clear_port_change_bit().

[Mathias Nyman contributed the idea. The commit log is based on patch
posted at http://marc.info/?l=linux-kernelm=142323612321434w=2]

Signed-off-by: Lu Baolu baolu...@linux.intel.com
Cc: stable sta...@vger.kernel.org # v3.2+
---
  drivers/usb/host/xhci-hub.c | 9 -
  1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index a7865c4..0827d7c 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -387,6 +387,10 @@ static void xhci_clear_port_change_bit(struct xhci_hcd 
*xhci, u16 wValue,
status = PORT_PLC;
port_change_bit = link state;
break;
+   case USB_PORT_FEAT_C_PORT_CONFIG_ERROR:
+   status = PORT_CEC;
+   port_change_bit = config error;
+   break;
default:
/* Should never happen */
return;
@@ -588,6 +592,8 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
status |= USB_PORT_STAT_C_LINK_STATE  16;
if ((raw_port_status  PORT_WRC))
status |= USB_PORT_STAT_C_BH_RESET  16;
+   if ((raw_port_status  PORT_CEC))
+   status |= USB_PORT_STAT_C_CONFIG_ERROR  16;
}
  
  	if (hcd-speed != HCD_USB3) {

@@ -1005,6 +1011,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, 
u16 wValue,
case USB_PORT_FEAT_C_OVER_CURRENT:
case USB_PORT_FEAT_C_ENABLE:
case USB_PORT_FEAT_C_PORT_LINK_STATE:
+   case USB_PORT_FEAT_C_PORT_CONFIG_ERROR:
xhci_clear_port_change_bit(xhci, wValue, wIndex,
port_array[wIndex], temp);
break;
@@ -1069,7 +1076,7 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
 */
status = bus_state-resuming_ports;
  
-	mask = PORT_CSC | PORT_PEC | PORT_OCC | PORT_PLC | PORT_WRC;

+   mask = PORT_CSC | PORT_PEC | PORT_OCC | PORT_PLC | PORT_WRC | PORT_CEC;
  
  	spin_lock_irqsave(xhci-lock, flags);

/* For each port, did anything change?  If so, set that bit in buf. */


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


Re: [V4.0.0-rc3] Xhci Regression: ERROR Transfer event TRB DMA ptr not part of current TD

2015-03-11 Thread Lu, Baolu



On 03/11/2015 02:49 AM, Alan Stern wrote:

On Tue, 10 Mar 2015, Mathias Nyman wrote:


Mathias:

Your patch description says this:


The endpoint might already processesed some TRBs on the endpiont ring
before we soft reset the endpoint.
Make sure we set the dequeue pointer to where we were befere soft reset

However, if a driver tries to issue an endpoint reset while there are
still some URBs queued, it is a bug.  Host controller drivers shouldn't
have to worry about this -- xhci_endpoint_reset() should simply return
an error if the endpoint ring isn't empty.

I suppose we should check for this in the USB core.  I'll write a patch
and CC: you.

Alan Stern


It's possible that there's something in usb core as well,
but I think the following was what happened:

1. First a normal configure endpoint command is issued, it sets endpoint 
dequeue pointer
to xxx400 = start of ring segment
2. two urbs get queued - two TDs put on endpoint ring.
3. xhci executes those, ring is in running (idle) state. sw dequeue at xxx430, 
No TDs queued.
Endpoint dequeue pointer is not written to the endpoint output context as 
the ring is still
in running state (even if idle, not advancing with no TDs queued) it still 
shows xxx400
4. - something happends, xhci_endpoint_reset() is called, we do a new 
configure endpoint
to 'soft reset' the endpiont, but we copy the dequeue pointer from the old 
endpoint
output context to the configure endpoint input context, which 
re-initializes the old
dequeue xxx400 pointer to xhci hardware, and it starts executing the old 
TDs from the ring.


Is it possible to return an error message up to client driver? The 
client driver then decides
how to handle this kind of error. It, possibly, unlink all ongoing 
transfers and ask host driver
to soft reset this endpoint. When xhci_endpoint_reset is called, there 
should be no ongoing

transfers.

Thanks,
Baolu


Obviously that's bad.

But don't you have to stop the endpoint ring in order to configure it?
When you stop the ring, doesn't the controller store the correct
current value of the dequeue pointer somewhere?


5. xhci driver notices that we get events for old TRBs that do not belong to 
the TD the driver
thinks we should be handling

Alan Stern

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




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


[PATCH v3 1/1] usb: xhci: apply XHCI_AVOID_BEI quirk to all Intel xHCI controllers

2015-03-12 Thread Lu Baolu
When a device with an isochronous endpoint is plugged into the Intel
xHCI host controller, and the driver submits multiple frames per URB,
the xHCI driver will set the Block Event Interrupt (BEI) flag on all
but the last TD for the URB. This causes the host controller to place
an event on the event ring, but not send an interrupt. When the last
TD for the URB completes, BEI is cleared, and we get an interrupt for
the whole URB.

However, under Intel xHCI host controllers, if the event ring is full
of events from transfers with BEI set,  an Event Ring is Full event
will be posted to the last entry of the event ring,  but no interrupt
is generated. Host will cease all transfer and command executions and
wait until software completes handling the pending events in the event
ring.  That means xHC stops, but event of event ring is full is not
notified. As the result, the xHC looks like dead to user.

This patch is to apply XHCI_AVOID_BEI quirk to Intel xHC devices. And
it should be backported to kernels as old as 3.0, that contains the
commit 69e848c2090a (Intel xhci: Support EHCI/xHCI port switching.).

Signed-off-by: Lu Baolu baolu...@linux.intel.com
Tested-by: Alistair Grant akgrant0...@gmail.com
Tested-by: Devin Heitmueller dheitmuel...@kernellabs.com
Cc: sta...@vger.kernel.org
---
 drivers/usb/host/xhci-pci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Change log:
v2: apply to all Intel xHC devices as suggested by Mathias
v3: add two Tested-by's

diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index fd53c9e..2af32e2 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -115,6 +115,7 @@ static void xhci_pci_quirks(struct device *dev, struct 
xhci_hcd *xhci)
if (pdev-vendor == PCI_VENDOR_ID_INTEL) {
xhci-quirks |= XHCI_LPM_SUPPORT;
xhci-quirks |= XHCI_INTEL_HOST;
+   xhci-quirks |= XHCI_AVOID_BEI;
}
if (pdev-vendor == PCI_VENDOR_ID_INTEL 
pdev-device == PCI_DEVICE_ID_INTEL_PANTHERPOINT_XHCI) {
@@ -130,7 +131,6 @@ static void xhci_pci_quirks(struct device *dev, struct 
xhci_hcd *xhci)
 * PPT chipsets.
 */
xhci-quirks |= XHCI_SPURIOUS_REBOOT;
-   xhci-quirks |= XHCI_AVOID_BEI;
}
if (pdev-vendor == PCI_VENDOR_ID_INTEL 
pdev-device == PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI) {
-- 
2.1.0

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


[PATCH 1/1] usb: xhci: apply XHCI_AVOID_BEI quirk to Intel ValleyView and LynxPoint LP

2015-03-11 Thread Lu Baolu
When a device with an isochronous endpoint is plugged into the Intel
xHCI host controller, and the driver submits multiple frames per URB,
the xHCI driver will set the Block Event Interrupt (BEI) flag on all
but the last TD for the URB. This causes the host controller to place
an event on the event ring, but not send an interrupt. When the last
TD for the URB completes, BEI is cleared, and we get an interrupt for
the whole URB.

However,  under some Intel xHCI host controllers like ValleyView and
Lynx Point LP, if the event ring is full of events from transfers with
BEI set, a Event Ring is Full event will be posted to the last entry
of the event ring, but no interrupt is generated. Host will cease all
transfer and command executions  and  wait until software completes
handling the pending events in event ring. That means xHC stops but
event of event ring is full is not notified. As the result, the xHC
looks like dead to user.

The patch is to apply XHCI_AVOID_BEI to Intel VallyView and Lynx Point
LP devices. And it should be backported to kernels as old as 3.0, that
contains the commit 69e848c2090a (Intel xhci: Support EHCI/xHCI port
switching.)

Signed-off-by: Lu Baolu baolu...@linux.intel.com
Cc: sta...@vger.kernel.org
---
 drivers/usb/host/xhci-pci.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index fd53c9e..5aa4893 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -40,6 +40,7 @@
 #define PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI0x22b5
 #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI0xa12f
 #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI   0x9d2f
+#definePCI_DEVICE_ID_INTEL_VALLEYVIEW_XHCI 0x0f35
 
 static const char hcd_name[] = xhci_hcd;
 
@@ -135,6 +136,7 @@ static void xhci_pci_quirks(struct device *dev, struct 
xhci_hcd *xhci)
if (pdev-vendor == PCI_VENDOR_ID_INTEL 
pdev-device == PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI) {
xhci-quirks |= XHCI_SPURIOUS_REBOOT;
+   xhci-quirks |= XHCI_AVOID_BEI;
}
if (pdev-vendor == PCI_VENDOR_ID_INTEL 
(pdev-device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI ||
@@ -142,6 +144,9 @@ static void xhci_pci_quirks(struct device *dev, struct 
xhci_hcd *xhci)
 pdev-device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI)) {
xhci-quirks |= XHCI_PME_STUCK_QUIRK;
}
+   if (pdev-vendor == PCI_VENDOR_ID_INTEL 
+   pdev-device == PCI_DEVICE_ID_INTEL_VALLEYVIEW_XHCI)
+   xhci-quirks |= XHCI_AVOID_BEI;
if (pdev-vendor == PCI_VENDOR_ID_ETRON 
pdev-device == PCI_DEVICE_ID_EJ168) {
xhci-quirks |= XHCI_RESET_ON_RESUME;
-- 
2.1.0

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


Re: [PATCHv2 01/12] usb: add bus type for USB ULPI

2015-03-23 Thread Lu, Baolu



On 03/18/2015 08:40 PM, Heikki Krogerus wrote:

+
+/**
+ * ulpi_register_driver - unregister a driver with the ULPI bus

Hi Heikki,

ulpi_register_driver should be changed to ulpi_unregister_driver.

Thanks,
Baolu

+ * @drv: driver to unregister
+ *
+ * Unregisters a driver with the ULPI bus.
+ */
+void ulpi_unregister_driver(struct ulpi_driver *drv)
+{
+   driver_unregister(drv-driver);
+}
+EXPORT_SYMBOL_GPL(ulpi_unregister_driver);
+




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


[PATCH 1/1] usb: xhci: handle Config Error Change (CEC) in xhci driver

2015-03-06 Thread Lu Baolu
Linux xHCI driver doesn't report and handle port cofig error change.
If Port Configure Error for root hub port occurs, CEC bit in PORTSC
would be set by xHC and remains 1. This happends when the root port
fails to configure its link partner, e.g. the port fails to exchange
port capabilities information using Port Capability LMPs.

Then the Port Status Change Events will be blocked until all status
change bits(CEC is one of the change bits) are cleared('0') (refer to
xHCI spec 4.19.2). Otherwise, the port status change event for this
root port will not be generated anymore, then root port would look
like dead for user and can't be recovered until a Host Controller
Reset(HCRST).

This patch is to check CEC bit in PORTSC in xhci_get_port_status()
and set a Config Error in the return status if CEC is set. This will
cause a ClearPortFeature request, where CEC bit is cleared in
xhci_clear_port_change_bit().

[Mathias Nyman contributed the idea. The commit log is based on patch
posted at http://marc.info/?l=linux-kernelm=142323612321434w=2]

Signed-off-by: Lu Baolu baolu...@linux.intel.com
Cc: stable sta...@vger.kernel.org # v3.2+
---
 drivers/usb/host/xhci-hub.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index a7865c4..0827d7c 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -387,6 +387,10 @@ static void xhci_clear_port_change_bit(struct xhci_hcd 
*xhci, u16 wValue,
status = PORT_PLC;
port_change_bit = link state;
break;
+   case USB_PORT_FEAT_C_PORT_CONFIG_ERROR:
+   status = PORT_CEC;
+   port_change_bit = config error;
+   break;
default:
/* Should never happen */
return;
@@ -588,6 +592,8 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
status |= USB_PORT_STAT_C_LINK_STATE  16;
if ((raw_port_status  PORT_WRC))
status |= USB_PORT_STAT_C_BH_RESET  16;
+   if ((raw_port_status  PORT_CEC))
+   status |= USB_PORT_STAT_C_CONFIG_ERROR  16;
}
 
if (hcd-speed != HCD_USB3) {
@@ -1005,6 +1011,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, 
u16 wValue,
case USB_PORT_FEAT_C_OVER_CURRENT:
case USB_PORT_FEAT_C_ENABLE:
case USB_PORT_FEAT_C_PORT_LINK_STATE:
+   case USB_PORT_FEAT_C_PORT_CONFIG_ERROR:
xhci_clear_port_change_bit(xhci, wValue, wIndex,
port_array[wIndex], temp);
break;
@@ -1069,7 +1076,7 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
 */
status = bus_state-resuming_ports;
 
-   mask = PORT_CSC | PORT_PEC | PORT_OCC | PORT_PLC | PORT_WRC;
+   mask = PORT_CSC | PORT_PEC | PORT_OCC | PORT_PLC | PORT_WRC | PORT_CEC;
 
spin_lock_irqsave(xhci-lock, flags);
/* For each port, did anything change?  If so, set that bit in buf. */
-- 
2.1.0

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


[RFC][PATCH 0/3] usb: add a hcd notify entry in hc_driver

2015-05-03 Thread Lu Baolu
This patch adds a new entry pointer in hc_driver. With this new entry,
USB core can notify host driver when something happens and host driver
is willing to be notified. One use case of this interface comes from
xHCI compatible host controller driver.

The xHCI spec is designed to allow an xHC implementation to cache the
endpoint state. Caching endpoint state allows an xHC to reduce latency
when handling ERDYs and other USB asynchronous events. However holding
this state in xHC consumes resources and power. The xHCI spec designs
some methods through which host controller driver can hint xHC about
how to optimize its operation, e.g. to determine when it holds state
internally or pushes it out to memory, when to power down logic, etc.

When a USB device is going to suspend, states of all endpoints cached
in the xHC should be pushed out to memory to save power and resources.
Vice versa, when a USB device resumes, those states should be brought
back to the cache. USB core suspends or resumes a USB device by sending
set/clear port feature requests to the parent hub where the USB device
is connected. Unfortunately, these operations are transparent to xHCI
driver unless the USB device is plugged in a root port. This patch
utilizes the notify interface to notify xHCI driver whenever a USB
device's power state is changed.

It is harmless if a USB devices under USB 3.0 host controller suspends
or resumes without a notification to hcd driver. However there may be
less opportunities for power savings and there may be increased latency
for restarting an endpoint. The precise impact will be different for
each xHC implementation. It all depends on what an implementation does
with the hints.


Lu Baolu (3):
  usb: add a hcd notify entry in hc_driver
  usb: xhci: implement hc_driver notify entry
  usb: xhci: cleanup unnecessary stop device and ring doorbell
operations

 drivers/usb/core/generic.c  | 10 +++--
 drivers/usb/core/hcd.c  | 23 +
 drivers/usb/host/xhci-hub.c | 49 +
 drivers/usb/host/xhci.c | 28 ++
 drivers/usb/host/xhci.h |  3 +++
 include/linux/usb/hcd.h | 11 +-
 6 files changed, 73 insertions(+), 51 deletions(-)

-- 
2.1.0

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


[RFC][PATCH 2/3] usb: xhci: implement hc_driver notify entry

2015-05-03 Thread Lu Baolu
This patch implements the notify entry defined in hc_driver for xHC
driver. For HCD_MSG_DEV_SUSPEND message, it will issue stop endpoint
command for each endpoint in the device. The Suspend(SP) bit in the
command TRB will be set, which gives xHC a hint about the suspend.
For HCD_MSG_DEV_RESUME, it will ring doorbells for all endpoints
unconditionally. XHC may use these hints to optimize its operation
on endpoint state cashes.

Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
 drivers/usb/host/xhci-hub.c |  2 +-
 drivers/usb/host/xhci.c | 28 
 drivers/usb/host/xhci.h |  3 +++
 3 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 0827d7c..a83e82e 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -266,7 +266,7 @@ int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct 
xhci_hcd *xhci,
  * to complete.
  * suspend will set to 1, if suspend bit need to set in command.
  */
-static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)
+int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)
 {
struct xhci_virt_device *virt_dev;
struct xhci_command *cmd;
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index ec8ac16..1e4aa78 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -4917,6 +4917,29 @@ error:
 }
 EXPORT_SYMBOL_GPL(xhci_gen_setup);
 
+void xhci_notify(struct usb_hcd *hcd, struct usb_device *udev,
+   enum hcd_notification_type type, void *data)
+{
+   struct xhci_hcd *xhci;
+
+   xhci = hcd_to_xhci(hcd);
+   if (!xhci || !xhci-devs[udev-slot_id])
+   return;
+
+   switch (type) {
+   case HCD_MSG_DEV_SUSPEND:
+   xhci_stop_device(xhci, udev-slot_id, 1);
+   break;
+   case HCD_MSG_DEV_RESUME:
+   xhci_ring_device(xhci, udev-slot_id);
+   break;
+   default:
+   xhci_dbg(xhci, unknown notification message %d.\n, type);
+   break;
+   }
+
+}
+
 static const struct hc_driver xhci_hc_driver = {
.description =  xhci-hcd,
.product_desc = xHCI Host Controller,
@@ -4976,6 +4999,11 @@ static const struct hc_driver xhci_hc_driver = {
.enable_usb3_lpm_timeout =  xhci_enable_usb3_lpm_timeout,
.disable_usb3_lpm_timeout = xhci_disable_usb3_lpm_timeout,
.find_raw_port_number = xhci_find_raw_port_number,
+
+   /*
+* notification call back
+*/
+   .notify =   xhci_notify,
 };
 
 void xhci_init_driver(struct hc_driver *drv, int (*setup_fn)(struct usb_hcd *))
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 8e421b8..f71c643 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1867,10 +1867,13 @@ u32 xhci_port_state_to_neutral(u32 state);
 int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci,
u16 port);
 void xhci_ring_device(struct xhci_hcd *xhci, int slot_id);
+int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend);
 
 /* xHCI contexts */
 struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct 
xhci_container_ctx *ctx);
 struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct 
xhci_container_ctx *ctx);
 struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, struct 
xhci_container_ctx *ctx, unsigned int ep_index);
 
+void xhci_notify(struct usb_hcd *hcd, struct usb_device *udev,
+   enum hcd_notification_type type, void *data);
 #endif /* __LINUX_XHCI_HCD_H */
-- 
2.1.0

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


[RFC][PATCH 3/3] usb: xhci: cleanup unnecessary stop device and ring doorbell operations

2015-05-03 Thread Lu Baolu
There is no need to call xhci_stop_device() and xhci_ring_device() in
hub control and bus suspend functions since all device suspend and
resume have been notified through the new notify entry in hc_driver.

Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
 drivers/usb/host/xhci-hub.c | 47 -
 1 file changed, 47 deletions(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index a83e82e..f12e1b7 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -704,7 +704,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 
wValue,
u32 temp, status;
int retval = 0;
__le32 __iomem **port_array;
-   int slot_id;
struct xhci_bus_state *bus_state;
u16 link_state = 0;
u16 wake_mask = 0;
@@ -818,17 +817,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 
wValue,
goto error;
}
 
-   slot_id = xhci_find_slot_id_by_port(hcd, xhci,
-   wIndex + 1);
-   if (!slot_id) {
-   xhci_warn(xhci, slot_id is zero\n);
-   goto error;
-   }
-   /* unlock to execute stop endpoint commands */
-   spin_unlock_irqrestore(xhci-lock, flags);
-   xhci_stop_device(xhci, slot_id, 1);
-   spin_lock_irqsave(xhci-lock, flags);
-
xhci_set_link_state(xhci, port_array, wIndex, XDEV_U3);
 
spin_unlock_irqrestore(xhci-lock, flags);
@@ -876,19 +864,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 
wValue,
goto error;
}
 
-   if (link_state == USB_SS_PORT_LS_U3) {
-   slot_id = xhci_find_slot_id_by_port(hcd, xhci,
-   wIndex + 1);
-   if (slot_id) {
-   /* unlock to execute stop endpoint
-* commands */
-   spin_unlock_irqrestore(xhci-lock,
-   flags);
-   xhci_stop_device(xhci, slot_id, 1);
-   spin_lock_irqsave(xhci-lock, flags);
-   }
-   }
-
xhci_set_link_state(xhci, port_array, wIndex,
link_state);
 
@@ -994,14 +969,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 
wValue,
XDEV_U0);
}
bus_state-port_c_suspend |= 1  wIndex;
-
-   slot_id = xhci_find_slot_id_by_port(hcd, xhci,
-   wIndex + 1);
-   if (!slot_id) {
-   xhci_dbg(xhci, slot_id is zero\n);
-   goto error;
-   }
-   xhci_ring_device(xhci, slot_id);
break;
case USB_PORT_FEAT_C_SUSPEND:
bus_state-port_c_suspend = ~(1  wIndex);
@@ -1133,20 +1100,12 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
while (port_index--) {
/* suspend the port if the port is not suspended */
u32 t1, t2;
-   int slot_id;
 
t1 = readl(port_array[port_index]);
t2 = xhci_port_state_to_neutral(t1);
 
if ((t1  PORT_PE)  !(t1  PORT_PLS_MASK)) {
xhci_dbg(xhci, port %d not suspended\n, port_index);
-   slot_id = xhci_find_slot_id_by_port(hcd, xhci,
-   port_index + 1);
-   if (slot_id) {
-   spin_unlock_irqrestore(xhci-lock, flags);
-   xhci_stop_device(xhci, slot_id, 1);
-   spin_lock_irqsave(xhci-lock, flags);
-   }
t2 = ~PORT_PLS_MASK;
t2 |= PORT_LINK_STROBE | XDEV_U3;
set_bit(port_index, bus_state-bus_suspended);
@@ -1207,7 +1166,6 @@ int xhci_bus_resume(struct usb_hcd *hcd)
/* Check whether need resume ports. If needed
   resume port and disable remote wakeup */
u32 temp;
-   int slot_id;
 
temp = readl(port_array[port_index]);
if (DEV_SUPERSPEED(temp))
@@ -1240,11 +1198,6 @@ int xhci_bus_resume(struct usb_hcd *hcd)
/* Clear PLC

[RFC][PATCH 1/3] usb: add a hcd notify entry in hc_driver

2015-05-03 Thread Lu Baolu
This patch adds a new entry pointer in hc_driver. With this new entry,
USB core can notify host driver when something happens and host driver
is willing to be notified. One use case of this interface comes from
xHCI compatible host controller driver.

The xHCI spec is designed to allow an xHC implementation to cache the
endpoint state. Caching endpoint state allows an xHC to reduce latency
when handling ERDYs and other USB asynchronous events. However holding
this state in xHC consumes resources and power. The xHCI spec designs
some methods through which host controller driver can hint xHC about
how to optimize its operation, e.g. to determine when it holds state
internally or pushes it out to memory, when to power down logic, etc.

When a USB device is going to suspend, states of all endpoints cached
in the xHC should be pushed out to memory to save power and resources.
Vice versa, when a USB device resumes, those states should be brought
back to the cache. USB core suspends or resumes a USB device by sending
set/clear port feature requests to the parent hub where the USB device
is connected. Unfortunately, these operations are transparent to xHCI
driver unless the USB device is plugged in a root port. This patch
utilizes the notify interface to notify xHCI driver whenever a USB
device's power state is changed.

It is harmless if a USB devices under USB 3.0 host controller suspends
or resumes without a notification to hcd driver. However there may be
less opportunities for power savings and there may be increased latency
for restarting an endpoint. The precise impact will be different for
each xHC implementation. It all depends on what an implementation does
with the hints.

Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
 drivers/usb/core/generic.c | 10 --
 drivers/usb/core/hcd.c | 23 +++
 include/linux/usb/hcd.h| 11 ++-
 3 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c
index 358ca8d..92bee33 100644
--- a/drivers/usb/core/generic.c
+++ b/drivers/usb/core/generic.c
@@ -211,8 +211,12 @@ static int generic_suspend(struct usb_device *udev, 
pm_message_t msg)
/* Non-root devices don't need to do anything for FREEZE or PRETHAW */
else if (msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_PRETHAW)
rc = 0;
-   else
+   else {
+   hcd_notify(udev, HCD_MSG_DEV_SUSPEND, msg);
rc = usb_port_suspend(udev, msg);
+   if (rc)
+   hcd_notify(udev, HCD_MSG_DEV_RESUME, msg);
+   }
 
return rc;
 }
@@ -228,8 +232,10 @@ static int generic_resume(struct usb_device *udev, 
pm_message_t msg)
 */
if (!udev-parent)
rc = hcd_bus_resume(udev, msg);
-   else
+   else {
rc = usb_port_resume(udev, msg);
+   hcd_notify(udev, HCD_MSG_DEV_RESUME, msg);
+   }
return rc;
 }
 
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 45a915c..725d611 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2289,6 +2289,29 @@ void usb_hcd_resume_root_hub (struct usb_hcd *hcd)
 }
 EXPORT_SYMBOL_GPL(usb_hcd_resume_root_hub);
 
+/**
+ * hcd_notify - notify hcd driver with a message
+ * @udev: USB device
+ * @type: message type of this notification
+ * @data: message type specific data
+ *
+ * Call back to hcd driver to notify an event.
+ */
+void hcd_notify(struct usb_device *udev,
+   enum hcd_notification_type type, void *data)
+{
+   struct usb_hcd *hcd;
+
+   if (!udev)
+   return;
+
+   hcd = bus_to_hcd(udev-bus);
+
+   if (hcd-driver-notify)
+   hcd-driver-notify(hcd, udev, type, data);
+}
+EXPORT_SYMBOL_GPL(hcd_notify);
+
 #endif /* CONFIG_PM */
 
 /*-*/
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index 68b1e83..bdb422c 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -76,6 +76,11 @@ struct giveback_urb_bh {
struct usb_host_endpoint *completing_ep;
 };
 
+enum hcd_notification_type {
+   HCD_MSG_DEV_SUSPEND = 0,/* USB device suspend */
+   HCD_MSG_DEV_RESUME, /* USB device resume */
+};
+
 struct usb_hcd {
 
/*
@@ -383,7 +388,9 @@ struct hc_driver {
int (*find_raw_port_number)(struct usb_hcd *, int);
/* Call for power on/off the port if necessary */
int (*port_power)(struct usb_hcd *hcd, int portnum, bool enable);
-
+   /* Call to notify hcd when it is necessary. */
+   void(*notify)(struct usb_hcd *, struct usb_device *,
+   enum hcd_notification_type, void *);
 };
 
 static inline int hcd_giveback_urb_in_bh(struct usb_hcd *hcd)
@@ -632,6 +639,8 @@ extern void usb_root_hub_lost_power(struct usb_device 
*rhdev);
 extern int

Re: [RFC][PATCH 1/3] usb: add a hcd notify entry in hc_driver

2015-05-04 Thread Lu, Baolu

Hi Alan,

Thanks for your review comments. Below has my response inline.

On 05/04/2015 10:28 PM, Alan Stern wrote:

On Mon, 4 May 2015, Lu Baolu wrote:


This patch adds a new entry pointer in hc_driver. With this new entry,
USB core can notify host driver when something happens and host driver
is willing to be notified. One use case of this interface comes from
xHCI compatible host controller driver.

Notify is too generic.  It's better to make the callback routine
specific to the activity in question.  So this patch series should add
device_suspend and device_resume callbacks, not a general notify
callback.

Fair enough. I will make this change in v2 if there is no objection.




The xHCI spec is designed to allow an xHC implementation to cache the
endpoint state. Caching endpoint state allows an xHC to reduce latency
when handling ERDYs and other USB asynchronous events. However holding
this state in xHC consumes resources and power. The xHCI spec designs
some methods through which host controller driver can hint xHC about
how to optimize its operation, e.g. to determine when it holds state
internally or pushes it out to memory, when to power down logic, etc.

When a USB device is going to suspend, states of all endpoints cached
in the xHC should be pushed out to memory to save power and resources.
Vice versa, when a USB device resumes, those states should be brought
back to the cache. USB core suspends or resumes a USB device by sending
set/clear port feature requests to the parent hub where the USB device
is connected. Unfortunately, these operations are transparent to xHCI
driver unless the USB device is plugged in a root port. This patch
utilizes the notify interface to notify xHCI driver whenever a USB
device's power state is changed.

It is harmless if a USB devices under USB 3.0 host controller suspends
or resumes without a notification to hcd driver. However there may be
less opportunities for power savings and there may be increased latency
for restarting an endpoint. The precise impact will be different for
each xHC implementation. It all depends on what an implementation does
with the hints.

Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
  drivers/usb/core/generic.c | 10 --
  drivers/usb/core/hcd.c | 23 +++
  include/linux/usb/hcd.h| 11 ++-
  3 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c
index 358ca8d..92bee33 100644
--- a/drivers/usb/core/generic.c
+++ b/drivers/usb/core/generic.c
@@ -211,8 +211,12 @@ static int generic_suspend(struct usb_device *udev, 
pm_message_t msg)
/* Non-root devices don't need to do anything for FREEZE or PRETHAW */
else if (msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_PRETHAW)
rc = 0;
-   else
+   else {
+   hcd_notify(udev, HCD_MSG_DEV_SUSPEND, msg);
rc = usb_port_suspend(udev, msg);
+   if (rc)
+   hcd_notify(udev, HCD_MSG_DEV_RESUME, msg);
+   }
  
  	return rc;

  }
@@ -228,8 +232,10 @@ static int generic_resume(struct usb_device *udev, 
pm_message_t msg)
 */
if (!udev-parent)
rc = hcd_bus_resume(udev, msg);
-   else
+   else {
rc = usb_port_resume(udev, msg);
+   hcd_notify(udev, HCD_MSG_DEV_RESUME, msg);
+   }

Don't you want to tell the HCD about the resume _before_ it happens?
After all, the devices endpoint will be used as soon as the resume
takes place.
The order that software should do during device suspend/resume is 
defined in 4.15.1.1 of xHCI spec 1.1.


Spec 4.15.1.1:

Software shall stop all endpoints of a device using the Stop Endpoint 
Command and setting the Suspend
(SP) flag to ‘1’ prior to selectively suspending a device. After the 
device is resumed software shall ring an

endpoint’s doorbell to restart it.

--end--

So the order looks like:

tell hcd device suspend
usb_port_suspend()

usb_port_resume()
tell hcd device resume



And besides, this should be symmetrical with the code above, where you
tell the HCD about a suspend _after_ it happens.

This was done in above change in generic_suspend():

@@ -211,8 +211,12 @@ static int generic_suspend(struct usb_device *udev, 
pm_message_t msg)
/* Non-root devices don't need to do anything for FREEZE or PRETHAW */
else if (msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_PRETHAW)
rc = 0;
-   else
+   else {
+   hcd_notify(udev, HCD_MSG_DEV_SUSPEND, msg);
rc = usb_port_suspend(udev, msg);
+   if (rc)
+   hcd_notify(udev, HCD_MSG_DEV_RESUME, msg);
+   }
 
 	return rc;

 }

If usb_port_suspend() returns error, we should roll back HCD to the previous 
state.





Alan Stern


Thanks again,
Baolu

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body

Re: [RFC][PATCH 1/3] usb: add a hcd notify entry in hc_driver

2015-05-05 Thread Lu, Baolu



On 05/05/2015 10:50 PM, Alan Stern wrote:

On Tue, 5 May 2015, Lu, Baolu wrote:


The order that software should do during device suspend/resume is
defined in 4.15.1.1 of xHCI spec 1.1.

Spec 4.15.1.1:

Software shall stop all endpoints of a device using the Stop Endpoint
Command and setting the Suspend
(SP) flag to 1 prior to selectively suspending a device.

But _after_ all the URBs sent to the device have completed, right?

Yes, that's right.




  After the
device is resumed software shall ring an
endpoint's doorbell to restart it.

The driver would ring the endpoint's doorbell anyway when a new URB is
submitted, wouldn't it?  Which means the resume callback doesn't
actually have to do anything.

The value of ringing door bell after resume is that hcd can fetch
endpoint state from memory to cache and get ready for transfer
as early as possible.




--end--

So the order looks like:

tell hcd device suspend
usb_port_suspend()

You have forgotten that usb_port_suspend() can send URBs to the device
(to enable remote wakeup, for example).  Therefore you shouldn't notify
the HCD until usb_port_suspend() is partly or totally finished.

Yes, I agree with you. I will move the notification into usb_port_suspend(),
just before sending suspend request to parent hub.




usb_port_resume()
tell hcd device resume

You have also forgotten that usb_port_resume() calls various functions
that send URBs to ep0 on the device.  Therefore if the HCD's
device_resume callback needs to do something (like ringing ep0's
doorbell), you had better invoke the callback _before_ calling
usb_port_resume().  Or maybe you had better do this _within_
usb_port_resume().

Agree. I will do this within usb_port_resume() just after completing
sending clear port feature.



Alan Stern

Thank you for the comments. I will send the v2 patch series with all
your comments addressed.

Thanks,
Baolu



--
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



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


[PATCH v2 2/3] usb: xhci: implement device_suspend/device_resume entries

2015-05-06 Thread Lu Baolu
This patch implements device_suspend/device_resume entries for xHC driver.
device_suspend will be called when a USB device is about to suspend. It
will issue a stop endpoint command for each endpoint in this device. The
Suspend(SP) bit in the command TRB will set which will give xHC a hint
about the suspend. device_resume will be called when a USB device is just
resumed. It will ring doorbells of all endpoint unconditionally. XHC may
use these suspend/resume hints to optimize its operation.

Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
 drivers/usb/host/xhci-hub.c |  2 +-
 drivers/usb/host/xhci.c | 40 
 drivers/usb/host/xhci.h |  5 +
 3 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 0827d7c..a83e82e 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -266,7 +266,7 @@ int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct 
xhci_hcd *xhci,
  * to complete.
  * suspend will set to 1, if suspend bit need to set in command.
  */
-static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)
+int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)
 {
struct xhci_virt_device *virt_dev;
struct xhci_command *cmd;
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index ec8ac16..b639627 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -4680,6 +4680,30 @@ int xhci_disable_usb3_lpm_timeout(struct usb_hcd *hcd,
return ret;
return 0;
 }
+
+void xhci_device_suspend(struct usb_hcd *hcd,
+   struct usb_device *udev, pm_message_t msg)
+{
+   struct xhci_hcd *xhci;
+
+   xhci = hcd_to_xhci(hcd);
+   if (!xhci || !xhci-devs[udev-slot_id])
+   return;
+
+   xhci_stop_device(xhci, udev-slot_id, 1);
+}
+
+void xhci_device_resume(struct usb_hcd *hcd,
+   struct usb_device *udev, pm_message_t msg)
+{
+   struct xhci_hcd *xhci;
+
+   xhci = hcd_to_xhci(hcd);
+   if (!xhci || !xhci-devs[udev-slot_id])
+   return;
+
+   xhci_ring_device(xhci, udev-slot_id);
+}
 #else /* CONFIG_PM */
 
 int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
@@ -4704,6 +4728,16 @@ int xhci_disable_usb3_lpm_timeout(struct usb_hcd *hcd,
 {
return 0;
 }
+
+void xhci_device_suspend(struct usb_hcd *hcd,
+   struct usb_device *udev, pm_message_t msg)
+{
+}
+
+void xhci_device_resume(struct usb_hcd *hcd,
+   struct usb_device *udev, pm_message_t msg)
+{
+}
 #endif /* CONFIG_PM */
 
 /*-*/
@@ -4976,6 +5010,12 @@ static const struct hc_driver xhci_hc_driver = {
.enable_usb3_lpm_timeout =  xhci_enable_usb3_lpm_timeout,
.disable_usb3_lpm_timeout = xhci_disable_usb3_lpm_timeout,
.find_raw_port_number = xhci_find_raw_port_number,
+
+   /*
+* call back when devices suspend or resume
+*/
+   .device_suspend =   xhci_device_suspend,
+   .device_resume =xhci_device_resume,
 };
 
 void xhci_init_driver(struct hc_driver *drv, int (*setup_fn)(struct usb_hcd *))
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 8e421b8..3d1f73b 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1867,10 +1867,15 @@ u32 xhci_port_state_to_neutral(u32 state);
 int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci,
u16 port);
 void xhci_ring_device(struct xhci_hcd *xhci, int slot_id);
+int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend);
 
 /* xHCI contexts */
 struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct 
xhci_container_ctx *ctx);
 struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct 
xhci_container_ctx *ctx);
 struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, struct 
xhci_container_ctx *ctx, unsigned int ep_index);
 
+void xhci_device_suspend(struct usb_hcd *hcd,
+   struct usb_device *udev, pm_message_t msg);
+void xhci_device_resume(struct usb_hcd *hcd,
+   struct usb_device *udev, pm_message_t msg);
 #endif /* __LINUX_XHCI_HCD_H */
-- 
2.1.0

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


[PATCH v2 0/3] usb: notify hcd when USB device suspend or resume

2015-05-06 Thread Lu Baolu
This patch series try to meet a design requirement in xHCI spec.

The xHCI spec is designed to allow an xHC implementation to cache the
endpoint state. Caching endpoint state allows an xHC to reduce latency
when handling ERDYs and other USB asynchronous events. However holding
this state in xHC consumes resources and power. The xHCI spec designs
some methods through which host controller driver can hint xHC about
how to optimize its operation, e.g. to determine when it holds state
internally or pushes it out to memory, when to power down logic, etc.

When a USB device is going to suspend, states of all endpoints cached
in the xHC should be pushed out to memory to save power and resources.
Vice versa, when a USB device resumes, those states should be brought
back to the cache.

It is harmless if a USB devices under USB 3.0 host controller suspends
or resumes without a notification to hcd driver. However there may be
less opportunities for power savings and there may be increased latency
for restarting an endpoint. The precise impact will be different for
each xHC implementation. It all depends on what an implementation does
with the hints.

Change log:
v1-v2:
- make the callback name specific to the activity in question
- no need to export hcd_notify
- put the callback in the right place

Lu Baolu (3):
  usb: notify hcd when USB device suspend or resume
  usb: xhci: implement device_suspend/device_resume entries
  usb: xhci: remove stop device and ring doorbell in hub control and bus
suspend

 drivers/usb/core/hcd.c  | 29 +++
 drivers/usb/core/hub.c  | 16 +++
 drivers/usb/host/xhci-hub.c | 49 +
 drivers/usb/host/xhci.c | 40 
 drivers/usb/host/xhci.h |  5 +
 include/linux/usb/hcd.h | 10 -
 6 files changed, 100 insertions(+), 49 deletions(-)

-- 
2.1.0

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


[PATCH v2 3/3] usb: xhci: remove stop device and ring doorbell in hub control and bus suspend

2015-05-06 Thread Lu Baolu
There is no need to call xhci_stop_device() and xhci_ring_device() in
hub control and bus suspend functions since all device suspend and
resume have been notified through device_suspend/device_resume interfaces.

Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
 drivers/usb/host/xhci-hub.c | 47 -
 1 file changed, 47 deletions(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index a83e82e..f12e1b7 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -704,7 +704,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 
wValue,
u32 temp, status;
int retval = 0;
__le32 __iomem **port_array;
-   int slot_id;
struct xhci_bus_state *bus_state;
u16 link_state = 0;
u16 wake_mask = 0;
@@ -818,17 +817,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 
wValue,
goto error;
}
 
-   slot_id = xhci_find_slot_id_by_port(hcd, xhci,
-   wIndex + 1);
-   if (!slot_id) {
-   xhci_warn(xhci, slot_id is zero\n);
-   goto error;
-   }
-   /* unlock to execute stop endpoint commands */
-   spin_unlock_irqrestore(xhci-lock, flags);
-   xhci_stop_device(xhci, slot_id, 1);
-   spin_lock_irqsave(xhci-lock, flags);
-
xhci_set_link_state(xhci, port_array, wIndex, XDEV_U3);
 
spin_unlock_irqrestore(xhci-lock, flags);
@@ -876,19 +864,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 
wValue,
goto error;
}
 
-   if (link_state == USB_SS_PORT_LS_U3) {
-   slot_id = xhci_find_slot_id_by_port(hcd, xhci,
-   wIndex + 1);
-   if (slot_id) {
-   /* unlock to execute stop endpoint
-* commands */
-   spin_unlock_irqrestore(xhci-lock,
-   flags);
-   xhci_stop_device(xhci, slot_id, 1);
-   spin_lock_irqsave(xhci-lock, flags);
-   }
-   }
-
xhci_set_link_state(xhci, port_array, wIndex,
link_state);
 
@@ -994,14 +969,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 
wValue,
XDEV_U0);
}
bus_state-port_c_suspend |= 1  wIndex;
-
-   slot_id = xhci_find_slot_id_by_port(hcd, xhci,
-   wIndex + 1);
-   if (!slot_id) {
-   xhci_dbg(xhci, slot_id is zero\n);
-   goto error;
-   }
-   xhci_ring_device(xhci, slot_id);
break;
case USB_PORT_FEAT_C_SUSPEND:
bus_state-port_c_suspend = ~(1  wIndex);
@@ -1133,20 +1100,12 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
while (port_index--) {
/* suspend the port if the port is not suspended */
u32 t1, t2;
-   int slot_id;
 
t1 = readl(port_array[port_index]);
t2 = xhci_port_state_to_neutral(t1);
 
if ((t1  PORT_PE)  !(t1  PORT_PLS_MASK)) {
xhci_dbg(xhci, port %d not suspended\n, port_index);
-   slot_id = xhci_find_slot_id_by_port(hcd, xhci,
-   port_index + 1);
-   if (slot_id) {
-   spin_unlock_irqrestore(xhci-lock, flags);
-   xhci_stop_device(xhci, slot_id, 1);
-   spin_lock_irqsave(xhci-lock, flags);
-   }
t2 = ~PORT_PLS_MASK;
t2 |= PORT_LINK_STROBE | XDEV_U3;
set_bit(port_index, bus_state-bus_suspended);
@@ -1207,7 +1166,6 @@ int xhci_bus_resume(struct usb_hcd *hcd)
/* Check whether need resume ports. If needed
   resume port and disable remote wakeup */
u32 temp;
-   int slot_id;
 
temp = readl(port_array[port_index]);
if (DEV_SUPERSPEED(temp))
@@ -1240,11 +1198,6 @@ int xhci_bus_resume(struct usb_hcd *hcd)
/* Clear PLC

[PATCH v2 1/3] usb: notify hcd when USB device suspend or resume

2015-05-06 Thread Lu Baolu
This patch adds two new entries in hc_driver. With these new entries,
USB core can notify host driver when a USB device is about to suspend
or just resumed.

The xHCI spec is designed to allow an xHC implementation to cache the
endpoint state. Caching endpoint state allows an xHC to reduce latency
when handling ERDYs and other USB asynchronous events. However holding
this state in xHC consumes resources and power. The xHCI spec designs
some methods through which host controller driver can hint xHC about
how to optimize its operation, e.g. to determine when it holds state
internally or pushes it out to memory, when to power down logic, etc.

When a USB device is going to suspend, states of all endpoints cached
in the xHC should be pushed out to memory to save power and resources.
Vice versa, when a USB device resumes, those states should be brought
back to the cache. USB core suspends or resumes a USB device by sending
set/clear port feature requests to the parent hub where the USB device
is connected. Unfortunately, these operations are transparent to xHCI
driver unless the USB device is plugged in a root port. This patch
utilizes the callback entries to notify xHCI driver whenever a USB
device suspends or resumes.

It is harmless if a USB devices under USB 3.0 host controller suspends
or resumes without a notification to hcd driver. However there may be
less opportunities for power savings and there may be increased latency
for restarting an endpoint. The precise impact will be different for
each xHC implementation. It all depends on what an implementation does
with the hints.

Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
 drivers/usb/core/hcd.c  | 29 +
 drivers/usb/core/hub.c  | 16 
 include/linux/usb/hcd.h | 10 +-
 3 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 45a915c..a4cfc2d 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2289,6 +2289,35 @@ void usb_hcd_resume_root_hub (struct usb_hcd *hcd)
 }
 EXPORT_SYMBOL_GPL(usb_hcd_resume_root_hub);
 
+/**
+ * hcd_suspend_notify - notify hcd driver when a device is going to suspend
+ * @udev: USB device to be suspended
+ * @msg: Power Management message describing this state transition
+ *
+ * Call back to hcd driver to notify that a USB device is going to suspend.
+ */
+void hcd_suspend_notify(struct usb_device *udev, pm_message_t msg)
+{
+   struct usb_hcd *hcd = bus_to_hcd(udev-bus);
+
+   if (hcd-driver-device_suspend)
+   hcd-driver-device_suspend(hcd, udev, msg);
+}
+
+/**
+ * hcd_resume_notify - notify hcd driver when a device is just resumed
+ * @udev: USB device just resumed
+ * @msg: Power Management message describing this state transition
+ *
+ * Call back to hcd driver to notify that a USB device is just resumed.
+ */
+void hcd_resume_notify(struct usb_device *udev, pm_message_t msg)
+{
+   struct usb_hcd *hcd = bus_to_hcd(udev-bus);
+
+   if (hcd-driver-device_resume)
+   hcd-driver-device_resume(hcd, udev, msg);
+}
 #endif /* CONFIG_PM */
 
 /*-*/
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 3b71516..ed22b51 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -3144,6 +3144,14 @@ int usb_port_suspend(struct usb_device *udev, 
pm_message_t msg)
goto err_lpm3;
}
 
+   /*
+* Call back to hcd if it expects. xHCI compatible host controller
+* driver expects to be notified prior to selectively suspending a
+* device. xHCI hcd could optimize the endpoint cache for power
+* saving purpose. Refer to 4.15.1.1 of xHCI 1.1 for more information.
+*/
+   hcd_suspend_notify(udev, msg);
+
/* see 7.1.7.6 */
if (hub_is_superspeed(hub-hdev))
status = hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_U3);
@@ -3169,6 +3177,8 @@ int usb_port_suspend(struct usb_device *udev, 
pm_message_t msg)
if (status) {
dev_dbg(port_dev-dev, can't suspend, status %d\n, status);
 
+   hcd_resume_notify(udev, msg);
+
/* Try to enable USB3 LPM and LTM again */
usb_unlocked_enable_lpm(udev);
  err_lpm3:
@@ -3422,6 +3432,12 @@ int usb_port_resume(struct usb_device *udev, 
pm_message_t msg)
}
 
  SuspendCleared:
+   /* Call back to hcd if it expects. xHCI compatible host controller
+* driver expects to be notified after a device is resumed. xHCI
+* hcd could optimize the endpoint cache for latency reducing
+* purpose. Refer to 4.15.1.1 of xHCI 1.1 for more information.
+*/
+   hcd_resume_notify(udev, msg);
if (status == 0) {
udev-port_is_suspended = 0;
if (hub_is_superspeed(hub-hdev)) {
diff --git a/include/linux/usb/hcd.h b

Re: [PATCH v3 2/3] usb: xhci: implement device_suspend/device_resume entries

2015-05-07 Thread Lu, Baolu



On 05/08/2015 04:47 AM, Greg Kroah-Hartman wrote:

On Thu, May 07, 2015 at 10:18:15AM +0800, Lu Baolu wrote:

This patch implements device_suspend/device_resume entries for xHC driver.
device_suspend will be called when a USB device is about to suspend. It
will issue a stop endpoint command for each endpoint in this device. The
Suspend(SP) bit in the command TRB will set which will give xHC a hint
about the suspend. device_resume will be called when a USB device is just
resumed. It will ring doorbells of all endpoint unconditionally. XHC may
use these suspend/resume hints to optimize its operation.

Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
  drivers/usb/host/xhci-hub.c |  2 +-
  drivers/usb/host/xhci.c | 40 
  drivers/usb/host/xhci.h | 11 +++
  3 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 0827d7c..a83e82e 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -266,7 +266,7 @@ int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct 
xhci_hcd *xhci,
   * to complete.
   * suspend will set to 1, if suspend bit need to set in command.
   */
-static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)
+int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)
  {
struct xhci_virt_device *virt_dev;
struct xhci_command *cmd;
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index ec8ac16..6b61833 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -4680,6 +4680,40 @@ int xhci_disable_usb3_lpm_timeout(struct usb_hcd *hcd,
return ret;
return 0;
  }
+
+/*
+ * xHCI compatible host controller driver expects to be notified prior to
+ * selectively suspending a device. xHCI hcd could optimize the endpoint
+ * cache for power saving purpose. Refer to 4.15.1.1 of xHCI 1.1.
+ */
+void xhci_device_suspend(struct usb_hcd *hcd,
+   struct usb_device *udev, pm_message_t msg)

You never use the 'msg' field, so please remove it from the callback.


'msg' could be used in another patch to determine the pm event types:
auto-suspend or system suspend. I didn't bring up that patch together
with this patch series because 1) that's part of xhci 1.1 features, and
2) it's still not tested yet.




+{
+   struct xhci_hcd *xhci;
+
+   xhci = hcd_to_xhci(hcd);
+   if (!xhci || !xhci-devs[udev-slot_id])
+   return;
+
+   xhci_stop_device(xhci, udev-slot_id, 1);
+}
+
+/*
+ * xHCI compatible host controller driver expects to be notified after a
+ * USB device is resumed. xHCI hcd could optimize the endpoint cache
+ * to reduce the latency. Refer to 4.15.1.1 of xHCI 1.1.
+ */
+void xhci_device_resume(struct usb_hcd *hcd,
+   struct usb_device *udev, pm_message_t msg)

Same here.


I will remove 'msg' field in this call back. I don't see any cases where
msg could be used.

Thank you,
Baolu



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




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


Re: [PATCH v2 1/3] usb: notify hcd when USB device suspend or resume

2015-05-07 Thread Lu, Baolu



On 05/07/2015 10:34 PM, Alan Stern wrote:

On Thu, 7 May 2015, Lu, Baolu wrote:


+   void(*device_suspend)(struct usb_hcd *, struct usb_device *udev,
+   pm_message_t msg);
+   void(*device_resume)(struct usb_hcd *, struct usb_device *udev,
+   pm_message_t msg);
   };

Your callbacks don't use the msg argument.  What makes you think it is
needed?

This msg argument is valuable. XHCI spec defines a capability named FSC
(Force Save context Capability). When this capability is implemented, the
Save State operation (do during host suspend) shall save any cached Slot,
Endpoint, Stream or other Context information to memory. xHCI hcd could
use this msg to determine whether it needs to issue stop endpoint with
SP (suspend) bit set.

I don't understand.  What is the advantage of using FSC?


I'm sorry, I didn't make it clear.

As part of host suspend, controller save state will be issued to save
host internal state in xhci_suspend():

/* step 4: set CSS flag */
command = readl(xhci-op_regs-command);
command |= CMD_CSS;
writel(command, xhci-op_regs-command);
if (xhci_handshake(xhci-op_regs-status,
STS_SAVE, 0, 10 * 1000)) {
xhci_warn(xhci, WARN: xHC save state timeout\n);
spin_unlock_irq(xhci-lock);
return -ETIMEDOUT;
}

If FSC is supported,  the cached Slot, Endpoint, Stream, or other
Context information are also saved.

Hence, when FSC is supported, software does not have to issue Stop
Endpoint Command to push public and private endpoint state into
memory as part of system suspend process.

The logic in xhci_device_suspend() will look like:

if xhci_device_suspend() callback was called due to system suspend,
(mesg.event  PM_EVENT_SUSPEND is true) and FSC is supported by
the xHC implementation, xhci_device_suspend() could ignore stop
endpoint command, since CSS will be done in xhc_suspend() later and
where all the endpoint caches will be pushed to memory.



How would xhci-hcd use msg to determine this?  And why doesn't your
2/3 patch already do it?


xhci-hcd can use msg to determine which case the callback is called,
run-time suspend or system suspend.

FSC needs a separate patch, I already have it in Mathias' gate. I didn't
bring it together with this patch series because it's still not tested yet.



Alan Stern


Thank you!
Baolu







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


Re: [PATCH v3 2/3] usb: xhci: implement device_suspend/device_resume entries

2015-05-08 Thread Lu, Baolu



On 05/08/2015 03:28 PM, Greg Kroah-Hartman wrote:

On Fri, May 08, 2015 at 09:23:40AM +0800, Lu, Baolu wrote:


On 05/08/2015 04:47 AM, Greg Kroah-Hartman wrote:

On Thu, May 07, 2015 at 10:18:15AM +0800, Lu Baolu wrote:

This patch implements device_suspend/device_resume entries for xHC driver.
device_suspend will be called when a USB device is about to suspend. It
will issue a stop endpoint command for each endpoint in this device. The
Suspend(SP) bit in the command TRB will set which will give xHC a hint
about the suspend. device_resume will be called when a USB device is just
resumed. It will ring doorbells of all endpoint unconditionally. XHC may
use these suspend/resume hints to optimize its operation.

Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
  drivers/usb/host/xhci-hub.c |  2 +-
  drivers/usb/host/xhci.c | 40 
  drivers/usb/host/xhci.h | 11 +++
  3 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 0827d7c..a83e82e 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -266,7 +266,7 @@ int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct 
xhci_hcd *xhci,
   * to complete.
   * suspend will set to 1, if suspend bit need to set in command.
   */
-static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)
+int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)
  {
struct xhci_virt_device *virt_dev;
struct xhci_command *cmd;
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index ec8ac16..6b61833 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -4680,6 +4680,40 @@ int xhci_disable_usb3_lpm_timeout(struct usb_hcd *hcd,
return ret;
return 0;
  }
+
+/*
+ * xHCI compatible host controller driver expects to be notified prior to
+ * selectively suspending a device. xHCI hcd could optimize the endpoint
+ * cache for power saving purpose. Refer to 4.15.1.1 of xHCI 1.1.
+ */
+void xhci_device_suspend(struct usb_hcd *hcd,
+   struct usb_device *udev, pm_message_t msg)

You never use the 'msg' field, so please remove it from the callback.

'msg' could be used in another patch to determine the pm event types:
auto-suspend or system suspend. I didn't bring up that patch together
with this patch series because 1) that's part of xhci 1.1 features, and
2) it's still not tested yet.

We don't add features to kernel code that is not used when it is
added.  We can always change function calls later as we do not have a
stable api at all.


Understand it now. I will remove 'msg' fields in v4 patch series.



thanks,

greg k-h


Thank you.
Baolu

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



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


Re: [PATCH v2 1/3] usb: notify hcd when USB device suspend or resume

2015-05-08 Thread Lu, Baolu



On 05/06/2015 10:35 PM, Alan Stern wrote:

diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index 68b1e83..621d9b7 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -383,7 +383,13 @@ struct hc_driver {
int (*find_raw_port_number)(struct usb_hcd *, int);
/* Call for power on/off the port if necessary */
int (*port_power)(struct usb_hcd *hcd, int portnum, bool enable);
-
+   /* Call back to hcd when a USB device is going to suspend or just
+* resumed.
+*/
+   void(*device_suspend)(struct usb_hcd *, struct usb_device *udev,
+   pm_message_t msg);
+   void(*device_resume)(struct usb_hcd *, struct usb_device *udev,
+   pm_message_t msg);
  };

Your callbacks don't use the msg argument.  What makes you think it is
needed?


'msg' arguments are not used in this patch series. I will remove them.



Alan Stern


Thank you,
Baolu
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 1/3] usb: notify hcd when USB device suspend or resume

2015-05-08 Thread Lu Baolu
This patch adds two new entries in hc_driver. With these new entries,
USB core can notify host driver when a USB device is about to suspend
or just resumed.

The xHCI spec is designed to allow an xHC implementation to cache the
endpoint state. Caching endpoint state allows an xHC to reduce latency
when handling ERDYs and other USB asynchronous events. However holding
this state in xHC consumes resources and power. The xHCI spec designs
some methods through which host controller driver can hint xHC about
how to optimize its operation, e.g. to determine when it holds state
internally or pushes it out to memory, when to power down logic, etc.

When a USB device is going to suspend, states of all endpoints cached
in the xHC should be pushed out to memory to save power and resources.
Vice versa, when a USB device resumes, those states should be brought
back to the cache. USB core suspends or resumes a USB device by sending
set/clear port feature requests to the parent hub where the USB device
is connected. Unfortunately, these operations are transparent to xHCI
driver unless the USB device is plugged in a root port. This patch
utilizes the callback entries to notify xHCI driver whenever a USB
device suspends or resumes.

It is harmless if a USB devices under USB 3.0 host controller suspends
or resumes without a notification to hcd driver. However there may be
less opportunities for power savings and there may be increased latency
for restarting an endpoint. The precise impact will be different for
each xHC implementation. It all depends on what an implementation does
with the hints.

Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
 drivers/usb/core/hcd.c  | 27 +++
 drivers/usb/core/hub.c  |  5 +
 include/linux/usb/hcd.h |  8 +++-
 3 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 45a915c..007450d 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2289,6 +2289,33 @@ void usb_hcd_resume_root_hub (struct usb_hcd *hcd)
 }
 EXPORT_SYMBOL_GPL(usb_hcd_resume_root_hub);
 
+/**
+ * hcd_suspend_notify - notify hcd driver when a device is going to suspend
+ * @udev: USB device to be suspended
+ *
+ * Call back to hcd driver to notify that a USB device is going to suspend.
+ */
+void hcd_suspend_notify(struct usb_device *udev)
+{
+   struct usb_hcd *hcd = bus_to_hcd(udev-bus);
+
+   if (hcd-driver-device_suspend)
+   hcd-driver-device_suspend(hcd, udev);
+}
+
+/**
+ * hcd_resume_notify - notify hcd driver when a device is just resumed
+ * @udev: USB device just resumed
+ *
+ * Call back to hcd driver to notify that a USB device is just resumed.
+ */
+void hcd_resume_notify(struct usb_device *udev)
+{
+   struct usb_hcd *hcd = bus_to_hcd(udev-bus);
+
+   if (hcd-driver-device_resume)
+   hcd-driver-device_resume(hcd, udev);
+}
 #endif /* CONFIG_PM */
 
 /*-*/
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 52178bc..28d76b7 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -3149,6 +3149,8 @@ int usb_port_suspend(struct usb_device *udev, 
pm_message_t msg)
goto err_lpm3;
}
 
+   hcd_suspend_notify(udev);
+
/* see 7.1.7.6 */
if (hub_is_superspeed(hub-hdev))
status = hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_U3);
@@ -3174,6 +3176,8 @@ int usb_port_suspend(struct usb_device *udev, 
pm_message_t msg)
if (status) {
dev_dbg(port_dev-dev, can't suspend, status %d\n, status);
 
+   hcd_resume_notify(udev);
+
/* Try to enable USB3 LPM and LTM again */
usb_unlocked_enable_lpm(udev);
  err_lpm3:
@@ -3427,6 +3431,7 @@ int usb_port_resume(struct usb_device *udev, pm_message_t 
msg)
}
 
  SuspendCleared:
+   hcd_resume_notify(udev);
if (status == 0) {
udev-port_is_suspended = 0;
if (hub_is_superspeed(hub-hdev)) {
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index 68b1e83..bc2eb1c 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -383,7 +383,11 @@ struct hc_driver {
int (*find_raw_port_number)(struct usb_hcd *, int);
/* Call for power on/off the port if necessary */
int (*port_power)(struct usb_hcd *hcd, int portnum, bool enable);
-
+   /* Call back to hcd when a USB device is going to suspend or just
+* resumed.
+*/
+   void(*device_suspend)(struct usb_hcd *, struct usb_device *udev);
+   void(*device_resume)(struct usb_hcd *, struct usb_device *udev);
 };
 
 static inline int hcd_giveback_urb_in_bh(struct usb_hcd *hcd)
@@ -632,6 +636,8 @@ extern void usb_root_hub_lost_power(struct usb_device 
*rhdev);
 extern int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg

[PATCH v4 3/3] usb: xhci: remove stop device and ring doorbell in hub control and bus suspend

2015-05-08 Thread Lu Baolu
There is no need to call xhci_stop_device() and xhci_ring_device() in
hub control and bus suspend functions since all device suspend and
resume have been notified through device_suspend/device_resume interfaces.

Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
 drivers/usb/host/xhci-hub.c | 47 -
 1 file changed, 47 deletions(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index a83e82e..f12e1b7 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -704,7 +704,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 
wValue,
u32 temp, status;
int retval = 0;
__le32 __iomem **port_array;
-   int slot_id;
struct xhci_bus_state *bus_state;
u16 link_state = 0;
u16 wake_mask = 0;
@@ -818,17 +817,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 
wValue,
goto error;
}
 
-   slot_id = xhci_find_slot_id_by_port(hcd, xhci,
-   wIndex + 1);
-   if (!slot_id) {
-   xhci_warn(xhci, slot_id is zero\n);
-   goto error;
-   }
-   /* unlock to execute stop endpoint commands */
-   spin_unlock_irqrestore(xhci-lock, flags);
-   xhci_stop_device(xhci, slot_id, 1);
-   spin_lock_irqsave(xhci-lock, flags);
-
xhci_set_link_state(xhci, port_array, wIndex, XDEV_U3);
 
spin_unlock_irqrestore(xhci-lock, flags);
@@ -876,19 +864,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 
wValue,
goto error;
}
 
-   if (link_state == USB_SS_PORT_LS_U3) {
-   slot_id = xhci_find_slot_id_by_port(hcd, xhci,
-   wIndex + 1);
-   if (slot_id) {
-   /* unlock to execute stop endpoint
-* commands */
-   spin_unlock_irqrestore(xhci-lock,
-   flags);
-   xhci_stop_device(xhci, slot_id, 1);
-   spin_lock_irqsave(xhci-lock, flags);
-   }
-   }
-
xhci_set_link_state(xhci, port_array, wIndex,
link_state);
 
@@ -994,14 +969,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 
wValue,
XDEV_U0);
}
bus_state-port_c_suspend |= 1  wIndex;
-
-   slot_id = xhci_find_slot_id_by_port(hcd, xhci,
-   wIndex + 1);
-   if (!slot_id) {
-   xhci_dbg(xhci, slot_id is zero\n);
-   goto error;
-   }
-   xhci_ring_device(xhci, slot_id);
break;
case USB_PORT_FEAT_C_SUSPEND:
bus_state-port_c_suspend = ~(1  wIndex);
@@ -1133,20 +1100,12 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
while (port_index--) {
/* suspend the port if the port is not suspended */
u32 t1, t2;
-   int slot_id;
 
t1 = readl(port_array[port_index]);
t2 = xhci_port_state_to_neutral(t1);
 
if ((t1  PORT_PE)  !(t1  PORT_PLS_MASK)) {
xhci_dbg(xhci, port %d not suspended\n, port_index);
-   slot_id = xhci_find_slot_id_by_port(hcd, xhci,
-   port_index + 1);
-   if (slot_id) {
-   spin_unlock_irqrestore(xhci-lock, flags);
-   xhci_stop_device(xhci, slot_id, 1);
-   spin_lock_irqsave(xhci-lock, flags);
-   }
t2 = ~PORT_PLS_MASK;
t2 |= PORT_LINK_STROBE | XDEV_U3;
set_bit(port_index, bus_state-bus_suspended);
@@ -1207,7 +1166,6 @@ int xhci_bus_resume(struct usb_hcd *hcd)
/* Check whether need resume ports. If needed
   resume port and disable remote wakeup */
u32 temp;
-   int slot_id;
 
temp = readl(port_array[port_index]);
if (DEV_SUPERSPEED(temp))
@@ -1240,11 +1198,6 @@ int xhci_bus_resume(struct usb_hcd *hcd)
/* Clear PLC

[PATCH v4 0/3] usb: notify hcd when USB device suspend or resume

2015-05-08 Thread Lu Baolu
This patch series try to meet a design requirement in xHCI spec.

The xHCI spec is designed to allow an xHC implementation to cache the
endpoint state. Caching endpoint state allows an xHC to reduce latency
when handling ERDYs and other USB asynchronous events. However holding
this state in xHC consumes resources and power. The xHCI spec designs
some methods through which host controller driver can hint xHC about
how to optimize its operation, e.g. to determine when it holds state
internally or pushes it out to memory, when to power down logic, etc.

When a USB device is going to suspend, states of all endpoints cached
in the xHC should be pushed out to memory to save power and resources.
Vice versa, when a USB device resumes, those states should be brought
back to the cache.

It is harmless if a USB devices under USB 3.0 host controller suspends
or resumes without a notification to hcd driver. However there may be
less opportunities for power savings and there may be increased latency
for restarting an endpoint. The precise impact will be different for
each xHC implementation. It all depends on what an implementation does
with the hints.

Change log:
v3-v4:
 - remove unused 'msg' parameter in the callbacks

v2-v3:
 - move two xhci specific comments from hub to xhci
 - define xhci_device_suspend(resume) as NULL when no PM_CONFIG

v1-v2:
 - make the callback name specific to the activity in question
 - no need to export hcd_notify
 - put the callback in the right place

Lu Baolu (3):
  usb: notify hcd when USB device suspend or resume
  usb: xhci: implement device_suspend/device_resume entries
  usb: xhci: remove stop device and ring doorbell in hub control and bus
suspend

 drivers/usb/core/hcd.c  | 27 +
 drivers/usb/core/hub.c  |  5 +
 drivers/usb/host/xhci-hub.c | 49 +
 drivers/usb/host/xhci.c | 38 +++
 drivers/usb/host/xhci.h |  9 +
 include/linux/usb/hcd.h |  8 +++-
 6 files changed, 87 insertions(+), 49 deletions(-)

-- 
2.1.0

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


[PATCH v4 2/3] usb: xhci: implement device_suspend/device_resume entries

2015-05-08 Thread Lu Baolu
This patch implements device_suspend/device_resume entries for xHC driver.
device_suspend will be called when a USB device is about to suspend. It
will issue a stop endpoint command for each endpoint in this device. The
Suspend(SP) bit in the command TRB will set which will give xHC a hint
about the suspend. device_resume will be called when a USB device is just
resumed. It will ring doorbells of all endpoint unconditionally. XHC may
use these suspend/resume hints to optimize its operation.

Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
 drivers/usb/host/xhci-hub.c |  2 +-
 drivers/usb/host/xhci.c | 38 ++
 drivers/usb/host/xhci.h |  9 +
 3 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 0827d7c..a83e82e 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -266,7 +266,7 @@ int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct 
xhci_hcd *xhci,
  * to complete.
  * suspend will set to 1, if suspend bit need to set in command.
  */
-static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)
+int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)
 {
struct xhci_virt_device *virt_dev;
struct xhci_command *cmd;
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index ec8ac16..330961d 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -4680,6 +4680,38 @@ int xhci_disable_usb3_lpm_timeout(struct usb_hcd *hcd,
return ret;
return 0;
 }
+
+/*
+ * xHCI compatible host controller driver expects to be notified prior to
+ * selectively suspending a device. xHCI hcd could optimize the endpoint
+ * cache for power saving purpose. Refer to 4.15.1.1 of xHCI 1.1.
+ */
+void xhci_device_suspend(struct usb_hcd *hcd, struct usb_device *udev)
+{
+   struct xhci_hcd *xhci;
+
+   xhci = hcd_to_xhci(hcd);
+   if (!xhci || !xhci-devs[udev-slot_id])
+   return;
+
+   xhci_stop_device(xhci, udev-slot_id, 1);
+}
+
+/*
+ * xHCI compatible host controller driver expects to be notified after a
+ * USB device is resumed. xHCI hcd could optimize the endpoint cache
+ * to reduce the latency. Refer to 4.15.1.1 of xHCI 1.1.
+ */
+void xhci_device_resume(struct usb_hcd *hcd, struct usb_device *udev)
+{
+   struct xhci_hcd *xhci;
+
+   xhci = hcd_to_xhci(hcd);
+   if (!xhci || !xhci-devs[udev-slot_id])
+   return;
+
+   xhci_ring_device(xhci, udev-slot_id);
+}
 #else /* CONFIG_PM */
 
 int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
@@ -4976,6 +5008,12 @@ static const struct hc_driver xhci_hc_driver = {
.enable_usb3_lpm_timeout =  xhci_enable_usb3_lpm_timeout,
.disable_usb3_lpm_timeout = xhci_disable_usb3_lpm_timeout,
.find_raw_port_number = xhci_find_raw_port_number,
+
+   /*
+* call back when devices suspend or resume
+*/
+   .device_suspend =   xhci_device_suspend,
+   .device_resume =xhci_device_resume,
 };
 
 void xhci_init_driver(struct hc_driver *drv, int (*setup_fn)(struct usb_hcd *))
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 8e421b8..67c13c5 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1867,10 +1867,19 @@ u32 xhci_port_state_to_neutral(u32 state);
 int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci,
u16 port);
 void xhci_ring_device(struct xhci_hcd *xhci, int slot_id);
+int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend);
 
 /* xHCI contexts */
 struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct 
xhci_container_ctx *ctx);
 struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct 
xhci_container_ctx *ctx);
 struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, struct 
xhci_container_ctx *ctx, unsigned int ep_index);
 
+#ifdef CONFIG_PM
+void xhci_device_suspend(struct usb_hcd *hcd, struct usb_device *udev);
+void xhci_device_resume(struct usb_hcd *hcd, struct usb_device *udev);
+#else
+#define xhci_device_suspendNULL
+#define xhci_device_resume NULL
+#endif /* CONFIG_PM */
+
 #endif /* __LINUX_XHCI_HCD_H */
-- 
2.1.0

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


Re: [PATCH v2 1/3] usb: notify hcd when USB device suspend or resume

2015-05-06 Thread Lu, Baolu



On 05/06/2015 10:35 PM, Alan Stern wrote:

On Wed, 6 May 2015, Lu Baolu wrote:


This patch adds two new entries in hc_driver. With these new entries,
USB core can notify host driver when a USB device is about to suspend
or just resumed.

The xHCI spec is designed to allow an xHC implementation to cache the
endpoint state. Caching endpoint state allows an xHC to reduce latency
when handling ERDYs and other USB asynchronous events. However holding
this state in xHC consumes resources and power. The xHCI spec designs
some methods through which host controller driver can hint xHC about
how to optimize its operation, e.g. to determine when it holds state
internally or pushes it out to memory, when to power down logic, etc.

When a USB device is going to suspend, states of all endpoints cached
in the xHC should be pushed out to memory to save power and resources.
Vice versa, when a USB device resumes, those states should be brought
back to the cache. USB core suspends or resumes a USB device by sending
set/clear port feature requests to the parent hub where the USB device
is connected. Unfortunately, these operations are transparent to xHCI
driver unless the USB device is plugged in a root port. This patch
utilizes the callback entries to notify xHCI driver whenever a USB
device suspends or resumes.

It is harmless if a USB devices under USB 3.0 host controller suspends
or resumes without a notification to hcd driver. However there may be
less opportunities for power savings and there may be increased latency
for restarting an endpoint. The precise impact will be different for
each xHC implementation. It all depends on what an implementation does
with the hints.

Signed-off-by: Lu Baolu baolu...@linux.intel.com



--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -3144,6 +3144,14 @@ int usb_port_suspend(struct usb_device *udev, 
pm_message_t msg)
goto err_lpm3;
}
  
+	/*

+* Call back to hcd if it expects. xHCI compatible host controller
+* driver expects to be notified prior to selectively suspending a
+* device. xHCI hcd could optimize the endpoint cache for power
+* saving purpose. Refer to 4.15.1.1 of xHCI 1.1 for more information.
+*/

Doesn't this comment belong in the xhci-hcd source code rather than the
hub driver source code?


Yes, I agree. I will move this and below comments to xhci driver.




+   hcd_suspend_notify(udev, msg);
+
/* see 7.1.7.6 */
if (hub_is_superspeed(hub-hdev))
status = hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_U3);
@@ -3169,6 +3177,8 @@ int usb_port_suspend(struct usb_device *udev, 
pm_message_t msg)
if (status) {
dev_dbg(port_dev-dev, can't suspend, status %d\n, status);
  
+		hcd_resume_notify(udev, msg);

+
/* Try to enable USB3 LPM and LTM again */
usb_unlocked_enable_lpm(udev);
   err_lpm3:
@@ -3422,6 +3432,12 @@ int usb_port_resume(struct usb_device *udev, 
pm_message_t msg)
}
  
   SuspendCleared:

+   /* Call back to hcd if it expects. xHCI compatible host controller
+* driver expects to be notified after a device is resumed. xHCI
+* hcd could optimize the endpoint cache for latency reducing
+* purpose. Refer to 4.15.1.1 of xHCI 1.1 for more information.
+*/

Same for this comment.


+   hcd_resume_notify(udev, msg);
if (status == 0) {
udev-port_is_suspended = 0;
if (hub_is_superspeed(hub-hdev)) {
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index 68b1e83..621d9b7 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -383,7 +383,13 @@ struct hc_driver {
int (*find_raw_port_number)(struct usb_hcd *, int);
/* Call for power on/off the port if necessary */
int (*port_power)(struct usb_hcd *hcd, int portnum, bool enable);
-
+   /* Call back to hcd when a USB device is going to suspend or just
+* resumed.
+*/
+   void(*device_suspend)(struct usb_hcd *, struct usb_device *udev,
+   pm_message_t msg);
+   void(*device_resume)(struct usb_hcd *, struct usb_device *udev,
+   pm_message_t msg);
  };

Your callbacks don't use the msg argument.  What makes you think it is
needed?


This msg argument is valuable. XHCI spec defines a capability named FSC
(Force Save context Capability). When this capability is implemented, the
Save State operation (do during host suspend) shall save any cached Slot,
Endpoint, Stream or other Context information to memory. xHCI hcd could
use this msg to determine whether it needs to issue stop endpoint with
SP (suspend) bit set.

FSC is optional prior 1.1 and mandatory since 1.1. I have patches for 1.1
features in Mathias' gate. We could bring them up after we test them on
the real hardware.



Alan Stern

--
To unsubscribe from this list: send

Re: [PATCH v2 2/3] usb: xhci: implement device_suspend/device_resume entries

2015-05-06 Thread Lu, Baolu



On 05/06/2015 10:30 PM, Alan Stern wrote:

On Wed, 6 May 2015, Lu Baolu wrote:


This patch implements device_suspend/device_resume entries for xHC driver.
device_suspend will be called when a USB device is about to suspend. It
will issue a stop endpoint command for each endpoint in this device. The
Suspend(SP) bit in the command TRB will set which will give xHC a hint
about the suspend. device_resume will be called when a USB device is just
resumed. It will ring doorbells of all endpoint unconditionally. XHC may
use these suspend/resume hints to optimize its operation.

Signed-off-by: Lu Baolu baolu...@linux.intel.com

...


  #else /* CONFIG_PM */
  
  int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,

@@ -4704,6 +4728,16 @@ int xhci_disable_usb3_lpm_timeout(struct usb_hcd *hcd,
  {
return 0;
  }
+
+void xhci_device_suspend(struct usb_hcd *hcd,
+   struct usb_device *udev, pm_message_t msg)
+{
+}
+
+void xhci_device_resume(struct usb_hcd *hcd,
+   struct usb_device *udev, pm_message_t msg)
+{
+}

You don't need to have empty functions.  Just do this:

#define xhci_device_suspend NULL
#define xhci_device_resume  NULL

in the appropriate place, when CONFIG_PM is not enabled.


Yes, I agree. I will change it.



Alan Stern


Thank you,
Baolu







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


[PATCH v3 1/3] usb: notify hcd when USB device suspend or resume

2015-05-06 Thread Lu Baolu
This patch adds two new entries in hc_driver. With these new entries,
USB core can notify host driver when a USB device is about to suspend
or just resumed.

The xHCI spec is designed to allow an xHC implementation to cache the
endpoint state. Caching endpoint state allows an xHC to reduce latency
when handling ERDYs and other USB asynchronous events. However holding
this state in xHC consumes resources and power. The xHCI spec designs
some methods through which host controller driver can hint xHC about
how to optimize its operation, e.g. to determine when it holds state
internally or pushes it out to memory, when to power down logic, etc.

When a USB device is going to suspend, states of all endpoints cached
in the xHC should be pushed out to memory to save power and resources.
Vice versa, when a USB device resumes, those states should be brought
back to the cache. USB core suspends or resumes a USB device by sending
set/clear port feature requests to the parent hub where the USB device
is connected. Unfortunately, these operations are transparent to xHCI
driver unless the USB device is plugged in a root port. This patch
utilizes the callback entries to notify xHCI driver whenever a USB
device suspends or resumes.

It is harmless if a USB devices under USB 3.0 host controller suspends
or resumes without a notification to hcd driver. However there may be
less opportunities for power savings and there may be increased latency
for restarting an endpoint. The precise impact will be different for
each xHC implementation. It all depends on what an implementation does
with the hints.

Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
 drivers/usb/core/hcd.c  | 29 +
 drivers/usb/core/hub.c  |  5 +
 include/linux/usb/hcd.h | 10 +-
 3 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 45a915c..a4cfc2d 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2289,6 +2289,35 @@ void usb_hcd_resume_root_hub (struct usb_hcd *hcd)
 }
 EXPORT_SYMBOL_GPL(usb_hcd_resume_root_hub);
 
+/**
+ * hcd_suspend_notify - notify hcd driver when a device is going to suspend
+ * @udev: USB device to be suspended
+ * @msg: Power Management message describing this state transition
+ *
+ * Call back to hcd driver to notify that a USB device is going to suspend.
+ */
+void hcd_suspend_notify(struct usb_device *udev, pm_message_t msg)
+{
+   struct usb_hcd *hcd = bus_to_hcd(udev-bus);
+
+   if (hcd-driver-device_suspend)
+   hcd-driver-device_suspend(hcd, udev, msg);
+}
+
+/**
+ * hcd_resume_notify - notify hcd driver when a device is just resumed
+ * @udev: USB device just resumed
+ * @msg: Power Management message describing this state transition
+ *
+ * Call back to hcd driver to notify that a USB device is just resumed.
+ */
+void hcd_resume_notify(struct usb_device *udev, pm_message_t msg)
+{
+   struct usb_hcd *hcd = bus_to_hcd(udev-bus);
+
+   if (hcd-driver-device_resume)
+   hcd-driver-device_resume(hcd, udev, msg);
+}
 #endif /* CONFIG_PM */
 
 /*-*/
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 3b71516..b3f0dc8 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -3144,6 +3144,8 @@ int usb_port_suspend(struct usb_device *udev, 
pm_message_t msg)
goto err_lpm3;
}
 
+   hcd_suspend_notify(udev, msg);
+
/* see 7.1.7.6 */
if (hub_is_superspeed(hub-hdev))
status = hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_U3);
@@ -3169,6 +3171,8 @@ int usb_port_suspend(struct usb_device *udev, 
pm_message_t msg)
if (status) {
dev_dbg(port_dev-dev, can't suspend, status %d\n, status);
 
+   hcd_resume_notify(udev, msg);
+
/* Try to enable USB3 LPM and LTM again */
usb_unlocked_enable_lpm(udev);
  err_lpm3:
@@ -3422,6 +3426,7 @@ int usb_port_resume(struct usb_device *udev, pm_message_t 
msg)
}
 
  SuspendCleared:
+   hcd_resume_notify(udev, msg);
if (status == 0) {
udev-port_is_suspended = 0;
if (hub_is_superspeed(hub-hdev)) {
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index 68b1e83..621d9b7 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -383,7 +383,13 @@ struct hc_driver {
int (*find_raw_port_number)(struct usb_hcd *, int);
/* Call for power on/off the port if necessary */
int (*port_power)(struct usb_hcd *hcd, int portnum, bool enable);
-
+   /* Call back to hcd when a USB device is going to suspend or just
+* resumed.
+*/
+   void(*device_suspend)(struct usb_hcd *, struct usb_device *udev,
+   pm_message_t msg);
+   void(*device_resume)(struct usb_hcd *, struct

[PATCH v3 2/3] usb: xhci: implement device_suspend/device_resume entries

2015-05-06 Thread Lu Baolu
This patch implements device_suspend/device_resume entries for xHC driver.
device_suspend will be called when a USB device is about to suspend. It
will issue a stop endpoint command for each endpoint in this device. The
Suspend(SP) bit in the command TRB will set which will give xHC a hint
about the suspend. device_resume will be called when a USB device is just
resumed. It will ring doorbells of all endpoint unconditionally. XHC may
use these suspend/resume hints to optimize its operation.

Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
 drivers/usb/host/xhci-hub.c |  2 +-
 drivers/usb/host/xhci.c | 40 
 drivers/usb/host/xhci.h | 11 +++
 3 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 0827d7c..a83e82e 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -266,7 +266,7 @@ int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct 
xhci_hcd *xhci,
  * to complete.
  * suspend will set to 1, if suspend bit need to set in command.
  */
-static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)
+int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)
 {
struct xhci_virt_device *virt_dev;
struct xhci_command *cmd;
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index ec8ac16..6b61833 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -4680,6 +4680,40 @@ int xhci_disable_usb3_lpm_timeout(struct usb_hcd *hcd,
return ret;
return 0;
 }
+
+/*
+ * xHCI compatible host controller driver expects to be notified prior to
+ * selectively suspending a device. xHCI hcd could optimize the endpoint
+ * cache for power saving purpose. Refer to 4.15.1.1 of xHCI 1.1.
+ */
+void xhci_device_suspend(struct usb_hcd *hcd,
+   struct usb_device *udev, pm_message_t msg)
+{
+   struct xhci_hcd *xhci;
+
+   xhci = hcd_to_xhci(hcd);
+   if (!xhci || !xhci-devs[udev-slot_id])
+   return;
+
+   xhci_stop_device(xhci, udev-slot_id, 1);
+}
+
+/*
+ * xHCI compatible host controller driver expects to be notified after a
+ * USB device is resumed. xHCI hcd could optimize the endpoint cache
+ * to reduce the latency. Refer to 4.15.1.1 of xHCI 1.1.
+ */
+void xhci_device_resume(struct usb_hcd *hcd,
+   struct usb_device *udev, pm_message_t msg)
+{
+   struct xhci_hcd *xhci;
+
+   xhci = hcd_to_xhci(hcd);
+   if (!xhci || !xhci-devs[udev-slot_id])
+   return;
+
+   xhci_ring_device(xhci, udev-slot_id);
+}
 #else /* CONFIG_PM */
 
 int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
@@ -4976,6 +5010,12 @@ static const struct hc_driver xhci_hc_driver = {
.enable_usb3_lpm_timeout =  xhci_enable_usb3_lpm_timeout,
.disable_usb3_lpm_timeout = xhci_disable_usb3_lpm_timeout,
.find_raw_port_number = xhci_find_raw_port_number,
+
+   /*
+* call back when devices suspend or resume
+*/
+   .device_suspend =   xhci_device_suspend,
+   .device_resume =xhci_device_resume,
 };
 
 void xhci_init_driver(struct hc_driver *drv, int (*setup_fn)(struct usb_hcd *))
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 8e421b8..d826439 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1867,10 +1867,21 @@ u32 xhci_port_state_to_neutral(u32 state);
 int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci,
u16 port);
 void xhci_ring_device(struct xhci_hcd *xhci, int slot_id);
+int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend);
 
 /* xHCI contexts */
 struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct 
xhci_container_ctx *ctx);
 struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct 
xhci_container_ctx *ctx);
 struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, struct 
xhci_container_ctx *ctx, unsigned int ep_index);
 
+#ifdef CONFIG_PM
+void xhci_device_suspend(struct usb_hcd *hcd,
+   struct usb_device *udev, pm_message_t msg);
+void xhci_device_resume(struct usb_hcd *hcd,
+   struct usb_device *udev, pm_message_t msg);
+#else
+#define xhci_device_suspendNULL
+#define xhci_device_resume NULL
+#endif /* CONFIG_PM */
+
 #endif /* __LINUX_XHCI_HCD_H */
-- 
2.1.0

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


[PATCH v3 3/3] usb: xhci: remove stop device and ring doorbell in hub control and bus suspend

2015-05-06 Thread Lu Baolu
There is no need to call xhci_stop_device() and xhci_ring_device() in
hub control and bus suspend functions since all device suspend and
resume have been notified through device_suspend/device_resume interfaces.

Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
 drivers/usb/host/xhci-hub.c | 47 -
 1 file changed, 47 deletions(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index a83e82e..f12e1b7 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -704,7 +704,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 
wValue,
u32 temp, status;
int retval = 0;
__le32 __iomem **port_array;
-   int slot_id;
struct xhci_bus_state *bus_state;
u16 link_state = 0;
u16 wake_mask = 0;
@@ -818,17 +817,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 
wValue,
goto error;
}
 
-   slot_id = xhci_find_slot_id_by_port(hcd, xhci,
-   wIndex + 1);
-   if (!slot_id) {
-   xhci_warn(xhci, slot_id is zero\n);
-   goto error;
-   }
-   /* unlock to execute stop endpoint commands */
-   spin_unlock_irqrestore(xhci-lock, flags);
-   xhci_stop_device(xhci, slot_id, 1);
-   spin_lock_irqsave(xhci-lock, flags);
-
xhci_set_link_state(xhci, port_array, wIndex, XDEV_U3);
 
spin_unlock_irqrestore(xhci-lock, flags);
@@ -876,19 +864,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 
wValue,
goto error;
}
 
-   if (link_state == USB_SS_PORT_LS_U3) {
-   slot_id = xhci_find_slot_id_by_port(hcd, xhci,
-   wIndex + 1);
-   if (slot_id) {
-   /* unlock to execute stop endpoint
-* commands */
-   spin_unlock_irqrestore(xhci-lock,
-   flags);
-   xhci_stop_device(xhci, slot_id, 1);
-   spin_lock_irqsave(xhci-lock, flags);
-   }
-   }
-
xhci_set_link_state(xhci, port_array, wIndex,
link_state);
 
@@ -994,14 +969,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 
wValue,
XDEV_U0);
}
bus_state-port_c_suspend |= 1  wIndex;
-
-   slot_id = xhci_find_slot_id_by_port(hcd, xhci,
-   wIndex + 1);
-   if (!slot_id) {
-   xhci_dbg(xhci, slot_id is zero\n);
-   goto error;
-   }
-   xhci_ring_device(xhci, slot_id);
break;
case USB_PORT_FEAT_C_SUSPEND:
bus_state-port_c_suspend = ~(1  wIndex);
@@ -1133,20 +1100,12 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
while (port_index--) {
/* suspend the port if the port is not suspended */
u32 t1, t2;
-   int slot_id;
 
t1 = readl(port_array[port_index]);
t2 = xhci_port_state_to_neutral(t1);
 
if ((t1  PORT_PE)  !(t1  PORT_PLS_MASK)) {
xhci_dbg(xhci, port %d not suspended\n, port_index);
-   slot_id = xhci_find_slot_id_by_port(hcd, xhci,
-   port_index + 1);
-   if (slot_id) {
-   spin_unlock_irqrestore(xhci-lock, flags);
-   xhci_stop_device(xhci, slot_id, 1);
-   spin_lock_irqsave(xhci-lock, flags);
-   }
t2 = ~PORT_PLS_MASK;
t2 |= PORT_LINK_STROBE | XDEV_U3;
set_bit(port_index, bus_state-bus_suspended);
@@ -1207,7 +1166,6 @@ int xhci_bus_resume(struct usb_hcd *hcd)
/* Check whether need resume ports. If needed
   resume port and disable remote wakeup */
u32 temp;
-   int slot_id;
 
temp = readl(port_array[port_index]);
if (DEV_SUPERSPEED(temp))
@@ -1240,11 +1198,6 @@ int xhci_bus_resume(struct usb_hcd *hcd)
/* Clear PLC

[PATCH v3 0/3] usb: notify hcd when USB device suspend or resume

2015-05-06 Thread Lu Baolu
This patch series try to meet a design requirement in xHCI spec.

The xHCI spec is designed to allow an xHC implementation to cache the
endpoint state. Caching endpoint state allows an xHC to reduce latency
when handling ERDYs and other USB asynchronous events. However holding
this state in xHC consumes resources and power. The xHCI spec designs
some methods through which host controller driver can hint xHC about
how to optimize its operation, e.g. to determine when it holds state
internally or pushes it out to memory, when to power down logic, etc.

When a USB device is going to suspend, states of all endpoints cached
in the xHC should be pushed out to memory to save power and resources.
Vice versa, when a USB device resumes, those states should be brought
back to the cache.

It is harmless if a USB devices under USB 3.0 host controller suspends
or resumes without a notification to hcd driver. However there may be
less opportunities for power savings and there may be increased latency
for restarting an endpoint. The precise impact will be different for
each xHC implementation. It all depends on what an implementation does
with the hints.

Change log:
v2-v3:
 - move two xhci specific comments from hub to xhci
 - define xhci_device_suspend(resume) as NULL when no PM_CONFIG

v1-v2:
 - make the callback name specific to the activity in question
 - no need to export hcd_notify
 - put the callback in the right place

Lu Baolu (3):
  usb: notify hcd when USB device suspend or resume
  usb: xhci: implement device_suspend/device_resume entries
  usb: xhci: remove stop device and ring doorbell in hub control and bus
suspend

 drivers/usb/core/hcd.c  | 29 +++
 drivers/usb/core/hub.c  |  5 +
 drivers/usb/host/xhci-hub.c | 49 +
 drivers/usb/host/xhci.c | 40 
 drivers/usb/host/xhci.h | 11 ++
 include/linux/usb/hcd.h | 10 -
 6 files changed, 95 insertions(+), 49 deletions(-)

-- 
2.1.0

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


Re: [RFC][PATCH 1/3] usb: add a hcd notify entry in hc_driver

2015-05-05 Thread Lu, Baolu



On 05/04/2015 04:14 PM, Greg Kroah-Hartman wrote:

On Mon, May 04, 2015 at 11:15:30AM +0800, Lu Baolu wrote:

This patch adds a new entry pointer in hc_driver. With this new entry,
USB core can notify host driver when something happens and host driver
is willing to be notified. One use case of this interface comes from
xHCI compatible host controller driver.

The xHCI spec is designed to allow an xHC implementation to cache the
endpoint state. Caching endpoint state allows an xHC to reduce latency
when handling ERDYs and other USB asynchronous events. However holding
this state in xHC consumes resources and power. The xHCI spec designs
some methods through which host controller driver can hint xHC about
how to optimize its operation, e.g. to determine when it holds state
internally or pushes it out to memory, when to power down logic, etc.

When a USB device is going to suspend, states of all endpoints cached
in the xHC should be pushed out to memory to save power and resources.
Vice versa, when a USB device resumes, those states should be brought
back to the cache. USB core suspends or resumes a USB device by sending
set/clear port feature requests to the parent hub where the USB device
is connected. Unfortunately, these operations are transparent to xHCI
driver unless the USB device is plugged in a root port. This patch
utilizes the notify interface to notify xHCI driver whenever a USB
device's power state is changed.

It is harmless if a USB devices under USB 3.0 host controller suspends
or resumes without a notification to hcd driver. However there may be
less opportunities for power savings and there may be increased latency
for restarting an endpoint. The precise impact will be different for
each xHC implementation. It all depends on what an implementation does
with the hints.

Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
  drivers/usb/core/generic.c | 10 --
  drivers/usb/core/hcd.c | 23 +++
  include/linux/usb/hcd.h| 11 ++-
  3 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c
index 358ca8d..92bee33 100644
--- a/drivers/usb/core/generic.c
+++ b/drivers/usb/core/generic.c
@@ -211,8 +211,12 @@ static int generic_suspend(struct usb_device *udev, 
pm_message_t msg)
/* Non-root devices don't need to do anything for FREEZE or PRETHAW */
else if (msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_PRETHAW)
rc = 0;
-   else
+   else {
+   hcd_notify(udev, HCD_MSG_DEV_SUSPEND, msg);
rc = usb_port_suspend(udev, msg);
+   if (rc)
+   hcd_notify(udev, HCD_MSG_DEV_RESUME, msg);
+   }
  
  	return rc;

  }
@@ -228,8 +232,10 @@ static int generic_resume(struct usb_device *udev, 
pm_message_t msg)
 */
if (!udev-parent)
rc = hcd_bus_resume(udev, msg);
-   else
+   else {
rc = usb_port_resume(udev, msg);
+   hcd_notify(udev, HCD_MSG_DEV_RESUME, msg);
+   }
return rc;
  }
  
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c

index 45a915c..725d611 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2289,6 +2289,29 @@ void usb_hcd_resume_root_hub (struct usb_hcd *hcd)
  }
  EXPORT_SYMBOL_GPL(usb_hcd_resume_root_hub);
  
+/**

+ * hcd_notify - notify hcd driver with a message
+ * @udev: USB device
+ * @type: message type of this notification
+ * @data: message type specific data
+ *
+ * Call back to hcd driver to notify an event.
+ */
+void hcd_notify(struct usb_device *udev,
+   enum hcd_notification_type type, void *data)
+{
+   struct usb_hcd *hcd;
+
+   if (!udev)
+   return;
+
+   hcd = bus_to_hcd(udev-bus);
+
+   if (hcd-driver-notify)
+   hcd-driver-notify(hcd, udev, type, data);
+}
+EXPORT_SYMBOL_GPL(hcd_notify);

Why does this have to be exported?

It doesn't have to be exported. I will remove it in v2.






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


Re: [PATCH v2 1/3] usb: notify hcd when USB device suspend or resume

2015-05-11 Thread Lu, Baolu



On 05/11/2015 10:25 PM, Alan Stern wrote:

On Sat, 9 May 2015, Lu, Baolu wrote:


If FSC is supported,  the cached Slot, Endpoint, Stream, or other
Context information are also saved.

Hence, when FSC is supported, software does not have to issue Stop
Endpoint Command to push public and private endpoint state into
memory as part of system suspend process.

Why do you have to push this state into memory at all?  Does the
controller hardware lose the cached state information when it is in low
power?

I don't think controller hardware will lose the cached state information
when it is in low power. But since cache in controller consumes power
and resources, by pushing state into memory, hardware can power
off the cache logic during suspend. Hence more power saving gains.


The logic in xhci_device_suspend() will look like:

if xhci_device_suspend() callback was called due to system suspend,
(mesg.event  PM_EVENT_SUSPEND is true) and FSC is supported by
the xHC implementation, xhci_device_suspend() could ignore stop
endpoint command, since CSS will be done in xhc_suspend() later and
where all the endpoint caches will be pushed to memory.

I still don't understand this.  You said earlier that according
to section 4.15.1.1 of the xHCI spec, the endpoint rings should
_always_ be stopped with SP set when a device is suspended.  Now you're

The intention of stop endpoint with SP set is to tell hardware that
a device is going to suspend, hardware don't need to contain the
endpoint state in internal cache anymore. Hardware _could_ use
this hint to push endpoint state into memory to reduce power
consumption.


saying that they don't need to be stopped during a system suspend if
the controller supports FSC.  (Or maybe you're saying they need to be
stopped but SP doesn't need to be set -- it's hard to tell.)

Even FSC is supported, controller hardware still need to push cached
endpoint state into memory when a USB device is suspended. The
difference is when FSC is enforced, CSS command will push any
cached endpoint state into memory unconditionally.

You said above that the hardware _could_ push endpoint state into
memory.  Now you're saying it _needs_ to do this!  Make up your mind.


I'm sorry that I confused you.

FSC is a different thing from what this patch series does.

I should say software could ask hardware to push endpoint
state into memory even FSC is supported. But in some cases,
it can be optimized as I will describe it below.





So, when xhci_device_suspend() knows that CSS command will be
executed later and CSS command will push cached endpoint state
into memory (a.k.a. FSC is enforced), it could skip issuing stop
endpoint command with SP bit set to avoid duplication and reduce
the suspend time.

This is the case for system suspend since CSS command is part of
xhci_suspend() and xhci_suspend() will be executed after all USB
devices have been suspended. But it's not case for run-time suspend
(auto-pm) since USB device suspend and host controller suspend
are independent for run-time case.

That's the reason why I wanted to keep 'msg' parameter. But just as
Greg said, we don't need to keep a parameter when it's not used
and can add it later when it is required.


So which is it?  Do you need to stop the endpoint rings?  Is it okay
not to set SP?

stop endpoint and stop endpoint with SP set serve different purposes
in Linux xhci driver as my understanding. stop endpoint command is
used to stop a active ring when upper layer want to cancel a URB.
stop endpoint with SP set is used to hint hardware that a USB is going
to suspend. Hence stop endpoint with SP set must be executed in case
that the transfer ring is empty.

(How does the contents of the transfer ring affect anything?  Besides,
there are never any active URBs when a device gets suspended, so the
transfer ring will _always_ be empty at such times.)

This is still extremely confusing.  You're not doing a good job of
explaining the situation clearly and logically.


I'm sorry for that.



Let's see if I understand it correctly:

When the controller goes into suspend, you want the cache to
be pushed into memory so that the cache can be powered down,
thereby saving additional energy.


Not the controller goes into suspend, but USB devices.

In order to talking to USB devices, xHCI has an endpoint state for each
endpoint of a device. When a USB device goes into suspend, xHC driver
could ask the hardware to push the state from cache to the memory.
Thereby saving additional energy. This is the intention of this patch 
series.




If the hardware supports FSC, this will happen automatically.

If the hardware doesn't support FSC, the cached data won't get
pushed to memory unless the driver tells the controller to do
so at the time the device is suspended.  But this will slow
things down, so the driver should avoid doing it when it's not
needed.

During system suspend you know

Re: [PATCH v4 3/3] usb: xhci: remove stop device and ring doorbell in hub control and bus suspend

2015-05-08 Thread Lu, Baolu



On 05/08/2015 07:01 PM, Greg Kroah-Hartman wrote:

On Fri, May 08, 2015 at 06:26:28PM +0800, Lu Baolu wrote:

There is no need to call xhci_stop_device() and xhci_ring_device() in
hub control and bus suspend functions since all device suspend and
resume have been notified through device_suspend/device_resume interfaces.

Does this mean that after patch 2, things are broken and require this
patch to prevent problems?


No. things work well without patch 3. stop device and ring doorbell
operations in hub control and bus suspend is harmless, but duplicated
and unnecessary, so I remove them.



I don't want to have any patch to make the system unstable.

thanks,

greg k-h


Thank you,
Baolu


--
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




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


Re: [PATCH v2 1/3] usb: notify hcd when USB device suspend or resume

2015-05-08 Thread Lu, Baolu



On 05/08/2015 10:21 PM, Alan Stern wrote:

On Fri, 8 May 2015, Lu, Baolu wrote:


On 05/07/2015 10:34 PM, Alan Stern wrote:

On Thu, 7 May 2015, Lu, Baolu wrote:


+   void(*device_suspend)(struct usb_hcd *, struct usb_device *udev,
+   pm_message_t msg);
+   void(*device_resume)(struct usb_hcd *, struct usb_device *udev,
+   pm_message_t msg);
};

Your callbacks don't use the msg argument.  What makes you think it is
needed?

This msg argument is valuable. XHCI spec defines a capability named FSC
(Force Save context Capability). When this capability is implemented, the
Save State operation (do during host suspend) shall save any cached Slot,
Endpoint, Stream or other Context information to memory. xHCI hcd could
use this msg to determine whether it needs to issue stop endpoint with
SP (suspend) bit set.

I don't understand.  What is the advantage of using FSC?

I'm sorry, I didn't make it clear.

As part of host suspend, controller save state will be issued to save
host internal state in xhci_suspend():

...


If FSC is supported,  the cached Slot, Endpoint, Stream, or other
Context information are also saved.

Hence, when FSC is supported, software does not have to issue Stop
Endpoint Command to push public and private endpoint state into
memory as part of system suspend process.

Why do you have to push this state into memory at all?  Does the
controller hardware lose the cached state information when it is in low
power?


I don't think controller hardware will lose the cached state information
when it is in low power. But since cache in controller consumes power
and resources, by pushing state into memory, hardware can power
off the cache logic during suspend. Hence more power saving gains.




The logic in xhci_device_suspend() will look like:

if xhci_device_suspend() callback was called due to system suspend,
(mesg.event  PM_EVENT_SUSPEND is true) and FSC is supported by
the xHC implementation, xhci_device_suspend() could ignore stop
endpoint command, since CSS will be done in xhc_suspend() later and
where all the endpoint caches will be pushed to memory.

I still don't understand this.  You said earlier that according
to section 4.15.1.1 of the xHCI spec, the endpoint rings should
_always_ be stopped with SP set when a device is suspended.  Now you're


The intention of stop endpoint with SP set is to tell hardware that
a device is going to suspend, hardware don't need to contain the
endpoint state in internal cache anymore. Hardware _could_ use
this hint to push endpoint state into memory to reduce power
consumption.


saying that they don't need to be stopped during a system suspend if
the controller supports FSC.  (Or maybe you're saying they need to be
stopped but SP doesn't need to be set -- it's hard to tell.)


Even FSC is supported, controller hardware still need to push cached
endpoint state into memory when a USB device is suspended. The
difference is when FSC is enforced, CSS command will push any
cached endpoint state into memory unconditionally.

So, when xhci_device_suspend() knows that CSS command will be
executed later and CSS command will push cached endpoint state
into memory (a.k.a. FSC is enforced), it could skip issuing stop
endpoint command with SP bit set to avoid duplication and reduce
the suspend time.

This is the case for system suspend since CSS command is part of
xhci_suspend() and xhci_suspend() will be executed after all USB
devices have been suspended. But it's not case for run-time suspend
(auto-pm) since USB device suspend and host controller suspend
are independent for run-time case.

That's the reason why I wanted to keep 'msg' parameter. But just as
Greg said, we don't need to keep a parameter when it's not used
and can add it later when it is required.



So which is it?  Do you need to stop the endpoint rings?  Is it okay
not to set SP?


stop endpoint and stop endpoint with SP set serve different purposes
in Linux xhci driver as my understanding. stop endpoint command is
used to stop a active ring when upper layer want to cancel a URB.
stop endpoint with SP set is used to hint hardware that a USB is going
to suspend. Hence stop endpoint with SP set must be executed in case
that the transfer ring is empty.



Alan Stern


Thank you,
Baolu






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


[PATCH v5 3/3] usb: xhci: remove stop device and ring doorbell in hub control and bus suspend

2015-05-08 Thread Lu Baolu
There is no need to call xhci_stop_device() and xhci_ring_device() in
hub control and bus suspend functions since all device suspend and
resume have been notified through device_suspend/device_resume interfaces.

Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
 drivers/usb/host/xhci-hub.c | 47 -
 1 file changed, 47 deletions(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index a83e82e..f12e1b7 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -704,7 +704,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 
wValue,
u32 temp, status;
int retval = 0;
__le32 __iomem **port_array;
-   int slot_id;
struct xhci_bus_state *bus_state;
u16 link_state = 0;
u16 wake_mask = 0;
@@ -818,17 +817,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 
wValue,
goto error;
}
 
-   slot_id = xhci_find_slot_id_by_port(hcd, xhci,
-   wIndex + 1);
-   if (!slot_id) {
-   xhci_warn(xhci, slot_id is zero\n);
-   goto error;
-   }
-   /* unlock to execute stop endpoint commands */
-   spin_unlock_irqrestore(xhci-lock, flags);
-   xhci_stop_device(xhci, slot_id, 1);
-   spin_lock_irqsave(xhci-lock, flags);
-
xhci_set_link_state(xhci, port_array, wIndex, XDEV_U3);
 
spin_unlock_irqrestore(xhci-lock, flags);
@@ -876,19 +864,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 
wValue,
goto error;
}
 
-   if (link_state == USB_SS_PORT_LS_U3) {
-   slot_id = xhci_find_slot_id_by_port(hcd, xhci,
-   wIndex + 1);
-   if (slot_id) {
-   /* unlock to execute stop endpoint
-* commands */
-   spin_unlock_irqrestore(xhci-lock,
-   flags);
-   xhci_stop_device(xhci, slot_id, 1);
-   spin_lock_irqsave(xhci-lock, flags);
-   }
-   }
-
xhci_set_link_state(xhci, port_array, wIndex,
link_state);
 
@@ -994,14 +969,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 
wValue,
XDEV_U0);
}
bus_state-port_c_suspend |= 1  wIndex;
-
-   slot_id = xhci_find_slot_id_by_port(hcd, xhci,
-   wIndex + 1);
-   if (!slot_id) {
-   xhci_dbg(xhci, slot_id is zero\n);
-   goto error;
-   }
-   xhci_ring_device(xhci, slot_id);
break;
case USB_PORT_FEAT_C_SUSPEND:
bus_state-port_c_suspend = ~(1  wIndex);
@@ -1133,20 +1100,12 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
while (port_index--) {
/* suspend the port if the port is not suspended */
u32 t1, t2;
-   int slot_id;
 
t1 = readl(port_array[port_index]);
t2 = xhci_port_state_to_neutral(t1);
 
if ((t1  PORT_PE)  !(t1  PORT_PLS_MASK)) {
xhci_dbg(xhci, port %d not suspended\n, port_index);
-   slot_id = xhci_find_slot_id_by_port(hcd, xhci,
-   port_index + 1);
-   if (slot_id) {
-   spin_unlock_irqrestore(xhci-lock, flags);
-   xhci_stop_device(xhci, slot_id, 1);
-   spin_lock_irqsave(xhci-lock, flags);
-   }
t2 = ~PORT_PLS_MASK;
t2 |= PORT_LINK_STROBE | XDEV_U3;
set_bit(port_index, bus_state-bus_suspended);
@@ -1207,7 +1166,6 @@ int xhci_bus_resume(struct usb_hcd *hcd)
/* Check whether need resume ports. If needed
   resume port and disable remote wakeup */
u32 temp;
-   int slot_id;
 
temp = readl(port_array[port_index]);
if (DEV_SUPERSPEED(temp))
@@ -1240,11 +1198,6 @@ int xhci_bus_resume(struct usb_hcd *hcd)
/* Clear PLC

[PATCH v5 1/3] usb: notify hcd when USB device suspend or resume

2015-05-08 Thread Lu Baolu
This patch adds two new entries in hc_driver. With these new entries,
USB core can notify host driver when a USB device is about to suspend
or just resumed.

The xHCI spec is designed to allow an xHC implementation to cache the
endpoint state. Caching endpoint state allows an xHC to reduce latency
when handling ERDYs and other USB asynchronous events. However holding
this state in xHC consumes resources and power. The xHCI spec designs
some methods through which host controller driver can hint xHC about
how to optimize its operation, e.g. to determine when it holds state
internally or pushes it out to memory, when to power down logic, etc.

When a USB device is going to suspend, states of all endpoints cached
in the xHC should be pushed out to memory to save power and resources.
Vice versa, when a USB device resumes, those states should be brought
back to the cache. USB core suspends or resumes a USB device by sending
set/clear port feature requests to the parent hub where the USB device
is connected. Unfortunately, these operations are transparent to xHCI
driver unless the USB device is plugged in a root port. This patch
utilizes the callback entries to notify xHCI driver whenever a USB
device suspends or resumes.

It is harmless if a USB devices under USB 3.0 host controller suspends
or resumes without a notification to hcd driver. However there may be
less opportunities for power savings and there may be increased latency
for restarting an endpoint. The precise impact will be different for
each xHC implementation. It all depends on what an implementation does
with the hints.

Signed-off-by: Lu Baolu baolu...@linux.intel.com
Acked-by: Alan Stern st...@rowland.harvard.edu
---
 drivers/usb/core/hcd.c  | 27 +++
 drivers/usb/core/hub.c  |  5 +
 include/linux/usb/hcd.h |  8 +++-
 3 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 45a915c..007450d 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2289,6 +2289,33 @@ void usb_hcd_resume_root_hub (struct usb_hcd *hcd)
 }
 EXPORT_SYMBOL_GPL(usb_hcd_resume_root_hub);
 
+/**
+ * hcd_suspend_notify - notify hcd driver when a device is going to suspend
+ * @udev: USB device to be suspended
+ *
+ * Call back to hcd driver to notify that a USB device is going to suspend.
+ */
+void hcd_suspend_notify(struct usb_device *udev)
+{
+   struct usb_hcd *hcd = bus_to_hcd(udev-bus);
+
+   if (hcd-driver-device_suspend)
+   hcd-driver-device_suspend(hcd, udev);
+}
+
+/**
+ * hcd_resume_notify - notify hcd driver when a device is just resumed
+ * @udev: USB device just resumed
+ *
+ * Call back to hcd driver to notify that a USB device is just resumed.
+ */
+void hcd_resume_notify(struct usb_device *udev)
+{
+   struct usb_hcd *hcd = bus_to_hcd(udev-bus);
+
+   if (hcd-driver-device_resume)
+   hcd-driver-device_resume(hcd, udev);
+}
 #endif /* CONFIG_PM */
 
 /*-*/
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 52178bc..28d76b7 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -3149,6 +3149,8 @@ int usb_port_suspend(struct usb_device *udev, 
pm_message_t msg)
goto err_lpm3;
}
 
+   hcd_suspend_notify(udev);
+
/* see 7.1.7.6 */
if (hub_is_superspeed(hub-hdev))
status = hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_U3);
@@ -3174,6 +3176,8 @@ int usb_port_suspend(struct usb_device *udev, 
pm_message_t msg)
if (status) {
dev_dbg(port_dev-dev, can't suspend, status %d\n, status);
 
+   hcd_resume_notify(udev);
+
/* Try to enable USB3 LPM and LTM again */
usb_unlocked_enable_lpm(udev);
  err_lpm3:
@@ -3427,6 +3431,7 @@ int usb_port_resume(struct usb_device *udev, pm_message_t 
msg)
}
 
  SuspendCleared:
+   hcd_resume_notify(udev);
if (status == 0) {
udev-port_is_suspended = 0;
if (hub_is_superspeed(hub-hdev)) {
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index 68b1e83..bc2eb1c 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -383,7 +383,11 @@ struct hc_driver {
int (*find_raw_port_number)(struct usb_hcd *, int);
/* Call for power on/off the port if necessary */
int (*port_power)(struct usb_hcd *hcd, int portnum, bool enable);
-
+   /* Call back to hcd when a USB device is going to suspend or just
+* resumed.
+*/
+   void(*device_suspend)(struct usb_hcd *, struct usb_device *udev);
+   void(*device_resume)(struct usb_hcd *, struct usb_device *udev);
 };
 
 static inline int hcd_giveback_urb_in_bh(struct usb_hcd *hcd)
@@ -632,6 +636,8 @@ extern void usb_root_hub_lost_power(struct usb_device 
*rhdev);
 extern int hcd_bus_suspend

[PATCH v5 2/3] usb: xhci: implement device_suspend/device_resume entries

2015-05-08 Thread Lu Baolu
This patch implements device_suspend/device_resume entries for xHC driver.
device_suspend will be called when a USB device is about to suspend. It
will issue a stop endpoint command for each endpoint in this device. The
Suspend(SP) bit in the command TRB will set which will give xHC a hint
about the suspend. device_resume will be called when a USB device is just
resumed. It will ring doorbells of all endpoint unconditionally. XHC may
use these suspend/resume hints to optimize its operation.

Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
 drivers/usb/host/xhci-hub.c |  2 +-
 drivers/usb/host/xhci.c | 38 ++
 drivers/usb/host/xhci.h |  9 +
 3 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 0827d7c..a83e82e 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -266,7 +266,7 @@ int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct 
xhci_hcd *xhci,
  * to complete.
  * suspend will set to 1, if suspend bit need to set in command.
  */
-static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)
+int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)
 {
struct xhci_virt_device *virt_dev;
struct xhci_command *cmd;
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index ec8ac16..330961d 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -4680,6 +4680,38 @@ int xhci_disable_usb3_lpm_timeout(struct usb_hcd *hcd,
return ret;
return 0;
 }
+
+/*
+ * xHCI compatible host controller driver expects to be notified prior to
+ * selectively suspending a device. xHCI hcd could optimize the endpoint
+ * cache for power saving purpose. Refer to 4.15.1.1 of xHCI 1.1.
+ */
+void xhci_device_suspend(struct usb_hcd *hcd, struct usb_device *udev)
+{
+   struct xhci_hcd *xhci;
+
+   xhci = hcd_to_xhci(hcd);
+   if (!xhci || !xhci-devs[udev-slot_id])
+   return;
+
+   xhci_stop_device(xhci, udev-slot_id, 1);
+}
+
+/*
+ * xHCI compatible host controller driver expects to be notified after a
+ * USB device is resumed. xHCI hcd could optimize the endpoint cache
+ * to reduce the latency. Refer to 4.15.1.1 of xHCI 1.1.
+ */
+void xhci_device_resume(struct usb_hcd *hcd, struct usb_device *udev)
+{
+   struct xhci_hcd *xhci;
+
+   xhci = hcd_to_xhci(hcd);
+   if (!xhci || !xhci-devs[udev-slot_id])
+   return;
+
+   xhci_ring_device(xhci, udev-slot_id);
+}
 #else /* CONFIG_PM */
 
 int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
@@ -4976,6 +5008,12 @@ static const struct hc_driver xhci_hc_driver = {
.enable_usb3_lpm_timeout =  xhci_enable_usb3_lpm_timeout,
.disable_usb3_lpm_timeout = xhci_disable_usb3_lpm_timeout,
.find_raw_port_number = xhci_find_raw_port_number,
+
+   /*
+* call back when devices suspend or resume
+*/
+   .device_suspend =   xhci_device_suspend,
+   .device_resume =xhci_device_resume,
 };
 
 void xhci_init_driver(struct hc_driver *drv, int (*setup_fn)(struct usb_hcd *))
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 8e421b8..67c13c5 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1867,10 +1867,19 @@ u32 xhci_port_state_to_neutral(u32 state);
 int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci,
u16 port);
 void xhci_ring_device(struct xhci_hcd *xhci, int slot_id);
+int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend);
 
 /* xHCI contexts */
 struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct 
xhci_container_ctx *ctx);
 struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct 
xhci_container_ctx *ctx);
 struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, struct 
xhci_container_ctx *ctx, unsigned int ep_index);
 
+#ifdef CONFIG_PM
+void xhci_device_suspend(struct usb_hcd *hcd, struct usb_device *udev);
+void xhci_device_resume(struct usb_hcd *hcd, struct usb_device *udev);
+#else
+#define xhci_device_suspendNULL
+#define xhci_device_resume NULL
+#endif /* CONFIG_PM */
+
 #endif /* __LINUX_XHCI_HCD_H */
-- 
2.1.0

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


[PATCH v5 0/3] usb: notify hcd when USB device suspend or resume

2015-05-08 Thread Lu Baolu
This patch series try to meet a design requirement in xHCI spec.

The xHCI spec is designed to allow an xHC implementation to cache the
endpoint state. Caching endpoint state allows an xHC to reduce latency
when handling ERDYs and other USB asynchronous events. However holding
this state in xHC consumes resources and power. The xHCI spec designs
some methods through which host controller driver can hint xHC about
how to optimize its operation, e.g. to determine when it holds state
internally or pushes it out to memory, when to power down logic, etc.

When a USB device is going to suspend, states of all endpoints cached
in the xHC should be pushed out to memory to save power and resources.
Vice versa, when a USB device resumes, those states should be brought
back to the cache.

It is harmless if a USB devices under USB 3.0 host controller suspends
or resumes without a notification to hcd driver. However there may be
less opportunities for power savings and there may be increased latency
for restarting an endpoint. The precise impact will be different for
each xHC implementation. It all depends on what an implementation does
with the hints.

Change log:
v4-v5:
 - add Alan's ACK for 1/3

v3-v4:
 - remove unused 'msg' parameter in the callbacks

v2-v3:
 - move two xhci specific comments from hub to xhci
 - define xhci_device_suspend(resume) as NULL when no PM_CONFIG

v1-v2:
 - make the callback name specific to the activity in question
 - no need to export hcd_notify
 - put the callback in the right place

Lu Baolu (3):
  usb: notify hcd when USB device suspend or resume
  usb: xhci: implement device_suspend/device_resume entries
  usb: xhci: remove stop device and ring doorbell in hub control and bus
suspend

 drivers/usb/core/hcd.c  | 27 +
 drivers/usb/core/hub.c  |  5 +
 drivers/usb/host/xhci-hub.c | 49 +
 drivers/usb/host/xhci.c | 38 +++
 drivers/usb/host/xhci.h |  9 +
 include/linux/usb/hcd.h |  8 +++-
 6 files changed, 87 insertions(+), 49 deletions(-)

-- 
2.1.0

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


Re: [PATCH v2 1/3] usb: notify hcd when USB device suspend or resume

2015-05-12 Thread Lu, Baolu



On 05/12/2015 11:54 PM, Alan Stern wrote:

On Tue, 12 May 2015, Lu, Baolu wrote:


I'm sorry that I confused you.

FSC is a different thing from what this patch series does.

I know that.  The patch series, in its current form, is fine.  Now I'm
trying to understand what you originally wanted to do.


Let's see if I understand it correctly:

When the controller goes into suspend, you want the cache to
be pushed into memory so that the cache can be powered down,
thereby saving additional energy.

Not the controller goes into suspend, but USB devices.

Suppose a USB device goes into runtime suspend, and suppose the
hardware pushes the cached information for the endpoints on that device
into memory.  The cache will still contain information for other,
non-suspended devices.  Consequently the cache _can't_ be powered down
at this time, right?  You seem to be saying:

When a USB device goes into suspend, you want the cache to
be pushed into memory so that the cache can be powered down,
thereby saving additional energy.

But that is just wrong!  The only time you know the hardware can safely
power-down the cache is when the _controller_ goes into suspend.  At
that time you _know_ all the attached devices are suspended, so the
cache isn't needed.

Therefore, when the controller goes into suspend, you want to make sure
that the cache has been pushed into memory.  The actual push operation
can occur earlier, during xhci_device_suspend, but the time when the
information's location matters is during xhci_suspend.


In order to talking to USB devices, xHCI has an endpoint state for each
endpoint of a device. When a USB device goes into suspend, xHC driver
could ask the hardware to push the state from cache to the memory.
Thereby saving additional energy. This is the intention of this patch
series.

You don't save any energy when the _device_ goes into suspend.  You
save energy only when the _controller_ goes into suspend, because
that's the only time when the cache can be powered down.  Right?


Yes, I agree with you.

Hardware could only power down the cache after all data has been
pushed out. That could happen during host suspend as far as I can see.




If the hardware supports FSC, this will happen automatically.

If the hardware doesn't support FSC, the cached data won't get
pushed to memory unless the driver tells the controller to do
so at the time the device is suspended.  But this will slow
things down, so the driver should avoid doing it when it's not
needed.

During system suspend you know in advance that the controller
will be suspended.  Therefore the driver should push the cache
to memory if the hardware doesn't support FSC.  During runtime
suspend you don't know in advance whether the controller will
be suspended, so the driver should not push the cache to
memory.

But what happens in the case where all the devices have gone
into runtime suspend, so the controller also goes into runtime
suspend, and the hardware doesn't support FSC?  It seems that
in this case the cache would have to remain powered on.

FSC is not part of this patch series. It was introduced when I tried to
explain the reason why I kept 'msg' parameter in the callback.

If the hardware support FSC, another operation named save context
operation will push everything in hardware cache into memory. So when
a USB device is going to suspend and xhci_device_suspend() callback is
being called, software can do an optimization. That is, if save context
operation will push everything in hardware cache to memory later,
xhci_device_suspend() could skip asking hardware for cache operation
and let save context operation do it later.

That's more or less the same as what I wrote above, except that I said
it would happen automatically if the hardware supports FSC.  It isn't
automatic; it requires the driver to issue a save context operation
command.


Yes, exactly.




One example of this situation is system suspend. During system suspend,
below process will be done for a USB3 fabric.

1) all USB devices suspend
2) root hub suspend
3) host controller suspend

In 1), xhci_device_suspend() call back will be called for each device
suspend.
In 3) save context operation will be executed.

In this case, if FSC is supported, xhci_device_suspend() could skip asking
host hardware for cache operation.

That's basically what I said.

But now why should msg matter?  It seems that xhci_device_suspend()
should skip asking for the cache operation whenever FSC is supported,
regardless of whether you're talking about runtime suspend or system
suspend.


In runtime case, a USB device could be selected to suspend while host
controller is busy with other USB devices. Since FSC only impacts the
behavior of save context operation, it's probably that a USB device
is selectively suspended while it's

Re: [PATCH 1/1] usb: ulpi: ulpi_init should be used in subsys_initcall

2015-05-21 Thread Lu, Baolu



On 05/21/2015 03:33 PM, Heikki Krogerus wrote:

On Thu, May 21, 2015 at 01:40:43PM +0800, Lu Baolu wrote:

The intention of this change is to fix below kernel panic when
USB_ULPI_BUS was configured as buildin.

That is actually incorrect. Having the bus build-in does not cause
this panic..


[0.746856] kernel BUG at drivers/base/driver.c:153!
[0.752418] invalid opcode:  [#1] PREEMPT SMP
[0.757804] Modules linked in:
[0.893985] Call Trace:
[0.896729]  [81870cb1] ? ulpi_register_driver+0x21/0x30
[0.903654]  [823d5cac] tusb1210_driver_init+0x10/0x12
[0.910386]  [81000318] do_one_initcall+0xd8/0x200
[0.916729]  [8239b094] kernel_init_freeable+0x196/0x21e
[0.923655]  [81affed0] ? rest_init+0x90/0x90
[0.929509]  [81affede] kernel_init+0xe/0xf0
[0.935266]  [81b0f442] ret_from_fork+0x42/0x70
[0.941315]  [81affed0] ? rest_init+0x90/0x90

This happens if the PHY drivers are build-in. If the bus is build-in,
but the drivers are modules, you are still fine.


I ever tried the config of bus =y and driver =n. It results in
panic as well. The call trace looks like below.

1.058876]  [8165a6d2] device_add+0x402/0x640
[1.064829]  [8165a92e] device_register+0x1e/0x30
[1.071072]  [81870bdc] ulpi_register_interface+0x14c/0x1f0
[1.078291]  [817c68d4] dwc3_ulpi_init+0x24/0x60
[1.084437]  [817be052] dwc3_probe+0x802/0x1650
[1.090487]  [8165fb54] platform_drv_probe+0x34/0xa0
[1.097022]  [8165d9e9] driver_probe_device+0x209/0x4b0
[1.103850]  [8165dc90] ? driver_probe_device+0x4b0/0x4b0
[1.110871]  [8165dccb] __device_attach+0x3b/0x40
[1.117114]  [8165b6d3] bus_for_each_drv+0x63/0xa0
[1.123454]  [8165d778] device_attach+0x98/0xb0
[1.129503]  [8165cb60] bus_probe_device+0xa0/0xc0
[1.135843]  [8165a73f] device_add+0x46f/0x640
[1.141799]  [81090fe0] ? __insert_resource+0x60/0x150
[1.148530]  [8165f780] platform_device_add+0xd0/0x2b0
[1.155260]  [817c7386] dwc3_pci_probe+0xf6/0x2c0
[1.161505]  [8149d86c] pci_device_probe+0x8c/0xf0
[1.167846]  [8165d9e9] driver_probe_device+0x209/0x4b0
[1.174673]  [8165dd6b] __driver_attach+0x9b/0xa0
[1.180917]  [8165dcd0] ? __device_attach+0x40/0x40
[1.187354]  [8165b60b] bus_for_each_dev+0x6b/0xb0
[1.193694]  [8165d2be] driver_attach+0x1e/0x20
[1.199742]  [8165ce80] bus_add_driver+0x180/0x250
[1.206086]  [823e453c] ? 
ftrace_define_fields_dwc3_log_trb+0x126/0x126

[1.214474]  [8165e5d4] driver_register+0x64/0xf0
[1.220718]  [8149c51b] __pci_register_driver+0x4b/0x50
[1.227546]  [823e4555] dwc3_pci_driver_init+0x19/0x1b
[1.234277]  [81000318] do_one_initcall+0xd8/0x200
[1.240619]  [8239b094] kernel_init_freeable+0x196/0x21e
[1.247545]  [81affbd0] ? rest_init+0x90/0x90
[1.253399]  [81affbde] kernel_init+0xe/0xf0
[1.259156]  [81b0f142] ret_from_fork+0x42/0x70
[1.265205]  [81affbd0] ? rest_init+0x90/0x90



Maybe it would have been better to explain that this is addressing an
issue with the execution sequence, and consider Sasha's patch as the
actual fix for panic.


Fair enough. I will resend the patch.




Thanks guys,



Thanks,
Baolu
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/1] usb: ulpi: ulpi_init should be used in subsys_initcall

2015-05-20 Thread Lu Baolu
The intention of this change is to fix below kernel panic when
USB_ULPI_BUS was configured as buildin.

[0.746856] kernel BUG at drivers/base/driver.c:153!
[0.752418] invalid opcode:  [#1] PREEMPT SMP
[0.757804] Modules linked in:
[0.893985] Call Trace:
[0.896729]  [81870cb1] ? ulpi_register_driver+0x21/0x30
[0.903654]  [823d5cac] tusb1210_driver_init+0x10/0x12
[0.910386]  [81000318] do_one_initcall+0xd8/0x200
[0.916729]  [8239b094] kernel_init_freeable+0x196/0x21e
[0.923655]  [81affed0] ? rest_init+0x90/0x90
[0.929509]  [81affede] kernel_init+0xe/0xf0
[0.935266]  [81b0f442] ret_from_fork+0x42/0x70
[0.941315]  [81affed0] ? rest_init+0x90/0x90

Reported-by: Zhuo Qiuxu qiuxu.z...@intel.com
Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
 drivers/usb/common/ulpi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c
index 0e6f968..01c0c04 100644
--- a/drivers/usb/common/ulpi.c
+++ b/drivers/usb/common/ulpi.c
@@ -242,7 +242,7 @@ static int __init ulpi_init(void)
 {
return bus_register(ulpi_bus);
 }
-module_init(ulpi_init);
+subsys_initcall(ulpi_init);
 
 static void __exit ulpi_exit(void)
 {
-- 
2.1.4

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


Re: [PATCH] usb: ulpi: don't register drivers if bus doesn't exist

2015-05-21 Thread Lu, Baolu



On 05/21/2015 05:22 AM, David Cohen wrote:

Hi,

On Wed, May 20, 2015 at 03:33:26PM -0400, Sasha Levin wrote:

ULPI registers it's bus at module_init so if the bus fails to register, the

A minor comment: s/it's/its/


module will fail to load and all will be well in the world.

However, if the ULPI code is built-in rather than a module, the bus
initialization may fail but we'd still try to register drivers later onto
a non-existant bus, which will panic the kernel.

Fix that by checking that the bus was indeed initialized before trying to
register drivers on top of it.

Signed-off-by: Sasha Levin sasha.le...@oracle.com
---
  drivers/usb/common/ulpi.c |4 
  1 file changed, 4 insertions(+)

diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c
index 0e6f968..0b0a5e7 100644
--- a/drivers/usb/common/ulpi.c
+++ b/drivers/usb/common/ulpi.c
@@ -132,6 +132,10 @@ int ulpi_register_driver(struct ulpi_driver *drv)
if (!drv-probe)
return -EINVAL;
  
+	/* Was the bus registered successfully? */

+   if (!ulpi_bus.p)
+   return -ENODEV;
+

Good catch. Otherwise it may trigger BUG() on driver_register().
I wonder if it would be nice to have a macro for that checking :)

Anyway,

Reviewed-by: David Cohen david.a.co...@linux.intel.com


Well, I was also encountering panic issue when running it on
Intel Bay Trail tablets. In my case, it's due to the execution
sequence. When ulpi bus is built-in, driver or device registered
before ulpi bus registration.

Thanks,
Baolu




drv-driver.bus = ulpi_bus;
  
  	return driver_register(drv-driver);

--
1.7.10.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




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


[PATCH 1/1] usb: ulpi: don't register drivers if bus doesn't exist

2015-05-21 Thread Lu Baolu
ULPI registers its bus at module_init, so if the bus fails to register, the
module will fail to load and all will be well in the world.

However, if the ULPI code is built-in rather than a module, the bus
initialization may fail, but we'd still try to register drivers later onto
a non-existent bus, which will panic the kernel.

Fix that by checking that the bus was indeed initialized before trying to
register drivers on top of it.

Signed-off-by: Sasha Levin sasha.le...@oracle.com
Signed-off-by: Heikki Krogerus heikki.kroge...@linux.intel.com
Signed-off-by: Lu Baolu baolu...@linux.intel.com
Reported-by: Zhuo Qiuxu qiuxu.z...@intel.com
Reviewed-by: David Cohen david.a.co...@linux.intel.com
---
 drivers/usb/common/ulpi.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c
index 0e6f968..af52b46 100644
--- a/drivers/usb/common/ulpi.c
+++ b/drivers/usb/common/ulpi.c
@@ -132,6 +132,10 @@ int ulpi_register_driver(struct ulpi_driver *drv)
if (!drv-probe)
return -EINVAL;
 
+   /* Was the bus registered successfully? */
+   if (unlikely(WARN_ON(!ulpi_bus.p)))
+   return -ENODEV;
+
drv-driver.bus = ulpi_bus;
 
return driver_register(drv-driver);
@@ -242,7 +246,7 @@ static int __init ulpi_init(void)
 {
return bus_register(ulpi_bus);
 }
-module_init(ulpi_init);
+subsys_initcall(ulpi_init);
 
 static void __exit ulpi_exit(void)
 {
-- 
2.1.4

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


Re: [PATCH v4 1/1] usb: ulpi: ulpi_init should be executed in subsys_initcall

2015-06-04 Thread Lu, Baolu


On 06/04/2015 08:17 PM, Heikki Krogerus wrote:

Hi Baolu,

On Thu, May 28, 2015 at 08:50:12AM +0800, Lu, Baolu wrote:

On 05/28/2015 12:53 AM, David Cohen wrote:

Hi,

On Tue, May 26, 2015 at 07:37:02PM -0700, Greg Kroah-Hartman wrote:

On Wed, May 27, 2015 at 09:45:37AM +0800, Lu Baolu wrote:

Phy drivers and the ulpi interface providers depend on the
registration of the ulpi bus.  Ulpi registers the bus in
module_init(). This could cause unnecessary probe delays.

What do you mean by probe delays?

I believe he meant the bus users' probe delays. i.e. unnecessary
-EPROBE_DEFER happening on ulpi_drivers in case they're registered
before ulpi bus itself.

Is that correct, Baolu?

Yes.

Could you prepare one more version of this patche with the change log
included.


Sure. I will resent it soon.




Thanks,



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


Re: [PATCH v5 3/3] usb: xhci: remove stop device and ring doorbell in hub control and bus suspend

2015-06-25 Thread Lu, Baolu



On 06/25/2015 10:53 PM, Mathias Nyman wrote:

On 09.05.2015 04:15, Lu Baolu wrote:

There is no need to call xhci_stop_device() and xhci_ring_device() in
hub control and bus suspend functions since all device suspend and
resume have been notified through device_suspend/device_resume interfaces.

I was looking through this code again before sending it forward, and it 
occurred to
me that this might be breaking the PORT_SUSPEND and PORT_SET_LINK_STATE port 
features
for xhci root hub.

In normal use these requests are called by usb core in usb_port_suspend(), which
also now notifies xhci, which makes sure xhci_stop_device() is called.

But I don't think there is anything preventing an URB to be sent to the xhci 
roothub
with a PORT_SUSPEND or PORT_SET_LINK_STATE port feature request. In this case 
the usb_port_suspend()
is not called, and no notify will stop the device.

For example hub validation tests might do this.


If that, we can drop this patch. It doesn't impact the other two patches 
in this patch series.


Thanks,
Baolu


-Mathias



--
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



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


Re: [PATCH 1/1] usb: core: lpm: set lpm_capable for root hub device

2015-06-12 Thread Lu, Baolu



On 06/12/2015 12:32 PM, Greg Kroah-Hartman wrote:

On Fri, Jun 12, 2015 at 09:29:37AM +0800, Lu Baolu wrote:

Commit 25cd2882e2fc (usb/xhci: Change how we indicate a host supports
Link PM.) removed the code to set lpm_capable for USB 3.0 super-speed
root hub. The intention of that change was to avoid touching usb core
internal field, a.k.a. lpm_capable, and let usb core to set it by
checking U1 and U2 exit latency values in the descriptor.

Usb core checks and sets lpm_capable in hub_port_init(). Unfortunately,
root hub is a special usb device as it has no parent. Hub_port_init()
will never be called for a root hub device. That means lpm_capable will
by no means be set for the root hub. As the result, lpm isn't functional
at all in Linux kernel.

This patch add the code to check and set lpm_capable when registering a
root hub device. It could be back-ported to kernels as old as v3.15,
that contains the Commit 25cd2882e2fc (usb/xhci: Change how we indicate
a host supports Link PM.).

Cc: sta...@vger.kernel.org # 3.15
Reported-by: Kevin Strasser kevin.stras...@linux.intel.com
Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
  drivers/usb/core/hcd.c | 6 ++
  drivers/usb/core/hub.c | 2 +-
  drivers/usb/core/usb.h | 1 +
  3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 45a915c..48b208d 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1032,6 +1032,12 @@ static int register_root_hub(struct usb_hcd *hcd)
}
}
  
+	if (le16_to_cpu(usb_dev-descriptor.bcdUSB) = 0x0201) {

Why are you treating a binary coded value as a hex number to compare
against?


The value of the bcdUSB field is 0xJJMN for version JJ.M.N, where
JJ – major version number,
M – minor version number,
N – sub-minor version number

I saw several places in usb core where it is treated as a hex and
check the version requirement like this. Do you want me to
separate it into three numbers and check major/minor/sub-minor
versions separately?

Thanks,
Baolu


--
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




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


[PATCH v2 1/1] usb: core: lpm: set lpm_capable for root hub device

2015-06-13 Thread Lu Baolu
Commit 25cd2882e2fc (usb/xhci: Change how we indicate a host supports
Link PM.) removed the code to set lpm_capable for USB 3.0 super-speed
root hub. The intention of that change was to avoid touching usb core
internal field, a.k.a. lpm_capable, and let usb core to set it by
checking U1 and U2 exit latency values in the descriptor.

Usb core checks and sets lpm_capable in hub_port_init(). Unfortunately,
root hub is a special usb device as it has no parent. Hub_port_init()
will never be called for a root hub device. That means lpm_capable will
by no means be set for the root hub. As the result, lpm isn't functional
at all in Linux kernel.

This patch add the code to check and set lpm_capable when registering a
root hub device. It could be back-ported to kernels as old as v3.15,
that contains the Commit 25cd2882e2fc (usb/xhci: Change how we indicate
a host supports Link PM.).

Cc: sta...@vger.kernel.org # 3.15
Reported-by: Kevin Strasser kevin.stras...@linux.intel.com
Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
 drivers/usb/core/hcd.c | 7 +--
 drivers/usb/core/hub.c | 2 +-
 drivers/usb/core/usb.h | 6 ++
 3 files changed, 12 insertions(+), 3 deletions(-)

 v1-v2 change log:
 1. two code blocks merged (Alan's feedback)
 2. fix build error when CONFIG_PM is not set (Alan's feedback)

diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 45a915c..1c1385e 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1022,9 +1022,12 @@ static int register_root_hub(struct usb_hcd *hcd)
dev_name(usb_dev-dev), retval);
return (retval  0) ? retval : -EMSGSIZE;
}
-   if (usb_dev-speed == USB_SPEED_SUPER) {
+
+   if (le16_to_cpu(usb_dev-descriptor.bcdUSB) = 0x0201) {
retval = usb_get_bos_descriptor(usb_dev);
-   if (retval  0) {
+   if (!retval) {
+   usb_dev-lpm_capable = usb_device_supports_lpm(usb_dev);
+   } else if (usb_dev-speed == USB_SPEED_SUPER) {
mutex_unlock(usb_bus_list_lock);
dev_dbg(parent_dev, can't read %s bos descriptor %d\n,
dev_name(usb_dev-dev), retval);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 3b71516..884d702 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -122,7 +122,7 @@ struct usb_hub *usb_hub_to_struct_hub(struct usb_device 
*hdev)
return usb_get_intfdata(hdev-actconfig-interface[0]);
 }
 
-static int usb_device_supports_lpm(struct usb_device *udev)
+int usb_device_supports_lpm(struct usb_device *udev)
 {
/* USB 2.1 (and greater) devices indicate LPM support through
 * their USB 2.0 Extended Capabilities BOS descriptor.
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 7eb1e26..d54a669 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -82,6 +82,7 @@ extern int usb_runtime_suspend(struct device *dev);
 extern int usb_runtime_resume(struct device *dev);
 extern int usb_runtime_idle(struct device *dev);
 extern int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable);
+extern int usb_device_supports_lpm(struct usb_device *udev);
 
 #else
 
@@ -106,6 +107,11 @@ static inline int usb_set_usb2_hardware_lpm(struct 
usb_device *udev, int enable)
return 0;
 }
 
+static inline int usb_device_supports_lpm(struct usb_device *udev)
+{
+   return 0;
+}
+
 #endif
 
 extern struct bus_type usb_bus_type;
-- 
2.1.4

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


Re: [PATCH 1/1] usb: core: lpm: set lpm_capable for root hub device

2015-06-12 Thread Lu, Baolu



On 06/13/2015 01:43 AM, Alan Stern wrote:

On Fri, 12 Jun 2015, Lu Baolu wrote:


Commit 25cd2882e2fc (usb/xhci: Change how we indicate a host supports
Link PM.) removed the code to set lpm_capable for USB 3.0 super-speed
root hub. The intention of that change was to avoid touching usb core
internal field, a.k.a. lpm_capable, and let usb core to set it by
checking U1 and U2 exit latency values in the descriptor.

Usb core checks and sets lpm_capable in hub_port_init(). Unfortunately,
root hub is a special usb device as it has no parent. Hub_port_init()
will never be called for a root hub device. That means lpm_capable will
by no means be set for the root hub. As the result, lpm isn't functional
at all in Linux kernel.

This patch add the code to check and set lpm_capable when registering a
root hub device. It could be back-ported to kernels as old as v3.15,
that contains the Commit 25cd2882e2fc (usb/xhci: Change how we indicate
a host supports Link PM.).

Cc: sta...@vger.kernel.org # 3.15
Reported-by: Kevin Strasser kevin.stras...@linux.intel.com
Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
  drivers/usb/core/hcd.c | 6 ++
  drivers/usb/core/hub.c | 2 +-
  drivers/usb/core/usb.h | 1 +
  3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 45a915c..48b208d 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1032,6 +1032,12 @@ static int register_root_hub(struct usb_hcd *hcd)
}
}
  
+	if (le16_to_cpu(usb_dev-descriptor.bcdUSB) = 0x0201) {

+   retval = usb_get_bos_descriptor(usb_dev);
+   if (!retval)
+   usb_dev-lpm_capable = usb_device_supports_lpm(usb_dev);
+   }
+

This should be integrated with the code immediately above it, which
also calls usb_get_bos_descriptor().  In fact, maybe you should simply
change the existing code to check bcdUSB = 0x0201 instead of speed ==
USB_SPEED_SUPER.


I agree with you and will change it in v2 patch.




retval = usb_new_device (usb_dev);
if (retval) {
dev_err (parent_dev, can't register root hub for %s, %d\n,
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 3b71516..884d702 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -122,7 +122,7 @@ struct usb_hub *usb_hub_to_struct_hub(struct usb_device 
*hdev)
return usb_get_intfdata(hdev-actconfig-interface[0]);
  }
  
-static int usb_device_supports_lpm(struct usb_device *udev)

+int usb_device_supports_lpm(struct usb_device *udev)
  {
/* USB 2.1 (and greater) devices indicate LPM support through
 * their USB 2.0 Extended Capabilities BOS descriptor.
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 7eb1e26..d5668c4 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -82,6 +82,7 @@ extern int usb_runtime_suspend(struct device *dev);
  extern int usb_runtime_resume(struct device *dev);
  extern int usb_runtime_idle(struct device *dev);
  extern int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable);
+extern int usb_device_supports_lpm(struct usb_device *udev);
  
  #else

This will break if you build it with CONFIG_PM disabled.


Yes. Will fix it in v2 patch.



Alan Stern


Thank you,
Baolu



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




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


[PATCH v4 1/1] usb: core: lpm: set lpm_capable for root hub device

2015-06-15 Thread Lu Baolu
Commit 25cd2882e2fc (usb/xhci: Change how we indicate a host supports
Link PM.) removed the code to set lpm_capable for USB 3.0 super-speed
root hub. The intention of that change was to avoid touching usb core
internal field, a.k.a. lpm_capable, and let usb core to set it by
checking U1 and U2 exit latency values in the descriptor.

Usb core checks and sets lpm_capable in hub_port_init(). Unfortunately,
root hub is a special usb device as it has no parent. Hub_port_init()
will never be called for a root hub device. That means lpm_capable will
by no means be set for the root hub. As the result, lpm isn't functional
at all in Linux kernel.

This patch add the code to check and set lpm_capable when registering a
root hub device. It could be back-ported to kernels as old as v3.15,
that contains the Commit 25cd2882e2fc (usb/xhci: Change how we indicate
a host supports Link PM.).

Cc: sta...@vger.kernel.org # 3.15
Reported-by: Kevin Strasser kevin.stras...@linux.intel.com
Signed-off-by: Lu Baolu baolu...@linux.intel.com
Acked-by: Alan Stern st...@rowland.harvard.edu
---
 drivers/usb/core/hcd.c | 7 +--
 drivers/usb/core/hub.c | 2 +-
 drivers/usb/core/usb.h | 1 +
 3 files changed, 7 insertions(+), 3 deletions(-)
 v1-v2 change log:
   1. two code blocks merged
   2. fix build error when CONFIG_PM is not set
 v2-v3 change log:
   1. further fix of build error when CONFIG_PM is not set
 v3-v4 change log:
   1. Add Alan's ACK

diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 45a915c..1c1385e 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1022,9 +1022,12 @@ static int register_root_hub(struct usb_hcd *hcd)
dev_name(usb_dev-dev), retval);
return (retval  0) ? retval : -EMSGSIZE;
}
-   if (usb_dev-speed == USB_SPEED_SUPER) {
+
+   if (le16_to_cpu(usb_dev-descriptor.bcdUSB) = 0x0201) {
retval = usb_get_bos_descriptor(usb_dev);
-   if (retval  0) {
+   if (!retval) {
+   usb_dev-lpm_capable = usb_device_supports_lpm(usb_dev);
+   } else if (usb_dev-speed == USB_SPEED_SUPER) {
mutex_unlock(usb_bus_list_lock);
dev_dbg(parent_dev, can't read %s bos descriptor %d\n,
dev_name(usb_dev-dev), retval);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 3b71516..884d702 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -122,7 +122,7 @@ struct usb_hub *usb_hub_to_struct_hub(struct usb_device 
*hdev)
return usb_get_intfdata(hdev-actconfig-interface[0]);
 }
 
-static int usb_device_supports_lpm(struct usb_device *udev)
+int usb_device_supports_lpm(struct usb_device *udev)
 {
/* USB 2.1 (and greater) devices indicate LPM support through
 * their USB 2.0 Extended Capabilities BOS descriptor.
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 7eb1e26..457255a 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -65,6 +65,7 @@ extern int  usb_hub_init(void);
 extern void usb_hub_cleanup(void);
 extern int usb_major_init(void);
 extern void usb_major_cleanup(void);
+extern int usb_device_supports_lpm(struct usb_device *udev);
 
 #ifdef CONFIG_PM
 
-- 
2.1.4

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


[PATCH 1/1] usb: core: lpm: set lpm_capable for root hub device

2015-06-11 Thread Lu Baolu
Commit 25cd2882e2fc (usb/xhci: Change how we indicate a host supports
Link PM.) removed the code to set lpm_capable for USB 3.0 super-speed
root hub. The intention of that change was to avoid touching usb core
internal field, a.k.a. lpm_capable, and let usb core to set it by
checking U1 and U2 exit latency values in the descriptor.

Usb core checks and sets lpm_capable in hub_port_init(). Unfortunately,
root hub is a special usb device as it has no parent. Hub_port_init()
will never be called for a root hub device. That means lpm_capable will
by no means be set for the root hub. As the result, lpm isn't functional
at all in Linux kernel.

This patch add the code to check and set lpm_capable when registering a
root hub device. It could be back-ported to kernels as old as v3.15,
that contains the Commit 25cd2882e2fc (usb/xhci: Change how we indicate
a host supports Link PM.).

Cc: sta...@vger.kernel.org # 3.15
Reported-by: Kevin Strasser kevin.stras...@linux.intel.com
Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
 drivers/usb/core/hcd.c | 6 ++
 drivers/usb/core/hub.c | 2 +-
 drivers/usb/core/usb.h | 1 +
 3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 45a915c..48b208d 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1032,6 +1032,12 @@ static int register_root_hub(struct usb_hcd *hcd)
}
}
 
+   if (le16_to_cpu(usb_dev-descriptor.bcdUSB) = 0x0201) {
+   retval = usb_get_bos_descriptor(usb_dev);
+   if (!retval)
+   usb_dev-lpm_capable = usb_device_supports_lpm(usb_dev);
+   }
+
retval = usb_new_device (usb_dev);
if (retval) {
dev_err (parent_dev, can't register root hub for %s, %d\n,
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 3b71516..884d702 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -122,7 +122,7 @@ struct usb_hub *usb_hub_to_struct_hub(struct usb_device 
*hdev)
return usb_get_intfdata(hdev-actconfig-interface[0]);
 }
 
-static int usb_device_supports_lpm(struct usb_device *udev)
+int usb_device_supports_lpm(struct usb_device *udev)
 {
/* USB 2.1 (and greater) devices indicate LPM support through
 * their USB 2.0 Extended Capabilities BOS descriptor.
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 7eb1e26..d5668c4 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -82,6 +82,7 @@ extern int usb_runtime_suspend(struct device *dev);
 extern int usb_runtime_resume(struct device *dev);
 extern int usb_runtime_idle(struct device *dev);
 extern int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable);
+extern int usb_device_supports_lpm(struct usb_device *udev);
 
 #else
 
-- 
2.1.4

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


[PATCH v3 1/1] usb: core: lpm: set lpm_capable for root hub device

2015-06-14 Thread Lu Baolu
Commit 25cd2882e2fc (usb/xhci: Change how we indicate a host supports
Link PM.) removed the code to set lpm_capable for USB 3.0 super-speed
root hub. The intention of that change was to avoid touching usb core
internal field, a.k.a. lpm_capable, and let usb core to set it by
checking U1 and U2 exit latency values in the descriptor.

Usb core checks and sets lpm_capable in hub_port_init(). Unfortunately,
root hub is a special usb device as it has no parent. Hub_port_init()
will never be called for a root hub device. That means lpm_capable will
by no means be set for the root hub. As the result, lpm isn't functional
at all in Linux kernel.

This patch add the code to check and set lpm_capable when registering a
root hub device. It could be back-ported to kernels as old as v3.15,
that contains the Commit 25cd2882e2fc (usb/xhci: Change how we indicate
a host supports Link PM.).

Cc: sta...@vger.kernel.org # 3.15
Reported-by: Kevin Strasser kevin.stras...@linux.intel.com
Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
 drivers/usb/core/hcd.c | 7 +--
 drivers/usb/core/hub.c | 2 +-
 drivers/usb/core/usb.h | 1 +
 3 files changed, 7 insertions(+), 3 deletions(-)

 v1-v2 change log:
   1. two code blocks merged
   2. fix build error when CONFIG_PM is not set
 v2-v3 change log:
   1. further fix of build error when CONFIG_PM is not set

diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 45a915c..1c1385e 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1022,9 +1022,12 @@ static int register_root_hub(struct usb_hcd *hcd)
dev_name(usb_dev-dev), retval);
return (retval  0) ? retval : -EMSGSIZE;
}
-   if (usb_dev-speed == USB_SPEED_SUPER) {
+
+   if (le16_to_cpu(usb_dev-descriptor.bcdUSB) = 0x0201) {
retval = usb_get_bos_descriptor(usb_dev);
-   if (retval  0) {
+   if (!retval) {
+   usb_dev-lpm_capable = usb_device_supports_lpm(usb_dev);
+   } else if (usb_dev-speed == USB_SPEED_SUPER) {
mutex_unlock(usb_bus_list_lock);
dev_dbg(parent_dev, can't read %s bos descriptor %d\n,
dev_name(usb_dev-dev), retval);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 3b71516..884d702 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -122,7 +122,7 @@ struct usb_hub *usb_hub_to_struct_hub(struct usb_device 
*hdev)
return usb_get_intfdata(hdev-actconfig-interface[0]);
 }
 
-static int usb_device_supports_lpm(struct usb_device *udev)
+int usb_device_supports_lpm(struct usb_device *udev)
 {
/* USB 2.1 (and greater) devices indicate LPM support through
 * their USB 2.0 Extended Capabilities BOS descriptor.
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 7eb1e26..457255a 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -65,6 +65,7 @@ extern int  usb_hub_init(void);
 extern void usb_hub_cleanup(void);
 extern int usb_major_init(void);
 extern void usb_major_cleanup(void);
+extern int usb_device_supports_lpm(struct usb_device *udev);
 
 #ifdef CONFIG_PM
 
-- 
2.1.4

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


Re: [PATCH v2 1/1] usb: core: lpm: set lpm_capable for root hub device

2015-06-14 Thread Lu, Baolu



On 06/13/2015 11:00 PM, Alan Stern wrote:

On Sat, 13 Jun 2015, Lu Baolu wrote:


Commit 25cd2882e2fc (usb/xhci: Change how we indicate a host supports
Link PM.) removed the code to set lpm_capable for USB 3.0 super-speed
root hub. The intention of that change was to avoid touching usb core
internal field, a.k.a. lpm_capable, and let usb core to set it by
checking U1 and U2 exit latency values in the descriptor.

Usb core checks and sets lpm_capable in hub_port_init(). Unfortunately,
root hub is a special usb device as it has no parent. Hub_port_init()
will never be called for a root hub device. That means lpm_capable will
by no means be set for the root hub. As the result, lpm isn't functional
at all in Linux kernel.

This patch add the code to check and set lpm_capable when registering a
root hub device. It could be back-ported to kernels as old as v3.15,
that contains the Commit 25cd2882e2fc (usb/xhci: Change how we indicate
a host supports Link PM.).

Cc: sta...@vger.kernel.org # 3.15
Reported-by: Kevin Strasser kevin.stras...@linux.intel.com
Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -82,6 +82,7 @@ extern int usb_runtime_suspend(struct device *dev);
  extern int usb_runtime_resume(struct device *dev);
  extern int usb_runtime_idle(struct device *dev);
  extern int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable);
+extern int usb_device_supports_lpm(struct usb_device *udev);
  
  #else
  
@@ -106,6 +107,11 @@ static inline int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable)

return 0;
  }
  
+static inline int usb_device_supports_lpm(struct usb_device *udev)

+{
+   return 0;
+}
+
  #endif
  
  extern struct bus_type usb_bus_type;

In fact, usb_device_supports_lpm() is compiled even when CONFIG_PM
isn't set.  Maybe this should be changed.  But if you don't want to
change it now, you need to put the declaration outside the #ifdef
CONFIG_PM region.  As it is, your patch is still broken (did you try
building it with CONFIG_PM unset?).


I am sorry for this silly mistake. I will move it out of CONFIG_PM region.

I tried building with CONFIG_PM unset. But it turns out that CONFIG_PM
was auto selected by some other items. I will test my next version of
patch with CONFIG_PM *really* unset before sending it out.

Thanks,
Baolu



Alan Stern




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


[PATCH v5 1/1] usb: ulpi: ulpi_init should be executed in subsys_initcall

2015-06-04 Thread Lu Baolu
Phy drivers and the ulpi interface providers depend on the
registration of the ulpi bus.  Ulpi registers the bus in
module_init(). This could cause unnecessary bus users'
probe delays. i.e. unnecessary -EPROBE_DEFER happening on
ulpi_drivers in case they're registered before ulpi bus
itself.

Reported-by: Zhuo Qiuxu qiuxu.z...@intel.com
Signed-off-by: Lu Baolu baolu...@linux.intel.com
Acked-by: Heikki Krogerus heikki.kroge...@linux.intel.com
---
 drivers/usb/common/ulpi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

v0-v5 change log:
Various changes in the commit description.

diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c
index 0e6f968..01c0c04 100644
--- a/drivers/usb/common/ulpi.c
+++ b/drivers/usb/common/ulpi.c
@@ -242,7 +242,7 @@ static int __init ulpi_init(void)
 {
return bus_register(ulpi_bus);
 }
-module_init(ulpi_init);
+subsys_initcall(ulpi_init);
 
 static void __exit ulpi_exit(void)
 {
-- 
2.1.4

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


Re: [PATCH v3 1/1] usb: ulpi: ulpi_init should be executed in subsys_initcall

2015-05-26 Thread Lu, Baolu



On 05/26/2015 10:50 PM, Felipe Balbi wrote:

Hi,

On Mon, May 25, 2015 at 02:24:00PM +0800, Lu, Baolu wrote:


On 05/23/2015 12:08 AM, David Cohen wrote:

Hi,

On Fri, May 22, 2015 at 07:29:15PM +0800, Lu Baolu wrote:

Phy drivers and the ulpi interface providers depend on the
registeration of the ulpi bus.  Ulpi registers the bus in
module_init(). This could result in a load order issue, i.e.

It's still not an issue :(
I'd say unnecessary probe delays.

I managed to boot a kernel built from the top of Felipe's
remotes/origin/next branch under an Ubuntu environment
on Intel's Bay Trail tablet.

The same panic (as I found in the Android environment previously)
shows up as well. And if I replace module_init() with sys_initcall(),
the panic disappears.

the problem is something else... Moving things around in the init levels
is just a workaround for another issue. Seems like there's some missing
EPROBE_DEFER somewhere.


Yes, I agree.

Heikki, I assume missing EPROBE_DEFER issue will be fixed by
Sasha's patch. I will resend the patch with a new commit
message.

Thanks,
Baolu





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


[PATCH v4 1/1] usb: ulpi: ulpi_init should be executed in subsys_initcall

2015-05-26 Thread Lu Baolu
Phy drivers and the ulpi interface providers depend on the
registration of the ulpi bus.  Ulpi registers the bus in
module_init(). This could cause unnecessary probe delays.

Reported-by: Zhuo Qiuxu qiuxu.z...@intel.com
Signed-off-by: Lu Baolu baolu...@linux.intel.com
Acked-by: Heikki Krogerus heikki.kroge...@linux.intel.com
---
 drivers/usb/common/ulpi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c
index 0e6f968..01c0c04 100644
--- a/drivers/usb/common/ulpi.c
+++ b/drivers/usb/common/ulpi.c
@@ -242,7 +242,7 @@ static int __init ulpi_init(void)
 {
return bus_register(ulpi_bus);
 }
-module_init(ulpi_init);
+subsys_initcall(ulpi_init);
 
 static void __exit ulpi_exit(void)
 {
-- 
2.1.4

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


Re: [PATCH v4 1/1] usb: ulpi: ulpi_init should be executed in subsys_initcall

2015-05-27 Thread Lu, Baolu



On 05/28/2015 12:53 AM, David Cohen wrote:

Hi,

On Tue, May 26, 2015 at 07:37:02PM -0700, Greg Kroah-Hartman wrote:

On Wed, May 27, 2015 at 09:45:37AM +0800, Lu Baolu wrote:

Phy drivers and the ulpi interface providers depend on the
registration of the ulpi bus.  Ulpi registers the bus in
module_init(). This could cause unnecessary probe delays.

What do you mean by probe delays?

I believe he meant the bus users' probe delays. i.e. unnecessary
-EPROBE_DEFER happening on ulpi_drivers in case they're registered
before ulpi bus itself.

Is that correct, Baolu?


Yes.



Br, David
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/



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


Re: [PATCH v2 1/1] usb: ulpi: ulpi_init should be executed in subsys_initcall

2015-05-22 Thread Lu, Baolu



On 05/22/2015 11:11 AM, David Cohen wrote:

On Thu, May 21, 2015 at 08:09:54PM -0700, David Cohen wrote:

Hi,

On Fri, May 22, 2015 at 10:07:05AM +0800, Lu Baolu wrote:

Many drivers and modules depend on ULPI bus registeration to
register ULPI interfaces and drivers. It's more appropriate
to register ULPI bus in subsys_initcall instead of module_init.

Kernel panic has been reported with some kind of kernel config.

Even though I agree subsys_initcall is better to register ulpi bus, it's
still no excuse to have kernel panic. What about ULPI bus being compiled
as module?


No kernel panic if ULPI is built as a module.


IMHO this is avoiding the proper kernel panic fix which should be
failing gracefully (or defer probe) from tusb1210 driver.

Maybe I need to express myself better :)
IMHO we should not consider work done with this patch only. It's still
incomplete.


I am with you on that we should know the real problem.

I could go ahead with further debugging. Do you have any suggestions
about which direction should I go?



Br, David


Thank you,
-Baolu


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




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


Re: [PATCH v2 1/1] usb: ulpi: ulpi_init should be executed in subsys_initcall

2015-05-22 Thread Lu, Baolu



On 05/22/2015 02:46 PM, Lu, Baolu wrote:



On 05/22/2015 11:11 AM, David Cohen wrote:

On Thu, May 21, 2015 at 08:09:54PM -0700, David Cohen wrote:

Hi,

On Fri, May 22, 2015 at 10:07:05AM +0800, Lu Baolu wrote:

Many drivers and modules depend on ULPI bus registeration to
register ULPI interfaces and drivers. It's more appropriate
to register ULPI bus in subsys_initcall instead of module_init.

Kernel panic has been reported with some kind of kernel config.
Even though I agree subsys_initcall is better to register ulpi bus, 
it's
still no excuse to have kernel panic. What about ULPI bus being 
compiled

as module?


No kernel panic if ULPI is built as a module.


IMHO this is avoiding the proper kernel panic fix which should be
failing gracefully (or defer probe) from tusb1210 driver.

Maybe I need to express myself better :)
IMHO we should not consider work done with this patch only. It's still
incomplete.


I am with you on that we should know the real problem.

I could go ahead with further debugging. Do you have any suggestions
about which direction should I go?


I forgot to mention that the panic was found in an Android environment.
The kernel version is  v4.1-rc3.





Br, David


Thank you,
-Baolu


--
To unsubscribe from this list: send the line unsubscribe 
linux-kernel in

the body of a message to majord...@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/




--
To unsubscribe from this list: send the line unsubscribe 
linux-kernel in

the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/



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


Re: [PATCH v3 1/1] usb: ulpi: ulpi_init should be executed in subsys_initcall

2015-05-25 Thread Lu, Baolu



On 05/23/2015 12:08 AM, David Cohen wrote:

Hi,

On Fri, May 22, 2015 at 07:29:15PM +0800, Lu Baolu wrote:

Phy drivers and the ulpi interface providers depend on the
registeration of the ulpi bus.  Ulpi registers the bus in
module_init(). This could result in a load order issue, i.e.

It's still not an issue :(
I'd say unnecessary probe delays.


I managed to boot a kernel built from the top of Felipe's
remotes/origin/next branch under an Ubuntu environment
on Intel's Bay Trail tablet.

The same panic (as I found in the Android environment previously)
shows up as well. And if I replace module_init() with sys_initcall(),
the panic disappears.

Thanks,
-Baolu



But of cource it's Felipe's call :) Description looks better now.

BR, David


ulpi phy drivers or the ulpi interface providers loading
before the bus registeration.

This patch fixes this load order issue by putting ulpi_init
in subsys_initcall().

Reported-by: Zhuo Qiuxu qiuxu.z...@intel.com
Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
  drivers/usb/common/ulpi.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c
index 0e6f968..01c0c04 100644
--- a/drivers/usb/common/ulpi.c
+++ b/drivers/usb/common/ulpi.c
@@ -242,7 +242,7 @@ static int __init ulpi_init(void)
  {
return bus_register(ulpi_bus);
  }
-module_init(ulpi_init);
+subsys_initcall(ulpi_init);
  
  static void __exit ulpi_exit(void)

  {
--
2.1.4





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


Re: [PATCH 1/1] usb: ulpi: don't register drivers if bus doesn't exist

2015-05-21 Thread Lu, Baolu

Hi Heikki, Sasha and others,

Please ignore this patch. I should not squash these two patches into one and
sign it off behalf of other people. I apologize for this and I'm sorry 
if this lets

you feel affronted.

Thanks,
Baolu


On 05/21/2015 04:57 PM, Lu Baolu wrote:

ULPI registers its bus at module_init, so if the bus fails to register, the
module will fail to load and all will be well in the world.

However, if the ULPI code is built-in rather than a module, the bus
initialization may fail, but we'd still try to register drivers later onto
a non-existent bus, which will panic the kernel.

Fix that by checking that the bus was indeed initialized before trying to
register drivers on top of it.

Signed-off-by: Sasha Levin sasha.le...@oracle.com
Signed-off-by: Heikki Krogerus heikki.kroge...@linux.intel.com
Signed-off-by: Lu Baolu baolu...@linux.intel.com
Reported-by: Zhuo Qiuxu qiuxu.z...@intel.com
Reviewed-by: David Cohen david.a.co...@linux.intel.com
---
  drivers/usb/common/ulpi.c | 6 +-
  1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c
index 0e6f968..af52b46 100644
--- a/drivers/usb/common/ulpi.c
+++ b/drivers/usb/common/ulpi.c
@@ -132,6 +132,10 @@ int ulpi_register_driver(struct ulpi_driver *drv)
if (!drv-probe)
return -EINVAL;
  
+	/* Was the bus registered successfully? */

+   if (unlikely(WARN_ON(!ulpi_bus.p)))
+   return -ENODEV;
+
drv-driver.bus = ulpi_bus;
  
  	return driver_register(drv-driver);

@@ -242,7 +246,7 @@ static int __init ulpi_init(void)
  {
return bus_register(ulpi_bus);
  }
-module_init(ulpi_init);
+subsys_initcall(ulpi_init);
  
  static void __exit ulpi_exit(void)

  {


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


[PATCH v2 1/1] usb: ulpi: ulpi_init should be executed in subsys_initcall

2015-05-21 Thread Lu Baolu
Many drivers and modules depend on ULPI bus registeration to
register ULPI interfaces and drivers. It's more appropriate
to register ULPI bus in subsys_initcall instead of module_init.

Kernel panic has been reported with some kind of kernel config.

[0.746856] kernel BUG at drivers/base/driver.c:153!
[0.752418] invalid opcode:  [#1] PREEMPT SMP
[0.757804] Modules linked in:
[0.893985] Call Trace:
[0.896729]  [81870cb1] ? ulpi_register_driver+0x21/0x30
[0.903654]  [823d5cac] tusb1210_driver_init+0x10/0x12
[0.910386]  [81000318] do_one_initcall+0xd8/0x200
[0.916729]  [8239b094] kernel_init_freeable+0x196/0x21e
[0.923655]  [81affed0] ? rest_init+0x90/0x90
[0.929509]  [81affede] kernel_init+0xe/0xf0
[0.935266]  [81b0f442] ret_from_fork+0x42/0x70
[0.941315]  [81affed0] ? rest_init+0x90/0x90

This patch fixes this kind of kernel panic by putting ulpi_init in
subsys_initcall().

Reported-by: Zhuo Qiuxu qiuxu.z...@intel.com
Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
 drivers/usb/common/ulpi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c
index 0e6f968..01c0c04 100644
--- a/drivers/usb/common/ulpi.c
+++ b/drivers/usb/common/ulpi.c
@@ -242,7 +242,7 @@ static int __init ulpi_init(void)
 {
return bus_register(ulpi_bus);
 }
-module_init(ulpi_init);
+subsys_initcall(ulpi_init);
 
 static void __exit ulpi_exit(void)
 {
-- 
2.1.4

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


[PATCH v3 1/1] usb: ulpi: ulpi_init should be executed in subsys_initcall

2015-05-22 Thread Lu Baolu
Phy drivers and the ulpi interface providers depend on the
registeration of the ulpi bus.  Ulpi registers the bus in
module_init(). This could result in a load order issue, i.e.
ulpi phy drivers or the ulpi interface providers loading
before the bus registeration.

This patch fixes this load order issue by putting ulpi_init
in subsys_initcall().

Reported-by: Zhuo Qiuxu qiuxu.z...@intel.com
Signed-off-by: Lu Baolu baolu...@linux.intel.com
---
 drivers/usb/common/ulpi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c
index 0e6f968..01c0c04 100644
--- a/drivers/usb/common/ulpi.c
+++ b/drivers/usb/common/ulpi.c
@@ -242,7 +242,7 @@ static int __init ulpi_init(void)
 {
return bus_register(ulpi_bus);
 }
-module_init(ulpi_init);
+subsys_initcall(ulpi_init);
 
 static void __exit ulpi_exit(void)
 {
-- 
2.1.4

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


Re: [PATCH v2 1/1] usb: xhci: fix checking ep busy for CFC

2015-10-29 Thread Lu, Baolu



On 10/29/2015 08:51 PM, Sergei Shtylyov wrote:

Hello.

On 10/29/2015 5:46 AM, Lu Baolu wrote:


Function ep_ring_is_processing() checks the dequeue pointer
in endpoint context to know whether an endpoint is busy with
processing TRBs. This is not correct since dequeue pointer
field in an endpoint context is only valid when the endpoint
is in Halted or Stopped states. This buggy code causes audio
noise when playing sound with USB headset connected to host
controllers which support CFC (one of xhci 1.1 features).

This patch should exist in stable kernel since v4.3.

Reported-and-tested-by: YD Tseng <yd_ts...@asmedia.com.tw>
Signed-off-by: Lu Baolu <baolu...@linux.intel.com>

---
v1->v2:
Implement the logic in xhci_queue_isoc_tx_prepare() instead of
a seperated function as suggested by Mathias.

---
  drivers/usb/host/xhci-ring.c | 32 ++--
  1 file changed, 6 insertions(+), 26 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index fa83625..8edc286 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c

[...]
@@ -3983,10 +3961,12 @@ int xhci_queue_isoc_tx_prepare(struct 
xhci_hcd *xhci, gfp_t mem_flags,

  }

  /* Calculate the start frame and put it in urb->start_frame. */
-if (HCC_CFC(xhci->hcc_params) &&
-ep_ring_is_processing(xhci, slot_id, ep_index)) {
-urb->start_frame = xep->next_frame_id;
-goto skip_start_over;
+if (HCC_CFC(xhci->hcc_params)) {
+if ((le32_to_cpu(ep_ctx->ep_info) & EP_STATE_MASK)
+== EP_STATE_RUNNING &&
+!list_empty(_ring->td_list))
+urb->start_frame = xep->next_frame_id;
+goto skip_start_over;


   Forgot {}?


Oh, I am sorry. I am wondering how it passed my test.

I will send v3 patch soon any way.




  }

  start_frame = readl(>run_regs->microframe_index);


MBR, Sergei

--
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



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


[PATCH v3 1/1] usb: xhci: fix checking ep busy for CFC

2015-10-29 Thread Lu Baolu
Function ep_ring_is_processing() checks the dequeue pointer
in endpoint context to know whether an endpoint is busy with
processing TRBs. This is not correct since dequeue pointer
field in an endpoint context is only valid when the endpoint
is in Halted or Stopped states. This buggy code causes audio
noise when playing sound with USB headset connected to host
controllers which support CFC (one of xhci 1.1 features).

This patch should exist in stable kernel since v4.3.

Reported-and-tested-by: YD Tseng <yd_ts...@asmedia.com.tw>
Signed-off-by: Lu Baolu <baolu...@linux.intel.com>
---
v1->v2:
Implement the logic in xhci_queue_isoc_tx_prepare() instead of
a seperated function as suggested by Mathias.

v2->v3:
Add the missing {} pair found by Sergei.
Adjust line for code readability as suggested by Mathias.
---
 drivers/usb/host/xhci-ring.c | 32 ++--
 1 file changed, 6 insertions(+), 26 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index fa83625..6c5e813 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -3896,28 +3896,6 @@ cleanup:
return ret;
 }
 
-static int ep_ring_is_processing(struct xhci_hcd *xhci,
-   int slot_id, unsigned int ep_index)
-{
-   struct xhci_virt_device *xdev;
-   struct xhci_ring *ep_ring;
-   struct xhci_ep_ctx *ep_ctx;
-   struct xhci_virt_ep *xep;
-   dma_addr_t hw_deq;
-
-   xdev = xhci->devs[slot_id];
-   xep = >devs[slot_id]->eps[ep_index];
-   ep_ring = xep->ring;
-   ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index);
-
-   if ((le32_to_cpu(ep_ctx->ep_info) & EP_STATE_MASK) != EP_STATE_RUNNING)
-   return 0;
-
-   hw_deq = le64_to_cpu(ep_ctx->deq) & ~EP_CTX_CYCLE_MASK;
-   return (hw_deq !=
-   xhci_trb_virt_to_dma(ep_ring->enq_seg, ep_ring->enqueue));
-}
-
 /*
  * Check transfer ring to guarantee there is enough room for the urb.
  * Update ISO URB start_frame and interval.
@@ -3983,10 +3961,12 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, 
gfp_t mem_flags,
}
 
/* Calculate the start frame and put it in urb->start_frame. */
-   if (HCC_CFC(xhci->hcc_params) &&
-   ep_ring_is_processing(xhci, slot_id, ep_index)) {
-   urb->start_frame = xep->next_frame_id;
-   goto skip_start_over;
+   if (HCC_CFC(xhci->hcc_params) && !list_empty(_ring->td_list)) {
+   if ((le32_to_cpu(ep_ctx->ep_info) & EP_STATE_MASK) ==
+   EP_STATE_RUNNING) {
+   urb->start_frame = xep->next_frame_id;
+   goto skip_start_over;
+   }
}
 
start_frame = readl(>run_regs->microframe_index);
-- 
2.1.4

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


Re: [PATCH v2 1/1] usb: xhci: fix checking ep busy for CFC

2015-10-29 Thread Lu, Baolu



On 10/29/2015 10:08 PM, Mathias Nyman wrote:

On 29.10.2015 14:58, Lu, Baolu wrote:



On 10/29/2015 08:51 PM, Sergei Shtylyov wrote:

Hello.

On 10/29/2015 5:46 AM, Lu Baolu wrote:


Function ep_ring_is_processing() checks the dequeue pointer
in endpoint context to know whether an endpoint is busy with
processing TRBs. This is not correct since dequeue pointer
field in an endpoint context is only valid when the endpoint
is in Halted or Stopped states. This buggy code causes audio
noise when playing sound with USB headset connected to host
controllers which support CFC (one of xhci 1.1 features).

This patch should exist in stable kernel since v4.3.

Reported-and-tested-by: YD Tseng <yd_ts...@asmedia.com.tw>
Signed-off-by: Lu Baolu <baolu...@linux.intel.com>

---
v1->v2:
Implement the logic in xhci_queue_isoc_tx_prepare() instead of
a seperated function as suggested by Mathias.

---
  drivers/usb/host/xhci-ring.c | 32 ++--
  1 file changed, 6 insertions(+), 26 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c 
b/drivers/usb/host/xhci-ring.c

index fa83625..8edc286 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c

[...]
@@ -3983,10 +3961,12 @@ int xhci_queue_isoc_tx_prepare(struct 
xhci_hcd *xhci, gfp_t mem_flags,

  }

  /* Calculate the start frame and put it in urb->start_frame. */
-if (HCC_CFC(xhci->hcc_params) &&
-ep_ring_is_processing(xhci, slot_id, ep_index)) {
-urb->start_frame = xep->next_frame_id;
-goto skip_start_over;
+if (HCC_CFC(xhci->hcc_params)) {
+if ((le32_to_cpu(ep_ctx->ep_info) & EP_STATE_MASK)
+== EP_STATE_RUNNING &&
+!list_empty(_ring->td_list))
+urb->start_frame = xep->next_frame_id;
+goto skip_start_over;


   Forgot {}?


Oh, I am sorry. I am wondering how it passed my test.

I will send v3 patch soon any way.




If you are anyway making a v3 then maybe one more change,
just for readability, no (real) functional change:

if (HCC_CFC(xhci->hcc_params) && !list_empty(_ring->td_list)) {
  if (le32_to_cpu(ep_...


Done.



While thinking about code cleanup I also think we should use a local 
variable
u32 ep_info = le32_to_cpu(ep_ctx->ep_info) as it's used several times 
in xhci_queue_isoc_tx_preapare(),

causing a lot of line splitting.

It should be ok as we are under the same spinlock so ep_ctx should not 
change.


But that is not a fix sent to a rc and stable, I can make a separate 
cleanup patch for it later.


-Mathias
--
To unsubscribe from this list: send the line "unsubscribe 
linux-kernel" in

the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/



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


[PATCH 1/1] usb: xhci: fix checking ep busy for CFC

2015-10-27 Thread Lu Baolu
Function ep_ring_is_processing() checks the dequeue pointer
in endpoint context to know whether an endpoint is busy with
processing TRBs. This is not correct since dequeue pointer
field in an endpoint context is only valid when the endpoint
is in Halted or Stopped states. This buggy code causes audio
noise when playing sound with USB headset connected to host
controllers which support CFC (one of xhci 1.1 features).

This patch should exist in stable kernel since v4.3.

Reported-and-tested-by: YD Tseng <yd_ts...@asmedia.com.tw>
Signed-off-by: Lu Baolu <baolu...@linux.intel.com>
---
 drivers/usb/host/xhci-ring.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index fa83625..2b50d45 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -3903,7 +3903,6 @@ static int ep_ring_is_processing(struct xhci_hcd *xhci,
struct xhci_ring *ep_ring;
struct xhci_ep_ctx *ep_ctx;
struct xhci_virt_ep *xep;
-   dma_addr_t hw_deq;
 
xdev = xhci->devs[slot_id];
xep = >devs[slot_id]->eps[ep_index];
@@ -3913,9 +3912,7 @@ static int ep_ring_is_processing(struct xhci_hcd *xhci,
if ((le32_to_cpu(ep_ctx->ep_info) & EP_STATE_MASK) != EP_STATE_RUNNING)
return 0;
 
-   hw_deq = le64_to_cpu(ep_ctx->deq) & ~EP_CTX_CYCLE_MASK;
-   return (hw_deq !=
-   xhci_trb_virt_to_dma(ep_ring->enq_seg, ep_ring->enqueue));
+   return !list_empty(_ring->td_list);
 }
 
 /*
-- 
2.1.4

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


[PATCH 12/12] usb: doc: add document for xHCI DbC driver

2015-10-28 Thread Lu Baolu
Add Documentation/usb/xhci-dbc.txt. This document includes
development status and usage guide for USB3 debug port.

Signed-off-by: Lu Baolu <baolu...@linux.intel.com>
---
 Documentation/usb/xhci-dbc.txt | 325 +
 MAINTAINERS|   1 +
 drivers/usb/early/xhci-dbc.c   |   3 +
 3 files changed, 329 insertions(+)
 create mode 100644 Documentation/usb/xhci-dbc.txt

diff --git a/Documentation/usb/xhci-dbc.txt b/Documentation/usb/xhci-dbc.txt
new file mode 100644
index 000..94b75a9
--- /dev/null
+++ b/Documentation/usb/xhci-dbc.txt
@@ -0,0 +1,325 @@
+xHCI debug capability driver
+
+         Lu Baolu <baolu...@linux.intel.com>
+
+Last-updated: September 2015
+
+
+   Contents:
+   -
+   * What is xHCI DbC?
+   * Debug topologies
+   * Debug stacks
+   * Port Multiplexing
+   * Hardware initialization
+   * External reset
+   * Port reset
+   * Interrupt/DMA/Memory during early boot
+   * Endpoint STALL
+   * Debug device information
+   * How to use DbC early printk?
+   * Limitations
+
+   What is xHCI DbC?
+   -
+
+The xHCI Debugging Capability defined in section 7.6 of xHCI spec 1.1
+provides an optional functionality that enables low-level system debug
+over USB. It provides a means of connecting two systems where one system
+is a Debug Host and the other a Debug Target (System Under Test). The
+Debug Capability provides an interface that is completely independent
+of the xHCI interface. A Debug Target enumerates as a USB debug device
+to the Debug Host, allowing a Debug Host to access a Debug Target through
+the standard USB software stack.
+
+   Debug topologies
+   
+
+Multiple Debug Targets may be attached to a single Debug Host. Debug
+Targets may be connected to any downstream facing port below a Debug
+Host (i.e. anywhere in the fabric, root port or external hub puts).
+A Debug Target may only connect to a Debug Host through a Root Hub port
+of the target. That means connection of a Debug Target to a Debug Host
+through the ports of an external hub is not supported.
+
+Below is a typical connection between Debug Host and Debug target. Two
+Debug targets are connected to a single Debug host.
+
+
+ 
+|   Debug Host   |  |  Debug Target  |
+||  ||
+|xHC without DbC |  |  xHC with DbC  |
+|or DbC disabled |  | enabled|
+||  ||
+|P1|  |p2|  |P1|  |p2|
+|__|  |__|  |__|  |__|
+  || |
+  ||_|
+  |_
+|
+ ___|
+|   HUB  |  |  Debug Target  |
+||  ||
+| Superspeed hub |  |  xHC with DbC  |
+||  | enabled|
+||  ||
+|P1|  |p2|  |P1|  |p2|
+|__|  |__|  |__|  |__|
+   | |
+   |_|
+
+   Debug stacks
+   
+
+Below is a software stack diagram of both Debug Host and Debug Target.
+
+ 
+|   Debug Host   |  |  Debug Target  |
+||  ||
+|   debug App|  ||
+||  | system debug   |
+|   usb_debug|  | hooks  |
+||  ||
+|usbcore |  ||
+||  |debug capability|
+|xhci_hcd|  | driver |
+||  ||
+|xHC without DbC |  |  xHC with DbC  |
+|or DbC disabled |  | enabled|
+||  ||
+|P1|  |p2|  |P1|  |p2|
+|__|  |__|  |__|  |__|
+   | |
+   |_|
+
+
+   Port Multiplexing
+   -
+
+A debug port is always multiplexed with the first xHCI root hub port.
+Whenever debug capability is supported and enabled, and the first root
+hub port is detected to be connected to a downstream super-speed port
+of a Debug Host, 

[PATCH 03/12] usb: xhci: dbc: probe and setup xhci debug capability

2015-10-28 Thread Lu Baolu
xHCI debug capability (DbC) is an optional functionality provided
by an xHCI host controller. Software learns this capability by
walking through the extended capability list in mmio of the host.

This patch introduces the code to probe and initialize the debug
capability hardware during early boot. With hardware initialization
done, the debug target (system under debug which has DbC enabled)
will present a debug device through the debug port. The debug device
is fully compliant with the USB framework and provides the equivalent
of a very high performance (USB3) full-duplex serial link between the
debug host and target.

Signed-off-by: Lu Baolu <baolu...@linux.intel.com>
---
 MAINTAINERS  |   7 +
 arch/x86/Kconfig.debug   |  12 +
 drivers/usb/early/Makefile   |   1 +
 drivers/usb/early/xhci-dbc.c | 787 +++
 include/linux/usb/xhci-dbc.h | 187 ++
 5 files changed, 994 insertions(+)
 create mode 100644 drivers/usb/early/xhci-dbc.c
 create mode 100644 include/linux/usb/xhci-dbc.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 0425167..585a369 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11040,6 +11040,13 @@ S: Supported
 F: drivers/usb/host/xhci*
 F: drivers/usb/host/pci-quirks*
 
+USB XHCI DEBUG PORT
+M:     Lu Baolu <baolu...@linux.intel.com>
+L: linux-...@vger.kernel.org
+S: Supported
+F: drivers/usb/early/xhci-dbc.c
+F: include/linux/usb/xhci-dbc.h
+
 USB ZD1201 DRIVER
 L: linux-wirel...@vger.kernel.org
 W: http://linux-lc100020.sourceforge.net
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
index d8c0d32..8d95abd 100644
--- a/arch/x86/Kconfig.debug
+++ b/arch/x86/Kconfig.debug
@@ -65,6 +65,18 @@ config EARLY_PRINTK_EFI
  This is useful for kernel debugging when your machine crashes very
  early before the console code is initialized.
 
+config EARLY_PRINTK_XDBC
+   bool "Early printk via xHCI debug port"
+   depends on EARLY_PRINTK && PCI
+   ---help---
+ Write kernel log output directly into the xHCI debug port.
+
+ This is useful for kernel debugging when your machine crashes very
+ early before the console code is initialized. For normal operation
+ it is not recommended because it looks ugly and doesn't cooperate
+ with klogd/syslogd or the X server. You should normally N here,
+ unless you want to debug such a crash.
+
 config X86_PTDUMP
bool "Export kernel pagetable layout to userspace via debugfs"
depends on DEBUG_KERNEL
diff --git a/drivers/usb/early/Makefile b/drivers/usb/early/Makefile
index 24bbe51..2db5906 100644
--- a/drivers/usb/early/Makefile
+++ b/drivers/usb/early/Makefile
@@ -3,3 +3,4 @@
 #
 
 obj-$(CONFIG_EARLY_PRINTK_DBGP) += ehci-dbgp.o
+obj-$(CONFIG_EARLY_PRINTK_XDBC) += xhci-dbc.o
diff --git a/drivers/usb/early/xhci-dbc.c b/drivers/usb/early/xhci-dbc.c
new file mode 100644
index 000..22a1de9
--- /dev/null
+++ b/drivers/usb/early/xhci-dbc.c
@@ -0,0 +1,787 @@
+/**
+ * xhci-dbc.c - xHCI debug capability driver
+ *
+ * Copyright (C) 2015 Intel Corporation
+ *
+ * Author: Lu Baolu <baolu...@linux.intel.com>
+ * Some code shared with EHCI debug port and xHCI driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "../host/xhci.h"
+
+#defineXDBC_PROTOCOL   1   /* GNU Remote Debug Command Set 
*/
+#defineXDBC_VENDOR_ID  0x1d6b  /* Linux Foundation 0x1d6b */
+#defineXDBC_PRODUCT_ID 0x0004  /* __le16 idProduct; device 
0004 */
+#defineXDBC_DEVICE_REV 0x0010  /* 0.10 */
+
+static struct xdbc_state xdbc_stat;
+static struct xdbc_state *xdbcp = _stat;
+
+#ifdef DBC_DEBUG
+/* place holder */
+#definexdbc_trace  printk
+static void xdbc_dbg_dump_regs(char *str)
+{
+   if (!xdbcp->xdbc_reg) {
+   xdbc_trace("register not mapped\n");
+   return;
+   }
+
+   xdbc_trace("XDBC registers: %s\n", str);
+   xdbc_trace("  Capability: %08x\n",
+   readl(>xdbc_reg->capability));
+   xdbc_trace("  Door bell: %08x\n",
+   readl(>xdbc_reg->doorbell));
+   xdbc_trace("  Event Ring Segment Table Size: %08x\n",
+   readl(>xdbc_reg->ersts));
+   xdbc_trace("  Event Ring Segment Table Base Address: %16llx\n",
+   xdbc_read64(>xdbc_reg->erstba));
+   xdbc_trace("  Event Ring Dequeue Pointer: %16llx\n",
+   xdbc_read64(>xdbc_reg->erdp));
+   xdbc

[PATCH 00/12] usb: early: add support for early printk through USB3 debug port

2015-10-28 Thread Lu Baolu
This patch series adds support for early printk through USB3 debug port.
USB3 debug port is described in xHCI specification as an optional extended
capability.

The first patch adds a file in debugfs, through which users can check
whether the debug capability is supported by a specific host controller.

Patch 2 to 10 add the driver for xHCI debug capability. It interfaces with
the register set and provides the required ops (read/write/control) to upper
layers. Early printk is one consumer of these ops. The hooks for early printk
are introduced in patch 9. This design is similar to what we have done in
drivers/usb/early/ehci-dbgp.c.

Patch 11 is a minor change to usb_debug module. This change is required to
bind usb_debug with the USB3 debug device.

Patch 12 is the design document and user guide.

Lu Baolu (12):
  usb: xhci: expose xhci extended capabilities via debugfs
  x86: fixmap: add permanent fixmap for xhci debug port
  usb: xhci: dbc: probe and setup xhci debug capability
  usb: xhci: dbc: add support for Intel xHCI dbc quirk
  usb: xhci: dbc: add debug buffer
  usb: xhci: dbc: add bulk out and bulk in interfaces
  usb: xhci: dbc: handle dbc-configured exit
  usb: xhci: dbc: handle endpoint stall
  x86: early_printk: add USB3 debug port earlyprintk support
  usb: xhci: dbc: add handshake between debug target and host
  usb: serial: usb_debug: add support for dbc debug device
  usb: doc: add document for xHCI DbC driver

 Documentation/kernel-parameters.txt |1 +
 Documentation/usb/xhci-dbc.txt  |  325 
 MAINTAINERS |8 +
 arch/x86/Kconfig.debug  |   12 +
 arch/x86/include/asm/fixmap.h   |4 +
 arch/x86/kernel/early_printk.c  |5 +
 drivers/usb/early/Makefile  |1 +
 drivers/usb/early/xhci-dbc.c| 1407 +++
 drivers/usb/host/xhci-dbg.c |  212 ++
 drivers/usb/host/xhci-ext-caps.h|9 +-
 drivers/usb/host/xhci.c |   27 +-
 drivers/usb/host/xhci.h |   10 +
 drivers/usb/serial/usb_debug.c  |   29 +-
 include/linux/usb/xhci-dbc.h|  224 ++
 14 files changed, 2269 insertions(+), 5 deletions(-)
 create mode 100644 Documentation/usb/xhci-dbc.txt
 create mode 100644 drivers/usb/early/xhci-dbc.c
 create mode 100644 include/linux/usb/xhci-dbc.h

-- 
2.1.4

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


  1   2   3   4   5   6   7   8   9   10   >