--- a/drivers/usb/host/ehci-adm8668.c	1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/usb/host/ehci-adm8668.c	2010-10-09 01:02:33.599999248 -0400
@@ -0,0 +1,200 @@
+/*
+ * EHCI HCD (Host Controller Driver) for USB.
+ *
+ * Bus Glue for ADM8668
+ *
+ * Based on "ohci-au1xxx.c" by Matt Porter <mporter@kernel.crashing.org>
+ *
+ * Modified for AMD Alchemy Au1200 EHC
+ *  by K.Boge <karsten.boge@amd.com>
+ *
+ * Modified for ADM8668
+ *  by neutronscott <sn@scottn.us>
+ *
+ * This file is licenced under the GPL.
+ */
+
+#include <linux/platform_device.h>
+
+extern int usb_disabled(void);
+
+static void adm8668_start_ehc(void)
+{
+	volatile u32 *ptr2workAround, version_id;
+
+	ptr2workAround = (volatile u32 *)0xB1400000;
+	version_id = *ptr2workAround;
+
+	ptr2workAround = (volatile u32 *)0xB1400108;
+	*ptr2workAround = 0x0C1600D9;
+	if (version_id != 0x86880001)
+	{
+		*ptr2workAround = *ptr2workAround & ~(3<<20);
+		*ptr2workAround = *ptr2workAround | (1<<20);
+	}
+	printk("ADM8668 version: %x\n", version_id);
+}
+
+static void adm8668_stop_ehc(void)
+{
+
+}
+
+static int ehci_adm8668_setup(struct usb_hcd *hcd)
+{
+	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+	int retval;
+
+	ehci_reset(ehci);
+	retval = ehci_halt(ehci);
+	if (retval)
+		return retval;
+
+	retval = ehci_init(hcd);
+	if (retval)
+		return retval;
+
+	/* non std burstsize */
+	ehci_writel(ehci, 0x0E10, &ehci->regs->burstsize);
+	hcd->has_tt = 1;
+	ehci->sbrn = 0x20;
+	ehci_port_power(ehci, 0);
+
+	return 0;
+}
+
+static const struct hc_driver ehci_adm8668_hc_driver = {
+	.description		= hcd_name,
+	.product_desc		= "ADM8668 EHCI",
+	.hcd_priv_size		= sizeof(struct ehci_hcd),
+
+	/*
+	 * generic hardware linkage
+	 */
+	.irq			= ehci_irq,
+	.flags			= HCD_MEMORY | HCD_USB2,
+
+	/*
+	 * basic lifecycle operations
+	 *
+	 * FIXME -- ehci_init() doesn't do enough here.
+	 * See ehci-ppc-soc for a complete implementation.
+	 */
+	.reset			= ehci_adm8668_setup,
+	.start			= ehci_run,
+	.stop			= ehci_stop,
+	.shutdown		= ehci_shutdown,
+
+	/*
+	 * managing i/o requests and associated device resources
+	 */
+	.urb_enqueue		= ehci_urb_enqueue,
+	.urb_dequeue		= ehci_urb_dequeue,
+	.endpoint_disable	= ehci_endpoint_disable,
+	.endpoint_reset		= ehci_endpoint_reset,
+
+	/*
+	 * scheduling support
+	 */
+	.get_frame_number	= ehci_get_frame,
+
+	/*
+	 * root hub support
+	 */
+	.hub_status_data	= ehci_hub_status_data,
+	.hub_control		= ehci_hub_control,
+	.bus_suspend		= ehci_bus_suspend,
+	.bus_resume		= ehci_bus_resume,
+	.relinquish_port	= ehci_relinquish_port,
+	.port_handed_over	= ehci_port_handed_over,
+
+	.clear_tt_buffer_complete	= ehci_clear_tt_buffer_complete,
+};
+
+
+static int ehci_hcd_adm8668_drv_probe(struct platform_device *pdev)
+{
+	struct usb_hcd *hcd;
+	struct ehci_hcd *ehci;
+	int ret;
+
+	if (usb_disabled())
+		return -ENODEV;
+
+	printk("Initalizing ADM8668 USB\n");
+
+	if (pdev->resource[1].flags != IORESOURCE_IRQ) {
+		pr_debug("resource[1] is not IORESOURCE_IRQ");
+		return -ENOMEM;
+	}
+	hcd = usb_create_hcd(&ehci_adm8668_hc_driver, &pdev->dev, "ADM8668");
+	if (!hcd)
+		return -ENOMEM;
+
+	hcd->rsrc_start = pdev->resource[0].start;
+	hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;
+
+	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+		pr_debug("request_mem_region failed");
+		ret = -EBUSY;
+		goto err1;
+	}
+
+	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+	if (!hcd->regs) {
+		pr_debug("ioremap failed");
+		ret = -ENOMEM;
+			goto err2;
+	}
+
+	ehci = hcd_to_ehci(hcd);
+	ehci->caps = hcd->regs;
+	ehci->regs = hcd->regs +
+		HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
+	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
+
+	/* Startup fix for some errata */
+	adm8668_start_ehc();
+
+	ret = usb_add_hcd(hcd, pdev->resource[1].start,
+			  IRQF_DISABLED | IRQF_SHARED);
+
+	if (ret == 0) {
+		platform_set_drvdata(pdev, hcd);
+		return ret;
+	}
+
+	adm8668_stop_ehc();
+	iounmap(hcd->regs);
+err2:
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+err1:
+	usb_put_hcd(hcd);
+	return ret;
+}
+
+static int ehci_hcd_adm8668_drv_remove(struct platform_device *pdev)
+{
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+	usb_remove_hcd(hcd);
+	iounmap(hcd->regs);
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+	usb_put_hcd(hcd);
+	adm8668_stop_ehc();
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+static struct platform_driver ehci_hcd_adm8668_driver = {
+	.probe		= ehci_hcd_adm8668_drv_probe,
+	.remove		= ehci_hcd_adm8668_drv_remove,
+	.shutdown	= usb_hcd_platform_shutdown,
+	.driver = {
+		.name	= "adm8668_ehci",
+		.owner	= THIS_MODULE,
+	}
+};
+
+MODULE_ALIAS("platform:adm8668_ehci");
--- a/drivers/usb/host/ehci-hcd.c	2010-09-28 21:09:08.000000000 -0400
+++ b/drivers/usb/host/ehci-hcd.c	2010-10-09 01:02:33.599999248 -0400
@@ -642,6 +648,8 @@
 	 * host side drivers though.
 	 */
 	hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params);
