diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 96fe76e9a6c46e22cb8a69c4a660a04a1f4ebcc7..89901962cbfd821bc454353f61ed1e4e66ecf8db 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -86,6 +86,21 @@ static void ohci_stop (struct usb_hcd *hcd);
 static int ohci_restart (struct ohci_hcd *ohci);
 #endif
 
+#ifdef CONFIG_PCI
+static void quirk_amd_pll(int state);
+static void amd_iso_dev_put(void);
+#else
+static inline void quirk_amd_pll(int state)
+{
+	return;
+}
+static inline void amd_iso_dev_put(void)
+{
+	return;
+}
+#endif
+
+
 #include "ohci-hub.c"
 #include "ohci-dbg.c"
 #include "ohci-mem.c"
@@ -886,6 +901,8 @@ static void ohci_stop (struct usb_hcd *hcd)
 
 	if (quirk_zfmicro(ohci))
 		del_timer(&ohci->unlink_watchdog);
+	if (quirk_amdiso(ohci))
+		amd_iso_dev_put();
 
 	remove_debug_files (ohci);
 	ohci_mem_cleanup (ohci);
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
index 4696cc912e16203540a5185568a27e02bb7c15e2..083e8df0a817f83b925ac397f5e90cb43b8af1d2 100644
--- a/drivers/usb/host/ohci-pci.c
+++ b/drivers/usb/host/ohci-pci.c
@@ -18,6 +18,28 @@
 #error "This file is PCI bus glue.  CONFIG_PCI must be defined."
 #endif
 
+#include <linux/pci.h>
+#include <linux/io.h>
+
+
+/* constants used to work around PM-related transfer
+ * glitches in some AMD 700 series southbridges
+ */
+#define AB_REG_BAR	0xf0
+#define AB_INDX(addr)	((addr) + 0x00)
+#define AB_DATA(addr)	((addr) + 0x04)
+#define AX_INDXC	0X30
+#define AX_DATAC	0x34
+
+#define NB_PCIE_INDX_ADDR	0xe0
+#define NB_PCIE_INDX_DATA	0xe4
+#define PCIE_P_CNTL		0x10040
+#define BIF_NB			0x10002
+
+static struct pci_dev *amd_smbus_dev;
+static struct pci_dev *amd_hb_dev;
+static int amd_ohci_iso_count;
+
 /*-------------------------------------------------------------------------*/
 
 static int broken_suspend(struct usb_hcd *hcd)
@@ -143,6 +165,103 @@ static int ohci_quirk_nec(struct usb_hcd *hcd)
 	return 0;
 }
 
