Hi,

Here is the patch we have in Freescale released BSP.  I post it here in case 
anyone may need it without the BSP.  It's for kernel 2.6.11, and won't have big 
problem for newer kernel, I think.  The patch is not done by myself, and maybe 
submitted later formally after merge with OTG and clean up.  Here goes the 
patch.


diff -Nur linux/drivers/usb/core/hcd.c linux-8349-2.6/drivers/usb/core/hcd.c
--- linux/drivers/usb/core/hcd.c        2005-03-02 15:38:10.000000000 +0800
+++ linux-8349-2.6/drivers/usb/core/hcd.c       2005-08-15 13:54:13.000000000 
+0800
@@ -1116,13 +1116,20 @@
        if (hcd->self.controller->dma_mask) {
                if (usb_pipecontrol (urb->pipe)
                        && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP))
+#ifdef CONFIG_FSL_USB20
+                       urb->setup_dma = (unsigned long)urb->setup_packet;
+#else
                        urb->setup_dma = dma_map_single (
                                        hcd->self.controller,
                                        urb->setup_packet,
                                        sizeof (struct usb_ctrlrequest),
                                        DMA_TO_DEVICE);
+#endif
                if (urb->transfer_buffer_length != 0
                        && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP))
+#ifdef CONFIG_FSL_USB20
+                       urb->transfer_dma = (unsigned long)urb->transfer_buffer;
+#else
                        urb->transfer_dma = dma_map_single (
                                        hcd->self.controller,
                                        urb->transfer_buffer,
@@ -1130,6 +1137,7 @@
                                        usb_pipein (urb->pipe)
                                            ? DMA_FROM_DEVICE
                                            : DMA_TO_DEVICE);
+#endif
        }
 
        status = hcd->driver->urb_enqueue (hcd, ep, urb, mem_flags);
@@ -1469,6 +1477,8 @@
        // It would catch exit/unlink paths for all urbs.
 
        /* lower level hcd code should use *_dma exclusively */
+#ifdef CONFIG_FSL_USB20
+#else
        if (hcd->self.controller->dma_mask) {
                if (usb_pipecontrol (urb->pipe)
                        && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP))
@@ -1484,7 +1494,7 @@
                                            ? DMA_FROM_DEVICE
                                            : DMA_TO_DEVICE);
        }
-
+#endif
        /* pass ownership to the completion handler */
        urb->complete (urb, regs);
        atomic_dec (&urb->use_count);
diff -Nur linux/drivers/usb/core/hub.c linux-8349-2.6/drivers/usb/core/hub.c
--- linux/drivers/usb/core/hub.c        2005-03-02 15:38:08.000000000 +0800
+++ linux-8349-2.6/drivers/usb/core/hub.c       2005-08-15 13:56:05.000000000 
+0800
@@ -2155,7 +2155,11 @@
        } else if (udev->speed != USB_SPEED_HIGH
                        && hdev->speed == USB_SPEED_HIGH) {
                udev->tt = &hub->tt;
+#ifdef CONFIG_FSL_USB20
+               udev->ttport = port1+1;
+#else
                udev->ttport = port1;
+#endif
        }
  
        /* Why interleave GET_DESCRIPTOR and SET_ADDRESS this way?
diff -Nur linux/drivers/usb/host/ehci.h linux-8349-2.6/drivers/usb/host/ehci.h
--- linux/drivers/usb/host/ehci.h       2005-03-02 15:38:25.000000000 +0800
+++ linux-8349-2.6/drivers/usb/host/ehci.h      2005-08-15 10:25:52.000000000 
+0800
@@ -59,6 +59,9 @@
 #define        DEFAULT_I_TDPS          1024            /* some HCs can do less 
*/
        unsigned                periodic_size;
        __le32                  *periodic;      /* hw periodic table */
+#ifdef CONFIG_FSL_USB20
+       u32                     orig_periodic;
+#endif
        dma_addr_t              periodic_dma;
        unsigned                i_thresh;       /* uframes HC might cache */
 
@@ -70,11 +73,17 @@
        unsigned long           reset_done [EHCI_MAX_ROOT_PORTS];
 
        /* per-HC memory pools (could be per-bus, but ...) */
+#ifdef CONFIG_FSL_USB20
+       t_MemorySegment   *qh_pool;     /* qh per active urb      */
+       t_MemorySegment   *qtd_pool;    /* one or more per qh     */
+       t_MemorySegment   *itd_pool;    /* itd per iso urb        */
+       t_MemorySegment   *sitd_pool;   /* sitd per split iso urb */
+#else
        struct dma_pool         *qh_pool;       /* qh per active urb */
        struct dma_pool         *qtd_pool;      /* one or more per qh */
        struct dma_pool         *itd_pool;      /* itd per iso urb */
        struct dma_pool         *sitd_pool;     /* sitd per split iso urb */
-
+#endif
        struct timer_list       watchdog;
        struct notifier_block   reboot_notifier;
        unsigned long           actions;
@@ -230,9 +239,26 @@
        u32             frame_list;     /* points to periodic list */
        /* ASYNCLISTADDR: offset 0x18 */
        u32             async_next;     /* address of next async queue head */
-
+#ifdef CONFIG_FSL_USB20
+        /* ASYNCTTSTS: offset 0x1c */
+       u32             async_tt_status;    /* async queue status for embedded 
TT */
+       /* BURSTSIZE: offset 0x20 */
+       u32             burst_size;         /* programmable burst size */
+       /* TXFILLTUNING: offset 0x24 */
+       u32             txfilltuning;       /* host transmit pre-buffer packet 
tuning */
+       /* TXTTFILLTUNING: offset 0x28 */
+       u32             txttfilltuning;     /* host TT transmit pre-buffer 
packet tuning */
+       u32             reserved0;
+       /* ULPIVIEWPORT: offset 0x30 */
+       u32             ulpi_view_port;     /* ULPI view port */
+       /* ENDPTNAK: offset 0x34 */
+       u32             endpoint_nack;      /* endpoint nack */
+       /* ENDPTNAKEN: offset 0x38 */
+       u32             endpoint_nack_en;   /* endpoint nack enable */
+       u32             reserved1;
+#else
        u32             reserved [9];
-
+#endif
        /* CONFIGFLAG: offset 0x40 */
        u32             configured_flag;
 #define FLAG_CF                (1<<0)          /* true: we'll support "high 
speed" */
diff -Nur linux/drivers/usb/host/ehci-hcd.c 
linux-8349-2.6/drivers/usb/host/ehci-hcd.c
--- linux/drivers/usb/host/ehci-hcd.c   2005-03-02 15:38:38.000000000 +0800
+++ linux-8349-2.6/drivers/usb/host/ehci-hcd.c  2005-08-15 10:40:35.000000000 
+0800
@@ -16,6 +16,13 @@
  * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#ifdef CONFIG_FSL_USB20
+#ifdef CONFIG_USB_DEBUG        
+       #define DEBUG
+#else
+       #undef DEBUG
+#endif
+#else
 #include <linux/config.h>
 
 #ifdef CONFIG_USB_DEBUG
@@ -101,8 +108,17 @@
 #define DRIVER_AUTHOR "David Brownell"
 #define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver"
 
-static const char      hcd_name [] = "ehci_hcd";
+#endif
 
