]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 27 Jun 2022 08:23:29 +0000 (10:23 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 27 Jun 2022 08:23:29 +0000 (10:23 +0200)
added patches:
xhci-turn-off-port-power-in-shutdown.patch

queue-4.19/series
queue-4.19/xhci-turn-off-port-power-in-shutdown.patch [new file with mode: 0644]

index d5cd7b3d65c5f74bc02ce25e966cf54398b37247..da028914cedb28cb352ef5fe2fc6903611036441 100644 (file)
@@ -19,3 +19,4 @@ igb-make-dma-faster-when-cpu-is-active-on-the-pcie-l.patch
 virtio_net-fix-xdp_rxq_info-bug-after-suspend-resume.patch
 gpio-winbond-fix-error-code-in-winbond_gpio_get.patch
 iio-adc-vf610-fix-conversion-mode-sysfs-node-name.patch
+xhci-turn-off-port-power-in-shutdown.patch
diff --git a/queue-4.19/xhci-turn-off-port-power-in-shutdown.patch b/queue-4.19/xhci-turn-off-port-power-in-shutdown.patch
new file mode 100644 (file)
index 0000000..410bbf0
--- /dev/null
@@ -0,0 +1,86 @@
+From 83810f84ecf11dfc5a9414a8b762c3501b328185 Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Thu, 23 Jun 2022 14:19:43 +0300
+Subject: xhci: turn off port power in shutdown
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit 83810f84ecf11dfc5a9414a8b762c3501b328185 upstream.
+
+If ports are not turned off in shutdown then runtime suspended
+self-powered USB devices may survive in U3 link state over S5.
+
+During subsequent boot, if firmware sends an IPC command to program
+the port in DISCONNECT state, it will time out, causing significant
+delay in the boot time.
+
+Turning off roothub port power is also recommended in xhci
+specification 4.19.4 "Port Power" in the additional note.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20220623111945.1557702-3-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/xhci-hub.c |    2 +-
+ drivers/usb/host/xhci.c     |   15 +++++++++++++--
+ drivers/usb/host/xhci.h     |    2 ++
+ 3 files changed, 16 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/host/xhci-hub.c
++++ b/drivers/usb/host/xhci-hub.c
+@@ -565,7 +565,7 @@ struct xhci_hub *xhci_get_rhub(struct us
+  * It will release and re-aquire the lock while calling ACPI
+  * method.
+  */
+-static void xhci_set_port_power(struct xhci_hcd *xhci, struct usb_hcd *hcd,
++void xhci_set_port_power(struct xhci_hcd *xhci, struct usb_hcd *hcd,
+                               u16 index, bool on, unsigned long *flags)
+ {
+       struct xhci_hub *rhub;
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -774,6 +774,8 @@ static void xhci_stop(struct usb_hcd *hc
+ void xhci_shutdown(struct usb_hcd *hcd)
+ {
+       struct xhci_hcd *xhci = hcd_to_xhci(hcd);
++      unsigned long flags;
++      int i;
+       if (xhci->quirks & XHCI_SPURIOUS_REBOOT)
+               usb_disable_xhci_ports(to_pci_dev(hcd->self.sysdev));
+@@ -789,12 +791,21 @@ void xhci_shutdown(struct usb_hcd *hcd)
+               del_timer_sync(&xhci->shared_hcd->rh_timer);
+       }
+-      spin_lock_irq(&xhci->lock);
++      spin_lock_irqsave(&xhci->lock, flags);
+       xhci_halt(xhci);
++
++      /* Power off USB2 ports*/
++      for (i = 0; i < xhci->usb2_rhub.num_ports; i++)
++              xhci_set_port_power(xhci, xhci->main_hcd, i, false, &flags);
++
++      /* Power off USB3 ports*/
++      for (i = 0; i < xhci->usb3_rhub.num_ports; i++)
++              xhci_set_port_power(xhci, xhci->shared_hcd, i, false, &flags);
++
+       /* Workaround for spurious wakeups at shutdown with HSW */
+       if (xhci->quirks & XHCI_SPURIOUS_WAKEUP)
+               xhci_reset(xhci, XHCI_RESET_SHORT_USEC);
+-      spin_unlock_irq(&xhci->lock);
++      spin_unlock_irqrestore(&xhci->lock, flags);
+       xhci_cleanup_msix(xhci);
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -2145,6 +2145,8 @@ int xhci_hub_control(struct usb_hcd *hcd
+ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf);
+ int xhci_find_raw_port_number(struct usb_hcd *hcd, int port1);
+ struct xhci_hub *xhci_get_rhub(struct usb_hcd *hcd);
++void xhci_set_port_power(struct xhci_hcd *xhci, struct usb_hcd *hcd, u16 index,
++                       bool on, unsigned long *flags);
+ void xhci_hc_died(struct xhci_hcd *xhci);