+static int ohci_quirk_amd700(struct usb_hcd *hcd)
+{
+	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+	u8 rev = 0;
+
+	if (!amd_smbus_dev)
+		amd_smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI,
+				PCI_DEVICE_ID_ATI_SBX00_SMBUS, NULL);
+	if (!amd_smbus_dev)
+		return 0;
+
+	pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev);
+	if ((rev > 0x3b) || (rev < 0x30)) {
+		pci_dev_put(amd_smbus_dev);
+		amd_smbus_dev = NULL;
+		return 0;
+	}
+
+	amd_ohci_iso_count++;
+
+	if (!amd_hb_dev)
+		amd_hb_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x9600, NULL);
+
+	ohci->flags |= OHCI_QUIRK_AMD_ISO;
+	ohci_dbg(ohci, "enabled AMD ISO transfers quirk\n");
+
+	return 0;
+}
+
+/*
+ * The hardware normally enables the A-link power management feature, which
+ * lets the system lower the power consumption in idle states.
+ *
+ * Assume the system is configured to have USB 1.1 ISO transfers going
+ * to or from a USB device.  Without this quirk, that stream may stutter
+ * or have breaks occasionally.  For transfers going to speakers, this
+ * makes a very audible mess...
+ *
+ * That audio playback corruption is due to the audio stream getting
+ * interrupted occasionally when the link goes in lower power state
+ * This USB quirk prevents the link going into that lower power state
+ * during audio playback or other ISO operations.
+ */
+static void quirk_amd_pll(int on)
+{
+	u32 addr;
+	u32 val;
+	u32 bit = (on > 0) ? 1 : 0;
+
+	pci_read_config_dword(amd_smbus_dev, AB_REG_BAR, &addr);
+
+	/* BIT names/meanings are NDA-protected, sorry ... */
+
+	outl(AX_INDXC, AB_INDX(addr));
+	outl(0x40, AB_DATA(addr));
+	outl(AX_DATAC, AB_INDX(addr));
+	val = inl(AB_DATA(addr));
+	val &= ~((1 << 3) | (1 << 4) | (1 << 9));
+	val |= (bit << 3) | ((!bit) << 4) | ((!bit) << 9);
+	outl(val, AB_DATA(addr));
+
+	if (amd_hb_dev) {
+		addr = PCIE_P_CNTL;
+		pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_ADDR, addr);
+
+		pci_read_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, &val);
+		val &= ~(1 | (1 << 3) | (1 << 4) | (1 << 9) | (1 << 12));
+		val |= bit | (bit << 3) | (bit << 12);
+		val |= ((!bit) << 4) | ((!bit) << 9);
+		pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, val);
+
+		addr = BIF_NB;
+		pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_ADDR, addr);
+
+		pci_read_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, &val);
+		val &= ~(1 << 8);
+		val |= bit << 8;
+		pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, val);
+	}
+}
+
+static void amd_iso_dev_put(void)
+{
+	amd_ohci_iso_count--;
+	if (amd_ohci_iso_count == 0) {
+		if (amd_smbus_dev) {
+			pci_dev_put(amd_smbus_dev);
+			amd_smbus_dev = NULL;
+		}
+		if (amd_hb_dev) {
+			pci_dev_put(amd_hb_dev);
+			amd_hb_dev = NULL;
+		}
+	}
+
+}
+
 /* List of quirks for OHCI */
 static const struct pci_device_id ohci_pci_quirks[] = {
 	{
@@ -181,6 +300,19 @@ static const struct pci_device_id ohci_pci_quirks[] = {
 		PCI_DEVICE(PCI_VENDOR_ID_ITE, 0x8152),
 		.driver_data = (unsigned long) broken_suspend,
 	},
+	{
+		PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4397),
+		.driver_data = (unsigned long)ohci_quirk_amd700,
+	},
+	{
+		PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4398),
+		.driver_data = (unsigned long)ohci_quirk_amd700,
+	},
+	{
+		PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4399),
+		.driver_data = (unsigned long)ohci_quirk_amd700,
+	},
+
 	/* FIXME for some of the early AMD 760 southbridges, OHCI
 	 * won't work at all.  blacklist them.
 	 */
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
index 6a9b4c5579536e161b596e824adccf3b81805922..c2d80f80448b2e77690f8f29cc64f3402cd9dd78 100644
--- a/drivers/usb/host/ohci-q.c
+++ b/drivers/usb/host/ohci-q.c
@@ -49,6 +49,9 @@ __acquires(ohci->lock)
 	switch (usb_pipetype (urb->pipe)) {
 	case PIPE_ISOCHRONOUS:
 		ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs--;
+		if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0
+				&& quirk_amdiso(ohci))
+			quirk_amd_pll(1);
 		break;
 	case PIPE_INTERRUPT:
 		ohci_to_hcd(ohci)->self.bandwidth_int_reqs--;
@@ -677,6 +680,9 @@ static void td_submit_urb (
 				data + urb->iso_frame_desc [cnt].offset,
 				urb->iso_frame_desc [cnt].length, urb, cnt);
 		}
+		if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0
+				&& quirk_amdiso(ohci))
+			quirk_amd_pll(0);
 		periodic = ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs++ == 0
 			&& ohci_to_hcd(ohci)->self.bandwidth_int_reqs == 0;
 		break;
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
index df5a8037dbafeeda38e08137ae2ef6f9960c18f1..faf622eafce7aab820b20ad55bae51b3076579ba 100644
--- a/drivers/usb/host/ohci.h
+++ b/drivers/usb/host/ohci.h
@@ -401,6 +401,7 @@ struct ohci_hcd {
 #define	OHCI_QUIRK_NEC		0x40			/* lost interrupts */
 #define	OHCI_QUIRK_FRAME_NO	0x80			/* no big endian frame_no shift */
 #define	OHCI_QUIRK_HUB_POWER	0x100			/* distrust firmware power/oc setup */
+#define	OHCI_QUIRK_AMD_ISO	0x200			/* ISO transfers*/
 	// there are also chip quirks/bugs in init logic
 
 	struct work_struct	nec_work;	/* Worker for NEC quirk */
@@ -428,6 +429,10 @@ static inline int quirk_zfmicro(struct ohci_hcd *ohci)
 {
 	return ohci->flags & OHCI_QUIRK_ZFMICRO;
 }
+static inline int quirk_amdiso(struct ohci_hcd *ohci)
+{
+	return ohci->flags & OHCI_QUIRK_AMD_ISO;
+}
 #else
 static inline int quirk_nec(struct ohci_hcd *ohci)
 {
@@ -437,6 +442,10 @@ static inline int quirk_zfmicro(struct ohci_hcd *ohci)
 {
 	return 0;
 }
+static inline int quirk_amdiso(struct ohci_hcd *ohci)
+{
+	return 0;
+}
 #endif
 
 /* convert between an hcd pointer and the corresponding ohci_hcd */