+#ifdef CONFIG_FSL_USB20
+#if defined (CONFIG_MPH_USB_SUPPORT)
+static const char      hcd_name [] = "fsl-usb2-mph";
+#elif defined (CONFIG_DR_USB_SUPPORT)
+static const char      hcd_name [] = "fsl-usb2-dr";
+#endif
+#else
+static const char      hcd_name [] = "ehci_hcd";
+#endif
 
 #undef EHCI_VERBOSE_DEBUG
 #undef EHCI_URB_TRACE
@@ -112,6 +128,7 @@
 #endif
 
 /* magic numbers that can affect system performance */
+
 #define        EHCI_TUNE_CERR          3       /* 0-3 qtd retries; 0 == don't 
stop */
 #define        EHCI_TUNE_RL_HS         4       /* nak throttle; see 4.9 */
 #define        EHCI_TUNE_RL_TT         0
@@ -126,13 +143,18 @@
 
 /* Initial IRQ latency:  faster than hw default */
 static int log2_irq_thresh = 0;                // 0 to 6
+#ifdef CONFIG_FSL_USB20
+#else
 module_param (log2_irq_thresh, int, S_IRUGO);
 MODULE_PARM_DESC (log2_irq_thresh, "log2 IRQ latency, 1-64 microframes");
-
+#endif
 /* initial park setting:  slower than hw default */
 static unsigned park = 0;
+#ifdef CONFIG_FSL_USB20
+#else
 module_param (park, uint, S_IRUGO);
 MODULE_PARM_DESC (park, "park setting; 1-3 back-to-back async packets");
+#endif
 
 #define        INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT)
 
@@ -190,7 +212,27 @@
        writel (temp, &ehci->regs->command);
        return handshake (&ehci->regs->status, STS_HALT, STS_HALT, 16 * 125);
 }
+#ifdef CONFIG_FSL_USB20
+static void mpc8349_usb_reset(void);
+/* reset a non-running (STS_HALT == 1) controller */
+static int ehci_reset (struct ehci_hcd *ehci)
+{
+       int retval;
+       u32     command = readl (&ehci->regs->command);
 
+       command |= CMD_RESET;
+       dbg_cmd (ehci, "reset", command);
+       writel (command, &ehci->regs->command);
+       ehci_to_hcd(ehci)->state = USB_STATE_HALT;
+       ehci->next_statechange = jiffies;
+       retval = handshake (&ehci->regs->command, CMD_RESET, 0, 250 * 1000);
+
+       if (retval)
+               return retval;
+       mpc8349_usb_reset ();
+       return retval;
+}
+#else
 /* reset a non-running (STS_HALT == 1) controller */
 static int ehci_reset (struct ehci_hcd *ehci)
 {
@@ -203,7 +245,7 @@
        ehci->next_statechange = jiffies;
        return handshake (&ehci->regs->command, CMD_RESET, 0, 250 * 1000);
 }
-
+#endif
 /* idle the controller (from running) */
 static void ehci_quiesce (struct ehci_hcd *ehci)
 {
@@ -276,7 +318,7 @@
        spin_unlock_irqrestore (&ehci->lock, flags);
 }
 
-#ifdef CONFIG_PCI
+#if defined(CONFIG_PCI) && !defined(CONFIG_FSL_USB20)
 
 /* EHCI 0.96 (and later) section 5.1 says how to kick BIOS/SMM/...
  * off the controller (maybe it can boot from highspeed USB disks).
@@ -285,18 +327,22 @@
 {
        if (cap & (1 << 16)) {
                int msec = 5000;
+
                struct pci_dev *pdev =
                                to_pci_dev(ehci_to_hcd(ehci)->self.controller);
 
                /* request handoff to OS */
                cap |= 1 << 24;
