]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 Jan 2017 10:56:43 +0000 (11:56 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 Jan 2017 10:56:43 +0000 (11:56 +0100)
added patches:
usb-dwc3-gadget-fix-full-speed-mode.patch
usb-dwc3-pci-add-intel-gemini-lake-pci-id.patch
usb-dwc3-pci-fix-dr_mode-misspelling.patch
usb-gadget-udc-core-fix-return-code-of-usb_gadget_probe_driver.patch
usb-hub-move-hub_port_disable-to-fix-warning-if-pm-is-disabled.patch
usb-musb-blackfin-add-bfin_fifo_offset-in-bfin_ops.patch
usb-musb-fix-trying-to-free-already-free-irq-4.patch
xhci-fix-race-related-to-abort-operation.patch
xhci-use-delayed_work-instead-of-timer-for-command-timeout.patch

queue-4.9/series
queue-4.9/usb-dwc3-gadget-fix-full-speed-mode.patch [new file with mode: 0644]
queue-4.9/usb-dwc3-pci-add-intel-gemini-lake-pci-id.patch [new file with mode: 0644]
queue-4.9/usb-dwc3-pci-fix-dr_mode-misspelling.patch [new file with mode: 0644]
queue-4.9/usb-gadget-udc-core-fix-return-code-of-usb_gadget_probe_driver.patch [new file with mode: 0644]
queue-4.9/usb-hub-move-hub_port_disable-to-fix-warning-if-pm-is-disabled.patch [new file with mode: 0644]
queue-4.9/usb-musb-blackfin-add-bfin_fifo_offset-in-bfin_ops.patch [new file with mode: 0644]
queue-4.9/usb-musb-fix-trying-to-free-already-free-irq-4.patch [new file with mode: 0644]
queue-4.9/xhci-fix-race-related-to-abort-operation.patch [new file with mode: 0644]
queue-4.9/xhci-use-delayed_work-instead-of-timer-for-command-timeout.patch [new file with mode: 0644]

index 39d80a3a75c5ba2461a40dca4566adaa716ff99c..1fad96bc821aa3fd8167f0198851d8d6e820d340 100644 (file)
@@ -61,3 +61,12 @@ usb-serial-mos7720-fix-use-after-free-on-probe-errors.patch
 usb-serial-mos7720-fix-parport-use-after-free-on-probe-errors.patch
 usb-serial-mos7720-fix-parallel-probe.patch
 usb-xhci-mem-use-passed-in-gfp-flags-instead-of-gfp_kernel.patch
+xhci-use-delayed_work-instead-of-timer-for-command-timeout.patch
+xhci-fix-race-related-to-abort-operation.patch
+usb-dwc3-pci-add-intel-gemini-lake-pci-id.patch
+usb-dwc3-pci-fix-dr_mode-misspelling.patch
+usb-dwc3-gadget-fix-full-speed-mode.patch
+usb-musb-fix-trying-to-free-already-free-irq-4.patch
+usb-hub-move-hub_port_disable-to-fix-warning-if-pm-is-disabled.patch
+usb-gadget-udc-core-fix-return-code-of-usb_gadget_probe_driver.patch
+usb-musb-blackfin-add-bfin_fifo_offset-in-bfin_ops.patch
diff --git a/queue-4.9/usb-dwc3-gadget-fix-full-speed-mode.patch b/queue-4.9/usb-dwc3-gadget-fix-full-speed-mode.patch
new file mode 100644 (file)
index 0000000..1830100
--- /dev/null
@@ -0,0 +1,72 @@
+From 9418ee15f718939aa7e650fd586d73765eb21f20 Mon Sep 17 00:00:00 2001
+From: Roger Quadros <rogerq@ti.com>
+Date: Tue, 3 Jan 2017 14:32:09 +0200
+Subject: usb: dwc3: gadget: Fix full speed mode
+
+From: Roger Quadros <rogerq@ti.com>
+
+commit 9418ee15f718939aa7e650fd586d73765eb21f20 upstream.
+
+DCFG.DEVSPD == 0x3 is not valid and we need to set
+DCFG.DEVSPD to 0x1 for full speed mode. Same goes for
+DSTS.CONNECTSPD.
+
+Old databooks had 0x3 for full speed in 48MHz mode for
+USB1.1 transceivers which was never supported. Newer databooks
+don't mention 0x3 at all.
+
+Cc: John Youn <John.Youn@synopsys.com>
+Signed-off-by: Roger Quadros <rogerq@ti.com>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/dwc3/core.h   |    6 ++----
+ drivers/usb/dwc3/gadget.c |    5 ++---
+ 2 files changed, 4 insertions(+), 7 deletions(-)
+
+--- a/drivers/usb/dwc3/core.h
++++ b/drivers/usb/dwc3/core.h
+@@ -301,9 +301,8 @@
+ #define DWC3_DCFG_SUPERSPEED_PLUS (5 << 0)  /* DWC_usb31 only */
+ #define DWC3_DCFG_SUPERSPEED  (4 << 0)
+ #define DWC3_DCFG_HIGHSPEED   (0 << 0)
+-#define DWC3_DCFG_FULLSPEED2  (1 << 0)
++#define DWC3_DCFG_FULLSPEED   (1 << 0)
+ #define DWC3_DCFG_LOWSPEED    (2 << 0)
+-#define DWC3_DCFG_FULLSPEED1  (3 << 0)
+ #define DWC3_DCFG_NUMP_SHIFT  17
+ #define DWC3_DCFG_NUMP(n)     (((n) >> DWC3_DCFG_NUMP_SHIFT) & 0x1f)
+@@ -395,9 +394,8 @@
+ #define DWC3_DSTS_SUPERSPEED_PLUS     (5 << 0) /* DWC_usb31 only */
+ #define DWC3_DSTS_SUPERSPEED          (4 << 0)
+ #define DWC3_DSTS_HIGHSPEED           (0 << 0)
+-#define DWC3_DSTS_FULLSPEED2          (1 << 0)
++#define DWC3_DSTS_FULLSPEED           (1 << 0)
+ #define DWC3_DSTS_LOWSPEED            (2 << 0)
+-#define DWC3_DSTS_FULLSPEED1          (3 << 0)
+ /* Device Generic Command Register */
+ #define DWC3_DGCMD_SET_LMP            0x01
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -1606,7 +1606,7 @@ static int __dwc3_gadget_start(struct dw
+                       reg |= DWC3_DCFG_LOWSPEED;
+                       break;
+               case USB_SPEED_FULL:
+-                      reg |= DWC3_DCFG_FULLSPEED1;
++                      reg |= DWC3_DCFG_FULLSPEED;
+                       break;
+               case USB_SPEED_HIGH:
+                       reg |= DWC3_DCFG_HIGHSPEED;
+@@ -2465,8 +2465,7 @@ static void dwc3_gadget_conndone_interru
+               dwc->gadget.ep0->maxpacket = 64;
+               dwc->gadget.speed = USB_SPEED_HIGH;
+               break;
+-      case DWC3_DSTS_FULLSPEED2:
+-      case DWC3_DSTS_FULLSPEED1:
++      case DWC3_DSTS_FULLSPEED:
+               dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(64);
+               dwc->gadget.ep0->maxpacket = 64;
+               dwc->gadget.speed = USB_SPEED_FULL;
diff --git a/queue-4.9/usb-dwc3-pci-add-intel-gemini-lake-pci-id.patch b/queue-4.9/usb-dwc3-pci-add-intel-gemini-lake-pci-id.patch
new file mode 100644 (file)
index 0000000..802df5d
--- /dev/null
@@ -0,0 +1,38 @@
+From 8f8983a5683623b62b339d159573f95a1fce44f3 Mon Sep 17 00:00:00 2001
+From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Date: Fri, 1 Apr 2016 17:13:12 +0300
+Subject: usb: dwc3: pci: add Intel Gemini Lake PCI ID
+
+From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+
+commit 8f8983a5683623b62b339d159573f95a1fce44f3 upstream.
+
+Intel Gemini Lake SoC has the same DWC3 than Broxton. Add
+the new ID to the supported Devices.
+
+Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/dwc3/dwc3-pci.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/usb/dwc3/dwc3-pci.c
++++ b/drivers/usb/dwc3/dwc3-pci.c
+@@ -38,6 +38,7 @@
+ #define PCI_DEVICE_ID_INTEL_BXT_M             0x1aaa
+ #define PCI_DEVICE_ID_INTEL_APL                       0x5aaa
+ #define PCI_DEVICE_ID_INTEL_KBP                       0xa2b0
++#define PCI_DEVICE_ID_INTEL_GLK                       0x31aa
+ static const struct acpi_gpio_params reset_gpios = { 0, 0, false };
+ static const struct acpi_gpio_params cs_gpios = { 1, 0, false };
+@@ -229,6 +230,7 @@ static const struct pci_device_id dwc3_p
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BXT_M), },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_APL), },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KBP), },
++      { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_GLK), },
+       { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB), },
+       {  }    /* Terminating Entry */
+ };
diff --git a/queue-4.9/usb-dwc3-pci-fix-dr_mode-misspelling.patch b/queue-4.9/usb-dwc3-pci-fix-dr_mode-misspelling.patch
new file mode 100644 (file)
index 0000000..e138583
--- /dev/null
@@ -0,0 +1,34 @@
+From 51c1685d956221576e165dd88a20063b169bae5a Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Tue, 27 Dec 2016 13:13:42 +0200
+Subject: usb: dwc3: pci: Fix dr_mode misspelling
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+commit 51c1685d956221576e165dd88a20063b169bae5a upstream.
+
+usb_get_dr_mode() expects the device-property to be spelled
+"dr_mode" not "dr-mode".
+
+Spelling it properly fixes the following warning showing up in dmesg:
+[ 8704.500545] dwc3 dwc3.2.auto: Configuration mismatch. dr_mode forced to gadget
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/dwc3/dwc3-pci.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/dwc3/dwc3-pci.c
++++ b/drivers/usb/dwc3/dwc3-pci.c
+@@ -82,7 +82,7 @@ static int dwc3_pci_quirks(struct pci_de
+               int ret;
+               struct property_entry properties[] = {
+-                      PROPERTY_ENTRY_STRING("dr-mode", "peripheral"),
++                      PROPERTY_ENTRY_STRING("dr_mode", "peripheral"),
+                       { }
+               };
diff --git a/queue-4.9/usb-gadget-udc-core-fix-return-code-of-usb_gadget_probe_driver.patch b/queue-4.9/usb-gadget-udc-core-fix-return-code-of-usb_gadget_probe_driver.patch
new file mode 100644 (file)
index 0000000..83e00e9
--- /dev/null
@@ -0,0 +1,131 @@
+From 7b01738112608ce47083178ae2b9ebadf02d32cc Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Felix=20H=C3=A4dicke?= <felixhaedicke@web.de>
+Date: Thu, 29 Dec 2016 23:02:11 +0100
+Subject: usb: gadget: udc: core: fix return code of usb_gadget_probe_driver()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Felix Hädicke <felixhaedicke@web.de>
+
+commit 7b01738112608ce47083178ae2b9ebadf02d32cc upstream.
+
+This fixes a regression which was introduced by commit f1bddbb, by
+reverting a small fragment of commit 855ed04.
+
+If the following conditions were met, usb_gadget_probe_driver() returned
+0, although the call was unsuccessful:
+1. A particular UDC was specified by thge gadget driver (using member
+"udc_name" of struct usb_gadget_driver).
+2. The UDC with this name is available.
+3. Another gadget driver is already bound to this gadget.
+4. The gadget driver has the "match_existing_only" flag set.
+In this case, the return code variable "ret" is set to 0, the return
+code of a strcmp() call (to check for the second condition).
+
+This also fixes an oops which could occur in the following scenario:
+1. Two usb gadget instances were configured using configfs.
+2. The first gadget configuration was bound to a UDC (using the configfs
+attribute "UDC").
+3. It was tried to bind the second gadget configuration to the same UDC
+in the same way. This operation was then wrongly reported as being
+successful.
+4. The second gadget configuration's "UDC" attribute is cleared, to
+unbind the (not really bound) second gadget configuration from the UDC.
+
+<BUG: unable to handle kernel NULL pointer dereference
+at           (null)
+IP: [<ffffffff94f5e5e9>] __list_del_entry+0x29/0xc0
+PGD 41b4c5067
+PUD 41a598067
+PMD 0
+
+Oops: 0000 [#1] SMP
+Modules linked in: cdc_acm usb_f_fs usb_f_serial
+usb_f_acm u_serial libcomposite configfs dummy_hcd bnep intel_rapl
+x86_pkg_temp_thermal intel_powerclamp coretemp kvm_intel kvm
+snd_hda_codec_hdmi irqbypass crct10dif_pclmul crc32_pclmul
+ghash_clmulni_intel aesni_intel aes_x86_64 lrw gf128mul glue_helper
+ablk_helper cryptd snd_hda_codec_realtek snd_hda_codec_generic serio_raw
+uvcvideo videobuf2_vmalloc btusb snd_usb_audio snd_hda_intel
+videobuf2_memops btrtl snd_hda_codec snd_hda_core snd_usbmidi_lib btbcm
+videobuf2_v4l2 btintel snd_hwdep videobuf2_core snd_seq_midi bluetooth
+snd_seq_midi_event videodev xpad efi_pstore snd_pcm_oss rfkill joydev
+media crc16 ff_memless snd_mixer_oss snd_rawmidi nls_ascii snd_pcm
+snd_seq snd_seq_device nls_cp437 mei_me snd_timer vfat sg udc_core
+lpc_ich fat
+efivars mfd_core mei snd soundcore battery nuvoton_cir rc_core evdev
+intel_smartconnect ie31200_edac edac_core shpchp tpm_tis tpm_tis_core
+tpm parport_pc ppdev lp parport efivarfs autofs4 btrfs xor raid6_pq
+hid_logitech_hidpp hid_logitech_dj hid_generic usbhid hid uas
+usb_storage sr_mod cdrom sd_mod ahci libahci nouveau i915 crc32c_intel
+i2c_algo_bit psmouse ttm xhci_pci libata scsi_mod ehci_pci
+drm_kms_helper xhci_hcd ehci_hcd r8169 mii usbcore drm nvme nvme_core
+fjes button [last unloaded: net2280]
+CPU: 5 PID: 829 Comm: bash Not tainted 4.9.0-rc7 #1
+Hardware name: To Be Filled By O.E.M. To Be Filled By O.E.M./Z77
+Extreme3, BIOS P1.50 07/11/2013
+task: ffff880419ce4040 task.stack: ffffc90002ed4000
+RIP: 0010:[<ffffffff94f5e5e9>]  [<ffffffff94f5e5e9>]
+__list_del_entry+0x29/0xc0
+RSP: 0018:ffffc90002ed7d68  EFLAGS: 00010207
+RAX: 0000000000000000 RBX: ffff88041787ec30 RCX: dead000000000200
+RDX: 0000000000000000 RSI: ffff880417482002 RDI: ffff88041787ec30
+RBP: ffffc90002ed7d68 R08: 0000000000000000 R09: 0000000000000010
+R10: 0000000000000000 R11: ffff880419ce4040 R12: ffff88041787eb68
+R13: ffff88041787eaa8 R14: ffff88041560a2c0 R15: 0000000000000001
+FS:  00007fe4e49b8700(0000) GS:ffff88042f340000(0000)
+knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 0000000000000000 CR3: 000000041b4c4000 CR4: 00000000001406e0
+Stack:
+ffffc90002ed7d80 ffffffff94f5e68d ffffffffc0ae5ef0 ffffc90002ed7da0
+ffffffffc0ae22aa ffff88041787e800 ffff88041787e800 ffffc90002ed7dc0
+ffffffffc0d7a727 ffffffff952273fa ffff88041aba5760 ffffc90002ed7df8
+Call Trace:
+[<ffffffff94f5e68d>] list_del+0xd/0x30
+[<ffffffffc0ae22aa>] usb_gadget_unregister_driver+0xaa/0xc0 [udc_core]
+[<ffffffffc0d7a727>] unregister_gadget+0x27/0x60 [libcomposite]
+[<ffffffff952273fa>] ? mutex_lock+0x1a/0x30
+[<ffffffffc0d7a9b8>] gadget_dev_desc_UDC_store+0x88/0xe0 [libcomposite]
+[<ffffffffc0af8aa0>] configfs_write_file+0xa0/0x100 [configfs]
+[<ffffffff94e10d27>] __vfs_write+0x37/0x160
+[<ffffffff94e31430>] ? __fd_install+0x30/0xd0
+[<ffffffff95229dae>] ? _raw_spin_unlock+0xe/0x10
+[<ffffffff94e11458>] vfs_write+0xb8/0x1b0
+[<ffffffff94e128f8>] SyS_write+0x58/0xc0
+[<ffffffff94e31594>] ? __close_fd+0x94/0xc0
+[<ffffffff9522a0fb>] entry_SYSCALL_64_fastpath+0x1e/0xad
+Code: 66 90 55 48 8b 07 48 b9 00 01 00 00 00 00 ad de 48 8b 57 08 48 89
+e5 48 39 c8 74 29 48 b9 00 02 00 00 00 00 ad de 48 39 ca 74 3a <4c> 8b
+02 4c 39 c7 75 52 4c 8b 40 08 4c 39 c7 75 66 48 89 50 08
+RIP  [<ffffffff94f5e5e9>] __list_del_entry+0x29/0xc0
+RSP <ffffc90002ed7d68>
+CR2: 0000000000000000
+---[ end trace 99fc090ab3ff6cbc ]---
+
+Fixes: f1bddbb ("usb: gadget: Fix binding to UDC via configfs interface")
+Signed-off-by: Felix Hädicke <felixhaedicke@web.de>
+Tested-by: Krzysztof Opasiak <k.opasiak@samsung.com>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/udc/core.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/gadget/udc/core.c
++++ b/drivers/usb/gadget/udc/core.c
+@@ -1317,7 +1317,11 @@ int usb_gadget_probe_driver(struct usb_g
+                       if (!ret)
+                               break;
+               }
+-              if (!ret && !udc->driver)
++              if (ret)
++                      ret = -ENODEV;
++              else if (udc->driver)
++                      ret = -EBUSY;
++              else
+                       goto found;
+       } else {
+               list_for_each_entry(udc, &udc_list, list) {
diff --git a/queue-4.9/usb-hub-move-hub_port_disable-to-fix-warning-if-pm-is-disabled.patch b/queue-4.9/usb-hub-move-hub_port_disable-to-fix-warning-if-pm-is-disabled.patch
new file mode 100644 (file)
index 0000000..9a5d4bc
--- /dev/null
@@ -0,0 +1,110 @@
+From 3bc02bce908c7250781376052248f5cd60a4e3d4 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert@linux-m68k.org>
+Date: Wed, 14 Dec 2016 15:37:30 +0100
+Subject: usb: hub: Move hub_port_disable() to fix warning if PM is disabled
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Geert Uytterhoeven <geert@linux-m68k.org>
+
+commit 3bc02bce908c7250781376052248f5cd60a4e3d4 upstream.
+
+If CONFIG_PM=n:
+
+    drivers/usb/core/hub.c:107: warning: ‘hub_usb3_port_prepare_disable’ declared inline after being called
+    drivers/usb/core/hub.c:107: warning: previous declaration of ‘hub_usb3_port_prepare_disable’ was here
+
+To fix this, move hub_port_disable() after
+hub_usb3_port_prepare_disable(), and adjust forward declarations.
+
+Fixes: 37be66767e3cae4f ("usb: hub: Fix auto-remount of safely removed or ejected USB-3 devices")
+Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/hub.c |   59 ++++++++++++++++++++++++-------------------------
+ 1 file changed, 29 insertions(+), 30 deletions(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -101,8 +101,7 @@ EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rws
+ static void hub_release(struct kref *kref);
+ static int usb_reset_and_verify_device(struct usb_device *udev);
+-static void hub_usb3_port_prepare_disable(struct usb_hub *hub,
+-                                        struct usb_port *port_dev);
++static int hub_port_disable(struct usb_hub *hub, int port1, int set_state);
+ static inline char *portspeed(struct usb_hub *hub, int portstatus)
+ {
+@@ -901,34 +900,6 @@ static int hub_set_port_link_state(struc
+ }
+ /*
+- * USB-3 does not have a similar link state as USB-2 that will avoid negotiating
+- * a connection with a plugged-in cable but will signal the host when the cable
+- * is unplugged. Disable remote wake and set link state to U3 for USB-3 devices
+- */
+-static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
+-{
+-      struct usb_port *port_dev = hub->ports[port1 - 1];
+-      struct usb_device *hdev = hub->hdev;
+-      int ret = 0;
+-
+-      if (!hub->error) {
+-              if (hub_is_superspeed(hub->hdev)) {
+-                      hub_usb3_port_prepare_disable(hub, port_dev);
+-                      ret = hub_set_port_link_state(hub, port_dev->portnum,
+-                                                    USB_SS_PORT_LS_U3);
+-              } else {
+-                      ret = usb_clear_port_feature(hdev, port1,
+-                                      USB_PORT_FEAT_ENABLE);
+-              }
+-      }
+-      if (port_dev->child && set_state)
+-              usb_set_device_state(port_dev->child, USB_STATE_NOTATTACHED);
+-      if (ret && ret != -ENODEV)
+-              dev_err(&port_dev->dev, "cannot disable (err = %d)\n", ret);
+-      return ret;
+-}
+-
+-/*
+  * Disable a port and mark a logical connect-change event, so that some
+  * time later hub_wq will disconnect() any existing usb_device on the port
+  * and will re-enumerate if there actually is a device attached.
+@@ -4153,6 +4124,34 @@ static int hub_handle_remote_wakeup(stru
+ #endif        /* CONFIG_PM */
++/*
++ * USB-3 does not have a similar link state as USB-2 that will avoid negotiating
++ * a connection with a plugged-in cable but will signal the host when the cable
++ * is unplugged. Disable remote wake and set link state to U3 for USB-3 devices
++ */
++static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
++{
++      struct usb_port *port_dev = hub->ports[port1 - 1];
++      struct usb_device *hdev = hub->hdev;
++      int ret = 0;
++
++      if (!hub->error) {
++              if (hub_is_superspeed(hub->hdev)) {
++                      hub_usb3_port_prepare_disable(hub, port_dev);
++                      ret = hub_set_port_link_state(hub, port_dev->portnum,
++                                                    USB_SS_PORT_LS_U3);
++              } else {
++                      ret = usb_clear_port_feature(hdev, port1,
++                                      USB_PORT_FEAT_ENABLE);
++              }
++      }
++      if (port_dev->child && set_state)
++              usb_set_device_state(port_dev->child, USB_STATE_NOTATTACHED);
++      if (ret && ret != -ENODEV)
++              dev_err(&port_dev->dev, "cannot disable (err = %d)\n", ret);
++      return ret;
++}
++
+ /* USB 2.0 spec, 7.1.7.3 / fig 7-29:
+  *
diff --git a/queue-4.9/usb-musb-blackfin-add-bfin_fifo_offset-in-bfin_ops.patch b/queue-4.9/usb-musb-blackfin-add-bfin_fifo_offset-in-bfin_ops.patch
new file mode 100644 (file)
index 0000000..8e9d817
--- /dev/null
@@ -0,0 +1,41 @@
+From 5563bb5743cb09bde0d0f4660a5e5b19c26903bf Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Lefaure?= <jeremy.lefaure@lse.epita.fr>
+Date: Tue, 3 Jan 2017 18:13:52 -0600
+Subject: usb: musb: blackfin: add bfin_fifo_offset in bfin_ops
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jérémy Lefaure <jeremy.lefaure@lse.epita.fr>
+
+commit 5563bb5743cb09bde0d0f4660a5e5b19c26903bf upstream.
+
+The function bfin_fifo_offset is defined but not used:
+
+drivers/usb/musb/blackfin.c:36:12: warning: ‘bfin_fifo_offset’ defined
+but not used [-Wunused-function]
+ static u32 bfin_fifo_offset(u8 epnum)
+             ^~~~~~~~~~~~~~~~
+
+Adding bfin_fifo_offset to bfin_ops fixes this warning and allows musb
+core to call this function instead of default_fifo_offset.
+
+Fixes: cc92f6818f6e ("usb: musb: Populate new IO functions for blackfin")
+Signed-off-by: Jérémy Lefaure <jeremy.lefaure@lse.epita.fr>
+Signed-off-by: Bin Liu <b-liu@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/musb/blackfin.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/musb/blackfin.c
++++ b/drivers/usb/musb/blackfin.c
+@@ -469,6 +469,7 @@ static const struct musb_platform_ops bf
+       .init           = bfin_musb_init,
+       .exit           = bfin_musb_exit,
++      .fifo_offset    = bfin_fifo_offset,
+       .readb          = bfin_readb,
+       .writeb         = bfin_writeb,
+       .readw          = bfin_readw,
diff --git a/queue-4.9/usb-musb-fix-trying-to-free-already-free-irq-4.patch b/queue-4.9/usb-musb-fix-trying-to-free-already-free-irq-4.patch
new file mode 100644 (file)
index 0000000..22c3f57
--- /dev/null
@@ -0,0 +1,44 @@
+From 8c300fe282fa254ea730c92cb0983e2642dc1fff Mon Sep 17 00:00:00 2001
+From: Tony Lindgren <tony@atomide.com>
+Date: Tue, 3 Jan 2017 18:13:48 -0600
+Subject: usb: musb: Fix trying to free already-free IRQ 4
+
+From: Tony Lindgren <tony@atomide.com>
+
+commit 8c300fe282fa254ea730c92cb0983e2642dc1fff upstream.
+
+When unloading omap2430, we can get the following splat:
+
+WARNING: CPU: 1 PID: 295 at kernel/irq/manage.c:1478 __free_irq+0xa8/0x2c8
+Trying to free already-free IRQ 4
+...
+[<c01a8b78>] (free_irq) from [<bf0aea84>]
+(musbhs_dma_controller_destroy+0x28/0xb0 [musb_hdrc])
+[<bf0aea84>] (musbhs_dma_controller_destroy [musb_hdrc]) from
+[<bf09f88c>] (musb_remove+0xf0/0x12c [musb_hdrc])
+[<bf09f88c>] (musb_remove [musb_hdrc]) from [<c056a384>]
+(platform_drv_remove+0x24/0x3c)
+...
+
+This is because the irq number in use is 260 nowadays, and the dma
+controller is using u8 instead of int.
+
+Fixes: 6995eb68aab7 ("USB: musb: enable low level DMA operation for Blackfin")
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+[b-liu@ti.com: added Fixes tag]
+Signed-off-by: Bin Liu <b-liu@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/musb/musbhsdma.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/musb/musbhsdma.h
++++ b/drivers/usb/musb/musbhsdma.h
+@@ -157,5 +157,5 @@ struct musb_dma_controller {
+       void __iomem                    *base;
+       u8                              channel_count;
+       u8                              used_channels;
+-      u8                              irq;
++      int                             irq;
+ };
diff --git a/queue-4.9/xhci-fix-race-related-to-abort-operation.patch b/queue-4.9/xhci-fix-race-related-to-abort-operation.patch
new file mode 100644 (file)
index 0000000..e65edd5
--- /dev/null
@@ -0,0 +1,312 @@
+From 1c111b6c3844a142e03bcfc2fa17bfbdea08e9dc Mon Sep 17 00:00:00 2001
+From: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
+Date: Tue, 3 Jan 2017 18:28:51 +0200
+Subject: xhci: Fix race related to abort operation
+
+From: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
+
+commit 1c111b6c3844a142e03bcfc2fa17bfbdea08e9dc upstream.
+
+Current abort operation has race.
+
+    xhci_handle_command_timeout()
+      xhci_abort_cmd_ring()
+        xhci_write_64(CMD_RING_ABORT)
+        xhci_handshake(5s)
+         do {
+           check CMD_RING_RUNNING
+            udelay(1)
+                                        ...
+                                        COMP_CMD_ABORT event
+                                        COMP_CMD_STOP event
+                                        xhci_handle_stopped_cmd_ring()
+                                          restart cmd_ring
+                                           CMD_RING_RUNNING become 1 again
+         } while ()
+          return -ETIMEDOUT
+        xhci_write_64(CMD_RING_ABORT)
+        /* can abort random command */
+
+To do abort operation correctly, we have to wait both of COMP_CMD_STOP
+event and negation of CMD_RING_RUNNING.
+
+But like above, while timeout handler is waiting negation of
+CMD_RING_RUNNING, event handler can restart cmd_ring. So timeout
+handler never be notice negation of CMD_RING_RUNNING, and retry of
+CMD_RING_ABORT can abort random command (BTW, I guess retry of
+CMD_RING_ABORT was workaround of this race).
+
+To fix this race, this moves xhci_handle_stopped_cmd_ring() to
+xhci_abort_cmd_ring().  And timeout handler waits COMP_CMD_STOP event.
+
+At this point, timeout handler is owner of cmd_ring, and safely
+restart cmd_ring by using xhci_handle_stopped_cmd_ring().
+
+[FWIW, as bonus, this way would be easily extend to add CMD_RING_PAUSE
+operation]
+
+[locks edited as patch is rebased on other locking fixes -Mathias]
+Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-mem.c  |    1 
+ drivers/usb/host/xhci-ring.c |  169 ++++++++++++++++++++++---------------------
+ drivers/usb/host/xhci.h      |    1 
+ 3 files changed, 91 insertions(+), 80 deletions(-)
+
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -2379,6 +2379,7 @@ int xhci_mem_init(struct xhci_hcd *xhci,
+       /* init command timeout work */
+       INIT_DELAYED_WORK(&xhci->cmd_timer, xhci_handle_command_timeout);
++      init_completion(&xhci->cmd_ring_stop_completion);
+       page_size = readl(&xhci->op_regs->page_size);
+       xhci_dbg_trace(xhci, trace_xhci_dbg_init,
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -265,23 +265,71 @@ static bool xhci_mod_cmd_timer(struct xh
+       return mod_delayed_work(system_wq, &xhci->cmd_timer, delay);
+ }
+-static int xhci_abort_cmd_ring(struct xhci_hcd *xhci)
++static struct xhci_command *xhci_next_queued_cmd(struct xhci_hcd *xhci)
++{
++      return list_first_entry_or_null(&xhci->cmd_list, struct xhci_command,
++                                      cmd_list);
++}
++
++/*
++ * Turn all commands on command ring with status set to "aborted" to no-op trbs.
++ * If there are other commands waiting then restart the ring and kick the timer.
++ * This must be called with command ring stopped and xhci->lock held.
++ */
++static void xhci_handle_stopped_cmd_ring(struct xhci_hcd *xhci,
++                                       struct xhci_command *cur_cmd)
++{
++      struct xhci_command *i_cmd;
++      u32 cycle_state;
++
++      /* Turn all aborted commands in list to no-ops, then restart */
++      list_for_each_entry(i_cmd, &xhci->cmd_list, cmd_list) {
++
++              if (i_cmd->status != COMP_CMD_ABORT)
++                      continue;
++
++              i_cmd->status = COMP_CMD_STOP;
++
++              xhci_dbg(xhci, "Turn aborted command %p to no-op\n",
++                       i_cmd->command_trb);
++              /* get cycle state from the original cmd trb */
++              cycle_state = le32_to_cpu(
++                      i_cmd->command_trb->generic.field[3]) & TRB_CYCLE;
++              /* modify the command trb to no-op command */
++              i_cmd->command_trb->generic.field[0] = 0;
++              i_cmd->command_trb->generic.field[1] = 0;
++              i_cmd->command_trb->generic.field[2] = 0;
++              i_cmd->command_trb->generic.field[3] = cpu_to_le32(
++                      TRB_TYPE(TRB_CMD_NOOP) | cycle_state);
++
++              /*
++               * caller waiting for completion is called when command
++               *  completion event is received for these no-op commands
++               */
++      }
++
++      xhci->cmd_ring_state = CMD_RING_STATE_RUNNING;
++
++      /* ring command ring doorbell to restart the command ring */
++      if ((xhci->cmd_ring->dequeue != xhci->cmd_ring->enqueue) &&
++          !(xhci->xhc_state & XHCI_STATE_DYING)) {
++              xhci->current_cmd = cur_cmd;
++              xhci_mod_cmd_timer(xhci, XHCI_CMD_DEFAULT_TIMEOUT);
++              xhci_ring_cmd_db(xhci);
++      }
++}
++
++/* Must be called with xhci->lock held, releases and aquires lock back */
++static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long flags)
+ {
+       u64 temp_64;
+       int ret;
+       xhci_dbg(xhci, "Abort command ring\n");
+-      temp_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
+-      xhci->cmd_ring_state = CMD_RING_STATE_ABORTED;
++      reinit_completion(&xhci->cmd_ring_stop_completion);
+-      /*
+-       * Writing the CMD_RING_ABORT bit should cause a cmd completion event,
+-       * however on some host hw the CMD_RING_RUNNING bit is correctly cleared
+-       * but the completion event in never sent. Use the cmd timeout timer to
+-       * handle those cases. Use twice the time to cover the bit polling retry
+-       */
+-      xhci_mod_cmd_timer(xhci, 2 * XHCI_CMD_DEFAULT_TIMEOUT);
++      temp_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
+       xhci_write_64(xhci, temp_64 | CMD_RING_ABORT,
+                       &xhci->op_regs->cmd_ring);
+@@ -301,16 +349,30 @@ static int xhci_abort_cmd_ring(struct xh
+               udelay(1000);
+               ret = xhci_handshake(&xhci->op_regs->cmd_ring,
+                                    CMD_RING_RUNNING, 0, 3 * 1000 * 1000);
+-              if (ret == 0)
+-                      return 0;
+-
+-              xhci_err(xhci, "Stopped the command ring failed, "
+-                              "maybe the host is dead\n");
+-              cancel_delayed_work(&xhci->cmd_timer);
+-              xhci->xhc_state |= XHCI_STATE_DYING;
+-              xhci_quiesce(xhci);
+-              xhci_halt(xhci);
+-              return -ESHUTDOWN;
++              if (ret < 0) {
++                      xhci_err(xhci, "Stopped the command ring failed, "
++                               "maybe the host is dead\n");
++                      xhci->xhc_state |= XHCI_STATE_DYING;
++                      xhci_quiesce(xhci);
++                      xhci_halt(xhci);
++                      return -ESHUTDOWN;
++              }
++      }
++      /*
++       * Writing the CMD_RING_ABORT bit should cause a cmd completion event,
++       * however on some host hw the CMD_RING_RUNNING bit is correctly cleared
++       * but the completion event in never sent. Wait 2 secs (arbitrary
++       * number) to handle those cases after negation of CMD_RING_RUNNING.
++       */
++      spin_unlock_irqrestore(&xhci->lock, flags);
++      ret = wait_for_completion_timeout(&xhci->cmd_ring_stop_completion,
++                                        msecs_to_jiffies(2000));
++      spin_lock_irqsave(&xhci->lock, flags);
++      if (!ret) {
++              xhci_dbg(xhci, "No stop event for abort, ring start fail?\n");
++              xhci_cleanup_command_queue(xhci);
++      } else {
++              xhci_handle_stopped_cmd_ring(xhci, xhci_next_queued_cmd(xhci));
+       }
+       return 0;
+@@ -1216,64 +1278,12 @@ void xhci_cleanup_command_queue(struct x
+               xhci_complete_del_and_free_cmd(cur_cmd, COMP_CMD_ABORT);
+ }
+-/*
+- * Turn all commands on command ring with status set to "aborted" to no-op trbs.
+- * If there are other commands waiting then restart the ring and kick the timer.
+- * This must be called with command ring stopped and xhci->lock held.
+- */
+-static void xhci_handle_stopped_cmd_ring(struct xhci_hcd *xhci,
+-                                       struct xhci_command *cur_cmd)
+-{
+-      struct xhci_command *i_cmd, *tmp_cmd;
+-      u32 cycle_state;
+-
+-      /* Turn all aborted commands in list to no-ops, then restart */
+-      list_for_each_entry_safe(i_cmd, tmp_cmd, &xhci->cmd_list,
+-                               cmd_list) {
+-
+-              if (i_cmd->status != COMP_CMD_ABORT)
+-                      continue;
+-
+-              i_cmd->status = COMP_CMD_STOP;
+-
+-              xhci_dbg(xhci, "Turn aborted command %p to no-op\n",
+-                       i_cmd->command_trb);
+-              /* get cycle state from the original cmd trb */
+-              cycle_state = le32_to_cpu(
+-                      i_cmd->command_trb->generic.field[3]) & TRB_CYCLE;
+-              /* modify the command trb to no-op command */
+-              i_cmd->command_trb->generic.field[0] = 0;
+-              i_cmd->command_trb->generic.field[1] = 0;
+-              i_cmd->command_trb->generic.field[2] = 0;
+-              i_cmd->command_trb->generic.field[3] = cpu_to_le32(
+-                      TRB_TYPE(TRB_CMD_NOOP) | cycle_state);
+-
+-              /*
+-               * caller waiting for completion is called when command
+-               *  completion event is received for these no-op commands
+-               */
+-      }
+-
+-      xhci->cmd_ring_state = CMD_RING_STATE_RUNNING;
+-
+-      /* ring command ring doorbell to restart the command ring */
+-      if ((xhci->cmd_ring->dequeue != xhci->cmd_ring->enqueue) &&
+-          !(xhci->xhc_state & XHCI_STATE_DYING)) {
+-              xhci->current_cmd = cur_cmd;
+-              xhci_mod_cmd_timer(xhci, XHCI_CMD_DEFAULT_TIMEOUT);
+-              xhci_ring_cmd_db(xhci);
+-      }
+-      return;
+-}
+-
+-
+ void xhci_handle_command_timeout(struct work_struct *work)
+ {
+       struct xhci_hcd *xhci;
+       int ret;
+       unsigned long flags;
+       u64 hw_ring_state;
+-      bool second_timeout = false;
+       xhci = container_of(to_delayed_work(work), struct xhci_hcd, cmd_timer);
+@@ -1287,18 +1297,17 @@ void xhci_handle_command_timeout(struct
+               spin_unlock_irqrestore(&xhci->lock, flags);
+               return;
+       }
+-
+       /* mark this command to be cancelled */
+-      if (xhci->current_cmd->status == COMP_CMD_ABORT)
+-              second_timeout = true;
+       xhci->current_cmd->status = COMP_CMD_ABORT;
+       /* Make sure command ring is running before aborting it */
+       hw_ring_state = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
+       if ((xhci->cmd_ring_state & CMD_RING_STATE_RUNNING) &&
+           (hw_ring_state & CMD_RING_RUNNING))  {
++              /* Prevent new doorbell, and start command abort */
++              xhci->cmd_ring_state = CMD_RING_STATE_ABORTED;
+               xhci_dbg(xhci, "Command timeout\n");
+-              ret = xhci_abort_cmd_ring(xhci);
++              ret = xhci_abort_cmd_ring(xhci, flags);
+               if (unlikely(ret == -ESHUTDOWN)) {
+                       xhci_err(xhci, "Abort command ring failed\n");
+                       xhci_cleanup_command_queue(xhci);
+@@ -1312,9 +1321,9 @@ void xhci_handle_command_timeout(struct
+               goto time_out_completed;
+       }
+-      /* command ring failed to restart, or host removed. Bail out */
+-      if (second_timeout || xhci->xhc_state & XHCI_STATE_REMOVING) {
+-              xhci_dbg(xhci, "command timed out twice, ring start fail?\n");
++      /* host removed. Bail out */
++      if (xhci->xhc_state & XHCI_STATE_REMOVING) {
++              xhci_dbg(xhci, "host removed, ring start fail?\n");
+               xhci_cleanup_command_queue(xhci);
+               goto time_out_completed;
+@@ -1365,7 +1374,7 @@ static void handle_cmd_completion(struct
+       /* If CMD ring stopped we own the trbs between enqueue and dequeue */
+       if (cmd_comp_code == COMP_CMD_STOP) {
+-              xhci_handle_stopped_cmd_ring(xhci, cmd);
++              complete_all(&xhci->cmd_ring_stop_completion);
+               return;
+       }
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1572,6 +1572,7 @@ struct xhci_hcd {
+       struct list_head        cmd_list;
+       unsigned int            cmd_ring_reserved_trbs;
+       struct delayed_work     cmd_timer;
++      struct completion       cmd_ring_stop_completion;
+       struct xhci_command     *current_cmd;
+       struct xhci_ring        *event_ring;
+       struct xhci_erst        erst;
diff --git a/queue-4.9/xhci-use-delayed_work-instead-of-timer-for-command-timeout.patch b/queue-4.9/xhci-use-delayed_work-instead-of-timer-for-command-timeout.patch
new file mode 100644 (file)
index 0000000..d3e7c0f
--- /dev/null
@@ -0,0 +1,164 @@
+From cb4d5ce588c5ff68e0fdd30370a0e6bc2c0a736b Mon Sep 17 00:00:00 2001
+From: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
+Date: Tue, 3 Jan 2017 18:28:50 +0200
+Subject: xhci: Use delayed_work instead of timer for command timeout
+
+From: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
+
+commit cb4d5ce588c5ff68e0fdd30370a0e6bc2c0a736b upstream.
+
+This is preparation to fix abort operation race (See "xhci: Fix race
+related to abort operation"). To make timeout sleepable, use
+delayed_work instead of timer.
+
+[change a newly added pending timer fix to pending work -Mathias]
+Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-mem.c  |    7 +++----
+ drivers/usb/host/xhci-ring.c |   26 ++++++++++++++++----------
+ drivers/usb/host/xhci.h      |    4 ++--
+ 3 files changed, 21 insertions(+), 16 deletions(-)
+
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -1830,7 +1830,7 @@ void xhci_mem_cleanup(struct xhci_hcd *x
+       int size;
+       int i, j, num_ports;
+-      del_timer_sync(&xhci->cmd_timer);
++      cancel_delayed_work_sync(&xhci->cmd_timer);
+       /* Free the Event Ring Segment Table and the actual Event Ring */
+       size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries);
+@@ -2377,9 +2377,8 @@ int xhci_mem_init(struct xhci_hcd *xhci,
+       INIT_LIST_HEAD(&xhci->cmd_list);
+-      /* init command timeout timer */
+-      setup_timer(&xhci->cmd_timer, xhci_handle_command_timeout,
+-                  (unsigned long)xhci);
++      /* init command timeout work */
++      INIT_DELAYED_WORK(&xhci->cmd_timer, xhci_handle_command_timeout);
+       page_size = readl(&xhci->op_regs->page_size);
+       xhci_dbg_trace(xhci, trace_xhci_dbg_init,
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -260,6 +260,11 @@ void xhci_ring_cmd_db(struct xhci_hcd *x
+       readl(&xhci->dba->doorbell[0]);
+ }
++static bool xhci_mod_cmd_timer(struct xhci_hcd *xhci, unsigned long delay)
++{
++      return mod_delayed_work(system_wq, &xhci->cmd_timer, delay);
++}
++
+ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci)
+ {
+       u64 temp_64;
+@@ -276,7 +281,7 @@ static int xhci_abort_cmd_ring(struct xh
+        * but the completion event in never sent. Use the cmd timeout timer to
+        * handle those cases. Use twice the time to cover the bit polling retry
+        */
+-      mod_timer(&xhci->cmd_timer, jiffies + (2 * XHCI_CMD_DEFAULT_TIMEOUT));
++      xhci_mod_cmd_timer(xhci, 2 * XHCI_CMD_DEFAULT_TIMEOUT);
+       xhci_write_64(xhci, temp_64 | CMD_RING_ABORT,
+                       &xhci->op_regs->cmd_ring);
+@@ -301,7 +306,7 @@ static int xhci_abort_cmd_ring(struct xh
+               xhci_err(xhci, "Stopped the command ring failed, "
+                               "maybe the host is dead\n");
+-              del_timer(&xhci->cmd_timer);
++              cancel_delayed_work(&xhci->cmd_timer);
+               xhci->xhc_state |= XHCI_STATE_DYING;
+               xhci_quiesce(xhci);
+               xhci_halt(xhci);
+@@ -1255,21 +1260,22 @@ static void xhci_handle_stopped_cmd_ring
+       if ((xhci->cmd_ring->dequeue != xhci->cmd_ring->enqueue) &&
+           !(xhci->xhc_state & XHCI_STATE_DYING)) {
+               xhci->current_cmd = cur_cmd;
+-              mod_timer(&xhci->cmd_timer, jiffies + XHCI_CMD_DEFAULT_TIMEOUT);
++              xhci_mod_cmd_timer(xhci, XHCI_CMD_DEFAULT_TIMEOUT);
+               xhci_ring_cmd_db(xhci);
+       }
+       return;
+ }
+-void xhci_handle_command_timeout(unsigned long data)
++void xhci_handle_command_timeout(struct work_struct *work)
+ {
+       struct xhci_hcd *xhci;
+       int ret;
+       unsigned long flags;
+       u64 hw_ring_state;
+       bool second_timeout = false;
+-      xhci = (struct xhci_hcd *) data;
++
++      xhci = container_of(to_delayed_work(work), struct xhci_hcd, cmd_timer);
+       spin_lock_irqsave(&xhci->lock, flags);
+@@ -1277,7 +1283,7 @@ void xhci_handle_command_timeout(unsigne
+        * If timeout work is pending, or current_cmd is NULL, it means we
+        * raced with command completion. Command is handled so just return.
+        */
+-      if (!xhci->current_cmd || timer_pending(&xhci->cmd_timer)) {
++      if (!xhci->current_cmd || delayed_work_pending(&xhci->cmd_timer)) {
+               spin_unlock_irqrestore(&xhci->lock, flags);
+               return;
+       }
+@@ -1351,7 +1357,7 @@ static void handle_cmd_completion(struct
+       cmd = list_entry(xhci->cmd_list.next, struct xhci_command, cmd_list);
+-      del_timer(&xhci->cmd_timer);
++      cancel_delayed_work(&xhci->cmd_timer);
+       trace_xhci_cmd_completion(cmd_trb, (struct xhci_generic_trb *) event);
+@@ -1442,7 +1448,7 @@ static void handle_cmd_completion(struct
+       if (cmd->cmd_list.next != &xhci->cmd_list) {
+               xhci->current_cmd = list_entry(cmd->cmd_list.next,
+                                              struct xhci_command, cmd_list);
+-              mod_timer(&xhci->cmd_timer, jiffies + XHCI_CMD_DEFAULT_TIMEOUT);
++              xhci_mod_cmd_timer(xhci, XHCI_CMD_DEFAULT_TIMEOUT);
+       } else if (xhci->current_cmd == cmd) {
+               xhci->current_cmd = NULL;
+       }
+@@ -3938,9 +3944,9 @@ static int queue_command(struct xhci_hcd
+       /* if there are no other commands queued we start the timeout timer */
+       if (xhci->cmd_list.next == &cmd->cmd_list &&
+-          !timer_pending(&xhci->cmd_timer)) {
++          !delayed_work_pending(&xhci->cmd_timer)) {
+               xhci->current_cmd = cmd;
+-              mod_timer(&xhci->cmd_timer, jiffies + XHCI_CMD_DEFAULT_TIMEOUT);
++              xhci_mod_cmd_timer(xhci, XHCI_CMD_DEFAULT_TIMEOUT);
+       }
+       queue_trb(xhci, xhci->cmd_ring, false, field1, field2, field3,
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1571,7 +1571,7 @@ struct xhci_hcd {
+ #define CMD_RING_STATE_STOPPED         (1 << 2)
+       struct list_head        cmd_list;
+       unsigned int            cmd_ring_reserved_trbs;
+-      struct timer_list       cmd_timer;
++      struct delayed_work     cmd_timer;
+       struct xhci_command     *current_cmd;
+       struct xhci_ring        *event_ring;
+       struct xhci_erst        erst;
+@@ -1941,7 +1941,7 @@ void xhci_queue_config_ep_quirk(struct x
+               unsigned int slot_id, unsigned int ep_index,
+               struct xhci_dequeue_state *deq_state);
+ void xhci_stop_endpoint_command_watchdog(unsigned long arg);
+-void xhci_handle_command_timeout(unsigned long data);
++void xhci_handle_command_timeout(struct work_struct *work);
+ void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, unsigned int slot_id,
+               unsigned int ep_index, unsigned int stream_id);