--- a/drivers/usb/host/ohci-ssb.c
+++ b/drivers/usb/host/ohci-ssb.c
@@ -106,10 +106,59 @@ static int ssb_ohci_attach(struct ssb_de
 	int err = -ENOMEM;
 	u32 tmp, flags = 0;
 
-	if (dev->id.coreid == SSB_DEV_USB11_HOSTDEV)
+	/*
+	 * THE FOLLOWING COMMENTS PRESERVED FROM GPL SOURCE RELEASE
+	 *
+	 * The USB core requires a special bit to be set during core
+	 * reset to enable host (OHCI) mode. Resetting the SB core in
+	 * pcibios_enable_device() is a hack for compatibility with
+	 * vanilla usb-ohci so that it does not have to know about
+	 * SB. A driver that wants to use the USB core in device mode
+	 * should know about SB and should reset the bit back to 0
+	 * after calling pcibios_enable_device().
+	 */
+
+	if (dev->id.coreid == SSB_DEV_USB11_HOSTDEV) {
 		flags |= SSB_OHCI_TMSLOW_HOSTMODE;
+		ssb_device_enable(dev, flags);
+	}
+
+	/*
+	 * USB 2.0 special considerations:
+	 *
+	 * 1. Since the core supports both OHCI and EHCI functions, it must
+	 *    only be reset once.
+	 * 
+	 * 2. In addition to the standard SB reset sequence, the Host Control
+	 *    Register must be programmed to bring the USB core and various
+	 *    phy components out of reset. 
+	 */
+
+	else if (dev->id.coreid == SSB_DEV_USB20_HOST) {
+#warning FIX ME need test for core being up & exit
+		ssb_device_enable(dev, 0);
+		ssb_write32(dev, 0x200, 0x7ff);
+		udelay(1);
+		if (dev->id.revision == 1) { // bug in rev 1
+
+			/* Change Flush control reg */
+			tmp = ssb_read32(dev, 0x400);
+			tmp &= ~8;
+			ssb_write32(dev, 0x400, tmp);
+			tmp = ssb_read32(dev, 0x400);
+			printk("USB20H fcr: 0x%0x\n", tmp);
+
+			/* Change Shim control reg */
+			tmp = ssb_read32(dev, 0x304);
+			tmp &= ~0x100;
+			ssb_write32(dev, 0x304, tmp);
+			tmp = ssb_read32(dev, 0x304);
+			printk("USB20H shim: 0x%0x\n", tmp);
+		}
+	}
+	else
+		ssb_device_enable(dev, 0);
 
-	ssb_device_enable(dev, flags);
 
 	hcd = usb_create_hcd(&ssb_ohci_hc_driver, dev->dev,
 			dev_name(dev->dev));
@@ -200,6 +249,7 @@ static int ssb_ohci_resume(struct ssb_de
 static const struct ssb_device_id ssb_ohci_table[] = {
 	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOSTDEV, SSB_ANY_REV),
 	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOST, SSB_ANY_REV),
+	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB20_HOST, SSB_ANY_REV),
 	SSB_DEVTABLE_END
 };
 MODULE_DEVICE_TABLE(ssb, ssb_ohci_table);