]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
.36 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Tue, 1 Feb 2011 00:24:09 +0000 (16:24 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 1 Feb 2011 00:24:09 +0000 (16:24 -0800)
queue-2.6.36/alsa-snd-usb-us122l-fix-midi-output.patch [new file with mode: 0644]
queue-2.6.36/alsa-snd-usb-us122l-fix-missing-null-checks.patch [new file with mode: 0644]
queue-2.6.36/rt2x00-add-device-id-for-windy31-usb-device.patch [new file with mode: 0644]
queue-2.6.36/staging-rt2870sta-add-id-for-linksys-wusb100v2.patch [new file with mode: 0644]
queue-2.6.36/staging-usbip-remove-double-giveback-of-urb.patch [new file with mode: 0644]
queue-2.6.36/usb-ehci-aspm-quirk-of-isoc-on-amd-sb800.patch [new file with mode: 0644]

diff --git a/queue-2.6.36/alsa-snd-usb-us122l-fix-midi-output.patch b/queue-2.6.36/alsa-snd-usb-us122l-fix-midi-output.patch
new file mode 100644 (file)
index 0000000..a52e3e0
--- /dev/null
@@ -0,0 +1,46 @@
+From 921eebdc18c82268eab446592191b39e35d031d6 Mon Sep 17 00:00:00 2001
+From: Karsten Wiese <fzu@wemgehoertderstaat.de>
+Date: Mon, 3 Jan 2011 02:41:58 +0100
+Subject: ALSA: snd-usb-us122l: Fix MIDI output
+
+From: Karsten Wiese <fzu@wemgehoertderstaat.de>
+
+commit 921eebdc18c82268eab446592191b39e35d031d6 upstream.
+
+The US-122L always reads 9 bytes per urb unless they are set to 0xFD.
+
+Signed-off-by: Karsten Wiese <fzu@wemgehoertderstaat.de>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ sound/usb/midi.c |   11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/sound/usb/midi.c
++++ b/sound/usb/midi.c
+@@ -843,8 +843,8 @@ static void snd_usbmidi_us122l_output(st
+               return;
+       }
+-      memset(urb->transfer_buffer + count, 0xFD, 9 - count);
+-      urb->transfer_buffer_length = count;
++      memset(urb->transfer_buffer + count, 0xFD, ep->max_transfer - count);
++      urb->transfer_buffer_length = ep->max_transfer;
+ }
+ static struct usb_protocol_ops snd_usbmidi_122l_ops = {
+@@ -1288,6 +1288,13 @@ static int snd_usbmidi_out_endpoint_crea
+       case USB_ID(0x1a86, 0x752d): /* QinHeng CH345 "USB2.0-MIDI" */
+               ep->max_transfer = 4;
+               break;
++              /*
++               * Some devices only work with 9 bytes packet size:
++               */
++      case USB_ID(0x0644, 0x800E): /* Tascam US-122L */
++      case USB_ID(0x0644, 0x800F): /* Tascam US-144 */
++              ep->max_transfer = 9;
++              break;
+       }
+       for (i = 0; i < OUTPUT_URBS; ++i) {
+               buffer = usb_alloc_coherent(umidi->dev,
diff --git a/queue-2.6.36/alsa-snd-usb-us122l-fix-missing-null-checks.patch b/queue-2.6.36/alsa-snd-usb-us122l-fix-missing-null-checks.patch
new file mode 100644 (file)
index 0000000..d3a4bd5
--- /dev/null
@@ -0,0 +1,105 @@
+From cdce2db74e156fbd9a2dc3c7b246166f8b70955b Mon Sep 17 00:00:00 2001
+From: Karsten Wiese <fzu@wemgehoertderstaat.de>
+Date: Tue, 4 Jan 2011 01:20:37 +0100
+Subject: ALSA: snd-usb-us122l: Fix missing NULL checks
+
+From: Karsten Wiese <fzu@wemgehoertderstaat.de>
+
+commit cdce2db74e156fbd9a2dc3c7b246166f8b70955b upstream.
+
+Fix missing NULL checks in usb_stream_hwdep_poll() and usb_stream_hwdep_ioctl().
+Wake up poll waiters before returning from usb_stream_hwdep_ioctl().
+
+Signed-off-by: Karsten Wiese <fzu@wemgehoertderstaat.de>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ sound/usb/usx2y/us122l.c |   41 ++++++++++++++++++++---------------------
+ 1 file changed, 20 insertions(+), 21 deletions(-)
+
+--- a/sound/usb/usx2y/us122l.c
++++ b/sound/usb/usx2y/us122l.c
+@@ -273,29 +273,26 @@ static unsigned int usb_stream_hwdep_pol
+                                         struct file *file, poll_table *wait)
+ {
+       struct us122l   *us122l = hw->private_data;
+-      struct usb_stream *s = us122l->sk.s;
+       unsigned        *polled;
+       unsigned int    mask;
+       poll_wait(file, &us122l->sk.sleep, wait);
+-      switch (s->state) {
+-      case usb_stream_ready:
+-              if (us122l->first == file)
+-                      polled = &s->periods_polled;
+-              else
+-                      polled = &us122l->second_periods_polled;
+-              if (*polled != s->periods_done) {
+-                      *polled = s->periods_done;
+-                      mask = POLLIN | POLLOUT | POLLWRNORM;
+-                      break;
++      mask = POLLIN | POLLOUT | POLLWRNORM | POLLERR;
++      if (mutex_trylock(&us122l->mutex)) {
++              struct usb_stream *s = us122l->sk.s;
++              if (s && s->state == usb_stream_ready) {
++                      if (us122l->first == file)
++                              polled = &s->periods_polled;
++                      else
++                              polled = &us122l->second_periods_polled;
++                      if (*polled != s->periods_done) {
++                              *polled = s->periods_done;
++                              mask = POLLIN | POLLOUT | POLLWRNORM;
++                      } else
++                              mask = 0;
+               }
+-              /* Fall through */
+-              mask = 0;
+-              break;
+-      default:
+-              mask = POLLIN | POLLOUT | POLLWRNORM | POLLERR;
+-              break;
++              mutex_unlock(&us122l->mutex);
+       }
+       return mask;
+ }
+@@ -381,6 +378,7 @@ static int usb_stream_hwdep_ioctl(struct
+ {
+       struct usb_stream_config *cfg;
+       struct us122l *us122l = hw->private_data;
++      struct usb_stream *s;
+       unsigned min_period_frames;
+       int err = 0;
+       bool high_speed;
+@@ -426,18 +424,18 @@ static int usb_stream_hwdep_ioctl(struct
+       snd_power_wait(hw->card, SNDRV_CTL_POWER_D0);
+       mutex_lock(&us122l->mutex);
++      s = us122l->sk.s;
+       if (!us122l->master)
+               us122l->master = file;
+       else if (us122l->master != file) {
+-              if (memcmp(cfg, &us122l->sk.s->cfg, sizeof(*cfg))) {
++              if (!s || memcmp(cfg, &s->cfg, sizeof(*cfg))) {
+                       err = -EIO;
+                       goto unlock;
+               }
+               us122l->slave = file;
+       }
+-      if (!us122l->sk.s ||
+-          memcmp(cfg, &us122l->sk.s->cfg, sizeof(*cfg)) ||
+-          us122l->sk.s->state == usb_stream_xrun) {
++      if (!s || memcmp(cfg, &s->cfg, sizeof(*cfg)) ||
++          s->state == usb_stream_xrun) {
+               us122l_stop(us122l);
+               if (!us122l_start(us122l, cfg->sample_rate, cfg->period_frames))
+                       err = -EIO;
+@@ -448,6 +446,7 @@ unlock:
+       mutex_unlock(&us122l->mutex);
+ free:
+       kfree(cfg);
++      wake_up_all(&us122l->sk.sleep);
+       return err;
+ }
diff --git a/queue-2.6.36/rt2x00-add-device-id-for-windy31-usb-device.patch b/queue-2.6.36/rt2x00-add-device-id-for-windy31-usb-device.patch
new file mode 100644 (file)
index 0000000..e056e0b
--- /dev/null
@@ -0,0 +1,35 @@
+From 9c4cf6d94fb362c27a24df5223ed6e327eb7279a Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@suse.de>
+Date: Tue, 25 Jan 2011 17:42:29 +0800
+Subject: rt2x00: add device id for windy31 usb device
+
+From: Greg Kroah-Hartman <gregkh@suse.de>
+
+commit 9c4cf6d94fb362c27a24df5223ed6e327eb7279a upstream.
+
+This patch adds the device id for the windy31 USB device to the rt73usb
+driver.
+
+Thanks to Ralf Flaxa for reporting this and providing testing and a
+sample device.
+
+Reported-by: Ralf Flaxa <rf@suse.de>
+Tested-by: Ralf Flaxa <rf@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+Acked-by: Ivo van Doorn <IvDoorn@gmail.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+
+---
+ drivers/net/wireless/rt2x00/rt73usb.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/wireless/rt2x00/rt73usb.c
++++ b/drivers/net/wireless/rt2x00/rt73usb.c
+@@ -2395,6 +2395,7 @@ static struct usb_device_id rt73usb_devi
+       { USB_DEVICE(0x04bb, 0x093d), USB_DEVICE_DATA(&rt73usb_ops) },
+       { USB_DEVICE(0x148f, 0x2573), USB_DEVICE_DATA(&rt73usb_ops) },
+       { USB_DEVICE(0x148f, 0x2671), USB_DEVICE_DATA(&rt73usb_ops) },
++      { USB_DEVICE(0x0812, 0x3101), USB_DEVICE_DATA(&rt73usb_ops) },
+       /* Qcom */
+       { USB_DEVICE(0x18e8, 0x6196), USB_DEVICE_DATA(&rt73usb_ops) },
+       { USB_DEVICE(0x18e8, 0x6229), USB_DEVICE_DATA(&rt73usb_ops) },
diff --git a/queue-2.6.36/staging-rt2870sta-add-id-for-linksys-wusb100v2.patch b/queue-2.6.36/staging-rt2870sta-add-id-for-linksys-wusb100v2.patch
new file mode 100644 (file)
index 0000000..1f577dd
--- /dev/null
@@ -0,0 +1,29 @@
+From 27c82819a5a42f08fc0f787ab1b0c129cbdda801 Mon Sep 17 00:00:00 2001
+From: Larry Finger <Larry.Finger@lwfinger.net>
+Date: Wed, 12 Jan 2011 22:24:28 -0600
+Subject: staging: rt2870sta: Add ID for Linksys WUSB100v2
+
+From: Larry Finger <Larry.Finger@lwfinger.net>
+
+commit 27c82819a5a42f08fc0f787ab1b0c129cbdda801 upstream.
+
+This device was tested with rt2870sta by setting new_id.
+
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Tested-by: Brian Ormond <brian.ormond@oit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/rt2860/usb_main_dev.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/staging/rt2860/usb_main_dev.c
++++ b/drivers/staging/rt2860/usb_main_dev.c
+@@ -106,6 +106,7 @@ struct usb_device_id rtusb_usb_id[] = {
+       {USB_DEVICE(0x0411, 0x016f)},   /* MelCo.,Inc. WLI-UC-G301N */
+       {USB_DEVICE(0x1737, 0x0070)},   /* Linksys WUSB100 */
+       {USB_DEVICE(0x1737, 0x0071)},   /* Linksys WUSB600N */
++      {USB_DEVICE(0x1737, 0x0078)},   /* Linksys WUSB100v2 */
+       {USB_DEVICE(0x0411, 0x00e8)},   /* Buffalo WLI-UC-G300N */
+       {USB_DEVICE(0x050d, 0x815c)},   /* Belkin F5D8053 */
+       {USB_DEVICE(0x100D, 0x9031)},   /* Motorola 2770 */
diff --git a/queue-2.6.36/staging-usbip-remove-double-giveback-of-urb.patch b/queue-2.6.36/staging-usbip-remove-double-giveback-of-urb.patch
new file mode 100644 (file)
index 0000000..d3dc0bd
--- /dev/null
@@ -0,0 +1,48 @@
+From 7571f089d7522a95c103558faf313c7af8856ceb Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?M=C3=A1rton=20N=C3=A9meth?= <nm127@freemail.hu>
+Date: Mon, 13 Dec 2010 21:59:09 +0100
+Subject: staging: usbip: remove double giveback of URB
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: =?UTF-8?q?M=C3=A1rton=20N=C3=A9meth?= <nm127@freemail.hu>
+
+commit 7571f089d7522a95c103558faf313c7af8856ceb upstream.
+
+In the vhci_urb_dequeue() function the TCP connection is checked twice.
+Each time when the TCP connection is closed the URB is unlinked and given
+back. Remove the second attempt of unlinking and giving back of the URB completely.
+
+This patch fixes the bug described at https://bugzilla.kernel.org/show_bug.cgi?id=24872 .
+
+Signed-off-by: Márton Németh <nm127@freemail.hu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/usbip/vhci_hcd.c |   14 --------------
+ 1 file changed, 14 deletions(-)
+
+--- a/drivers/staging/usbip/vhci_hcd.c
++++ b/drivers/staging/usbip/vhci_hcd.c
+@@ -799,20 +799,6 @@ static int vhci_urb_dequeue(struct usb_h
+               spin_unlock_irqrestore(&vdev->priv_lock, flags2);
+       }
+-
+-      if (!vdev->ud.tcp_socket) {
+-              /* tcp connection is closed */
+-              usbip_uinfo("vhci_hcd: vhci_urb_dequeue() gives back urb %p\n",
+-                                                                      urb);
+-
+-              usb_hcd_unlink_urb_from_ep(hcd, urb);
+-
+-              spin_unlock_irqrestore(&the_controller->lock, flags);
+-              usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb,
+-                                                              urb->status);
+-              spin_lock_irqsave(&the_controller->lock, flags);
+-      }
+-
+       spin_unlock_irqrestore(&the_controller->lock, flags);
+       usbip_dbg_vhci_hc("leave\n");
diff --git a/queue-2.6.36/usb-ehci-aspm-quirk-of-isoc-on-amd-sb800.patch b/queue-2.6.36/usb-ehci-aspm-quirk-of-isoc-on-amd-sb800.patch
new file mode 100644 (file)
index 0000000..b0c24b8
--- /dev/null
@@ -0,0 +1,228 @@
+From 05570297ecbe834b1756b522412b68eaffb9ab11 Mon Sep 17 00:00:00 2001
+From: Alex He <alex.he@amd.com>
+Date: Tue, 7 Dec 2010 10:10:08 +0800
+Subject: USB: EHCI: ASPM quirk of ISOC on AMD SB800
+
+From: Alex He <alex.he@amd.com>
+
+commit 05570297ecbe834b1756b522412b68eaffb9ab11 upstream.
+
+When ASPM PM Feature is enabled on UMI link, devices that use ISOC stream of
+data transfer may be exposed to longer latency causing less than optimal per-
+formance of the device. The longer latencies are normal and are due to link
+wake time coming out of low power state which happens frequently to save
+power when the link is not active.
+The following code will make exception for certain features of ASPM to be by
+passed and keep the logic normal state only when the ISOC device is connected
+and active. This change will allow the device to run at optimal performance
+yet minimize the impact on overall power savings.
+
+Signed-off-by: Alex He <alex.he@amd.com>
+Acked-by: David Brownell <dbrownell@users.sourceforge.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/ehci-hcd.c   |    8 ++++
+ drivers/usb/host/ehci-pci.c   |   32 +++++++++++++++++
+ drivers/usb/host/ehci-sched.c |   79 ++++++++++++++++++++++++++++++++++++++++++
+ drivers/usb/host/ehci.h       |    1 
+ 4 files changed, 120 insertions(+)
+
+--- a/drivers/usb/host/ehci-hcd.c
++++ b/drivers/usb/host/ehci-hcd.c
+@@ -114,6 +114,9 @@ MODULE_PARM_DESC(hird, "host initiated r
+ #define       INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT)
++/* for ASPM quirk of ISOC on AMD SB800 */
++static struct pci_dev *amd_nb_dev;
++
+ /*-------------------------------------------------------------------------*/
+ #include "ehci.h"
+@@ -514,6 +517,11 @@ static void ehci_stop (struct usb_hcd *h
+       spin_unlock_irq (&ehci->lock);
+       ehci_mem_cleanup (ehci);
++      if (amd_nb_dev) {
++              pci_dev_put(amd_nb_dev);
++              amd_nb_dev = NULL;
++      }
++
+ #ifdef        EHCI_STATS
+       ehci_dbg (ehci, "irq normal %ld err %ld reclaim %ld (lost %ld)\n",
+               ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim,
+--- a/drivers/usb/host/ehci-pci.c
++++ b/drivers/usb/host/ehci-pci.c
+@@ -41,6 +41,35 @@ static int ehci_pci_reinit(struct ehci_h
+       return 0;
+ }
++static int ehci_quirk_amd_SB800(struct ehci_hcd *ehci)
++{
++      struct pci_dev *amd_smbus_dev;
++      u8 rev = 0;
++
++      amd_smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI, 0x4385, NULL);
++      if (!amd_smbus_dev)
++              return 0;
++
++      pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev);
++      if (rev < 0x40) {
++              pci_dev_put(amd_smbus_dev);
++              amd_smbus_dev = NULL;
++              return 0;
++      }
++
++      if (!amd_nb_dev)
++              amd_nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x1510, NULL);
++      if (!amd_nb_dev)
++              ehci_err(ehci, "QUIRK: unable to get AMD NB device\n");
++
++      ehci_info(ehci, "QUIRK: Enable AMD SB800 L1 fix\n");
++
++      pci_dev_put(amd_smbus_dev);
++      amd_smbus_dev = NULL;
++
++      return 1;
++}
++
+ /* called during probe() after chip reset completes */
+ static int ehci_pci_setup(struct usb_hcd *hcd)
+ {
+@@ -99,6 +128,9 @@ static int ehci_pci_setup(struct usb_hcd
+       /* cache this readonly data; minimize chip reads */
+       ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
++      if (ehci_quirk_amd_SB800(ehci))
++              ehci->amd_l1_fix = 1;
++
+       retval = ehci_halt(ehci);
+       if (retval)
+               return retval;
+--- a/drivers/usb/host/ehci-sched.c
++++ b/drivers/usb/host/ehci-sched.c
+@@ -1583,6 +1583,63 @@ itd_link (struct ehci_hcd *ehci, unsigne
+       *hw_p = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD);
+ }
++#define AB_REG_BAR_LOW 0xe0
++#define AB_REG_BAR_HIGH 0xe1
++#define AB_INDX(addr) ((addr) + 0x00)
++#define AB_DATA(addr) ((addr) + 0x04)
++#define NB_PCIE_INDX_ADDR 0xe0
++#define NB_PCIE_INDX_DATA 0xe4
++#define NB_PIF0_PWRDOWN_0 0x01100012
++#define NB_PIF0_PWRDOWN_1 0x01100013
++
++static void ehci_quirk_amd_L1(struct ehci_hcd *ehci, int disable)
++{
++      u32 addr, addr_low, addr_high, val;
++
++      outb_p(AB_REG_BAR_LOW, 0xcd6);
++      addr_low = inb_p(0xcd7);
++      outb_p(AB_REG_BAR_HIGH, 0xcd6);
++      addr_high = inb_p(0xcd7);
++      addr = addr_high << 8 | addr_low;
++      outl_p(0x30, AB_INDX(addr));
++      outl_p(0x40, AB_DATA(addr));
++      outl_p(0x34, AB_INDX(addr));
++      val = inl_p(AB_DATA(addr));
++
++      if (disable) {
++              val &= ~0x8;
++              val |= (1 << 4) | (1 << 9);
++      } else {
++              val |= 0x8;
++              val &= ~((1 << 4) | (1 << 9));
++      }
++      outl_p(val, AB_DATA(addr));
++
++      if (amd_nb_dev) {
++              addr = NB_PIF0_PWRDOWN_0;
++              pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_ADDR, addr);
++              pci_read_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, &val);
++              if (disable)
++                      val &= ~(0x3f << 7);
++              else
++                      val |= 0x3f << 7;
++
++              pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, val);
++
++              addr = NB_PIF0_PWRDOWN_1;
++              pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_ADDR, addr);
++              pci_read_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, &val);
++              if (disable)
++                      val &= ~(0x3f << 7);
++              else
++                      val |= 0x3f << 7;
++
++              pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, val);
++      }
++
++      return;
++}
++
+ /* fit urb's itds into the selected schedule slot; activate as needed */
+ static int
+ itd_link_urb (
+@@ -1609,6 +1666,12 @@ itd_link_urb (
+                       urb->interval,
+                       next_uframe >> 3, next_uframe & 0x7);
+       }
++
++      if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) {
++              if (ehci->amd_l1_fix == 1)
++                      ehci_quirk_amd_L1(ehci, 1);
++      }
++
+       ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++;
+       /* fill iTDs uframe by uframe */
+@@ -1733,6 +1796,11 @@ itd_complete (
+       (void) disable_periodic(ehci);
+       ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
++      if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) {
++              if (ehci->amd_l1_fix == 1)
++                      ehci_quirk_amd_L1(ehci, 0);
++      }
++
+       if (unlikely(list_is_singular(&stream->td_list))) {
+               ehci_to_hcd(ehci)->self.bandwidth_allocated
+                               -= stream->bandwidth;
+@@ -2018,6 +2086,12 @@ sitd_link_urb (
+                       (next_uframe >> 3) & (ehci->periodic_size - 1),
+                       stream->interval, hc32_to_cpu(ehci, stream->splits));
+       }
++
++      if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) {
++              if (ehci->amd_l1_fix == 1)
++                      ehci_quirk_amd_L1(ehci, 1);
++      }
++
+       ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++;
+       /* fill sITDs frame by frame */
+@@ -2118,6 +2192,11 @@ sitd_complete (
+       (void) disable_periodic(ehci);
+       ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
++      if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) {
++              if (ehci->amd_l1_fix == 1)
++                      ehci_quirk_amd_L1(ehci, 0);
++      }
++
+       if (list_is_singular(&stream->td_list)) {
+               ehci_to_hcd(ehci)->self.bandwidth_allocated
+                               -= stream->bandwidth;
+--- a/drivers/usb/host/ehci.h
++++ b/drivers/usb/host/ehci.h
+@@ -130,6 +130,7 @@ struct ehci_hcd {                  /* one per controlle
+       unsigned                has_amcc_usb23:1;
+       unsigned                need_io_watchdog:1;
+       unsigned                broken_periodic:1;
++      unsigned                amd_l1_fix:1;
+       unsigned                fs_i_thresh:1;  /* Intel iso scheduling */
+       /* required for usb32 quirk */