Patchwork [U-Boot,v4,2/4] usb: ehci: rework to take advantage of new lowlevel interface

login
register
mail settings
Submitter Lucas Stach
Date Sept. 24, 2012, 9:03 p.m.
Message ID <1348520629-18241-3-git-send-email-dev@lynxeye.de>
Download mbox | patch
Permalink /patch/186564/
State Superseded
Delegated to: Marek Vasut
Headers show

Comments

Lucas Stach - Sept. 24, 2012, 9:03 p.m.
Kill off ehci-core.h
It was used to specify some static controller data. To support more than
one controller being active at any time we have to carry the controller
data ourselfes. Change the ehci interface accordingly.

NOTE: OMAP implemented the ehci stuff a bit backwards and should be fixed
to do the same thing as other platforms. But the change for now is at least
compile clean.

Signed-off-by: Lucas Stach <dev@lynxeye.de>
Reviewed-by: Marek Vasut <marex@denx.de>

---
v2: fix build failures in ehci-fsl.c and ehci-mxs.c
---
 arch/arm/include/asm/ehci-omap.h     |  10 ++-
 board/htkw/mcx/mcx.c                 |   6 +-
 board/technexion/twister/twister.c   |   6 +-
 board/teejet/mt_ventoux/mt_ventoux.c |   6 +-
 board/ti/beagle/beagle.c             |   6 +-
 board/ti/panda/panda.c               |   6 +-
 drivers/usb/host/ehci-armada100.c    |  15 ++---
 drivers/usb/host/ehci-atmel.c        |  11 ++--
 drivers/usb/host/ehci-core.h         |  29 ---------
 drivers/usb/host/ehci-exynos.c       |  15 ++---
 drivers/usb/host/ehci-fsl.c          |  15 ++---
 drivers/usb/host/ehci-hcd.c          | 120 +++++++++++++++++++----------------
 drivers/usb/host/ehci-ixp4xx.c       |  15 ++---
 drivers/usb/host/ehci-marvell.c      |  15 ++---
 drivers/usb/host/ehci-mpc512x.c      |  25 +++-----
 drivers/usb/host/ehci-mx5.c          |  11 ++--
 drivers/usb/host/ehci-mx6.c          |  11 ++--
 drivers/usb/host/ehci-mxc.c          |  11 ++--
 drivers/usb/host/ehci-mxs.c          |  20 ++++--
 drivers/usb/host/ehci-omap.c         |  10 +--
 drivers/usb/host/ehci-pci.c          |  15 ++---
 drivers/usb/host/ehci-ppc4xx.c       |  11 ++--
 drivers/usb/host/ehci-tegra.c        |   9 ++-
 drivers/usb/host/ehci-vct.c          |   9 ++-
 drivers/usb/host/ehci.h              |   4 +-
 25 Dateien geändert, 195 Zeilen hinzugefügt(+), 216 Zeilen entfernt(-)
 delete mode 100644 drivers/usb/host/ehci-core.h

Patch