+/* they did it in 2.4, ya'd think it not return true? */
+#ifndef	CONFIG_ADM8668
 	if (HCC_64BIT_ADDR(hcc_params)) {
 		ehci_writel(ehci, 0, &ehci->regs->segment);
 #if 0
@@ -650,6 +658,7 @@
 			ehci_info(ehci, "enabled 64bit DMA\n");
 #endif
 	}
+#endif /* CONFIG_ADM8668 */
 
 
 	// Philips, Intel, and maybe others need CMD_RUN before the
@@ -675,7 +684,7 @@
 	 */
 	down_write(&ehci_cf_port_reset_rwsem);
 	hcd->state = HC_STATE_RUNNING;
-	ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
+//	ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
 	ehci_readl(ehci, &ehci->regs->command);	/* unblock posted writes */
 	msleep(5);
 	up_write(&ehci_cf_port_reset_rwsem);
@@ -1113,6 +1122,11 @@
 #define PLATFORM_DRIVER		ehci_mxc_driver
 #endif
 
+#ifdef CONFIG_ADM8668
+#include "ehci-adm8668.c"
+#define	PLATFORM_DRIVER		ehci_hcd_adm8668_driver
+#endif
+
 #ifdef CONFIG_SOC_AU1200
 #include "ehci-au1xxx.c"
 #define	PLATFORM_DRIVER		ehci_hcd_au1xxx_driver
--- a/drivers/usb/host/ehci-q.c	2010-09-28 21:09:08.000000000 -0400
+++ b/drivers/usb/host/ehci-q.c	2010-10-09 01:02:33.632002126 -0400
@@ -239,6 +239,9 @@
 				usb_pipein(urb->pipe) ? "in" : "out");
 			status = -EPROTO;
 		} else {	/* unknown */
+			if ((token & 0xFF) == QTD_STS_HALT)
+				status = -EPIPE;
+			else
 			status = -EPROTO;
 		}
 
--- a/include/linux/usb/ehci_def.h	2010-09-28 21:09:08.000000000 -0400
+++ b/include/linux/usb/ehci_def.h	2010-10-09 01:04:57.003998034 -0400
@@ -92,7 +92,13 @@
 	/* ASYNCLISTADDR: offset 0x18 */
 	u32		async_next;	/* address of next async queue head */
 
+#ifdef	CONFIG_ADM8668
+	u32		asyncttsts;
+	u32		burstsize;
+	u32		reserved[7];
+#else
 	u32		reserved[9];
+#endif
 
 	/* CONFIGFLAG: offset 0x40 */
 	u32		configured_flag;
