]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
drop broken xhci patch
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 4 Jul 2018 12:51:15 +0000 (14:51 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 4 Jul 2018 12:51:15 +0000 (14:51 +0200)
queue-4.14/series
queue-4.14/xhci-fix-perceived-dead-host-due-to-runtime-suspend-race-with-event-handler.patch [deleted file]
queue-4.17/series
queue-4.17/xhci-fix-perceived-dead-host-due-to-runtime-suspend-race-with-event-handler.patch [deleted file]
queue-4.4/series
queue-4.4/xhci-fix-perceived-dead-host-due-to-runtime-suspend-race-with-event-handler.patch [deleted file]
queue-4.9/series
queue-4.9/xhci-fix-perceived-dead-host-due-to-runtime-suspend-race-with-event-handler.patch [deleted file]

index 089284f03c6b3bb4fdb185570398b4272da1cfb1..dea431c6b9ea313b19eca4a9b8cd4e8d34a81358 100644 (file)
@@ -5,7 +5,6 @@ usb-dwc2-fix-the-incorrect-bitmaps-for-the-ports-of-multi_tt-hub.patch
 acpi-add-helper-for-deactivating-memory-region.patch
 usb-typec-ucsi-acpi-workaround-for-cache-mode-issue.patch
 usb-typec-ucsi-fix-for-incorrect-status-data-issue.patch
-xhci-fix-perceived-dead-host-due-to-runtime-suspend-race-with-event-handler.patch
 xhci-fix-kernel-oops-in-trace_xhci_free_virt_device.patch
 n_tty-fix-stall-at-n_tty_receive_char_special.patch
 n_tty-access-echo_-variables-carefully.patch
diff --git a/queue-4.14/xhci-fix-perceived-dead-host-due-to-runtime-suspend-race-with-event-handler.patch b/queue-4.14/xhci-fix-perceived-dead-host-due-to-runtime-suspend-race-with-event-handler.patch
deleted file mode 100644 (file)
index 92759bb..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-From 229bc19fd7aca4f37964af06e3583c1c8f36b5d6 Mon Sep 17 00:00:00 2001
-From: Mathias Nyman <mathias.nyman@linux.intel.com>
-Date: Thu, 21 Jun 2018 16:19:41 +0300
-Subject: xhci: Fix perceived dead host due to runtime suspend race with event handler
-
-From: Mathias Nyman <mathias.nyman@linux.intel.com>
-
-commit 229bc19fd7aca4f37964af06e3583c1c8f36b5d6 upstream.
-
-Don't rely on event interrupt (EINT) bit alone to detect pending port
-change in resume. If no change event is detected the host may be suspended
-again, oterwise roothubs are resumed.
-
-There is a lag in xHC setting EINT. If we don't notice the pending change
-in resume, and the controller is runtime suspeded again, it causes the
-event handler to assume host is dead as it will fail to read xHC registers
-once PCI puts the controller to D3 state.
-
-[  268.520969] xhci_hcd: xhci_resume: starting port polling.
-[  268.520985] xhci_hcd: xhci_hub_status_data: stopping port polling.
-[  268.521030] xhci_hcd: xhci_suspend: stopping port polling.
-[  268.521040] xhci_hcd: // Setting command ring address to 0x349bd001
-[  268.521139] xhci_hcd: Port Status Change Event for port 3
-[  268.521149] xhci_hcd: resume root hub
-[  268.521163] xhci_hcd: port resume event for port 3
-[  268.521168] xhci_hcd: xHC is not running.
-[  268.521174] xhci_hcd: handle_port_status: starting port polling.
-[  268.596322] xhci_hcd: xhci_hc_died: xHCI host controller not responding, assume dead
-
-The EINT lag is described in a additional note in xhci specs 4.19.2:
-
-"Due to internal xHC scheduling and system delays, there will be a lag
-between a change bit being set and the Port Status Change Event that it
-generated being written to the Event Ring. If SW reads the PORTSC and
-sees a change bit set, there is no guarantee that the corresponding Port
-Status Change Event has already been written into the Event Ring."
-
-Cc: <stable@vger.kernel.org>
-Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
----
- drivers/usb/host/xhci.c |   40 +++++++++++++++++++++++++++++++++++++---
- drivers/usb/host/xhci.h |    4 ++++
- 2 files changed, 41 insertions(+), 3 deletions(-)
-
---- a/drivers/usb/host/xhci.c
-+++ b/drivers/usb/host/xhci.c
-@@ -856,6 +856,41 @@ static void xhci_disable_port_wake_on_bi
-       spin_unlock_irqrestore(&xhci->lock, flags);
- }
-+static bool xhci_pending_portevent(struct xhci_hcd *xhci)
-+{
-+      struct xhci_port        **ports;
-+      int                     port_index;
-+      u32                     status;
-+      u32                     portsc;
-+
-+      status = readl(&xhci->op_regs->status);
-+      if (status & STS_EINT)
-+              return true;
-+      /*
-+       * Checking STS_EINT is not enough as there is a lag between a change
-+       * bit being set and the Port Status Change Event that it generated
-+       * being written to the Event Ring. See note in xhci 1.1 section 4.19.2.
-+       */
-+
-+      port_index = xhci->usb2_rhub.num_ports;
-+      ports = xhci->usb2_rhub.ports;
-+      while (port_index--) {
-+              portsc = readl(ports[port_index]->addr);
-+              if (portsc & PORT_CHANGE_MASK ||
-+                  (portsc & PORT_PLS_MASK) == XDEV_RESUME)
-+                      return true;
-+      }
-+      port_index = xhci->usb3_rhub.num_ports;
-+      ports = xhci->usb3_rhub.ports;
-+      while (port_index--) {
-+              portsc = readl(ports[port_index]->addr);
-+              if (portsc & PORT_CHANGE_MASK ||
-+                  (portsc & PORT_PLS_MASK) == XDEV_RESUME)
-+                      return true;
-+      }
-+      return false;
-+}
-+
- /*
-  * Stop HC (not bus-specific)
-  *
-@@ -955,7 +990,7 @@ EXPORT_SYMBOL_GPL(xhci_suspend);
-  */
- int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
- {
--      u32                     command, temp = 0, status;
-+      u32                     command, temp = 0;
-       struct usb_hcd          *hcd = xhci_to_hcd(xhci);
-       struct usb_hcd          *secondary_hcd;
-       int                     retval = 0;
-@@ -1077,8 +1112,7 @@ int xhci_resume(struct xhci_hcd *xhci, b
-  done:
-       if (retval == 0) {
-               /* Resume root hubs only when have pending events. */
--              status = readl(&xhci->op_regs->status);
--              if (status & STS_EINT) {
-+              if (xhci_pending_portevent(xhci)) {
-                       usb_hcd_resume_root_hub(xhci->shared_hcd);
-                       usb_hcd_resume_root_hub(hcd);
-               }
---- a/drivers/usb/host/xhci.h
-+++ b/drivers/usb/host/xhci.h
-@@ -392,6 +392,10 @@ struct xhci_op_regs {
- #define PORT_PLC      (1 << 22)
- /* port configure error change - port failed to configure its link partner */
- #define PORT_CEC      (1 << 23)
-+#define PORT_CHANGE_MASK      (PORT_CSC | PORT_PEC | PORT_WRC | PORT_OCC | \
-+                               PORT_RC | PORT_PLC | PORT_CEC)
-+
-+
- /* Cold Attach Status - xHC can set this bit to report device attached during
-  * Sx state. Warm port reset should be perfomed to clear this bit and move port
-  * to connected state.
index c94869e35b8b01402a94bcd5396c5438a173a0e3..4b52e5233c3e5b46f41afc147d3ef7cf81982003 100644 (file)
@@ -6,7 +6,6 @@ usb-typec-tcpm-fix-logbuffer-index-is-wrong-if-_tcpm_log-is-re-entered.patch
 acpi-add-helper-for-deactivating-memory-region.patch
 usb-typec-ucsi-acpi-workaround-for-cache-mode-issue.patch
 usb-typec-ucsi-fix-for-incorrect-status-data-issue.patch
-xhci-fix-perceived-dead-host-due-to-runtime-suspend-race-with-event-handler.patch
 xhci-fix-kernel-oops-in-trace_xhci_free_virt_device.patch
 n_tty-fix-stall-at-n_tty_receive_char_special.patch
 n_tty-access-echo_-variables-carefully.patch
diff --git a/queue-4.17/xhci-fix-perceived-dead-host-due-to-runtime-suspend-race-with-event-handler.patch b/queue-4.17/xhci-fix-perceived-dead-host-due-to-runtime-suspend-race-with-event-handler.patch
deleted file mode 100644 (file)
index 2e34c8f..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-From 229bc19fd7aca4f37964af06e3583c1c8f36b5d6 Mon Sep 17 00:00:00 2001
-From: Mathias Nyman <mathias.nyman@linux.intel.com>
-Date: Thu, 21 Jun 2018 16:19:41 +0300
-Subject: xhci: Fix perceived dead host due to runtime suspend race with event handler
-
-From: Mathias Nyman <mathias.nyman@linux.intel.com>
-
-commit 229bc19fd7aca4f37964af06e3583c1c8f36b5d6 upstream.
-
-Don't rely on event interrupt (EINT) bit alone to detect pending port
-change in resume. If no change event is detected the host may be suspended
-again, oterwise roothubs are resumed.
-
-There is a lag in xHC setting EINT. If we don't notice the pending change
-in resume, and the controller is runtime suspeded again, it causes the
-event handler to assume host is dead as it will fail to read xHC registers
-once PCI puts the controller to D3 state.
-
-[  268.520969] xhci_hcd: xhci_resume: starting port polling.
-[  268.520985] xhci_hcd: xhci_hub_status_data: stopping port polling.
-[  268.521030] xhci_hcd: xhci_suspend: stopping port polling.
-[  268.521040] xhci_hcd: // Setting command ring address to 0x349bd001
-[  268.521139] xhci_hcd: Port Status Change Event for port 3
-[  268.521149] xhci_hcd: resume root hub
-[  268.521163] xhci_hcd: port resume event for port 3
-[  268.521168] xhci_hcd: xHC is not running.
-[  268.521174] xhci_hcd: handle_port_status: starting port polling.
-[  268.596322] xhci_hcd: xhci_hc_died: xHCI host controller not responding, assume dead
-
-The EINT lag is described in a additional note in xhci specs 4.19.2:
-
-"Due to internal xHC scheduling and system delays, there will be a lag
-between a change bit being set and the Port Status Change Event that it
-generated being written to the Event Ring. If SW reads the PORTSC and
-sees a change bit set, there is no guarantee that the corresponding Port
-Status Change Event has already been written into the Event Ring."
-
-Cc: <stable@vger.kernel.org>
-Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
----
- drivers/usb/host/xhci.c |   40 +++++++++++++++++++++++++++++++++++++---
- drivers/usb/host/xhci.h |    4 ++++
- 2 files changed, 41 insertions(+), 3 deletions(-)
-
---- a/drivers/usb/host/xhci.c
-+++ b/drivers/usb/host/xhci.c
-@@ -844,6 +844,41 @@ static void xhci_disable_port_wake_on_bi
-       spin_unlock_irqrestore(&xhci->lock, flags);
- }
-+static bool xhci_pending_portevent(struct xhci_hcd *xhci)
-+{
-+      struct xhci_port        **ports;
-+      int                     port_index;
-+      u32                     status;
-+      u32                     portsc;
-+
-+      status = readl(&xhci->op_regs->status);
-+      if (status & STS_EINT)
-+              return true;
-+      /*
-+       * Checking STS_EINT is not enough as there is a lag between a change
-+       * bit being set and the Port Status Change Event that it generated
-+       * being written to the Event Ring. See note in xhci 1.1 section 4.19.2.
-+       */
-+
-+      port_index = xhci->usb2_rhub.num_ports;
-+      ports = xhci->usb2_rhub.ports;
-+      while (port_index--) {
-+              portsc = readl(ports[port_index]->addr);
-+              if (portsc & PORT_CHANGE_MASK ||
-+                  (portsc & PORT_PLS_MASK) == XDEV_RESUME)
-+                      return true;
-+      }
-+      port_index = xhci->usb3_rhub.num_ports;
-+      ports = xhci->usb3_rhub.ports;
-+      while (port_index--) {
-+              portsc = readl(ports[port_index]->addr);
-+              if (portsc & PORT_CHANGE_MASK ||
-+                  (portsc & PORT_PLS_MASK) == XDEV_RESUME)
-+                      return true;
-+      }
-+      return false;
-+}
-+
- /*
-  * Stop HC (not bus-specific)
-  *
-@@ -945,7 +980,7 @@ EXPORT_SYMBOL_GPL(xhci_suspend);
-  */
- int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
- {
--      u32                     command, temp = 0, status;
-+      u32                     command, temp = 0;
-       struct usb_hcd          *hcd = xhci_to_hcd(xhci);
-       struct usb_hcd          *secondary_hcd;
-       int                     retval = 0;
-@@ -1069,8 +1104,7 @@ int xhci_resume(struct xhci_hcd *xhci, b
-  done:
-       if (retval == 0) {
-               /* Resume root hubs only when have pending events. */
--              status = readl(&xhci->op_regs->status);
--              if (status & STS_EINT) {
-+              if (xhci_pending_portevent(xhci)) {
-                       usb_hcd_resume_root_hub(xhci->shared_hcd);
-                       usb_hcd_resume_root_hub(hcd);
-               }
---- a/drivers/usb/host/xhci.h
-+++ b/drivers/usb/host/xhci.h
-@@ -382,6 +382,10 @@ struct xhci_op_regs {
- #define PORT_PLC      (1 << 22)
- /* port configure error change - port failed to configure its link partner */
- #define PORT_CEC      (1 << 23)
-+#define PORT_CHANGE_MASK      (PORT_CSC | PORT_PEC | PORT_WRC | PORT_OCC | \
-+                               PORT_RC | PORT_PLC | PORT_CEC)
-+
-+
- /* Cold Attach Status - xHC can set this bit to report device attached during
-  * Sx state. Warm port reset should be perfomed to clear this bit and move port
-  * to connected state.
index 7d992fdb115adfa56fdda3bf0577b23828946315..5c3b508e62685ae852efc17f3aa78376d1362f75 100644 (file)
@@ -1,6 +1,5 @@
 usb-cdc_acm-add-quirk-for-uniden-ubc125-scanner.patch
 usb-serial-cp210x-add-cesinel-device-ids.patch
 usb-serial-cp210x-add-silicon-labs-ids-for-windows-update.patch
-xhci-fix-perceived-dead-host-due-to-runtime-suspend-race-with-event-handler.patch
 n_tty-fix-stall-at-n_tty_receive_char_special.patch
 staging-android-ion-return-an-err_ptr-in-ion_map_kernel.patch
diff --git a/queue-4.4/xhci-fix-perceived-dead-host-due-to-runtime-suspend-race-with-event-handler.patch b/queue-4.4/xhci-fix-perceived-dead-host-due-to-runtime-suspend-race-with-event-handler.patch
deleted file mode 100644 (file)
index a3c1375..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-From 229bc19fd7aca4f37964af06e3583c1c8f36b5d6 Mon Sep 17 00:00:00 2001
-From: Mathias Nyman <mathias.nyman@linux.intel.com>
-Date: Thu, 21 Jun 2018 16:19:41 +0300
-Subject: xhci: Fix perceived dead host due to runtime suspend race with event handler
-
-From: Mathias Nyman <mathias.nyman@linux.intel.com>
-
-commit 229bc19fd7aca4f37964af06e3583c1c8f36b5d6 upstream.
-
-Don't rely on event interrupt (EINT) bit alone to detect pending port
-change in resume. If no change event is detected the host may be suspended
-again, oterwise roothubs are resumed.
-
-There is a lag in xHC setting EINT. If we don't notice the pending change
-in resume, and the controller is runtime suspeded again, it causes the
-event handler to assume host is dead as it will fail to read xHC registers
-once PCI puts the controller to D3 state.
-
-[  268.520969] xhci_hcd: xhci_resume: starting port polling.
-[  268.520985] xhci_hcd: xhci_hub_status_data: stopping port polling.
-[  268.521030] xhci_hcd: xhci_suspend: stopping port polling.
-[  268.521040] xhci_hcd: // Setting command ring address to 0x349bd001
-[  268.521139] xhci_hcd: Port Status Change Event for port 3
-[  268.521149] xhci_hcd: resume root hub
-[  268.521163] xhci_hcd: port resume event for port 3
-[  268.521168] xhci_hcd: xHC is not running.
-[  268.521174] xhci_hcd: handle_port_status: starting port polling.
-[  268.596322] xhci_hcd: xhci_hc_died: xHCI host controller not responding, assume dead
-
-The EINT lag is described in a additional note in xhci specs 4.19.2:
-
-"Due to internal xHC scheduling and system delays, there will be a lag
-between a change bit being set and the Port Status Change Event that it
-generated being written to the Event Ring. If SW reads the PORTSC and
-sees a change bit set, there is no guarantee that the corresponding Port
-Status Change Event has already been written into the Event Ring."
-
-Cc: <stable@vger.kernel.org>
-Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
----
- drivers/usb/host/xhci.c |   40 +++++++++++++++++++++++++++++++++++++---
- drivers/usb/host/xhci.h |    4 ++++
- 2 files changed, 41 insertions(+), 3 deletions(-)
-
---- a/drivers/usb/host/xhci.c
-+++ b/drivers/usb/host/xhci.c
-@@ -887,6 +887,41 @@ static void xhci_disable_port_wake_on_bi
-       spin_unlock_irqrestore(&xhci->lock, flags);
- }
-+static bool xhci_pending_portevent(struct xhci_hcd *xhci)
-+{
-+      struct xhci_port        **ports;
-+      int                     port_index;
-+      u32                     status;
-+      u32                     portsc;
-+
-+      status = readl(&xhci->op_regs->status);
-+      if (status & STS_EINT)
-+              return true;
-+      /*
-+       * Checking STS_EINT is not enough as there is a lag between a change
-+       * bit being set and the Port Status Change Event that it generated
-+       * being written to the Event Ring. See note in xhci 1.1 section 4.19.2.
-+       */
-+
-+      port_index = xhci->usb2_rhub.num_ports;
-+      ports = xhci->usb2_rhub.ports;
-+      while (port_index--) {
-+              portsc = readl(ports[port_index]->addr);
-+              if (portsc & PORT_CHANGE_MASK ||
-+                  (portsc & PORT_PLS_MASK) == XDEV_RESUME)
-+                      return true;
-+      }
-+      port_index = xhci->usb3_rhub.num_ports;
-+      ports = xhci->usb3_rhub.ports;
-+      while (port_index--) {
-+              portsc = readl(ports[port_index]->addr);
-+              if (portsc & PORT_CHANGE_MASK ||
-+                  (portsc & PORT_PLS_MASK) == XDEV_RESUME)
-+                      return true;
-+      }
-+      return false;
-+}
-+
- /*
-  * Stop HC (not bus-specific)
-  *
-@@ -983,7 +1018,7 @@ EXPORT_SYMBOL_GPL(xhci_suspend);
-  */
- int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
- {
--      u32                     command, temp = 0, status;
-+      u32                     command, temp = 0;
-       struct usb_hcd          *hcd = xhci_to_hcd(xhci);
-       struct usb_hcd          *secondary_hcd;
-       int                     retval = 0;
-@@ -1105,8 +1140,7 @@ int xhci_resume(struct xhci_hcd *xhci, b
-  done:
-       if (retval == 0) {
-               /* Resume root hubs only when have pending events. */
--              status = readl(&xhci->op_regs->status);
--              if (status & STS_EINT) {
-+              if (xhci_pending_portevent(xhci)) {
-                       usb_hcd_resume_root_hub(xhci->shared_hcd);
-                       usb_hcd_resume_root_hub(hcd);
-               }
---- a/drivers/usb/host/xhci.h
-+++ b/drivers/usb/host/xhci.h
-@@ -382,6 +382,10 @@ struct xhci_op_regs {
- #define PORT_PLC      (1 << 22)
- /* port configure error change - port failed to configure its link partner */
- #define PORT_CEC      (1 << 23)
-+#define PORT_CHANGE_MASK      (PORT_CSC | PORT_PEC | PORT_WRC | PORT_OCC | \
-+                               PORT_RC | PORT_PLC | PORT_CEC)
-+
-+
- /* Cold Attach Status - xHC can set this bit to report device attached during
-  * Sx state. Warm port reset should be perfomed to clear this bit and move port
-  * to connected state.
index dc964544d0b35f3f96ffe57d182ca783d32ff1dc..9d169086bc43b9cbd2a98bf41c6b10e7402f6fef 100644 (file)
@@ -2,7 +2,6 @@ usb-cdc_acm-add-quirk-for-uniden-ubc125-scanner.patch
 usb-serial-cp210x-add-cesinel-device-ids.patch
 usb-serial-cp210x-add-silicon-labs-ids-for-windows-update.patch
 usb-dwc2-fix-the-incorrect-bitmaps-for-the-ports-of-multi_tt-hub.patch
-xhci-fix-perceived-dead-host-due-to-runtime-suspend-race-with-event-handler.patch
 n_tty-fix-stall-at-n_tty_receive_char_special.patch
 n_tty-access-echo_-variables-carefully.patch
 staging-android-ion-return-an-err_ptr-in-ion_map_kernel.patch
diff --git a/queue-4.9/xhci-fix-perceived-dead-host-due-to-runtime-suspend-race-with-event-handler.patch b/queue-4.9/xhci-fix-perceived-dead-host-due-to-runtime-suspend-race-with-event-handler.patch
deleted file mode 100644 (file)
index a2fba3e..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-From 229bc19fd7aca4f37964af06e3583c1c8f36b5d6 Mon Sep 17 00:00:00 2001
-From: Mathias Nyman <mathias.nyman@linux.intel.com>
-Date: Thu, 21 Jun 2018 16:19:41 +0300
-Subject: xhci: Fix perceived dead host due to runtime suspend race with event handler
-
-From: Mathias Nyman <mathias.nyman@linux.intel.com>
-
-commit 229bc19fd7aca4f37964af06e3583c1c8f36b5d6 upstream.
-
-Don't rely on event interrupt (EINT) bit alone to detect pending port
-change in resume. If no change event is detected the host may be suspended
-again, oterwise roothubs are resumed.
-
-There is a lag in xHC setting EINT. If we don't notice the pending change
-in resume, and the controller is runtime suspeded again, it causes the
-event handler to assume host is dead as it will fail to read xHC registers
-once PCI puts the controller to D3 state.
-
-[  268.520969] xhci_hcd: xhci_resume: starting port polling.
-[  268.520985] xhci_hcd: xhci_hub_status_data: stopping port polling.
-[  268.521030] xhci_hcd: xhci_suspend: stopping port polling.
-[  268.521040] xhci_hcd: // Setting command ring address to 0x349bd001
-[  268.521139] xhci_hcd: Port Status Change Event for port 3
-[  268.521149] xhci_hcd: resume root hub
-[  268.521163] xhci_hcd: port resume event for port 3
-[  268.521168] xhci_hcd: xHC is not running.
-[  268.521174] xhci_hcd: handle_port_status: starting port polling.
-[  268.596322] xhci_hcd: xhci_hc_died: xHCI host controller not responding, assume dead
-
-The EINT lag is described in a additional note in xhci specs 4.19.2:
-
-"Due to internal xHC scheduling and system delays, there will be a lag
-between a change bit being set and the Port Status Change Event that it
-generated being written to the Event Ring. If SW reads the PORTSC and
-sees a change bit set, there is no guarantee that the corresponding Port
-Status Change Event has already been written into the Event Ring."
-
-Cc: <stable@vger.kernel.org>
-Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
----
- drivers/usb/host/xhci.c |   40 +++++++++++++++++++++++++++++++++++++---
- drivers/usb/host/xhci.h |    4 ++++
- 2 files changed, 41 insertions(+), 3 deletions(-)
-
---- a/drivers/usb/host/xhci.c
-+++ b/drivers/usb/host/xhci.c
-@@ -891,6 +891,41 @@ static void xhci_disable_port_wake_on_bi
-       spin_unlock_irqrestore(&xhci->lock, flags);
- }
-+static bool xhci_pending_portevent(struct xhci_hcd *xhci)
-+{
-+      struct xhci_port        **ports;
-+      int                     port_index;
-+      u32                     status;
-+      u32                     portsc;
-+
-+      status = readl(&xhci->op_regs->status);
-+      if (status & STS_EINT)
-+              return true;
-+      /*
-+       * Checking STS_EINT is not enough as there is a lag between a change
-+       * bit being set and the Port Status Change Event that it generated
-+       * being written to the Event Ring. See note in xhci 1.1 section 4.19.2.
-+       */
-+
-+      port_index = xhci->usb2_rhub.num_ports;
-+      ports = xhci->usb2_rhub.ports;
-+      while (port_index--) {
-+              portsc = readl(ports[port_index]->addr);
-+              if (portsc & PORT_CHANGE_MASK ||
-+                  (portsc & PORT_PLS_MASK) == XDEV_RESUME)
-+                      return true;
-+      }
-+      port_index = xhci->usb3_rhub.num_ports;
-+      ports = xhci->usb3_rhub.ports;
-+      while (port_index--) {
-+              portsc = readl(ports[port_index]->addr);
-+              if (portsc & PORT_CHANGE_MASK ||
-+                  (portsc & PORT_PLS_MASK) == XDEV_RESUME)
-+                      return true;
-+      }
-+      return false;
-+}
-+
- /*
-  * Stop HC (not bus-specific)
-  *
-@@ -987,7 +1022,7 @@ EXPORT_SYMBOL_GPL(xhci_suspend);
-  */
- int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
- {
--      u32                     command, temp = 0, status;
-+      u32                     command, temp = 0;
-       struct usb_hcd          *hcd = xhci_to_hcd(xhci);
-       struct usb_hcd          *secondary_hcd;
-       int                     retval = 0;
-@@ -1109,8 +1144,7 @@ int xhci_resume(struct xhci_hcd *xhci, b
-  done:
-       if (retval == 0) {
-               /* Resume root hubs only when have pending events. */
--              status = readl(&xhci->op_regs->status);
--              if (status & STS_EINT) {
-+              if (xhci_pending_portevent(xhci)) {
-                       usb_hcd_resume_root_hub(xhci->shared_hcd);
-                       usb_hcd_resume_root_hub(hcd);
-               }
---- a/drivers/usb/host/xhci.h
-+++ b/drivers/usb/host/xhci.h
-@@ -385,6 +385,10 @@ struct xhci_op_regs {
- #define PORT_PLC      (1 << 22)
- /* port configure error change - port failed to configure its link partner */
- #define PORT_CEC      (1 << 23)
-+#define PORT_CHANGE_MASK      (PORT_CSC | PORT_PEC | PORT_WRC | PORT_OCC | \
-+                               PORT_RC | PORT_PLC | PORT_CEC)
-+
-+
- /* Cold Attach Status - xHC can set this bit to report device attached during
-  * Sx state. Warm port reset should be perfomed to clear this bit and move port
-  * to connected state.