+
                pci_write_config_dword(pdev, where, cap);
 
                /* and wait a while for it to happen */
                do {
                        msleep(10);
                        msec -= 10;
+
                        pci_read_config_dword(pdev, where, &cap);
+
                } while ((cap & (1 << 16)) && msec);
                if (cap & (1 << 16)) {
                        ehci_err (ehci, "BIOS handoff failed (%d, %04x)\n",
@@ -332,7 +378,10 @@
 {
        struct ehci_hcd         *ehci = hcd_to_ehci (hcd);
        u32                     temp;
+#ifdef CONFIG_FSL_USB20
+#else
        unsigned                count = 256/4;
+#endif
 
        spin_lock_init (&ehci->lock);
 
@@ -340,8 +389,14 @@
        ehci->regs = hcd->regs + HC_LENGTH (readl (&ehci->caps->hc_capbase));
        dbg_hcs_params (ehci, "reset");
        dbg_hcc_params (ehci, "reset");
+       
 
-#ifdef CONFIG_PCI
+#ifdef CONFIG_FSL_USB20
+       mpc8349_usb_reset ();
+       ehci->is_arc_rh_tt = 1;
+#endif
+
+#if defined(CONFIG_PCI) && !defined(CONFIG_FSL_USB20)
        /* EHCI 0.96 and later may have "extended capabilities" */
        if (hcd->self.controller->bus == &pci_bus_type) {
                struct pci_dev  *pdev = to_pci_dev(hcd->self.controller);
@@ -395,7 +450,7 @@
                        HCS_N_PCC(ehci->hcs_params),
                        HCS_N_PORTS(ehci->hcs_params));
 
-#ifdef CONFIG_PCI
+#if defined(CONFIG_PCI) && !defined(CONFIG_FSL_USB20)
                if (hcd->self.controller->bus == &pci_bus_type) {
                        struct pci_dev  *pdev;
 
@@ -465,7 +520,7 @@
        }
        writel (ehci->periodic_dma, &ehci->regs->frame_list);
 
-#ifdef CONFIG_PCI
+#if defined(CONFIG_PCI) && !defined(CONFIG_FSL_USB20)
        if (hcd->self.controller->bus == &pci_bus_type) {
                struct pci_dev          *pdev;
                u16                     port_wake;
@@ -829,7 +884,7 @@
        struct ehci_hcd         *ehci = hcd_to_ehci (hcd);
        u32                     status;
        int                     bh;
-
+       
        spin_lock (&ehci->lock);
 
        status = readl (&ehci->regs->status);
@@ -1181,6 +1236,9 @@
 /*-------------------------------------------------------------------------*/
 
 /* EHCI 1.0 doesn't require PCI */
+#ifdef CONFIG_FSL_USB20
+
+#else
 
 #ifdef CONFIG_PCI
 
@@ -1236,3 +1294,4 @@
        pci_unregister_driver (&ehci_pci_driver);
 }
 module_exit (cleanup);
+#endif
diff -Nur linux/drivers/usb/host/ehci-mem.c 
linux-8349-2.6/drivers/usb/host/ehci-mem.c
--- linux/drivers/usb/host/ehci-mem.c   2005-03-02 15:38:26.000000000 +0800
+++ linux-8349-2.6/drivers/usb/host/ehci-mem.c  2005-08-15 10:46:53.000000000 
+0800
@@ -49,8 +49,13 @@
 {
        struct ehci_qtd         *qtd;
        dma_addr_t              dma;
-
+#ifdef CONFIG_FSL_USB20
+       qtd = MEM_Get( ehci->qtd_pool);
+       dma = virt_to_phys(qtd);
+       memset(qtd, 0, sizeof(*qtd));
+#else
        qtd = dma_pool_alloc (ehci->qtd_pool, flags, &dma);
+#endif
        if (qtd != NULL) {
                ehci_qtd_init (qtd, dma);
        }
@@ -59,7 +64,11 @@
 
 static inline void ehci_qtd_free (struct ehci_hcd *ehci, struct ehci_qtd *qtd)
 {
+#ifdef CONFIG_FSL_USB20
+       MEM_Put(ehci->qtd_pool, qtd);
+#else
        dma_pool_free (ehci->qtd_pool, qtd, qtd->qtd_dma);
+#endif
 }
 
 
@@ -75,8 +84,12 @@
        }
        if (qh->dummy)
                ehci_qtd_free (ehci, qh->dummy);
+#ifdef CONFIG_FSL_USB20
+       MEM_Put(ehci->qh_pool, qh);
+#else
        usb_put_dev (qh->dev);
        dma_pool_free (ehci->qh_pool, qh, qh->qh_dma);
+#endif
 }
 
 static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, int flags)
@@ -84,8 +97,14 @@
        struct ehci_qh          *qh;
        dma_addr_t              dma;
 
+#ifdef CONFIG_FSL_USB20
+       qh = (struct ehci_qh *) MEM_Get(ehci->qh_pool);
+       dma = virt_to_phys(qh);
+       memset(qh, 0, sizeof(*qh));
+#else
        qh = (struct ehci_qh *)
                dma_pool_alloc (ehci->qh_pool, flags, &dma);
+#endif
        if (!qh)
                return qh;
 
@@ -100,7 +119,11 @@
        qh->dummy = ehci_qtd_alloc (ehci, flags);
        if (qh->dummy == NULL) {
                ehci_dbg (ehci, "no dummy td\n");
+#ifdef CONFIG_FSL_USB20
+               MEM_Put(ehci->qh_pool, qh);
+#else
                dma_pool_free (ehci->qh_pool, qh, qh->qh_dma);
+#endif
                qh = NULL;
        }
        return qh;
@@ -133,26 +156,46 @@
 
        /* DMA consistent memory and pools */
        if (ehci->qtd_pool)
+#ifdef CONFIG_FSL_USB20
+               MEM_Free(ehci->qtd_pool);
+#else
                dma_pool_destroy (ehci->qtd_pool);
+#endif
        ehci->qtd_pool = NULL;
 
        if (ehci->qh_pool) {
+#ifdef CONFIG_FSL_USB20
+               MEM_Free(ehci->qh_pool);
+#else
                dma_pool_destroy (ehci->qh_pool);
+#endif
                ehci->qh_pool = NULL;
        }
 
        if (ehci->itd_pool)
+#ifdef CONFIG_FSL_USB20
+               MEM_Free(ehci->itd_pool);
+#else  
                dma_pool_destroy (ehci->itd_pool);
+#endif
        ehci->itd_pool = NULL;
 
        if (ehci->sitd_pool)
+#ifdef CONFIG_FSL_USB20
+               MEM_Free(ehci->sitd_pool);
+#else  
                dma_pool_destroy (ehci->sitd_pool);
+#endif
        ehci->sitd_pool = NULL;
 
        if (ehci->periodic)
+#ifdef CONFIG_FSL_USB20
+               kfree((void *)ehci->orig_periodic);
+#else
                dma_free_coherent (ehci_to_hcd(ehci)->self.controller,
                        ehci->periodic_size * sizeof (u32),
                        ehci->periodic, ehci->periodic_dma);
+#endif
        ehci->periodic = NULL;
 
        /* shadow periodic table */
@@ -165,23 +208,31 @@
 static int ehci_mem_init (struct ehci_hcd *ehci, int flags)
 {
        int i;
+       int err;
 
        /* QTDs for control/bulk/intr transfers */
+#ifdef CONFIG_FSL_USB20
+       err = MEM_Init("ehci_qtd_pool", (void **)&ehci->qtd_pool, 128, 
sizeof(struct ehci_qtd), 0, 0, 32);
+#else
        ehci->qtd_pool = dma_pool_create ("ehci_qtd", 
                        ehci_to_hcd(ehci)->self.controller,
                        sizeof (struct ehci_qtd),
                        32 /* byte alignment (for hw parts) */,
                        4096 /* can't cross 4K */);
+#endif
        if (!ehci->qtd_pool) {
                goto fail;
        }
-
+#ifdef CONFIG_FSL_USB20
+       err = MEM_Init("ehci_qh_pool", (void **)&ehci->qh_pool, 128, 
sizeof(struct ehci_qh), 0, 0, 64);
+#else
        /* QHs for control/bulk/intr transfers */
        ehci->qh_pool = dma_pool_create ("ehci_qh", 
                        ehci_to_hcd(ehci)->self.controller,
                        sizeof (struct ehci_qh),
                        32 /* byte alignment (for hw parts) */,
                        4096 /* can't cross 4K */);
+#endif
        if (!ehci->qh_pool) {
                goto fail;
        }
@@ -191,30 +242,47 @@
        }
 
        /* ITD for high speed ISO transfers */
+#ifdef CONFIG_FSL_USB20
+       err = MEM_Init("ehci_itd_pool", (void **)&ehci->itd_pool, 128, 
sizeof(struct ehci_itd), 0, 0, 32);
+#else
        ehci->itd_pool = dma_pool_create ("ehci_itd", 
                        ehci_to_hcd(ehci)->self.controller,
                        sizeof (struct ehci_itd),
                        32 /* byte alignment (for hw parts) */,
                        4096 /* can't cross 4K */);
+#endif
        if (!ehci->itd_pool) {
                goto fail;
        }
 
        /* SITD for full/low speed split ISO transfers */
+#ifdef CONFIG_FSL_USB20
+        err = MEM_Init("ehci_sitd_pool", (void**)&ehci->sitd_pool, 128, 
sizeof(struct ehci_sitd), 0, 0, 32);
+#else
        ehci->sitd_pool = dma_pool_create ("ehci_sitd", 
                        ehci_to_hcd(ehci)->self.controller,
                        sizeof (struct ehci_sitd),
                        32 /* byte alignment (for hw parts) */,
                        4096 /* can't cross 4K */);
+#endif
        if (!ehci->sitd_pool) {
                goto fail;
        }
 
        /* Hardware periodic table */
+#ifdef CONFIG_FSL_USB20
+       ehci->orig_periodic =(u32)kmalloc((int)(ehci->periodic_size * sizeof 
(u32))+0x1000,GFP_KERNEL);
+       if(ehci->orig_periodic%0x1000)
+               ehci->periodic = (__le32 
*)(((ehci->orig_periodic>>12)<<12)+0x1000);
+       else
+               ehci->periodic = (__le32 *)ehci->orig_periodic;
+       ehci->periodic_dma = virt_to_phys(ehci->periodic);
+#else
        ehci->periodic = (__le32 *)
                dma_alloc_coherent (ehci_to_hcd(ehci)->self.controller,
                        ehci->periodic_size * sizeof(__le32),
                        &ehci->periodic_dma, 0);
+#endif
        if (ehci->periodic == NULL) {
                goto fail;
        }
diff -Nur linux/drivers/usb/host/ehci-q.c 
linux-8349-2.6/drivers/usb/host/ehci-q.c
--- linux/drivers/usb/host/ehci-q.c     2005-03-02 15:38:19.000000000 +0800
+++ linux-8349-2.6/drivers/usb/host/ehci-q.c    2005-08-15 10:50:13.000000000 
+0800
@@ -500,7 +500,11 @@
        is_input = usb_pipein (urb->pipe);
        if (usb_pipecontrol (urb->pipe)) {
                /* SETUP pid */
+#ifdef CONFIG_FSL_USB20
+               qtd_fill (qtd, virt_to_phys(urb->setup_packet), sizeof (struct 
usb_ctrlrequest),
+#else
                qtd_fill (qtd, urb->setup_dma, sizeof (struct usb_ctrlrequest),
+#endif
                        token | (2 /* "setup" */ << 8), 8);
 
                /* ... and always at least one more pid */
@@ -518,7 +522,11 @@
         * data transfer stage:  buffer setup
         */
        if (likely (len > 0))
+#ifdef CONFIG_FSL_USB20
+               buf = virt_to_phys(urb->transfer_buffer);
+#else
                buf = urb->transfer_dma;
+#endif
        else
                buf = 0;
 
@@ -712,8 +720,11 @@
                info1 |= maxp << 16;
 
                info2 |= (EHCI_TUNE_MULT_TT << 30);
+#ifdef CONFIG_FSL_USB20
+               info2 |= (urb->dev->ttport-1) << 23;
+#else
                info2 |= urb->dev->ttport << 23;
-
+#endif
                /* set the address of the TT; for ARC's integrated
                 * root hub tt, leave it zeroed.
                 */
@@ -863,7 +874,11 @@
                        dummy = qh->dummy;
 
                        dma = dummy->qtd_dma;
+#ifdef CONFIG_FSL_USB20
+                       memcpy(dummy,qtd,sizeof(struct ehci_qtd));
+#else
                        *dummy = *qtd;
+#endif
                        dummy->qtd_dma = dma;
 
                        list_del (&qtd->qtd_list);
@@ -925,6 +940,7 @@
        if (likely (qh != NULL)) {
                if (likely (qh->qh_state == QH_STATE_IDLE))
                        qh_link_async (ehci, qh_get (qh));
+               
        }
        spin_unlock_irqrestore (&ehci->lock, flags);
        if (unlikely (qh == NULL)) {
diff -Nur linux/drivers/usb/host/ehci-sched.c 
linux-8349-2.6/drivers/usb/host/ehci-sched.c
--- linux/drivers/usb/host/ehci-sched.c 2005-03-02 15:37:53.000000000 +0800
+++ linux-8349-2.6/drivers/usb/host/ehci-sched.c        2005-08-15 
10:53:16.000000000 +0800
@@ -699,8 +699,11 @@
 
        } else {
                u32             addr;
-
+#ifdef CONFIG_FSL_USB20
+               addr = (u32)((dev->ttport-1) << 24);
+#else
                addr = dev->ttport << 24;
+#endif
                addr |= dev->tt->hub->devnum << 16;
                addr |= epnum << 8;
                addr |= dev->devnum;
@@ -759,15 +762,23 @@
 
                                itd = list_entry (entry, struct ehci_itd,
                                                itd_list);
+#ifdef CONFIG_FSL_USB20
+                               MEM_Put(ehci->itd_pool, itd);
+#else
                                dma_pool_free (ehci->itd_pool, itd,
                                                itd->itd_dma);
+#endif
                        } else {
                                struct ehci_sitd        *sitd;
 
                                sitd = list_entry (entry, struct ehci_sitd,
                                                sitd_list);
+#ifdef CONFIG_FSL_USB20
+                               MEM_Put(ehci->sitd_pool, sitd);
+#else
                                dma_pool_free (ehci->sitd_pool, sitd,
                                                sitd->sitd_dma);
+#endif
                        }
                }
 
@@ -865,8 +876,11 @@
 )
 {
        unsigned        i;
+#ifdef CONFIG_FSL_USB20
+       dma_addr_t      dma = virt_to_phys(urb->transfer_buffer);
+#else
        dma_addr_t      dma = urb->transfer_dma;
-
+#endif
        /* how many uframes are needed for these transfers */
        iso_sched->span = urb->number_of_packets * stream->interval;
 
@@ -956,8 +970,14 @@
 
                if (!itd) {
                        spin_unlock_irqrestore (&ehci->lock, flags);
+#ifdef CONFIG_FSL_USB20
+                       itd = MEM_Get(ehci->itd_pool);
+                       itd_dma = virt_to_phys(itd);
+
+#else
                        itd = dma_pool_alloc (ehci->itd_pool, mem_flags,
                                        &itd_dma);
+#endif
                        spin_lock_irqsave (&ehci->lock, flags);
                }
 
@@ -1559,8 +1579,13 @@
 
                if (!sitd) {
                        spin_unlock_irqrestore (&ehci->lock, flags);
+#ifdef CONFIG_FSL_USB20
+                       sitd = MEM_Get (ehci->sitd_pool);
+                       sitd_dma = virt_to_phys(sitd);
+#else
                        sitd = dma_pool_alloc (ehci->sitd_pool, mem_flags,
                                        &sitd_dma);
+#endif
                        spin_lock_irqsave (&ehci->lock, flags);
                }
 
diff -Nur linux/drivers/usb/host/fsl-usb.c 
linux-8349-2.6/drivers/usb/host/fsl-usb.c
--- linux/drivers/usb/host/fsl-usb.c    1970-01-01 08:00:00.000000000 +0800
+++ linux-8349-2.6/drivers/usb/host/fsl-usb.c   2005-08-25 11:50:08.000000000 
+0800
@@ -0,0 +1,303 @@
+/* 
+ * Copyright (c) 2005 freescale semiconductor
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the  GNU General Public License along
+ * with this program; if not, write  to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/smp_lock.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/reboot.h>
+#include <linux/timer.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/usb.h>
+
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/byteorder.h>
+#include <asm/uaccess.h>
+
+#include <asm/unaligned.h>
+
+#include "../core/hcd.h"
+#include "fsl-usb.h"
+
+#define DRIVER_VERSION "$Revision: 1.11 $"
+#define DRIVER_AUTHOR "Hunter Wu"
+#define DRIVER_DESC "USB 2.0 Freescale EHCI Driver"
+#define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC
+
+MODULE_DESCRIPTION("MPC8249 USB Host Controller Driver");
+
+#include "ehci-hcd.c"
+
+void mpc8349_board_init(void)
+{
+       volatile unsigned char *bcsr5_p;
+
+       /* if SYS board is plug into PIB board, force to use the PHY on SYS 
board */
+       bcsr5_p = (volatile unsigned char *)(CFG_BCSR_BASE + 0x00000005); 
+       if ( (*bcsr5_p & BCSR5_INT_USB) == 0 ) 
+               *bcsr5_p = (*bcsr5_p | BCSR5_INT_USB);
+}
+
+void mpc8349_usb_clk_cfg(void)
+{
+       unsigned long sccr;
+       volatile unsigned long *p;
+       
+       p = (volatile unsigned long *)(CFG_IMMR_BASE + SCCR_OFFS); /* SCCR */
+       sccr = *p;
+               
+#if defined(CONFIG_MPH_USB_SUPPORT)
+       sccr &= ~SCCR_USB_MPHCM_11;
+       sccr |= SCCR_USB_MPHCM_11;  /* USB CLK 1:3 CSB CLK */
+       *p = sccr;
+#elif defined(CONFIG_DR_USB_SUPPORT)
+       sccr &= ~SCCR_USB_DRCM_11;
+       sccr |= SCCR_USB_DRCM_11;  /* USB CLK 1:3 CSB CLK */
+       *p = sccr;
+#endif
+
+}
+
+void mpc8349_usb_pin_cfg(void)
+{
+       unsigned long sicrl;
+       volatile unsigned long *p;
+       
+       p = (volatile unsigned long *)(CFG_IMMR_BASE + SICRL_OFFS); /* SCCR */
+       sicrl = *p;
+       
+#if defined(CONFIG_MPH_USB_SUPPORT)
+#ifdef CONFIG_MPH0_USB_ENABLE 
+       sicrl &= ~SICRL_USB0;
+       *p = sicrl;
+#endif
+
+#ifdef CONFIG_MPH1_USB_ENABLE
+       sicrl &= ~SICRL_USB1;
+       *p = sicrl;
+#endif
+#elif defined(CONFIG_DR_USB_SUPPORT)
+       sicrl &= ~SICRL_USB0;
+       sicrl |= SICRL_USB1 ;
+       *p = sicrl;
+#if defined(CONFIG_DR_UTMI)
+       sicrl &= ~SICRL_USB0;
+       sicrl |= SICRL_USB0;
+       *p = sicrl;
+#endif
+
+#endif
+}
+
+static void mpc8349_usb_reset(void)
+{
+       u32      portsc;
+    
+#if defined(CONFIG_MPH_USB_SUPPORT)    
+       t_USB_MPH_MAP *p_MphMemMap;
+       /* Enable PHY interface in the control reg. */
+       p_MphMemMap = (t_USB_MPH_MAP *)MPC83xx_USB_MPH_BASE;
+       p_MphMemMap->control = 0x00000004;
+       p_MphMemMap->snoop1 = 0x0000001b;
+#ifdef CONFIG_MPH0_USB_ENABLE
+       portsc = readl(&p_MphMemMap->port_status[0]);
+       portsc &= ~PORT_TS;
+#if defined(CONFIG_MPH0_ULPI)       
+       portsc |= PORT_TS_ULPI; 
+#elif defined (CONFIG_MPH0_SERIAL)
+       portsc |= PORT_TS_SERIAL;
+#endif 
+       writel(portsc,&p_MphMemMap->port_status[0]);
+#endif
+       
+#ifdef CONFIG_MPH1_USB_ENABLE
+       portsc = readl(&p_MphMemMap->port_status[1]);
+       portsc &= ~PORT_TS;
+#if defined(CONFIG_MPH1_ULPI)       
+       portsc |= PORT_TS_ULPI; 
+#elif defined (CONFIG_MPH1_SERIAL)
+       portsc |= PORT_TS_SERIAL;
+#endif 
+       writel(portsc,&p_MphMemMap->port_status[1]);
+#endif
+        
+       p_MphMemMap->pri_ctrl = 0x0000000c;
+       p_MphMemMap->age_cnt_thresh = 0x00000040;
+       p_MphMemMap->si_ctrl= 0x00000001;
+
+#elif defined(CONFIG_DR_USB_SUPPORT)
+       t_USB_DR_MAP *p_DrMemMap;
+       p_DrMemMap = (t_USB_DR_MAP *)MPC83xx_USB_DR_BASE;
+       p_DrMemMap->control = 0x00000004;
+       p_DrMemMap->snoop1 = 0x0000001b;
+       portsc = readl(&p_DrMemMap->port_status[0]);
+       portsc &= ~PORT_TS;
+#if defined(CONFIG_DR_ULPI)     
+       portsc |= PORT_TS_ULPI;
+#elif defined(CONFIG_DR_SERIAL)
+       portsc |= PORT_TS_SERIAL;
+#elif defined(CONFIG_DR_UTMI)
+       portsc |= PORT_TS_ULPI;
+#endif
+           
+       writel(portsc,&p_DrMemMap->port_status[0]);
+       writel(0x00000003,&p_DrMemMap->usbmode);
+       p_DrMemMap->pri_ctrl = 0x0000000c;
+       p_DrMemMap->age_cnt_thresh = 0x00000040;
+       p_DrMemMap->si_ctrl= 0x00000001;
+#endif
+}
+
+
+static int __init
+fsl_usb20_probe(struct device *dev)
+{
+       struct usb_hcd          *hcd;
+       struct ehci_hcd         *ehci;
+       int                     retval;
+#if defined (CONFIG_MPH_USB_SUPPORT)
+       t_USB_MPH_MAP           *p_MphMemMap;
+#elif defined (CONFIG_DR_USB_SUPPORT)
+       t_USB_DR_MAP            *p_DrMemMap;
+#endif 
+       mpc8349_board_init();
+       mpc8349_usb_clk_cfg();
+       mpc8349_usb_pin_cfg();
+       
+       hcd = usb_create_hcd(&ehci_driver);
+       if (!hcd) {
+               retval = 0;
+               goto err1;
+       }
+
+       ehci = hcd_to_ehci(hcd);
+       dev_set_drvdata(dev, ehci);
+       
+#if defined(CONFIG_MPH_USB_SUPPORT)
+       p_MphMemMap = (t_USB_MPH_MAP *)MPC83xx_USB_MPH_BASE;
+        
+        hcd->regs = (void *)(&p_MphMemMap->hc_capbase);
+        hcd->irq = MPC83xx_USB_MPH_IVEC;
+
+#elif defined (CONFIG_DR_USB_SUPPORT)
+       /* Enable PHY interface in the control reg. */
+        p_DrMemMap = (t_USB_DR_MAP *)MPC83xx_USB_DR_BASE;
+       hcd->regs = (void *)(&p_DrMemMap->hc_capbase);/* Set the interrupt that 
is called for this USB. */
+        hcd->irq = MPC83xx_USB_DR_IVEC;
+
+#endif
+
+       hcd->self.controller = dev;
+       hcd->self.bus_name = dev->bus_id;
+       hcd->product_desc ="fsl usb20";
+
+       retval = request_irq(hcd->irq, usb_hcd_irq, 
SA_INTERRUPT,hcd->driver->description, hcd);
+       if (retval != 0)
+               goto err2;
+       retval = usb_register_bus(&hcd->self);
+       if (retval < 0)
+               goto err3;
+
+       retval=ehci_hc_reset(hcd);
+
+       if (retval < 0)
+               goto err4;
+
+       if ((retval = ehci_start (hcd)) < 0) {
+               goto err4;
+       }
+
+       return 0;
+err4:
+       usb_deregister_bus(&hcd->self);
+err3:
+       free_irq(hcd->irq, hcd);
+err2:
+       usb_put_hcd(hcd);
+err1:
+       printk("init error, %d\n", retval);
+       return retval;  
+}
+
+static int __init_or_module
+fsl_usb20_remove(struct device *dev)
+{
+       struct ehci_hcd         *ehci = dev_get_drvdata(dev);
+       struct usb_hcd          *hcd = ehci_to_hcd(ehci);
+       
+
+       if (HCD_IS_RUNNING(hcd->state))
+               hcd->state = USB_STATE_QUIESCING;
+
+       usb_disconnect(&hcd->self.root_hub);
+       
+       hcd->driver->stop (hcd);
+       
+       usb_deregister_bus(&hcd->self);
+
+       free_irq(hcd->irq, hcd);
+
+       usb_put_hcd(hcd);
+       return 0;
+}
+       
+#define        fsl_usb20_suspend       NULL
+#define        fsl_usb20_resume        NULL
+
+static struct device_driver fsl_usb20_driver = {
+       .name =         (char *) hcd_name,
+       .bus =          &platform_bus_type,
+
+       .probe =        fsl_usb20_probe,
+       .remove =       fsl_usb20_remove,
+
+       .suspend =      fsl_usb20_suspend,
+       .resume =       fsl_usb20_resume,
+};
+
+/*-------------------------------------------------------------------------*/
+ 
+static int __init mpc8349_usb_hc_init(void) 
+{
+       if (usb_disabled())
+               return -ENODEV;
+
+       printk(KERN_INFO"driver %s, %s\n", hcd_name, DRIVER_VERSION);
+       return driver_register(&fsl_usb20_driver);
+}
+
+
+static void __exit mpc8349_usb_hc_deinit(void) 
+{      
+       driver_unregister(&fsl_usb20_driver);
+}
+MODULE_DESCRIPTION (DRIVER_INFO);
+MODULE_AUTHOR (DRIVER_AUTHOR);
+MODULE_LICENSE ("GPL");
+module_init(mpc8349_usb_hc_init);
+module_exit(mpc8349_usb_hc_deinit);
diff -Nur linux/drivers/usb/host/fsl-usb.h 
linux-8349-2.6/drivers/usb/host/fsl-usb.h
--- linux/drivers/usb/host/fsl-usb.h    1970-01-01 08:00:00.000000000 +0800
+++ linux-8349-2.6/drivers/usb/host/fsl-usb.h   2005-08-25 11:49:00.000000000 
+0800
@@ -0,0 +1,406 @@
+/* Copyright (c) 2005 freescale semiconductor
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the  GNU General Public License along
+ * with this program; if not, write  to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef _MPC8349_USB_EHCI_H
+#define _MPC8349_USB_EHCI_H
+
+/**************************************************************************/
+/[EMAIL PROTECTED]   t_USB_MPH_MAP - USB Multi-Port-Host internal memory map.*/
+/***************************************************************************/
+typedef   struct{
+       volatile u32    id;                     /* Identification register */
+       volatile u32    hwgeneral;
+       volatile u32    hwhost;
+       volatile u8     RESERVED01[0x004];      /* Reserved area           */
+       volatile u32    hwtxbuf;
+       volatile u32    hwrxbuf;
+       volatile u8     RESERVED02[0x0e8];      /* Reserved area           */
+    
+       /* Capability Registers */
+       volatile u32    hc_capbase;
+       volatile u32    hcs_params;             /* HCSPARAMS - offset 0x4 */
+       volatile u32    hcc_params;             /* HCCPARAMS - offset 0x8 */
+       volatile u8     portroute [8];          /* nibbles for routing - offset 
0xC */
+       volatile u8     RESERVED03[0x02c];      /* Reserved area           */
+
+       /* Operational Registers */
+       volatile u32    command;
+       volatile u32    status;
+       volatile u32    intr_enable;
+       volatile u32    frame_index;            /* current microframe number */
+       volatile u32    segment;                /* address bits 63:32 if needed 
*/
+       volatile u32    frame_list;             /* points to periodic list */
+       volatile u32    async_next;             /* address of next async queue 
head */
+       volatile u32    async_tt_status;        /* async queue status for 
embedded TT */
+       volatile u32    burst_size;             /* programmable burst size */
+       volatile u32    txfilltuning;           /* host transmit pre-buffer 
packet tuning */
+       volatile u32    txttfilltuning;         /* host TT transmit pre-buffer 
packet tuning */
+       volatile u8     RESERVED04[4];
+       volatile u32    ulpi_view_port;         /* ULPI view port */
+       volatile u32    endpoint_nack;          /* endpoint nack */
+       volatile u32    endpoint_nack_en;       /* endpoint nack enable */
+       volatile u8     RESERVED05[4];
+       volatile u32    configured_flag;
+       volatile u32    port_status [2];        /* up to N_PORTS */
+   
+       volatile u8     RESERVED06[0x01c];      /* Reserved area           */
+       volatile u32    usbmode;
+       volatile u8     RESERVED07[0x254];      /* Reserved area           */
+       volatile u32    snoop1;
+       volatile u32    snoop2;
+       volatile u32    age_cnt_thresh;
+       volatile u32    si_ctrl;
+       volatile u32    pri_ctrl;
+       volatile u8     RESERVED08[0x0ec];      /* Reserved area           */
+       volatile u32    control;
+       volatile u8     RESERVED09[0xaf8];      /* Reserved area           */
+} t_USB_MPH_MAP;
+
+/**************************************************************************/
+/** @Description   t_USB_DR_MAP - USB Dual-Role internal memory map.      */
+/***************************************************************************/
+typedef   struct{
+       volatile u32    id;                     /* Identification register */
+       volatile u32    hwgeneral;
+       volatile u32    hwhost;
+       volatile u32    hwdevice;
+       volatile u32    hwtxbuf;
+       volatile u32    hwrxbuf;
+       volatile u8     RESERVED01[0x0e8];      /* Reserved area           */
+   
+       /* Capability Registers */
+       volatile u32    hc_capbase;
+       volatile u32    hcs_params;             /* HCSPARAMS - offset 0x4 */
+       volatile u32    hcc_params;             /* HCCPARAMS - offset 0x8 */
+       volatile u8     portroute [8];          /* nibbles for routing - offset 
0xC */
+       volatile u8     RESERVED02[0x00c];      /* Reserved area           */
+       volatile u32    dciversion;
+       volatile u32    dccparms;
+       volatile u8     RESERVED03[0x018];      /* Reserved area           */
+          
+       /* Operational Registers */
+       volatile u32    command;
+       volatile u32    status;
+       volatile u32    intr_enable;
+       volatile u32    frame_index;            /* current microframe number */
+       union    t_host_slave_regs {
+               struct         t_ehci_regs 
+               {
+                       volatile u32    segment;        /* address bits 63:32 
if needed */
+                       volatile u32    frame_list;     /* points to periodic 
list */
+                       volatile u32    async_next;     /* address of next 
async queue head */
+               } host_regs;
+               struct         t_slave_regs {
+                       volatile u8     RESERVED04 [0x04];
+                       volatile u32    deviceaddr;
+                       volatile u32    endpoint_list_addr;     /* points to 
periodic list */
+               } slave_regs;
+       } host_slave_regs;
+       volatile u32    async_tt_status;        /* async queue status for 
embedded TT */
+       volatile u32    burst_size;             /* programmable burst size */
+       volatile u32    txfilltuning;           /* host transmit pre-buffer 
packet tuning */
+       volatile u32    txttfilltuning;         /* host TT transmit pre-buffer 
packet tuning */
+       volatile u8     RESERVED04[4];
+       volatile u32    ulpi_view_port;         /* ULPI view port */
+       volatile u32    endpoint_nack;          /* endpoint nack */
+       volatile u32    endpoint_nack_en;       /* endpoint nack enable */
+       volatile u8     RESERVED05[4];
+       volatile u32    configured_flag;
+       volatile u32    port_status [1];        /* up to N_PORTS */
+          
+       volatile u8     RESERVED06[0x01c];      /* Reserved area           */
+       volatile u32    otgsc;
+       volatile u32    usbmode;
+       volatile u32    endptsetupstat;
+       volatile u32    endptprime;
+       volatile u32    endptflush;
+       volatile u32    endptstatus;
+       volatile u32    endptcomplete;
+       volatile u32    endptctrl[6];
+       volatile u8     RESERVED07[0x228];      /* Reserved area           */
+       volatile u32    snoop1;
+       volatile u32    snoop2;
+       volatile u32    age_cnt_thresh;
+       volatile u32    si_ctrl;
+       volatile u32    pri_ctrl;
+       volatile u8     RESERVED08[0x0ec];      /* Reserved area           */
+       volatile u32    control;
+       volatile u8     RESERVED09[0xaf8];      /* Reserved area           */
+} __attribute__ ((packed)) t_USB_DR_MAP, * t_pUSB_DR_MAP;
+
+
+
+#define PORT_OFF        0
+#define PORT_ULPI       1
+#define PORT_UTMI       2
+#define PORT_SERIAL     3
+#define PORT_SERIAL_OTG 4
+
+
+#define PORT_TS          0xc0000000
+#define PORT_TS_UTMI     0x00000000
+#define PORT_TS_ULPI     0x80000000
+#define PORT_TS_SERIAL   0xc0000000
+#define PORT_TW          0x10000000
+#define PORT_SPD         0x0c000000
+#define PORT_FSC         0x01000000
+#define PORT_PP          0x00001000
+
+
+
+#define CFG_IMMR_BASE          (0xfe000000)
+#define MPC83xx_USB_MPH_BASE    (CFG_IMMR_BASE + 0x22000)
+#define MPC83xx_USB_DR_BASE     (CFG_IMMR_BASE + 0x23000)
+#define MPC83xx_USB_DR_IVEC    (38)
+#define MPC83xx_USB_MPH_IVEC   (39)
+#define CFG_BCSR_BASE          (0xfe100000)
+#define BCSR5_INT_USB          (0x02)
+
+#define e_USB_MPH 0
+#define e_USB_DR 1
+#define e_ULPI          0
+#define e_UTMI_8BIT     1 
+#define e_UTMI_16BIT    2
+#define e_SERIAL        3
+
+#define SCCR_OFFS          0xA08
+#define SCCR_USB_MPHCM_11  0x00c00000
+#define SCCR_USB_MPHCM_01  0x00400000
+#define SCCR_USB_MPHCM_10  0x00800000
+#define SCCR_USB_DRCM_11   0x00300000
+#define SCCR_USB_DRCM_01   0x00100000
+#define SCCR_USB_DRCM_10   0x00200000
+
+#define SICRL_OFFS         0x114
+#define SICRL_USB1         0x40000000
+#define SICRL_USB0         0x20000000
+
+#define SICRH_OFFS         0x118
+#define SICRH_USB_UTMI     0x00020000
+
+#define SPCR_OFFS          0x00000110
+#define SPCR_TBEN          0x00400000
+
+#define POWER_OF_2(n)           (!(n & (n-1)))
+
+/*------------------------------------------------------*/
+
+typedef struct
+{
+       char            Name[4];        /* this segment's name          */
+       spinlock_t      lock;
+       u16             Num;    /* number of blocks in segment  */
+       int         Size;       /* size of blocks in segment    */
+                               /* in case of TMP_DEF -         */
+                               /* only the data                */
+       u32     GetFailures;    /* number of times get failed   */
+       int     LocallyAllocated;       /* TRUE if memory was allocated */
+       /* at MEM_Init.   */
+       u8      *p_Base;        /* base address of segment      */
+       void    **p_First;      /* first block in segment       */
+       void    **p_Last;       /* last block in segment        */
+       int     (*f_MemPut)(void* Handle, void *p_Block );
+                               /* a routine for returning a memory block */
+
+       u16     PrefixSize;     /* replaces B_OFFSET - how many     */
+                               /* bytes to reserve before the data     */
+       u16     PostfixSize ;   /* replaces B_TRAILER - how many   */
+                               /* bytes to reserve after the data     */
+                               /* Trailer also includes a pad needed for */
+                               /* padding the entire block to 4 byte     */
+                               /* alignment for faster access to the     */
+                               /* control field                          */
+       u16     Alignment;      /* requested alignment for the data field */
+       u16     AlignPad;       /* pad the offset field so that the data  */
+                               /* field shall have the proper alignment  */
+       u16     EndPad;         /* Pad to make entire block size a */
+                               /* multiple of Alignment        */
+} t_MemorySegment;
+
+#define PAD_ALIGNMENT( align, x ) ( ((x)%(align)) ? ((align)-((x)%(align))) : 
0 )
+
+
+void *MEM_Get( void* Handle )
+{
+       unsigned long           flags;  
+       u8              *p_F;
+       t_MemorySegment         *p ;
+       
+       p = (t_MemorySegment *)Handle;
+  
+       spin_lock_irqsave(&p->lock,flags);
+
+       /* check if the chain is not empty */
+       if( !(*(p->p_First)) )
+       {
+               p->GetFailures++;
+               spin_unlock_irqrestore(p->lock,flags);
+               return 0;
+       }
+       /* advance first pointer and return the old head of chain */
+       p_F = ((u8 *)p->p_First) + ( 4 + p->AlignPad + p->PrefixSize );   
+       p->p_First = (void **) *(p->p_First); /* skip the next pointer */
+
+       spin_unlock_irqrestore(&p->lock,flags);
+
+       return (void *)p_F;
+}
+
+
+int MEM_Put_Default( void * Handle, void *p_Block )
+{
+       unsigned long   flags;  
+       t_MemorySegment         *p = (t_MemorySegment *)Handle;
+       u8              *p_B = (u8 *)p_Block;
+   
+       /* if handle is NULL, use user's free routine */
+       if( Handle == 0 )
+       {
+               kfree( p_Block );
+               return 0;
+       }
+
+       spin_lock_irqsave(&p->lock,flags);
+
+       /* get the pointer to the start of the memory */
+       p_B -= ( 4 + p->AlignPad + p->PrefixSize );    /* skip back over next 
pointer */ 
+       /* chain to end and advance last pointer */
+       *((void **)p_B) = 0;
+       *(p->p_Last) = (void *)p_B;
+       p->p_Last = (void **)p_B;
+
+       spin_unlock_irqrestore(&p->lock,flags);
+       return 0;
+}
+
+int MEM_Init( char Name[], 
+       void* *p_Handle, 
+       u16 Num, 
+       u16 Size , 
+       u16 PrefixSize, 
+       u16 PostfixSize, 
+       u16 Alignment )
+{
+       t_MemorySegment         *p;
+       u8              *p_Blocks;
+       int                     i ;
+       int                     blockSize;
+
+       /* always allocate a dummy block at the end */
+       Num++;
+
+       /* make sure size is always a multiple of 4 */
+       if( Size & 3 )
+       {
+               Size &= ~3;
+               Size += 4;
+       }
+
+       if (Alignment < 4 ) 
+               Alignment = 4;
+
+       /** make sure that the alignment is a power of two */
+       if( !POWER_OF_2(Alignment) ) 
+       {
+               printk("MEM_Init: requested alignment is not a power of 
two.\n");
+               return -EINVAL;
+       }                          
+
+       /* prepare in case of error */
+       *p_Handle = 0;
+
+       /* first allocate the segment descriptor */
+       p = (t_MemorySegment *)kmalloc( sizeof(t_MemorySegment),GFP_KERNEL );
+
+       if( !p )
+               return -ENOMEM;
+       /* calculate blockSize */
+  
+       /* store info about this segment */
+       spin_lock_init (&p->lock);
+       p->Num = (u16)(Num - 1);  
+       p->Size = Size;
+       p->GetFailures = 0L;
+       p->f_MemPut = MEM_Put_Default;
+       p->LocallyAllocated = 1;
+       p->PrefixSize = PrefixSize;
+       p->Alignment = Alignment; 
+       p->AlignPad  = (u16)PAD_ALIGNMENT((u16)4, (u16)PrefixSize+4); 
+       p->PostfixSize = PostfixSize;
+       /* Make sure the entire size is a multiple of Alignment */
+       p->EndPad = (u16)PAD_ALIGNMENT((u16)Alignment, 4 + p->AlignPad + 
PrefixSize + Size + PostfixSize); 
+
+       blockSize = 4 + p->AlignPad + PrefixSize + Size + PostfixSize + 
p->EndPad;
+
+       p_Blocks = (u8 *)kmalloc(( Alignment +  Num * blockSize ),GFP_KERNEL);
+
+       if( !p_Blocks )
+       {
+               kfree( p );
+               return -ENOMEM;
+       }
+       /* store the memory segment address */
+       p->p_Base = p_Blocks;
+       
+       p_Blocks += (PrefixSize+4);
+       p_Blocks += (PAD_ALIGNMENT( Alignment, (u32)p_Blocks)); 
+       p_Blocks -= (PrefixSize+4+p->AlignPad);
+
+       /* store name */
+       strncpy( p->Name, Name, 4 );
+
+       /* finally, initialize the blocks */
+       p->p_Last = p->p_First = (void **)p_Blocks;
+       for(i = 0; i < (Num-1); i++)
+       {
+       /* get next block */
+               p_Blocks += blockSize;
+
+       /* attach to end of chain */
+               if( p->p_Last )
+                       *(p->p_Last) = (void *)p_Blocks;
+
+       /* advance last pointer */
+               p->p_Last = (void **)p_Blocks;
+       }
+
+       /* zero next pointer in last block */
+       *(p->p_Last) = 0;
+
+       /* return handle to caller */
+       *p_Handle = (void *)p;
+
+       return 0;
+}
+
+
+
+void  MEM_Free( void* p_Handle)
+{
+       t_MemorySegment *p = (t_MemorySegment*)p_Handle;
+
+       if ( p && p->LocallyAllocated)
+               kfree (p->p_Base);
+       kfree(p);
+}
+
+#define MEM_Put(Handle, p_Block)    \
+       ((t_MemorySegment *)Handle)->f_MemPut( Handle, p_Block)
+
+
+
+
+#endif /* __STD_EXT_H */
diff -Nur linux/drivers/usb/host/Kconfig linux-8349-2.6/drivers/usb/host/Kconfig
--- linux/drivers/usb/host/Kconfig      2004-12-25 05:35:29.000000000 +0800
+++ linux-8349-2.6/drivers/usb/host/Kconfig     2005-08-16 14:58:56.000000000 
+0800
@@ -5,6 +5,7 @@
        boolean
        default y if USB_ARCH_HAS_OHCI
        default y if ARM                                # SL-811
+       default y if FSL_USB20                          # MPC83xx SYS
        default PCI
 
 # many non-PCI hcds implement OHCI
@@ -24,7 +25,7 @@
 
 config USB_EHCI_HCD
        tristate "EHCI HCD (USB 2.0) support"
-       depends on USB && PCI
+       depends on (USB && PCI) || (USB && FSL_USB20)
        ---help---
          The Enhanced Host Controller Interface (EHCI) is standard for USB 2.0
          "high speed" (480 Mbit/sec, 60 Mbyte/sec) host controller hardware.
diff -Nur linux/drivers/usb/host/Makefile 
linux-8349-2.6/drivers/usb/host/Makefile
--- linux/drivers/usb/host/Makefile     2004-12-25 05:35:39.000000000 +0800
+++ linux-8349-2.6/drivers/usb/host/Makefile    2005-08-15 13:41:35.000000000 
+0800
@@ -2,8 +2,11 @@
 # Makefile for USB Host Controller Driver
 # framework and drivers
 #
-
+ifeq ($(CONFIG_FSL_USB20),y)
+obj-$(CONFIG_USB_EHCI_HCD)     += fsl-usb.o
+else
 obj-$(CONFIG_USB_EHCI_HCD)     += ehci-hcd.o
+endif
 obj-$(CONFIG_USB_OHCI_HCD)     += ohci-hcd.o
 obj-$(CONFIG_USB_UHCI_HCD)     += uhci-hcd.o
 obj-$(CONFIG_USB_SL811_HCD)    += sl811-hcd.o
diff -Nur linux/arch/ppc/platforms/83xx/Kconfig 
linux-8349-2.6/arch/ppc/platforms/83xx/Kconfig
--- linux/arch/ppc/platforms/83xx/Kconfig       2005-03-03 01:46:54.000000000 
+0800
+++ linux-8349-2.6/arch/ppc/platforms/83xx/Kconfig      2005-08-25 
11:44:57.000000000 +0800
@@ -27,4 +27,78 @@
        depends on 83xx
        default y
 
+config FSL_USB20
+       bool "MPC834x USB20 Host Support"
+       depends on MPC834x_SYS
+
+
+menu "USB20 Host Configuration"
+       depends on FSL_USB20 
+
+choice
+       prompt "MPC83xx USB20 host Mode"
+       depends on FSL_USB20 
+       default MPH_USB_SUPPORT
+
+config MPH_USB_SUPPORT
+       bool "MPH_MODE"
+               
+config DR_USB_SUPPORT
+       bool "DR_MODE"
+
+endchoice
+
+config MPH0_USB_ENABLE
+       bool "MPH0 USB HOST Enable"
+       depends on MPH_USB_SUPPORT
+
+choice
+       prompt "MPH0 PHY Interface Selection"
+       depends on MPH0_USB_ENABLE
+       default MPH0_ULPI
+
+config MPH0_ULPI
+       bool "ULPI"
+
+config MPH0_SERIAL
+       bool "Serial"
+
+endchoice
+
+config MPH1_USB_ENABLE
+       bool "MPH1 USB HOST Enable"
+       depends on MPH_USB_SUPPORT
+
+choice
+       prompt "MPH1 PHY Interface Selection"
+       depends on MPH1_USB_ENABLE
+       default MPH1_ULPI
+
+config MPH1_ULPI
+       bool "ULPI"
+
+config MPH1_SERIAL
+       bool "Serial"
+
+endchoice
+
+
+choice
+       prompt "DR PHY Interface Selection"
+       depends on DR_USB_SUPPORT
+       default DR_ULPI
+
+config DR_ULPI
+       bool "ULPI"
+
+config DR_SERIAL
+       bool "Serial"
+
+config DR_UTMI
+       bool "UTMI"
+
+endchoice
+
+endmenu
+
 endmenu


--
Leo Li
Freescale Semiconductor
 
LeoLi at freescale.com 
 


Reply via email to