diff --git a/arch/arm/include/asm/ehci-omap.h b/arch/arm/include/asm/ehci-omap.h
index e72c5df..77e8170 100644
--- a/arch/arm/include/asm/ehci-omap.h
+++ b/arch/arm/include/asm/ehci-omap.h
@@ -136,7 +136,15 @@  struct omap_ehci {
 	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_ */
diff --git a/board/htkw/mcx/mcx.c b/board/htkw/mcx/mcx.c
index 454ff0a..7c9d34a 100644
--- a/board/htkw/mcx/mcx.c
+++ b/board/htkw/mcx/mcx.c
@@ -46,12 +46,12 @@  static struct omap_usbhs_board_data usbhs_bdata = {
 	.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();
 }
diff --git a/board/technexion/twister/twister.c b/board/technexion/twister/twister.c
index c2b10ac..69b1cc2 100644
--- a/board/technexion/twister/twister.c
+++ b/board/technexion/twister/twister.c
@@ -67,12 +67,12 @@  static struct omap_usbhs_board_data usbhs_bdata = {
 	.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();
 }
diff --git a/board/teejet/mt_ventoux/mt_ventoux.c b/board/teejet/mt_ventoux/mt_ventoux.c
index 9fbaedd..7bbd536 100644
--- a/board/teejet/mt_ventoux/mt_ventoux.c
+++ b/board/teejet/mt_ventoux/mt_ventoux.c
@@ -67,12 +67,12 @@  static struct omap_usbhs_board_data usbhs_bdata = {
 	.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();
 }
diff --git a/board/ti/beagle/beagle.c b/board/ti/beagle/beagle.c
index 99f833f..59b9924 100644
--- a/board/ti/beagle/beagle.c
+++ b/board/ti/beagle/beagle.c
@@ -502,12 +502,12 @@  static struct omap_usbhs_board_data usbhs_bdata = {
 	.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();
 }
diff --git a/board/ti/panda/panda.c b/board/ti/panda/panda.c
index ee82771..4feef78 100644
--- a/board/ti/panda/panda.c
+++ b/board/ti/panda/panda.c
@@ -192,7 +192,7 @@  static struct omap_usbhs_board_data usbhs_bdata = {
 	.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;
@@ -202,14 +202,14 @@  int ehci_hcd_init(void)
 	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();
 }
diff --git a/drivers/usb/host/ehci-armada100.c b/drivers/usb/host/ehci-armada100.c
index 7725641..d24ed3e 100644
--- a/drivers/usb/host/ehci-armada100.c
+++ b/drivers/usb/host/ehci-armada100.c
@@ -31,7 +31,6 @@ 
 #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>
@@ -39,18 +38,18 @@ 
 /*
  * 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;
 }
@@ -58,7 +57,7 @@  int ehci_hcd_init(void)
 /*
  * EHCI host controller stop
  */
-int ehci_hcd_stop(void)
+int ehci_hcd_stop(int index)
 {
 	return 0;
 }
diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c
index 15b9b60..05058d3 100644
--- a/drivers/usb/host/ehci-atmel.c
+++ b/drivers/usb/host/ehci-atmel.c
@@ -31,14 +31,13 @@ 
 #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;
@@ -58,14 +57,14 @@  int ehci_hcd_init(void)
 	/* 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;
diff --git a/drivers/usb/host/ehci-core.h b/drivers/usb/host/ehci-core.h
deleted file mode 100644
index 39e5c5e..0000000
--- a/drivers/usb/host/ehci-core.h
+++ /dev/null
@@ -1,29 +0,0 @@ 
-/*-
- * 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
diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c
index a71b397..9f0ed06 100644
--- a/drivers/usb/host/ehci-exynos.c
+++ b/drivers/usb/host/ehci-exynos.c
@@ -27,7 +27,6 @@ 
 #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)
@@ -85,20 +84,20 @@  static void reset_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;
 }
@@ -107,7 +106,7 @@  int ehci_hcd_init(void)
  * 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;
 
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index b2d294e..7b8f033 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -29,7 +29,6 @@ 
 #include <hwconfig.h>
 
 #include "ehci.h"
-#include "ehci-core.h"
 
 /*
  * Create the appropriate control structures to manage
@@ -37,7 +36,7 @@ 
  *
  * 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;
@@ -49,9 +48,9 @@  int ehci_hcd_init(void)
 #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);
@@ -82,14 +81,14 @@  int ehci_hcd_init(void)
 		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. */
@@ -108,7 +107,7 @@  int ehci_hcd_init(void)
  * Destroy the appropriate control structures corresponding
  * the the EHCI host controller.
  */
-int ehci_hcd_stop(void)
+int ehci_hcd_stop(int index)
 {
 	return 0;
 }
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 6027c4f..9518ab9 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -30,12 +30,17 @@ 
 
 #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))
@@ -136,24 +141,25 @@  static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec)
 	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)
@@ -163,10 +169,10 @@  static int ehci_reset(void)
 	}
 
 #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;
@@ -224,7 +230,6 @@  ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 	struct qTD *qtd;
 	int qtd_count = 0;
 	int qtd_counter = 0;
-
 	volatile struct qTD *vtd;
 	unsigned long ts;
 	uint32_t *tdp;
@@ -233,6 +238,7 @@  ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 	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);
@@ -323,7 +329,7 @@  ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 	 *   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 = (dev->speed != USB_SPEED_HIGH) && !usb_pipeendpoint(pipe);
 	maxpacket = usb_maxpacket(dev, pipe);
 	endpt = QH_ENDPT1_RL(8) | QH_ENDPT1_C(c) |
@@ -457,27 +463,27 @@  ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 		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");
@@ -490,8 +496,8 @@  ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 	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,
@@ -520,11 +526,11 @@  ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 		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");
@@ -563,9 +569,9 @@  ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 	} 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);
@@ -596,13 +602,14 @@  ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 	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;
 
@@ -670,7 +677,7 @@  ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 		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");
@@ -720,7 +727,7 @@  ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 			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;
@@ -735,7 +742,7 @@  ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 			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);
 			}
