u32 insreg08;           /* 0xb0 */
 };
 
-int omap_ehci_hcd_init(struct omap_usbhs_board_data *usbhs_pdata);
+/*
+ * FIXME: forward declaration of this structs needed because omap got the
+ * ehci implementation backwards. move out ehci_hcd_x from board files
+ */
+struct ehci_hccr;
+struct ehci_hcor;
+
+int omap_ehci_hcd_init(struct omap_usbhs_board_data *usbhs_pdata,
+               struct ehci_hccr **hccr, struct ehci_hcor **hcor);
 int omap_ehci_hcd_stop(void);
 
 #endif /* _OMAP_COMMON_EHCI_H_ */
 
        .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
 };
 
-int ehci_hcd_init(void)
+int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 {
-       return omap_ehci_hcd_init(&usbhs_bdata);
+       return omap_ehci_hcd_init(&usbhs_bdata, hccr, hcor);
 }
 
-int ehci_hcd_stop(void)
+int ehci_hcd_stop(int index)
 {
        return omap_ehci_hcd_stop();
 }
 
        .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
 };
 
-int ehci_hcd_init(void)
+int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 {
-       return omap_ehci_hcd_init(&usbhs_bdata);
+       return omap_ehci_hcd_init(&usbhs_bdata, hccr, hcor);
 }
 
-int ehci_hcd_stop(void)
+int ehci_hcd_stop(int index)
 {
        return omap_ehci_hcd_stop();
 }
 
        .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
 };
 
-int ehci_hcd_init(void)
+int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 {
-       return omap_ehci_hcd_init(&usbhs_bdata);
+       return omap_ehci_hcd_init(&usbhs_bdata, hccr, hcor);
 }
 
-int ehci_hcd_stop(void)
+int ehci_hcd_stop(int index)
 {
        return omap_ehci_hcd_stop();
 }
 
        .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED
 };
 
-int ehci_hcd_init(void)
+int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 {
-       return omap_ehci_hcd_init(&usbhs_bdata);
+       return omap_ehci_hcd_init(&usbhs_bdata, hccr, hcor);
 }
 
-int ehci_hcd_stop(void)
+int ehci_hcd_stop(int index)
 {
        return omap_ehci_hcd_stop();
 }
 
        .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
 };
 
-int ehci_hcd_init(void)
+int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 {
        int ret;
        unsigned int utmi_clk;
        utmi_clk |= HSUSBHOST_CLKCTRL_CLKSEL_UTMI_P1_MASK;
        sr32((void *)CM_L3INIT_HSUSBHOST_CLKCTRL, 0, 32, utmi_clk);
 
-       ret = omap_ehci_hcd_init(&usbhs_bdata);
+       ret = omap_ehci_hcd_init(&usbhs_bdata, hccr, hcor);
        if (ret < 0)
                return ret;
 
        return 0;
 }
 
-int ehci_hcd_stop(void)
+int ehci_hcd_stop(int index)
 {
        return omap_ehci_hcd_stop();
 }
 
 #include <asm/io.h>
 #include <usb.h>
 #include "ehci.h"
-#include "ehci-core.h"
 #include <asm/arch/cpu.h>
 #include <asm/arch/armada100.h>
 #include <asm/arch/utmi-armada100.h>
 /*
  * EHCI host controller init
  */