@@ -772,7 +779,7 @@  ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 				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",
@@ -784,7 +791,7 @@  ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 			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);
@@ -796,7 +803,7 @@  ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 			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;
@@ -805,7 +812,7 @@  ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 			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));
@@ -813,7 +820,7 @@  ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 		}
 		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");
@@ -843,26 +850,29 @@  unknown:
 
 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);
@@ -874,7 +884,7 @@  int usb_lowlevel_init(int index, void **controller)
 	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 */
@@ -887,27 +897,28 @@  int usb_lowlevel_init(int index, void **controller)
 				| 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;
 }
 
@@ -927,14 +938,15 @@  int
 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);
 	}
diff --git a/drivers/usb/host/ehci-ixp4xx.c b/drivers/usb/host/ehci-ixp4xx.c
index b8f15ae..cf3d5f5 100644
--- a/drivers/usb/host/ehci-ixp4xx.c
+++ b/drivers/usb/host/ehci-ixp4xx.c
@@ -23,20 +23,19 @@ 
 #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;
 }
 
@@ -44,7 +43,7 @@  int ehci_hcd_init(void)
  * Destroy the appropriate control structures corresponding
  * the the EHCI host controller.
  */
-int ehci_hcd_stop(void)
+int ehci_hcd_stop(int index)
 {
 	return 0;
 }
diff --git a/drivers/usb/host/ehci-marvell.c b/drivers/usb/host/ehci-marvell.c
index 89c8af7..2b73e4a 100644
--- a/drivers/usb/host/ehci-marvell.c
+++ b/drivers/usb/host/ehci-marvell.c
@@ -26,7 +26,6 @@ 
 #include <asm/io.h>
 #include <usb.h>
 #include "ehci.h"
-#include "ehci-core.h"
 #include <asm/arch/cpu.h>
 
 #if defined(CONFIG_KIRKWOOD)
@@ -91,17 +90,17 @@  static void usb_brg_adrdec_setup(void)
  * 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;
 }
@@ -110,7 +109,7 @@  int ehci_hcd_init(void)
  * Destroy the appropriate control structures corresponding
  * the the EHCI host controller.
  */
-int ehci_hcd_stop(void)
+int ehci_hcd_stop(int index)
 {
 	return 0;
 }
diff --git a/drivers/usb/host/ehci-mpc512x.c b/drivers/usb/host/ehci-mpc512x.c
index d360108..e98f79f 100644
--- a/drivers/usb/host/ehci-mpc512x.c
+++ b/drivers/usb/host/ehci-mpc512x.c
@@ -33,7 +33,6 @@ 
 #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);
@@ -46,21 +45,21 @@  static void usb_platform_dr_init(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);
@@ -89,20 +88,14 @@  int ehci_hcd_init(void)
  * 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;
 }
diff --git a/drivers/usb/host/ehci-mx5.c b/drivers/usb/host/ehci-mx5.c
index 58cdcbe..9c34773 100644
--- a/drivers/usb/host/ehci-mx5.c
+++ b/drivers/usb/host/ehci-mx5.c
@@ -25,7 +25,6 @@ 
 #include <asm/arch/iomux.h>
 
 #include "ehci.h"
-#include "ehci-core.h"
 
 #define MX5_USBOTHER_REGS_OFFSET 0x800
 
@@ -206,7 +205,7 @@  void __board_ehci_hcd_postinit(struct usb_ehci *ehci, int port)
 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
@@ -230,9 +229,9 @@  int ehci_hcd_init(void)
 
 	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);
@@ -247,7 +246,7 @@  int ehci_hcd_init(void)
 	return 0;
 }
 
-int ehci_hcd_stop(void)
+int ehci_hcd_stop(int index)
 {
 	return 0;
 }
diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c
index 0280242..9ce25da 100644
--- a/drivers/usb/host/ehci-mx6.c
+++ b/drivers/usb/host/ehci-mx6.c
@@ -25,7 +25,6 @@ 
 #include <asm/imx-common/iomux-v3.h>
 
 #include "ehci.h"
-#include "ehci-core.h"
 
 #define USB_OTGREGS_OFFSET	0x000
 #define USB_H1REGS_OFFSET	0x200
@@ -160,7 +159,7 @@  static void usbh1_oc_config(void)
 	__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;
 
@@ -182,9 +181,9 @@  int ehci_hcd_init(void)
 
 	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);
@@ -195,7 +194,7 @@  int ehci_hcd_init(void)
 	return 0;
 }
 
-int ehci_hcd_stop(void)
+int ehci_hcd_stop(int index)
 {
 	return 0;
 }
diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c
index 45cbd18..a38bc9c 100644
--- a/drivers/usb/host/ehci-mxc.c
+++ b/drivers/usb/host/ehci-mxc.c
@@ -25,7 +25,6 @@ 
 #include <errno.h>
 
 #include "ehci.h"
-#include "ehci-core.h"
 
 #define USBCTRL_OTGBASE_OFFSET	0x600
 
@@ -106,7 +105,7 @@  static int mxc_set_usbcontrol(int port, unsigned int flags)
 	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
@@ -121,9 +120,9 @@  int ehci_hcd_init(void)
 
 	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);
@@ -137,7 +136,7 @@  int ehci_hcd_init(void)
  * Destroy the appropriate control structures corresponding
  * the the EHCI host controller.
  */
-int ehci_hcd_stop(void)
+int ehci_hcd_stop(int index)
 {
 	return 0;
 }
diff --git a/drivers/usb/host/ehci-mxs.c b/drivers/usb/host/ehci-mxs.c
index 6e21669..5062af5 100644
--- a/drivers/usb/host/ehci-mxs.c
+++ b/drivers/usb/host/ehci-mxs.c
@@ -27,7 +27,6 @@ 
 #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)
@@ -70,7 +69,7 @@  int mxs_ehci_get_port(struct ehci_mxs *mxs_usb, int port)
 #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;
@@ -107,28 +106,35 @@  int ehci_hcd_init(void)
 		&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);
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index 292673b..086c697 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -33,7 +33,8 @@ 
 #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;
@@ -155,7 +156,8 @@  int omap_ehci_hcd_stop(void)
  * 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;
@@ -246,8 +248,8 @@  int omap_ehci_hcd_init(struct omap_usbhs_board_data *usbhs_pdata)
 		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;
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index 020ab11..29af02d 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -23,7 +23,6 @@ 
 #include <usb.h>
 
 #include "ehci.h"
-#include "ehci-core.h"
 
 #ifdef CONFIG_PCI_EHCI_DEVICE
 static struct pci_device_id ehci_pci_ids[] = {
@@ -39,7 +38,7 @@  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;
 
@@ -49,14 +48,14 @@  int ehci_hcd_init(void)
 		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;
 }
@@ -65,7 +64,7 @@  int ehci_hcd_init(void)
  * Destroy the appropriate control structures corresponding
  * the the EHCI host controller.
  */
-int ehci_hcd_stop(void)
+int ehci_hcd_stop(int index)
 {
 	return 0;
 }
diff --git a/drivers/usb/host/ehci-ppc4xx.c b/drivers/usb/host/ehci-ppc4xx.c
index 1179919..e389c75 100644
--- a/drivers/usb/host/ehci-ppc4xx.c
+++ b/drivers/usb/host/ehci-ppc4xx.c
@@ -23,17 +23,16 @@ 
 #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;
 }
 
@@ -41,7 +40,7 @@  int ehci_hcd_init(void)
  * Destroy the appropriate control structures corresponding
  * the the EHCI host controller.
  */
-int ehci_hcd_stop(void)
+int ehci_hcd_stop(int index)
 {
 	return 0;
 }
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 4646b29..bb5a68e 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -24,7 +24,6 @@ 
 #include <usb.h>
 
 #include "ehci.h"
-#include "ehci-core.h"
 
 #include <asm/errno.h>
 #include <asm/arch/usb.h>
@@ -50,7 +49,7 @@  void ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg)
  * 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;
 
@@ -61,8 +60,8 @@  int ehci_hcd_init(void)
 	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;
 }
@@ -71,7 +70,7 @@  int ehci_hcd_init(void)
  * 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;
diff --git a/drivers/usb/host/ehci-vct.c b/drivers/usb/host/ehci-vct.c
index 3063dd1..5f8a159 100644
--- a/drivers/usb/host/ehci-vct.c
+++ b/drivers/usb/host/ehci-vct.c
@@ -21,7 +21,6 @@ 
 #include <usb.h>
 
 #include "ehci.h"
-#include "ehci-core.h"
 
 int vct_ehci_hcd_init(u32 *hccr, u32 *hcor);
 
@@ -29,7 +28,7 @@  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;
@@ -42,8 +41,8 @@  int ehci_hcd_init(void)
 	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;
 }
@@ -52,7 +51,7 @@  int ehci_hcd_init(void)
  * Destroy the appropriate control structures corresponding
  * the the EHCI host controller.
  */
-int ehci_hcd_stop(void)
+int ehci_hcd_stop(int index)
 {
 	return 0;
 }
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 39acdf9..1e3cd79 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -249,7 +249,7 @@  struct QH {
 };
 
 /* 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 */