-int ehci_hcd_init(void)
+int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 {
        if (utmi_init() < 0)
                return -1;
 
-       hccr = (struct ehci_hccr *)(ARMD1_USB_HOST_BASE + 0x100);
-       hcor = (struct ehci_hcor *)((uint32_t) hccr
-                       + HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+       *hccr = (struct ehci_hccr *)(ARMD1_USB_HOST_BASE + 0x100);
+       *hcor = (struct ehci_hcor *)((uint32_t) *hccr
+                       + HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
 
        debug("armada100-ehci: init hccr %x and hcor %x hc_length %d\n",
-               (uint32_t)hccr, (uint32_t)hcor,
-               (uint32_t)HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+               (uint32_t)*hccr, (uint32_t)*hcor,
+               (uint32_t)HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
 
        return 0;
 }
 /*
  * EHCI host controller stop
  */
-int ehci_hcd_stop(void)
+int ehci_hcd_stop(int index)
 {
        return 0;
 }
 
 #include <asm/arch/clk.h>
 
 #include "ehci.h"
-#include "ehci-core.h"
 
 /* Enable UTMI PLL time out 500us
  * 10 times as datasheet specified
  */
 #define EN_UPLL_TIMEOUT        500UL
 
-int ehci_hcd_init(void)
+int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 {
        at91_pmc_t *pmc = (at91_pmc_t *)ATMEL_BASE_PMC;
        ulong start_time, tmp_time;
        /* Enable USB Host clock */
        writel(1 << ATMEL_ID_UHPHS, &pmc->pcer);
 
-       hccr = (struct ehci_hccr *)ATMEL_BASE_EHCI;
-       hcor = (struct ehci_hcor *)((uint32_t)hccr +
-                       HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+       *hccr = (struct ehci_hccr *)ATMEL_BASE_EHCI;
+       *hcor = (struct ehci_hcor *)((uint32_t)*hccr +
+                       HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
 
        return 0;
 }
 
-int ehci_hcd_stop(void)
+int ehci_hcd_stop(int index)
 {
        at91_pmc_t *pmc = (at91_pmc_t *)ATMEL_BASE_PMC;
        ulong start_time, tmp_time;
 
+++ /dev/null
-/*-
- * Copyright (c) 2007-2008, Juniper Networks, Inc.
- * Copyright (c) 2008, Excito Elektronik i Skåne AB
- * All rights reserved.
- *
- * 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 version 2 of
- * the License.
- *
- * 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., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#ifndef USB_EHCI_CORE_H
-#define USB_EHCI_CORE_H
-
-extern int rootdev;
-extern struct ehci_hccr *hccr;
-extern volatile struct ehci_hcor *hcor;
-
-#endif
 
 #include <asm/arch/system.h>
 #include <asm/arch/power.h>
 #include "ehci.h"
-#include "ehci-core.h"
 
 /* Setup the EHCI host controller. */
 static void setup_usb_phy(struct exynos_usb_phy *usb)
  * Create the appropriate control structures to manage
  * a new EHCI host controller.
  */
-int ehci_hcd_init(void)
+int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 {
        struct exynos_usb_phy *usb;
 
        usb = (struct exynos_usb_phy *)samsung_get_base_usb_phy();
        setup_usb_phy(usb);
 
-       hccr = (struct ehci_hccr *)samsung_get_base_usb_ehci();
-       hcor = (struct ehci_hcor *)((uint32_t) hccr
-                               + HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+       *hccr = (struct ehci_hccr *)samsung_get_base_usb_ehci();
+       *hcor = (struct ehci_hcor *)((uint32_t) *hccr
+                               + HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
 
        debug("Exynos5-ehci: init hccr %x and hcor %x hc_length %d\n",
-               (uint32_t)hccr, (uint32_t)hcor,
-               (uint32_t)HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+               (uint32_t)*hccr, (uint32_t)*hcor,
+               (uint32_t)HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
 
        return 0;
 }
  * Destroy the appropriate control structures corresponding
  * the EHCI host controller.
  */
-int ehci_hcd_stop()
+int ehci_hcd_stop(int index)
 {
        struct exynos_usb_phy *usb;
 
 
 #include <hwconfig.h>
 
 #include "ehci.h"
-#include "ehci-core.h"
 
 /*
  * Create the appropriate control structures to manage
  *
  * Excerpts from linux ehci fsl driver.
  */
-int ehci_hcd_init(void)
+int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 {
        struct usb_ehci *ehci;
        const char *phy_type = NULL;
 #endif
 
        ehci = (struct usb_ehci *)CONFIG_SYS_FSL_USB_ADDR;
-       hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
-       hcor = (struct ehci_hcor *)((uint32_t) hccr +
-                       HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+       *hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
+       *hcor = (struct ehci_hcor *)((uint32_t) *hccr +
+                       HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
 
        /* Set to Host mode */
        setbits_le32(&ehci->usbmode, CM_HOST);
                setbits_be32(&ehci->control, UTMI_PHY_EN);
                udelay(1000); /* delay required for PHY Clk to appear */
 #endif
-               out_le32(&(hcor->or_portsc[0]), PORT_PTS_UTMI);
+               out_le32(&(*hcor)->or_portsc[0], PORT_PTS_UTMI);
        } else {
 #if defined(CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY)
                clrbits_be32(&ehci->control, UTMI_PHY_EN);
                setbits_be32(&ehci->control, PHY_CLK_SEL_ULPI);
                udelay(1000); /* delay required for PHY Clk to appear */
 #endif
-               out_le32(&(hcor->or_portsc[0]), PORT_PTS_ULPI);
+               out_le32(&(*hcor)->or_portsc[0], PORT_PTS_ULPI);
        }
 
        /* Enable interface. */
  * Destroy the appropriate control structures corresponding
  * the the EHCI host controller.
  */
-int ehci_hcd_stop(void)
+int ehci_hcd_stop(int index)
 {
        return 0;
 }
 
 
 #include "ehci.h"
 
-int rootdev;
-struct ehci_hccr *hccr;        /* R/O registers, not need for volatile */
-volatile struct ehci_hcor *hcor;
+#ifndef CONFIG_USB_MAX_CONTROLLER_COUNT
+#define CONFIG_USB_MAX_CONTROLLER_COUNT 1
+#endif
 
-static uint16_t portreset;
-DEFINE_ALIGN_BUFFER(struct QH, qh_list, 1, USB_DMA_MINALIGN);
+static struct ehci_ctrl {
+       struct ehci_hccr *hccr; /* R/O registers, not need for volatile */
+       struct ehci_hcor *hcor;
+       int rootdev;
+       uint16_t portreset;
+       struct QH qh_list __attribute__((aligned(USB_DMA_MINALIGN)));
+} ehcic[CONFIG_USB_MAX_CONTROLLER_COUNT];
 
 #define ALIGN_END_ADDR(type, ptr, size)                        \
        ((uint32_t)(ptr) + roundup((size) * sizeof(type), USB_DMA_MINALIGN))
        return -1;
 }
 
-static int ehci_reset(void)
+static int ehci_reset(int index)
 {
        uint32_t cmd;
        uint32_t tmp;
        uint32_t *reg_ptr;
        int ret = 0;
 
-       cmd = ehci_readl(&hcor->or_usbcmd);
+       cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
        cmd = (cmd & ~CMD_RUN) | CMD_RESET;
-       ehci_writel(&hcor->or_usbcmd, cmd);
-       ret = handshake((uint32_t *)&hcor->or_usbcmd, CMD_RESET, 0, 250 * 1000);
+       ehci_writel(&ehcic[index].hcor->or_usbcmd, cmd);
+       ret = handshake((uint32_t *)&ehcic[index].hcor->or_usbcmd,
+                       CMD_RESET, 0, 250 * 1000);
        if (ret < 0) {
                printf("EHCI fail to reset\n");
                goto out;
        }
 
        if (ehci_is_TDI()) {
-               reg_ptr = (uint32_t *)((u8 *)hcor + USBMODE);
+               reg_ptr = (uint32_t *)((u8 *)ehcic[index].hcor + USBMODE);
                tmp = ehci_readl(reg_ptr);
                tmp |= USBMODE_CM_HC;
 #if defined(CONFIG_EHCI_MMIO_BIG_ENDIAN)
        }
 
 #ifdef CONFIG_USB_EHCI_TXFIFO_THRESH
-       cmd = ehci_readl(&hcor->or_txfilltuning);
+       cmd = ehci_readl(&ehcic[index].hcor->or_txfilltuning);
        cmd &= ~TXFIFO_THRESH_MASK;
        cmd |= TXFIFO_THRESH(CONFIG_USB_EHCI_TXFIFO_THRESH);
-       ehci_writel(&hcor->or_txfilltuning, cmd);
+       ehci_writel(&ehcic[index].hcor->or_txfilltuning, cmd);
 #endif
 out:
        return ret;
        struct qTD *qtd;
        int qtd_count = 0;
        int qtd_counter = 0;
-
        volatile struct qTD *vtd;
        unsigned long ts;
        uint32_t *tdp;
        uint32_t cmd;
        int timeout;
        int ret = 0;
+       struct ehci_ctrl *ctrl = dev->controller;
 
        debug("dev=%p, pipe=%lx, buffer=%p, length=%d, req=%p\n", dev, pipe,
              buffer, length, req);
         *   qh_overlay.qt_next ...... 13-10 H
         * - qh_overlay.qt_altnext
         */
-       qh->qh_link = cpu_to_hc32((uint32_t)qh_list | QH_LINK_TYPE_QH);
+       qh->qh_link = cpu_to_hc32((uint32_t)&ctrl->qh_list | QH_LINK_TYPE_QH);
        c = usb_pipespeed(pipe) != USB_SPEED_HIGH && !usb_pipeendpoint(pipe);
        maxpacket = usb_maxpacket(dev, pipe);
        endpt = QH_ENDPT1_RL(8) | QH_ENDPT1_C(c) |
                tdp = &qtd[qtd_counter++].qt_next;
        }
 
-       qh_list->qh_link = cpu_to_hc32((uint32_t)qh | QH_LINK_TYPE_QH);
+       ctrl->qh_list.qh_link = cpu_to_hc32((uint32_t)qh | QH_LINK_TYPE_QH);
 
        /* Flush dcache */
-       flush_dcache_range((uint32_t)qh_list,
-               ALIGN_END_ADDR(struct QH, qh_list, 1));
+       flush_dcache_range((uint32_t)&ctrl->qh_list,
+               ALIGN_END_ADDR(struct QH, &ctrl->qh_list, 1));
        flush_dcache_range((uint32_t)qh, ALIGN_END_ADDR(struct QH, qh, 1));
        flush_dcache_range((uint32_t)qtd,
                           ALIGN_END_ADDR(struct qTD, qtd, qtd_count));
 
        /* Set async. queue head pointer. */
-       ehci_writel(&hcor->or_asynclistaddr, (uint32_t)qh_list);
+       ehci_writel(&ctrl->hcor->or_asynclistaddr, (uint32_t)&ctrl->qh_list);
 
-       usbsts = ehci_readl(&hcor->or_usbsts);
-       ehci_writel(&hcor->or_usbsts, (usbsts & 0x3f));
+       usbsts = ehci_readl(&ctrl->hcor->or_usbsts);
+       ehci_writel(&ctrl->hcor->or_usbsts, (usbsts & 0x3f));
 
        /* Enable async. schedule. */
-       cmd = ehci_readl(&hcor->or_usbcmd);
+       cmd = ehci_readl(&ctrl->hcor->or_usbcmd);
        cmd |= CMD_ASE;
-       ehci_writel(&hcor->or_usbcmd, cmd);
+       ehci_writel(&ctrl->hcor->or_usbcmd, cmd);
 
-       ret = handshake((uint32_t *)&hcor->or_usbsts, STS_ASS, STS_ASS,
+       ret = handshake((uint32_t *)&ctrl->hcor->or_usbsts, STS_ASS, STS_ASS,
                        100 * 1000);
        if (ret < 0) {
                printf("EHCI fail timeout STS_ASS set\n");
        timeout = USB_TIMEOUT_MS(pipe);
        do {
                /* Invalidate dcache */
-               invalidate_dcache_range((uint32_t)qh_list,
-                       ALIGN_END_ADDR(struct QH, qh_list, 1));
+               invalidate_dcache_range((uint32_t)&ctrl->qh_list,
+                       ALIGN_END_ADDR(struct QH, &ctrl->qh_list, 1));
                invalidate_dcache_range((uint32_t)qh,
                        ALIGN_END_ADDR(struct QH, qh, 1));
                invalidate_dcache_range((uint32_t)qtd,
                printf("EHCI timed out on TD - token=%#x\n", token);
 
        /* Disable async schedule. */
-       cmd = ehci_readl(&hcor->or_usbcmd);
+       cmd = ehci_readl(&ctrl->hcor->or_usbcmd);
        cmd &= ~CMD_ASE;
-       ehci_writel(&hcor->or_usbcmd, cmd);
+       ehci_writel(&ctrl->hcor->or_usbcmd, cmd);
 
-       ret = handshake((uint32_t *)&hcor->or_usbsts, STS_ASS, 0,
+       ret = handshake((uint32_t *)&ctrl->hcor->or_usbsts, STS_ASS, 0,
                        100 * 1000);
        if (ret < 0) {
                printf("EHCI fail timeout STS_ASS reset\n");
        } else {
                dev->act_len = 0;
                debug("dev=%u, usbsts=%#x, p[1]=%#x, p[2]=%#x\n",
-                     dev->devnum, ehci_readl(&hcor->or_usbsts),
-                     ehci_readl(&hcor->or_portsc[0]),
-                     ehci_readl(&hcor->or_portsc[1]));
+                     dev->devnum, ehci_readl(&ctrl->hcor->or_usbsts),
+                     ehci_readl(&ctrl->hcor->or_portsc[0]),
+                     ehci_readl(&ctrl->hcor->or_portsc[1]));
        }
 
        free(qtd);
        int len, srclen;
        uint32_t reg;
        uint32_t *status_reg;
+       struct ehci_ctrl *ctrl = dev->controller;
 
        if (le16_to_cpu(req->index) > CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
                printf("The request port(%d) is not configured\n",
                        le16_to_cpu(req->index) - 1);
                return -1;
        }
-       status_reg = (uint32_t *)&hcor->or_portsc[
+       status_reg = (uint32_t *)&ctrl->hcor->or_portsc[
                                                le16_to_cpu(req->index) - 1];
        srclen = 0;
 
                break;
        case USB_REQ_SET_ADDRESS | (USB_RECIP_DEVICE << 8):
                debug("USB_REQ_SET_ADDRESS\n");
-               rootdev = le16_to_cpu(req->value);
+               ctrl->rootdev = le16_to_cpu(req->value);
                break;
        case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
                debug("USB_REQ_SET_CONFIGURATION\n");
                        tmpbuf[2] |= USB_PORT_STAT_C_ENABLE;
                if (reg & EHCI_PS_OCC)
                        tmpbuf[2] |= USB_PORT_STAT_C_OVERCURRENT;
-               if (portreset & (1 << le16_to_cpu(req->index)))
+               if (ctrl->portreset & (1 << le16_to_cpu(req->index)))
                        tmpbuf[2] |= USB_PORT_STAT_C_RESET;
 
                srcptr = tmpbuf;
                        ehci_writel(status_reg, reg);
                        break;
                case USB_PORT_FEAT_POWER:
-                       if (HCS_PPC(ehci_readl(&hccr->cr_hcsparams))) {
+                       if (HCS_PPC(ehci_readl(&ctrl->hccr->cr_hcsparams))) {
                                reg |= EHCI_PS_PP;
                                ehci_writel(status_reg, reg);
                        }
                                ret = handshake(status_reg, EHCI_PS_PR, 0,
                                                2 * 1000);
                                if (!ret)
-                                       portreset |=
+                                       ctrl->portreset |=
                                                1 << le16_to_cpu(req->index);
                                else
                                        printf("port(%d) reset error\n",
                        goto unknown;
                }
                /* unblock posted writes */
-               (void) ehci_readl(&hcor->or_usbcmd);
+               (void) ehci_readl(&ctrl->hcor->or_usbcmd);
                break;
        case USB_REQ_CLEAR_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
                reg = ehci_readl(status_reg);
                        reg = (reg & ~EHCI_PS_CLEAR) | EHCI_PS_PE;
                        break;
                case USB_PORT_FEAT_POWER:
-                       if (HCS_PPC(ehci_readl(&hccr->cr_hcsparams)))
+                       if (HCS_PPC(ehci_readl(&ctrl->hccr->cr_hcsparams)))
                                reg = reg & ~(EHCI_PS_CLEAR | EHCI_PS_PP);
                case USB_PORT_FEAT_C_CONNECTION:
                        reg = (reg & ~EHCI_PS_CLEAR) | EHCI_PS_CSC;
                        reg = (reg & ~EHCI_PS_CLEAR) | EHCI_PS_OCC;
                        break;
                case USB_PORT_FEAT_C_RESET:
-                       portreset &= ~(1 << le16_to_cpu(req->index));
+                       ctrl->portreset &= ~(1 << le16_to_cpu(req->index));
                        break;
                default:
                        debug("unknown feature %x\n", le16_to_cpu(req->value));
                }
                ehci_writel(status_reg, reg);
                /* unblock posted write */
-               (void) ehci_readl(&hcor->or_usbcmd);
+               (void) ehci_readl(&ctrl->hcor->or_usbcmd);
                break;
        default:
                debug("Unknown request\n");
 
 int usb_lowlevel_stop(int index)
 {
-       return ehci_hcd_stop();
+       return ehci_hcd_stop(index);
 }
 
 int usb_lowlevel_init(int index, void **controller)
 {
        uint32_t reg;
        uint32_t cmd;
+       struct QH *qh_list;
 
-       if (ehci_hcd_init())
+       if (ehci_hcd_init(index, &ehcic[index].hccr, &ehcic[index].hcor))
                return -1;
 
        /* EHCI spec section 4.1 */
-       if (ehci_reset())
+       if (ehci_reset(index))
                return -1;
 
 #if defined(CONFIG_EHCI_HCD_INIT_AFTER_RESET)
-       if (ehci_hcd_init())
+       if (ehci_hcd_init(index, &ehcic[index].hccr, &ehcic[index].hcor))
                return -1;
 #endif
 
+       qh_list = &ehcic[index].qh_list;
+
        /* Set head of reclaim list */
        memset(qh_list, 0, sizeof(*qh_list));
        qh_list->qh_link = cpu_to_hc32((uint32_t)qh_list | QH_LINK_TYPE_QH);
        qh_list->qh_overlay.qt_token =
                        cpu_to_hc32(QT_TOKEN_STATUS(QT_TOKEN_STATUS_HALTED));
 
-       reg = ehci_readl(&hccr->cr_hcsparams);
+       reg = ehci_readl(&ehcic[index].hccr->cr_hcsparams);
        descriptor.hub.bNbrPorts = HCS_N_PORTS(reg);
        printf("Register %x NbrPorts %d\n", reg, descriptor.hub.bNbrPorts);
        /* Port Indicators */
                                | 0x01, &descriptor.hub.wHubCharacteristics);
 
        /* Start the host controller. */
-       cmd = ehci_readl(&hcor->or_usbcmd);
+       cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
        /*
         * Philips, Intel, and maybe others need CMD_RUN before the
         * root hub will detect new devices (why?); NEC doesn't
         */
        cmd &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET);
        cmd |= CMD_RUN;
-       ehci_writel(&hcor->or_usbcmd, cmd);
+       ehci_writel(&ehcic[index].hcor->or_usbcmd, cmd);
 
        /* take control over the ports */
-       cmd = ehci_readl(&hcor->or_configflag);
+       cmd = ehci_readl(&ehcic[index].hcor->or_configflag);
        cmd |= FLAG_CF;
-       ehci_writel(&hcor->or_configflag, cmd);
+       ehci_writel(&ehcic[index].hcor->or_configflag, cmd);
        /* unblock posted write */
-       cmd = ehci_readl(&hcor->or_usbcmd);
+       cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
        mdelay(5);
-       reg = HC_VERSION(ehci_readl(&hccr->cr_capbase));
+       reg = HC_VERSION(ehci_readl(&ehcic[index].hccr->cr_capbase));
        printf("USB EHCI %x.%02x\n", reg >> 8, reg & 0xff);
 
-       rootdev = 0;
+       ehcic[index].rootdev = 0;
 
+       *controller = &ehcic[index];
        return 0;
 }
 
 submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
                   int length, struct devrequest *setup)
 {
+       struct ehci_ctrl *ctrl = dev->controller;
 
        if (usb_pipetype(pipe) != PIPE_CONTROL) {
                debug("non-control pipe (type=%lu)", usb_pipetype(pipe));
                return -1;
        }
 
-       if (usb_pipedevice(pipe) == rootdev) {
-               if (!rootdev)
+       if (usb_pipedevice(pipe) == ctrl->rootdev) {
+               if (!ctrl->rootdev)
                        dev->speed = USB_SPEED_HIGH;
                return ehci_submit_root(dev, pipe, buffer, length, setup);
        }
 
 #include <usb.h>
 
 #include "ehci.h"
-#include "ehci-core.h"
 /*
  * Create the appropriate control structures to manage
  * a new EHCI host controller.
  */
-int ehci_hcd_init(void)
+int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 {
-       hccr = (struct ehci_hccr *)(0xcd000100);
-       hcor = (struct ehci_hcor *)((uint32_t) hccr
-                       + HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+       *hccr = (struct ehci_hccr *)(0xcd000100);
+       *hcor = (struct ehci_hcor *)((uint32_t) *hccr
+                       + HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
 
        printf("IXP4XX init hccr %x and hcor %x hc_length %d\n",
-               (uint32_t)hccr, (uint32_t)hcor,
-               (uint32_t)HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+               (uint32_t)*hccr, (uint32_t)*hcor,
+               (uint32_t)HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
        return 0;
 }
 
  * Destroy the appropriate control structures corresponding
  * the the EHCI host controller.
  */
-int ehci_hcd_stop(void)
+int ehci_hcd_stop(int index)
 {
        return 0;
 }
 
 #include <asm/io.h>
 #include <usb.h>
 #include "ehci.h"
-#include "ehci-core.h"
 #include <asm/arch/cpu.h>
 
 #if defined(CONFIG_KIRKWOOD)
  * Create the appropriate control structures to manage
  * a new EHCI host controller.
  */
-int ehci_hcd_init(void)
+int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 {
        usb_brg_adrdec_setup();
 
-       hccr = (struct ehci_hccr *)(MVUSB0_BASE + 0x100);
-       hcor = (struct ehci_hcor *)((uint32_t) hccr
-                       + HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+       *hccr = (struct ehci_hccr *)(MVUSB0_BASE + 0x100);
+       *hcor = (struct ehci_hcor *)((uint32_t) *hccr
+                       + HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
 
        debug("ehci-marvell: init hccr %x and hcor %x hc_length %d\n",
-               (uint32_t)hccr, (uint32_t)hcor,
-               (uint32_t)HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+               (uint32_t)*hccr, (uint32_t)*hcor,
+               (uint32_t)HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
 
        return 0;
 }
  * Destroy the appropriate control structures corresponding
  * the the EHCI host controller.
  */
-int ehci_hcd_stop(void)
+int ehci_hcd_stop(int index)
 {
        return 0;
 }
 
 #include <usb/ehci-fsl.h>
 
 #include "ehci.h"
-#include "ehci-core.h"
 
 static void fsl_setup_phy(volatile struct ehci_hcor *);
 static void fsl_platform_set_host_mode(volatile struct usb_ehci *ehci);
  * This code is derived from EHCI FSL USB Linux driver for MPC5121
  *
  */
-int ehci_hcd_init(void)
+int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 {
        volatile struct usb_ehci *ehci;
 
        /* Hook the memory mapped registers for EHCI-Controller */
        ehci = (struct usb_ehci *)CONFIG_SYS_FSL_USB_ADDR;
-       hccr = (struct ehci_hccr *)((uint32_t)&(ehci->caplength));
-       hcor = (struct ehci_hcor *)((uint32_t) hccr +
-                               HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+       *hccr = (struct ehci_hccr *)((uint32_t)&(ehci->caplength));
+       *hcor = (struct ehci_hcor *)((uint32_t) *hccr +
+                               HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
 
        /* configure interface for UTMI_WIDE */
        usb_platform_dr_init(ehci);
 
        /* Init Phy USB0 to UTMI+ */
-       fsl_setup_phy(hcor);
+       fsl_setup_phy(*hcor);
 
        /* Set to host mode */
        fsl_platform_set_host_mode(ehci);
  * Destroy the appropriate control structures corresponding
  * the the EHCI host controller.
  */
-int ehci_hcd_stop(void)
+int ehci_hcd_stop(int index)
 {
        volatile struct usb_ehci *ehci;
        int exit_status = 0;
 
-       if (hcor) {
-               /* Unhook struct */
-               hccr = NULL;
-               hcor = NULL;
-
-               /* Reset the USB controller */
-               ehci = (struct usb_ehci *)CONFIG_SYS_FSL_USB_ADDR;
-               exit_status = reset_usb_controller(ehci);
-       }
+       /* Reset the USB controller */
+       ehci = (struct usb_ehci *)CONFIG_SYS_FSL_USB_ADDR;
+       exit_status = reset_usb_controller(ehci);
 
        return exit_status;
 }
 
 #include <asm/arch/iomux.h>
 
 #include "ehci.h"
-#include "ehci-core.h"
 
 #define MX5_USBOTHER_REGS_OFFSET 0x800
 
 void board_ehci_hcd_postinit(struct usb_ehci *ehci, int port)
        __attribute((weak, alias("__board_ehci_hcd_postinit")));
 
-int ehci_hcd_init(void)
+int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 {
        struct usb_ehci *ehci;
 #ifdef CONFIG_MX53
 
        ehci = (struct usb_ehci *)(OTG_BASE_ADDR +
                (0x200 * CONFIG_MXC_USB_PORT));
-       hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
-       hcor = (struct ehci_hcor *)((uint32_t)hccr +
-                       HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+       *hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
+       *hcor = (struct ehci_hcor *)((uint32_t)*hccr +
+                       HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
        setbits_le32(&ehci->usbmode, CM_HOST);
 
        __raw_writel(CONFIG_MXC_USB_PORTSC, &ehci->portsc);
        return 0;
 }
 
-int ehci_hcd_stop(void)
+int ehci_hcd_stop(int index)
 {
        return 0;
 }
 
 #include <asm/imx-common/iomux-v3.h>
 
 #include "ehci.h"
-#include "ehci-core.h"
 
 #define USB_OTGREGS_OFFSET     0x000
 #define USB_H1REGS_OFFSET      0x200
        __raw_writel(val, usbother_base + USB_H1_CTRL_OFFSET);
 }
 
-int ehci_hcd_init(void)
+int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 {
        struct usb_ehci *ehci;
 
 
        ehci = (struct usb_ehci *)(USBOH3_USB_BASE_ADDR +
                (0x200 * CONFIG_MXC_USB_PORT));
-       hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
-       hcor = (struct ehci_hcor *)((uint32_t)hccr +
-                       HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+       *hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
+       *hcor = (struct ehci_hcor *)((uint32_t)*hccr +
+                       HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
        setbits_le32(&ehci->usbmode, CM_HOST);
 
        __raw_writel(CONFIG_MXC_USB_PORTSC, &ehci->portsc);
        return 0;
 }
 
-int ehci_hcd_stop(void)
+int ehci_hcd_stop(int index)
 {
        return 0;
 }
 
 #include <errno.h>
 
 #include "ehci.h"
-#include "ehci-core.h"
 
 #define USBCTRL_OTGBASE_OFFSET 0x600
 
        return 0;
 }
 
-int ehci_hcd_init(void)
+int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 {
        struct usb_ehci *ehci;
 #ifdef CONFIG_MX31
 
        ehci = (struct usb_ehci *)(IMX_USB_BASE +
                (0x200 * CONFIG_MXC_USB_PORT));
-       hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
-       hcor = (struct ehci_hcor *)((uint32_t) hccr +
-                       HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+       *hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
+       *hcor = (struct ehci_hcor *)((uint32_t) *hccr +
+                       HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
        setbits_le32(&ehci->usbmode, CM_HOST);
        __raw_writel(CONFIG_MXC_USB_PORTSC, &ehci->portsc);
        mxc_set_usbcontrol(CONFIG_MXC_USB_PORT, CONFIG_MXC_USB_FLAGS);
  * Destroy the appropriate control structures corresponding
  * the the EHCI host controller.
  */
-int ehci_hcd_stop(void)
+int ehci_hcd_stop(int index)
 {
        return 0;
 }
 
 #include <asm/arch/regs-usb.h>
 #include <asm/arch/regs-usbphy.h>
 
-#include "ehci-core.h"
 #include "ehci.h"
 
 #if    (CONFIG_EHCI_MXS_PORT != 0) && (CONFIG_EHCI_MXS_PORT != 1)
 #define        HW_DIGCTL_CTRL_USB0_CLKGATE     (1 << 2)
 #define        HW_DIGCTL_CTRL_USB1_CLKGATE     (1 << 16)
 
-int ehci_hcd_init(void)
+int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 {
 
        int ret;
                &ehci_mxs.phy_regs->hw_usbphy_ctrl_set);
 
        usb_base = ((uint32_t)ehci_mxs.usb_regs) + 0x100;
-       hccr = (struct ehci_hccr *)usb_base;
+       *hccr = (struct ehci_hccr *)usb_base;
 
-       cap_base = ehci_readl(&hccr->cr_capbase);
-       hcor = (struct ehci_hcor *)(usb_base + HC_LENGTH(cap_base));
+       cap_base = ehci_readl(&(*hccr)->cr_capbase);
+       *hcor = (struct ehci_hcor *)(usb_base + HC_LENGTH(cap_base));
 
        return 0;
 }
 
-int ehci_hcd_stop(void)
+int ehci_hcd_stop(int index)
 {
        int ret;
-       uint32_t tmp;
+       uint32_t usb_base, cap_base, tmp;
        struct mxs_register_32 *digctl_ctrl =
                (struct mxs_register_32 *)HW_DIGCTL_CTRL;
        struct mxs_clkctrl_regs *clkctrl_regs =
                (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
+       struct ehci_hccr *hccr;
+       struct ehci_hcor *hcor;
 
        ret = mxs_ehci_get_port(&ehci_mxs, CONFIG_EHCI_MXS_PORT);
        if (ret)
                return ret;
 
        /* Stop the USB port */
+       usb_base = ((uint32_t)ehci_mxs.usb_regs) + 0x100;
+       hccr = (struct ehci_hccr *)usb_base;
+       cap_base = ehci_readl(&hccr->cr_capbase);
+       hcor = (struct ehci_hcor *)(usb_base + HC_LENGTH(cap_base));
+
        tmp = ehci_readl(&hcor->or_usbcmd);
        tmp &= ~CMD_RUN;
        ehci_writel(tmp, &hcor->or_usbcmd);
 
 #include <asm/gpio.h>
 #include <asm/arch/ehci.h>
 #include <asm/ehci-omap.h>
-#include "ehci-core.h"
+
+#include "ehci.h"
 
 static struct omap_uhh *const uhh = (struct omap_uhh *)OMAP_UHH_BASE;
 static struct omap_usbtll *const usbtll = (struct omap_usbtll *)OMAP_USBTLL_BASE;
  * Based on "drivers/usb/host/ehci-omap.c" from Linux 3.1
  * See there for additional Copyrights.
  */
-int omap_ehci_hcd_init(struct omap_usbhs_board_data *usbhs_pdata)
+int omap_ehci_hcd_init(struct omap_usbhs_board_data *usbhs_pdata,
+               struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 {
        int ret;
        unsigned int i, reg = 0, rev = 0;
                if (is_ehci_phy_mode(usbhs_pdata->port_mode[i]))
                        omap_ehci_soft_phy_reset(i);
 
-       hccr = (struct ehci_hccr *)(OMAP_EHCI_BASE);
-       hcor = (struct ehci_hcor *)(OMAP_EHCI_BASE + 0x10);
+       *hccr = (struct ehci_hccr *)(OMAP_EHCI_BASE);
+       *hcor = (struct ehci_hcor *)(OMAP_EHCI_BASE + 0x10);
 
        debug("OMAP EHCI init done\n");
        return 0;
 
 #include <usb.h>
 
 #include "ehci.h"
-#include "ehci-core.h"
 
 #ifdef CONFIG_PCI_EHCI_DEVICE
 static struct pci_device_id ehci_pci_ids[] = {
  * Create the appropriate control structures to manage
  * a new EHCI host controller.
  */
-int ehci_hcd_init(void)
+int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 {
        pci_dev_t pdev;
 
                return -1;
        }
 
-       hccr = (struct ehci_hccr *)pci_map_bar(pdev,
+       *hccr = (struct ehci_hccr *)pci_map_bar(pdev,
                        PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
-       hcor = (struct ehci_hcor *)((uint32_t) hccr +
-                       HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+       *hcor = (struct ehci_hcor *)((uint32_t) *hccr +
+                       HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
 
        debug("EHCI-PCI init hccr 0x%x and hcor 0x%x hc_length %d\n",
-                       (uint32_t)hccr, (uint32_t)hcor,
-                       (uint32_t)HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+                       (uint32_t)*hccr, (uint32_t)*hcor,
+                       (uint32_t)HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
 
        return 0;
 }
  * Destroy the appropriate control structures corresponding
  * the the EHCI host controller.
  */
-int ehci_hcd_stop(void)
+int ehci_hcd_stop(int index)
 {
        return 0;
 }
 
 #include <usb.h>
 
 #include "ehci.h"
-#include "ehci-core.h"
 
 /*
  * Create the appropriate control structures to manage
  * a new EHCI host controller.
  */
-int ehci_hcd_init(void)
+int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 {
-       hccr = (struct ehci_hccr *)(CONFIG_SYS_PPC4XX_USB_ADDR);
-       hcor = (struct ehci_hcor *)((uint32_t) hccr +
-               HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+       *hccr = (struct ehci_hccr *)(CONFIG_SYS_PPC4XX_USB_ADDR);
+       *hcor = (struct ehci_hcor *)((uint32_t) *hccr +
+               HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
        return 0;
 }
 
  * Destroy the appropriate control structures corresponding
  * the the EHCI host controller.
  */
-int ehci_hcd_stop(void)
+int ehci_hcd_stop(int index)
 {
        return 0;
 }
 
 #include <usb.h>
 
 #include "ehci.h"
-#include "ehci-core.h"
 
 #include <asm/errno.h>
 #include <asm/arch/usb.h>
  * Create the appropriate control structures to manage
  * a new EHCI host controller.
  */
-int ehci_hcd_init(void)
+int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 {
        u32 our_hccr, our_hcor;
 
        if (tegrausb_start_port(0, &our_hccr, &our_hcor))
                return -1;
 
-       hccr = (struct ehci_hccr *)our_hccr;
-       hcor = (struct ehci_hcor *)our_hcor;
+       *hccr = (struct ehci_hccr *)our_hccr;
+       *hcor = (struct ehci_hcor *)our_hcor;
 
        return 0;
 }
  * Destroy the appropriate control structures corresponding
  * the the EHCI host controller.
  */
-int ehci_hcd_stop(void)
+int ehci_hcd_stop(int index)
 {
        tegrausb_stop_port();
        return 0;
 
 #include <usb.h>
 
 #include "ehci.h"
-#include "ehci-core.h"
 
 int vct_ehci_hcd_init(u32 *hccr, u32 *hcor);
 
  * Create the appropriate control structures to manage
  * a new EHCI host controller.
  */
-int ehci_hcd_init(void)
+int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 {
        int ret;
        u32 vct_hccr;
        if (ret)
                return ret;
 
-       hccr = (struct ehci_hccr *)vct_hccr;
-       hcor = (struct ehci_hcor *)vct_hcor;
+       *hccr = (struct ehci_hccr *)vct_hccr;
+       *hcor = (struct ehci_hcor *)vct_hcor;
 
        return 0;
 }
  * Destroy the appropriate control structures corresponding
  * the the EHCI host controller.
  */
-int ehci_hcd_stop(void)
+int ehci_hcd_stop(int index)
 {
        return 0;
 }
 
 };
 
 /* Low level init functions */
-int ehci_hcd_init(void);
-int ehci_hcd_stop(void);
+int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor);
+int ehci_hcd_stop(int index);
 
 #endif /* USB_EHCI_H */