All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 0/4] USB multi controller
@ 2012-08-30 16:03 Lucas Stach
  2012-08-30 16:03 ` [U-Boot] [PATCH 1/4] usb: lowlevel interface change to support multiple controllers Lucas Stach
                   ` (4 more replies)
  0 siblings, 5 replies; 18+ messages in thread
From: Lucas Stach @ 2012-08-30 16:03 UTC (permalink / raw)
  To: u-boot

Hi all,

this is a follow up on the patch "USB: EHCI: Initialize multiple
USB controllers at once" from Jim Lin. It takes some of the
code but has undergone some heavy reworking.

When we remove the ifdef horror from the above mentioned patch it's
mostly a big interface change to the usb subsystem. As this creates
a lot of churn I've split this up into a series. Every patch is self
contained so it doesn't break compiles and *should* not regress
any functionality on it's own. At least the series is bisectable in
case anything goes wrong. I've compile tested all the ARM configs.

Both the lowlevel usb and ehci interface change are backward
compatible, so implementations that only use one controller can
choose to ignore the new interface. All implementations are
updated to work with the new function prototypes.

For Tegra I've included a patch to actually use the new ehci
interface. Patches are based on a Tegra tree with some relevant
changes from u-boot-usb picked over, so they should apply to
u-boot-usb/master.

Patch 4 also includes some cosmetic changes, to make the output
of the usb commands more readable.

On my Colibri T20, with a total of 3 usb controllers of which 2
are enabled in the device tree, output now looks like this:

Tegra20 (Colibri) # usb start
(Re)start USB...
USB0:   USB EHCI 1.00
scanning bus 0 for devices... 2 USB Device(s) found
USB1:   USB EHCI 1.00
scanning bus 1 for devices... 2 USB Device(s) found
USB2:   lowlevel init failed
       scanning usb for storage devices... 1 Storage Device(s) found
       scanning usb for ethernet devices... 1 Ethernet Device(s) found

Tegra20 (Colibri) # usb tree
USB device tree:
  1  Hub (480 Mb/s, 0mA)
  |  u-boot EHCI Host Controller
  |
  +-2  Mass Storage (480 Mb/s, 200mA)
       SanDisk U3 Titanium 2845221DC342AE8F

  3  Hub (480 Mb/s, 0mA)
  |  u-boot EHCI Host Controller
  |
  +-4  Vendor specific (480 Mb/s, 4mA)
       ASIX Elec. Corp. AX88772B 000001

Lucas Stach (4):
  usb: lowlevel interface change to support multiple controllers
  usb: ehci: rework to take advantage of new lowlevel interface
  tegra20: port to new ehci interface
  usb: add support for multiple usb controllers

 arch/arm/cpu/arm920t/s3c24x0/usb_ohci.c       |   4 +-
 arch/arm/cpu/armv7/tegra20/usb.c              |  15 +---
 arch/arm/include/asm/arch-tegra20/usb.h       |   4 +-
 arch/arm/include/asm/ehci-omap.h              |  10 ++-
 arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c |   4 +-
 arch/powerpc/cpu/mpc5xxx/usb_ohci.c           |   4 +-
 arch/powerpc/cpu/ppc4xx/usb_ohci.c            |   4 +-
 arch/sparc/cpu/leon3/usb_uhci.c               |   4 +-
 arch/sparc/lib/bootm.c                        |   2 +-
 board/htkw/mcx/mcx.c                          |   6 +-
 board/mpl/common/usb_uhci.c                   |   4 +-
 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 +-
 common/cmd_usb.c                              |  16 +++-
 common/usb.c                                  | 106 +++++++++++-----------
 common/usb_hub.c                              |   2 +-
 common/usb_storage.c                          |   2 +-
 drivers/usb/eth/usb_ether.c                   |   2 +-
 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                   |  11 ++-
 drivers/usb/host/ehci-hcd.c                   | 124 ++++++++++++++------------
 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                   |  28 +++---
 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                 |  14 ++-
 drivers/usb/host/ehci-vct.c                   |   9 +-
 drivers/usb/host/ehci.h                       |   4 +-
 drivers/usb/host/isp116x-hcd.c                |   4 +-
 drivers/usb/host/ohci-hcd.c                   |   4 +-
 drivers/usb/host/r8a66597-hcd.c               |   4 +-
 drivers/usb/host/sl811-hcd.c                  |   4 +-
 drivers/usb/musb/musb_hcd.c                   |   4 +-
 include/usb.h                                 |  10 ++-
 include/usb/mv_udc.h                          |   2 +-
 46 Dateien ge?ndert, 309 Zeilen hinzugef?gt(+), 320 Zeilen entfernt(-)
 delete mode 100644 drivers/usb/host/ehci-core.h

-- 
1.7.11.4

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH 1/4] usb: lowlevel interface change to support multiple controllers
  2012-08-30 16:03 [U-Boot] [PATCH 0/4] USB multi controller Lucas Stach
@ 2012-08-30 16:03 ` Lucas Stach
  2012-08-30 21:03   ` Marek Vasut
  2012-08-30 16:03 ` [U-Boot] [PATCH 2/4] usb: ehci: rework to take advantage of new lowlevel interface Lucas Stach
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 18+ messages in thread
From: Lucas Stach @ 2012-08-30 16:03 UTC (permalink / raw)
  To: u-boot

Carry an index in the lowlevel usb functions to make specify the
respective usb controller.

Also pass through an controller struct from lowlevel_init to the
creation of the root usb device of this controller.

Signed-off-by: Lucas Stach <dev@lynxeye.de>
---
 arch/arm/cpu/arm920t/s3c24x0/usb_ohci.c       |  4 ++--
 arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c |  4 ++--
 arch/powerpc/cpu/mpc5xxx/usb_ohci.c           |  4 ++--
 arch/powerpc/cpu/ppc4xx/usb_ohci.c            |  4 ++--
 arch/sparc/cpu/leon3/usb_uhci.c               |  4 ++--
 arch/sparc/lib/bootm.c                        |  2 +-
 board/mpl/common/usb_uhci.c                   |  4 ++--
 common/usb.c                                  | 10 ++++++----
 common/usb_hub.c                              |  2 +-
 drivers/usb/host/ehci-hcd.c                   |  4 ++--
 drivers/usb/host/isp116x-hcd.c                |  4 ++--
 drivers/usb/host/ohci-hcd.c                   |  4 ++--
 drivers/usb/host/r8a66597-hcd.c               |  4 ++--
 drivers/usb/host/sl811-hcd.c                  |  4 ++--
 drivers/usb/musb/musb_hcd.c                   |  4 ++--
 include/usb.h                                 | 10 +++++++---
 include/usb/mv_udc.h                          |  2 +-
 17 Dateien ge?ndert, 40 Zeilen hinzugef?gt(+), 34 Zeilen entfernt(-)

diff --git a/arch/arm/cpu/arm920t/s3c24x0/usb_ohci.c b/arch/arm/cpu/arm920t/s3c24x0/usb_ohci.c
index cf0335c..944bb32 100644
--- a/arch/arm/cpu/arm920t/s3c24x0/usb_ohci.c
+++ b/arch/arm/cpu/arm920t/s3c24x0/usb_ohci.c
@@ -1659,7 +1659,7 @@ static void hc_release_ohci(struct ohci *ohci)
  */
 static char ohci_inited = 0;
 
-int usb_lowlevel_init(void)
+int usb_lowlevel_init(int index, void **controller)
 {
 	struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
 	struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio();
@@ -1738,7 +1738,7 @@ int usb_lowlevel_init(void)
 	return 0;
 }
 
-int usb_lowlevel_stop(void)
+int usb_lowlevel_stop(int index)
 {
 	struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
 
diff --git a/arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c b/arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c
index 7647e11..c747767 100644
--- a/arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c
+++ b/arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c
@@ -1565,7 +1565,7 @@ static void hc_release_ohci (ohci_t *ohci)
  */
 static char ohci_inited = 0;
 
-int usb_lowlevel_init(void)
+int usb_lowlevel_init(int index, void **controller)
 {
 	u32 pin_func;
 	u32 sys_freqctrl, sys_clksrc;
@@ -1707,7 +1707,7 @@ int usb_lowlevel_init(void)
 	return -1;
 }
 
-int usb_lowlevel_stop(void)
+int usb_lowlevel_stop(int index)
 {
 	/* this gets called really early - before the controller has */
 	/* even been initialized! */
diff --git a/arch/powerpc/cpu/mpc5xxx/usb_ohci.c b/arch/powerpc/cpu/mpc5xxx/usb_ohci.c
index 6d91525..607034b 100644
--- a/arch/powerpc/cpu/mpc5xxx/usb_ohci.c
+++ b/arch/powerpc/cpu/mpc5xxx/usb_ohci.c
@@ -1561,7 +1561,7 @@ static void hc_release_ohci (ohci_t *ohci)
  */
 static char ohci_inited = 0;
 
-int usb_lowlevel_init(void)
+int usb_lowlevel_init(int index, void **controller)
 {
 
 	/* Set the USB Clock						     */
@@ -1629,7 +1629,7 @@ int usb_lowlevel_init(void)
 	return 0;
 }
 
-int usb_lowlevel_stop(void)
+int usb_lowlevel_stop(int index)
 {
 	/* this gets called really early - before the controller has */
 	/* even been initialized! */
diff --git a/arch/powerpc/cpu/ppc4xx/usb_ohci.c b/arch/powerpc/cpu/ppc4xx/usb_ohci.c
index 14c6a28..4ce2726 100644
--- a/arch/powerpc/cpu/ppc4xx/usb_ohci.c
+++ b/arch/powerpc/cpu/ppc4xx/usb_ohci.c
@@ -1566,7 +1566,7 @@ static void hc_release_ohci (ohci_t *ohci)
  */
 static char ohci_inited = 0;
 
-int usb_lowlevel_init(void)
+int usb_lowlevel_init(int index, void **controller)
 {
 	memset (&gohci, 0, sizeof (ohci_t));
 	memset (&urb_priv, 0, sizeof (urb_priv_t));
@@ -1624,7 +1624,7 @@ int usb_lowlevel_init(void)
 	return 0;
 }
 
-int usb_lowlevel_stop(void)
+int usb_lowlevel_stop(int index)
 {
 	/* this gets called really early - before the controller has */
 	/* even been initialized! */
diff --git a/arch/sparc/cpu/leon3/usb_uhci.c b/arch/sparc/cpu/leon3/usb_uhci.c
index 62cc25d..b3b8a4d 100644
--- a/arch/sparc/cpu/leon3/usb_uhci.c
+++ b/arch/sparc/cpu/leon3/usb_uhci.c
@@ -706,7 +706,7 @@ void handle_usb_interrupt(void)
 
 /* init uhci
  */
-int usb_lowlevel_init(void)
+int usb_lowlevel_init(int index, void **controller)
 {
 	unsigned char temp;
 	ambapp_ahbdev ahbdev;
@@ -745,7 +745,7 @@ int usb_lowlevel_init(void)
 
 /* stop uhci
  */
-int usb_lowlevel_stop(void)
+int usb_lowlevel_stop(int index)
 {
 	if (grusb_irq == -1)
 		return 1;
diff --git a/arch/sparc/lib/bootm.c b/arch/sparc/lib/bootm.c
index e5b933d..bcc6358 100644
--- a/arch/sparc/lib/bootm.c
+++ b/arch/sparc/lib/bootm.c
@@ -36,7 +36,7 @@ extern void srmmu_init_cpu(unsigned int entry);
 extern void prepare_bootargs(char *bootargs);
 
 #ifdef CONFIG_USB_UHCI
-extern int usb_lowlevel_stop(void);
+extern int usb_lowlevel_stop(int index);
 #endif
 
 /* sparc kernel argument (the ROM vector) */
diff --git a/board/mpl/common/usb_uhci.c b/board/mpl/common/usb_uhci.c
index ddca587..254f263 100644
--- a/board/mpl/common/usb_uhci.c
+++ b/board/mpl/common/usb_uhci.c
@@ -602,7 +602,7 @@ void handle_usb_interrupt(void)
 
 /* init uhci
  */
-int usb_lowlevel_init(void)
+int usb_lowlevel_init(int index, void **controller)
 {
 	unsigned char temp;
 	int	busdevfunc;
@@ -632,7 +632,7 @@ int usb_lowlevel_init(void)
 
 /* stop uhci
  */
-int usb_lowlevel_stop(void)
+int usb_lowlevel_stop(int index)
 {
 	if(irqvec==-1)
 		return 1;
diff --git a/common/usb.c b/common/usb.c
index 1b40228..e58b6f4 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -76,6 +76,7 @@ static int running;
 static int asynch_allowed;
 
 char usb_started; /* flag for the started/stopped USB status */
+void *ctrl; /* goes away in a following commit, but don't break bisect */
 
 /**********************************************************************
  * some forward declerations...
@@ -96,7 +97,7 @@ int usb_init(void)
 	usb_hub_reset();
 	/* init low_level USB */
 	printf("USB:   ");
-	result = usb_lowlevel_init();
+	result = usb_lowlevel_init(0, &ctrl);
 	/* if lowlevel init is OK, scan the bus for devices
 	 * i.e. search HUBs and configure them */
 	if (result == 0) {
@@ -123,7 +124,7 @@ int usb_stop(void)
 		asynch_allowed = 1;
 		usb_started = 0;
 		usb_hub_reset();
-		res = usb_lowlevel_stop();
+		res = usb_lowlevel_stop(0);
 	}
 	return res;
 }
@@ -754,7 +755,7 @@ struct usb_device *usb_get_dev_index(int index)
 /* returns a pointer of a new device structure or NULL, if
  * no device struct is available
  */
-struct usb_device *usb_alloc_new_device(void)
+struct usb_device *usb_alloc_new_device(void *controller)
 {
 	int i;
 	USB_PRINTF("New Device %d\n", dev_index);
@@ -768,6 +769,7 @@ struct usb_device *usb_alloc_new_device(void)
 	for (i = 0; i < USB_MAXCHILDREN; i++)
 		usb_dev[dev_index].children[i] = NULL;
 	usb_dev[dev_index].parent = NULL;
+	usb_dev[dev_index].controller = controller;
 	dev_index++;
 	return &usb_dev[dev_index - 1];
 }
@@ -958,7 +960,7 @@ static void usb_scan_devices(void)
 	}
 	dev_index = 0;
 	/* device 0 is always present (root hub, so let it analyze) */
-	dev = usb_alloc_new_device();
+	dev = usb_alloc_new_device(ctrl);
 	if (usb_new_device(dev))
 		printf("No USB Device found\n");
 	else
diff --git a/common/usb_hub.c b/common/usb_hub.c
index f35ad95..53d939c 100644
--- a/common/usb_hub.c
+++ b/common/usb_hub.c
@@ -243,7 +243,7 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
 	mdelay(200);
 
 	/* Allocate a new device struct for it */
-	usb = usb_alloc_new_device();
+	usb = usb_alloc_new_device(dev->controller);
 
 	if (portstatus & USB_PORT_STAT_HIGH_SPEED)
 		usb->speed = USB_SPEED_HIGH;
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index eb9e323..4dd1f9b 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -828,12 +828,12 @@ unknown:
 	return -1;
 }
 
-int usb_lowlevel_stop(void)
+int usb_lowlevel_stop(int index)
 {
 	return ehci_hcd_stop();
 }
 
-int usb_lowlevel_init(void)
+int usb_lowlevel_init(int index, void **controller)
 {
 	uint32_t reg;
 	uint32_t cmd;
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
index 5ef34c3..19e16a4 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -1391,7 +1391,7 @@ int isp116x_check_id(struct isp116x *isp116x)
 	return 0;
 }
 
-int usb_lowlevel_init(void)
+int usb_lowlevel_init(int index, void **controller))
 {
 	struct isp116x *isp116x = &isp116x_dev;
 
@@ -1428,7 +1428,7 @@ int usb_lowlevel_init(void)
 	return 0;
 }
 
-int usb_lowlevel_stop(void)
+int usb_lowlevel_stop(int index)
 {
 	struct isp116x *isp116x = &isp116x_dev;
 
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 9f47351..c2106ad 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1865,7 +1865,7 @@ static void hc_release_ohci(ohci_t *ohci)
  */
 static char ohci_inited = 0;
 
-int usb_lowlevel_init(void)
+int usb_lowlevel_init(int index, void **controller)
 {
 #ifdef CONFIG_PCI_OHCI
 	pci_dev_t pdev;
@@ -1971,7 +1971,7 @@ int usb_lowlevel_init(void)
 	return 0;
 }
 
-int usb_lowlevel_stop(void)
+int usb_lowlevel_stop(int index)
 {
 	/* this gets called really early - before the controller has */
 	/* even been initialized! */
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index ab1b8d0..2a4e7ff 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -908,7 +908,7 @@ int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 	return 0;
 }
 
-int usb_lowlevel_init(void)
+int usb_lowlevel_init(int index, void **controller))
 {
 	struct r8a66597 *r8a66597 = &gr8a66597;
 
@@ -931,7 +931,7 @@ int usb_lowlevel_init(void)
 	return 0;
 }
 
-int usb_lowlevel_stop(void)
+int usb_lowlevel_stop(int index)
 {
 	disable_controller(&gr8a66597);
 
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
index bb27dd5..2830616 100644
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -210,14 +210,14 @@ static int sl811_hc_reset(void)
 	return 1;
 }
 
-int usb_lowlevel_init(void)
+int usb_lowlevel_init(int index, void **controller)
 {
 	root_hub_devnum = 0;
 	sl811_hc_reset();
 	return 0;
 }
 
-int usb_lowlevel_stop(void)
+int usb_lowlevel_stop(int index)
 {
 	sl811_hc_reset();
 	return 0;
diff --git a/drivers/usb/musb/musb_hcd.c b/drivers/usb/musb/musb_hcd.c
index 2df52c1..5c8deca 100644
--- a/drivers/usb/musb/musb_hcd.c
+++ b/drivers/usb/musb/musb_hcd.c
@@ -1092,7 +1092,7 @@ int submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
 /*
  * This function initializes the usb controller module.
  */
-int usb_lowlevel_init(void)
+int usb_lowlevel_init(int index, void **controller)
 {
 	u8  power;
 	u32 timeout;
@@ -1144,7 +1144,7 @@ int usb_lowlevel_init(void)
 /*
  * This function stops the operation of the davinci usb module.
  */
-int usb_lowlevel_stop(void)
+int usb_lowlevel_stop(int index)
 {
 	/* Reset the USB module */
 	musb_platform_deinit();
diff --git a/include/usb.h b/include/usb.h
index 63730ee..e80c3be 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -140,6 +140,8 @@ struct usb_device {
 	int portnr;
 	struct usb_device *parent;
 	struct usb_device *children[USB_MAXCHILDREN];
+
+	void *controller;		/* hardware controller private data */
 };
 
 /**********************************************************************
@@ -153,8 +155,9 @@ struct usb_device {
 	defined(CONFIG_USB_OMAP3) || defined(CONFIG_USB_DA8XX) || \
 	defined(CONFIG_USB_BLACKFIN) || defined(CONFIG_USB_AM35X)
 
-int usb_lowlevel_init(void);
-int usb_lowlevel_stop(void);
+int usb_lowlevel_init(int index, void **controller);
+int usb_lowlevel_stop(int index);
+
 int submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
 			void *buffer, int transfer_len);
 int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
@@ -382,7 +385,8 @@ void usb_hub_reset(void);
 int hub_port_reset(struct usb_device *dev, int port,
 			  unsigned short *portstat);
 
-struct usb_device *usb_alloc_new_device(void);
+struct usb_device *usb_alloc_new_device(void *controller);
+
 int usb_new_device(struct usb_device *dev);
 
 #endif /*_USB_H_ */
diff --git a/include/usb/mv_udc.h b/include/usb/mv_udc.h
index 51d36c3..221e626 100644
--- a/include/usb/mv_udc.h
+++ b/include/usb/mv_udc.h
@@ -147,5 +147,5 @@ struct ept_queue_item {
 #define INFO_BUFFER_ERROR     (1 << 5)
 #define INFO_TX_ERROR         (1 << 3)
 
-extern int usb_lowlevel_init(void);
+extern int usb_lowlevel_init(int index, void **controller);
 #endif /* __MV_UDC_H__ */
-- 
1.7.11.4

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH 2/4] usb: ehci: rework to take advantage of new lowlevel interface
  2012-08-30 16:03 [U-Boot] [PATCH 0/4] USB multi controller Lucas Stach
  2012-08-30 16:03 ` [U-Boot] [PATCH 1/4] usb: lowlevel interface change to support multiple controllers Lucas Stach
@ 2012-08-30 16:03 ` Lucas Stach
  2012-08-30 21:09   ` Marek Vasut
  2012-08-30 16:03 ` [U-Boot] [PATCH 3/4] tegra20: port to new ehci interface Lucas Stach
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 18+ messages in thread
From: Lucas Stach @ 2012-08-30 16:03 UTC (permalink / raw)
  To: u-boot

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>
---
 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          |  11 ++--
 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          |  28 ++++----
 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, 197 Zeilen hinzugef?gt(+), 218 Zeilen entfernt(-)
 delete mode 100644 drivers/usb/host/ehci-core.h

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..15c7ab4 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);
@@ -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 4dd1f9b..bc8674d 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -29,12 +29,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))
@@ -135,24 +140,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)
@@ -162,10 +168,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;
@@ -211,7 +217,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;
@@ -220,6 +225,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);
@@ -310,7 +316,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 = usb_pipespeed(pipe) != USB_SPEED_HIGH && !usb_pipeendpoint(pipe);
 	maxpacket = usb_maxpacket(dev, pipe);
 	endpt = QH_ENDPT1_RL(8) | QH_ENDPT1_C(c) |
@@ -444,27 +450,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");
@@ -477,8 +483,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,
@@ -507,11 +513,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");
@@ -550,9 +556,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);
@@ -583,13 +589,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;
 
@@ -657,7 +664,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");
@@ -707,7 +714,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;
@@ -722,7 +729,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);
 			}
@@ -759,7 +766,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",
@@ -771,7 +778,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);
@@ -783,7 +790,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;
@@ -792,7 +799,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));
@@ -800,7 +807,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");
@@ -830,26 +837,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);
@@ -861,7 +871,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);
 	debug("Register %x NbrPorts %d\n", reg, descriptor.hub.bNbrPorts);
 	/* Port Indicators */
@@ -872,27 +882,28 @@ int usb_lowlevel_init(int index, void **controller)
 		descriptor.hub.wHubCharacteristics |= 0x01;
 
 	/* 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;
 }
 
@@ -912,14 +923,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 e263747..470b0b4 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;
-	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;
+	uint32_t usb_base, cap_base, tmp;
+	struct mx28_register_32 *digctl_ctrl =
+		(struct mx28_register_32 *)HW_DIGCTL_CTRL;
+	struct mx28_clkctrl_regs *clkctrl_regs =
+		(struct mx28_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 */
-- 
1.7.11.4

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH 3/4] tegra20: port to new ehci interface
  2012-08-30 16:03 [U-Boot] [PATCH 0/4] USB multi controller Lucas Stach
  2012-08-30 16:03 ` [U-Boot] [PATCH 1/4] usb: lowlevel interface change to support multiple controllers Lucas Stach
  2012-08-30 16:03 ` [U-Boot] [PATCH 2/4] usb: ehci: rework to take advantage of new lowlevel interface Lucas Stach
@ 2012-08-30 16:03 ` Lucas Stach
  2012-08-30 16:03 ` [U-Boot] [PATCH 4/4] usb: add support for multiple usb controllers Lucas Stach
  2012-09-04 23:05 ` [U-Boot] [PATCH 0/4] USB multi controller Stephen Warren
  4 siblings, 0 replies; 18+ messages in thread
From: Lucas Stach @ 2012-08-30 16:03 UTC (permalink / raw)
  To: u-boot

EHCI interface now supports more than one controller. Wire up our usb functions
to use this new interface.

Signed-off-by: Lucas Stach <dev@lynxeye.de>
---
 arch/arm/cpu/armv7/tegra20/usb.c        | 15 ++++-----------
 arch/arm/include/asm/arch-tegra20/usb.h |  4 ++--
 drivers/usb/host/ehci-tegra.c           |  5 ++---
 3 Dateien ge?ndert, 8 Zeilen hinzugef?gt(+), 16 Zeilen entfernt(-)

diff --git a/arch/arm/cpu/armv7/tegra20/usb.c b/arch/arm/cpu/armv7/tegra20/usb.c
index 4a3ec7c..219f9c2 100644
--- a/arch/arm/cpu/armv7/tegra20/usb.c
+++ b/arch/arm/cpu/armv7/tegra20/usb.c
@@ -87,7 +87,6 @@ struct fdt_usb {
 
 static struct fdt_usb port[USB_PORTS_MAX];	/* List of valid USB ports */
 static unsigned port_count;			/* Number of available ports */
-static int port_current;			/* Current port (-1 = none) */
 
 /*
  * This table has USB timing parameters for each Oscillator frequency we
@@ -453,30 +452,25 @@ static int add_port(struct fdt_usb *config, const u32 timing[])
 	return 0;
 }
 
-int tegrausb_start_port(unsigned portnum, u32 *hccr, u32 *hcor)
+int tegrausb_start_port(int portnum, u32 *hccr, u32 *hcor)
 {
 	struct usb_ctlr *usbctlr;
 
 	if (portnum >= port_count)
 		return -1;
-	tegrausb_stop_port();
 	set_host_mode(&port[portnum]);
 
 	usbctlr = port[portnum].reg;
 	*hccr = (u32)&usbctlr->cap_length;
 	*hcor = (u32)&usbctlr->usb_cmd;
-	port_current = portnum;
 	return 0;
 }
 
-int tegrausb_stop_port(void)
+int tegrausb_stop_port(int portnum)
 {
 	struct usb_ctlr *usbctlr;
 
-	if (port_current == -1)
-		return -1;
-
-	usbctlr = port[port_current].reg;
+	usbctlr = port[portnum].reg;
 
 	/* Stop controller */
 	writel(0, &usbctlr->usb_cmd);
@@ -485,7 +479,7 @@ int tegrausb_stop_port(void)
 	/* Initiate controller reset */
 	writel(2, &usbctlr->usb_cmd);
 	udelay(1000);
-	port_current = -1;
+
 	return 0;
 }
 
@@ -565,7 +559,6 @@ int board_usb_init(const void *blob)
 			return -1;
 		set_host_mode(&config);
 	}
-	port_current = -1;
 
 	return 0;
 }
diff --git a/arch/arm/include/asm/arch-tegra20/usb.h b/arch/arm/include/asm/arch-tegra20/usb.h
index bd89d66..fdbd127 100644
--- a/arch/arm/include/asm/arch-tegra20/usb.h
+++ b/arch/arm/include/asm/arch-tegra20/usb.h
@@ -259,13 +259,13 @@ int board_usb_init(const void *blob);
  * @param hcor		returns start address of EHCI HCOR registers
  * @return 0 if ok, -1 on error (generally invalid port number)
  */
-int tegrausb_start_port(unsigned portnum, u32 *hccr, u32 *hcor);
+int tegrausb_start_port(int portnum, u32 *hccr, u32 *hcor);
 
 /**
  * Stop the current port
  *
  * @return 0 if ok, -1 if no port was active
  */
-int tegrausb_stop_port(void);
+int tegrausb_stop_port(int portnum);
 
 #endif	/* _TEGRA_USB_H_ */
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index bb5a68e..a1c43f8 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -57,7 +57,7 @@ int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 	 * Select the first port, as we don't have a way of selecting others
 	 * yet
 	 */
-	if (tegrausb_start_port(0, &our_hccr, &our_hcor))
+	if (tegrausb_start_port(index, &our_hccr, &our_hcor))
 		return -1;
 
 	*hccr = (struct ehci_hccr *)our_hccr;
@@ -72,6 +72,5 @@ int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
  */
 int ehci_hcd_stop(int index)
 {
-	tegrausb_stop_port();
-	return 0;
+	return tegrausb_stop_port(index);
 }
-- 
1.7.11.4

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH 4/4] usb: add support for multiple usb controllers
  2012-08-30 16:03 [U-Boot] [PATCH 0/4] USB multi controller Lucas Stach
                   ` (2 preceding siblings ...)
  2012-08-30 16:03 ` [U-Boot] [PATCH 3/4] tegra20: port to new ehci interface Lucas Stach
@ 2012-08-30 16:03 ` Lucas Stach
  2012-08-30 21:12   ` Marek Vasut
  2012-09-04 23:05 ` [U-Boot] [PATCH 0/4] USB multi controller Stephen Warren
  4 siblings, 1 reply; 18+ messages in thread
From: Lucas Stach @ 2012-08-30 16:03 UTC (permalink / raw)
  To: u-boot

Allows to initialize more than one USB controller at once.

Signed-off-by: Lucas Stach <dev@lynxeye.de>
---
 common/cmd_usb.c            |  16 +++++--
 common/usb.c                | 104 +++++++++++++++++++++++---------------------
 common/usb_storage.c        |   2 +-
 drivers/usb/eth/usb_ether.c |   2 +-
 4 Dateien ge?ndert, 68 Zeilen hinzugef?gt(+), 56 Zeilen entfernt(-)

diff --git a/common/cmd_usb.c b/common/cmd_usb.c
index a8e3ae5..6cefc0c 100644
--- a/common/cmd_usb.c
+++ b/common/cmd_usb.c
@@ -517,8 +517,7 @@ int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 		bootstage_mark_name(BOOTSTAGE_ID_USB_START, "usb_start");
 		usb_stop();
 		printf("(Re)start USB...\n");
-		i = usb_init();
-		if (i >= 0) {
+		if (usb_init() >= 0) {
 #ifdef CONFIG_USB_STORAGE
 			/* try to recognize storage devices immediately */
 			usb_stor_curr_dev = usb_stor_scan(1);
@@ -527,6 +526,9 @@ int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 			/* try to recognize ethernet devices immediately */
 			usb_ether_curr_dev = usb_host_eth_scan(1);
 #endif
+#ifdef CONFIG_USB_KEYBOARD
+			drv_usb_kbd_init();
+#endif
 		}
 		return 0;
 	}
@@ -553,8 +555,14 @@ int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 		return 1;
 	}
 	if (strncmp(argv[1], "tree", 4) == 0) {
-		printf("\nDevice Tree:\n");
-		usb_show_tree(usb_get_dev_index(0));
+		puts("USB device tree:\n");
+		for (i = 0; i < USB_MAX_DEVICE; i++) {
+			dev = usb_get_dev_index(i);
+			if (dev == NULL)
+				break;
+			if (dev->parent == NULL)
+				usb_show_tree(dev);
+		}
 		return 0;
 	}
 	if (strncmp(argv[1], "inf", 3) == 0) {
diff --git a/common/usb.c b/common/usb.c
index e58b6f4..78a410d 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -72,45 +72,72 @@
 
 static struct usb_device usb_dev[USB_MAX_DEVICE];
 static int dev_index;
-static int running;
 static int asynch_allowed;
 
 char usb_started; /* flag for the started/stopped USB status */
-void *ctrl; /* goes away in a following commit, but don't break bisect */
 
-/**********************************************************************
- * some forward declerations...
- */
-static void usb_scan_devices(void);
+#ifndef CONFIG_USB_MAX_CONTROLLER_COUNT
+#define CONFIG_USB_MAX_CONTROLLER_COUNT 1
+#endif
 
 /***************************************************************************
  * Init USB Device
  */
-
 int usb_init(void)
 {
-	int result;
+	void *ctrl;
+	struct usb_device *dev;
+	int i, start_index = 0;
 
-	running = 0;
 	dev_index = 0;
 	asynch_allowed = 1;
 	usb_hub_reset();
+
+	/* first make all devices unknown */
+	for (i = 0; i < USB_MAX_DEVICE; i++) {
+		memset(&usb_dev[i], 0, sizeof(struct usb_device));
+		usb_dev[i].devnum = -1;
+	}
+
 	/* init low_level USB */
-	printf("USB:   ");
-	result = usb_lowlevel_init(0, &ctrl);
-	/* if lowlevel init is OK, scan the bus for devices
-	 * i.e. search HUBs and configure them */
-	if (result == 0) {
-		printf("scanning bus for devices... ");
-		running = 1;
-		usb_scan_devices();
+	for (i = 0; i < CONFIG_USB_MAX_CONTROLLER_COUNT; i++) {
+		/* init low_level USB */
+		printf("USB%d:   ", i);
+		if (usb_lowlevel_init(i, &ctrl)) {
+			puts("lowlevel init failed\n");
+			continue;
+		}
+		/*
+		 * lowlevel init is OK, now scan the bus for devices
+		 * i.e. search HUBs and configure them
+		 */
+		start_index = dev_index;
+		printf("scanning bus %d for devices... ", i);
+		dev = usb_alloc_new_device(ctrl);
+		/*
+		 * device 0 is always present
+		 * (root hub, so let it analyze)
+		 */
+		if (dev)
+			usb_new_device(dev);
+
+		if (start_index == dev_index)
+			puts("No USB Device found\n");
+		else
+			printf("%d USB Device(s) found\n",
+				dev_index - start_index);
+
 		usb_started = 1;
-		return 0;
-	} else {
-		printf("Error, couldn't init Lowlevel part\n");
-		usb_started = 0;
+	}
+
+	USB_PRINTF("scan end\n");
+	/* if we were not able to find@least one working bus, bail out */
+	if (!usb_started) {
+		puts("USB error: all controllers failed lowlevel init\n");
 		return -1;
 	}
+
+	return 0;
 }
 
 /******************************************************************************
@@ -118,15 +145,18 @@ int usb_init(void)
  */
 int usb_stop(void)
 {
-	int res = 0;
+	int i;
 
 	if (usb_started) {
 		asynch_allowed = 1;
 		usb_started = 0;
 		usb_hub_reset();
-		res = usb_lowlevel_stop(0);
+
+		for (i = 0; i < CONFIG_USB_MAX_CONTROLLER_COUNT; i++)
+			usb_lowlevel_stop(i);
 	}
-	return res;
+
+	return 0;
 }
 
 /*
@@ -751,7 +781,6 @@ struct usb_device *usb_get_dev_index(int index)
 		return &usb_dev[index];
 }
 
-
 /* returns a pointer of a new device structure or NULL, if
  * no device struct is available
  */
@@ -947,29 +976,4 @@ int usb_new_device(struct usb_device *dev)
 	return 0;
 }
 
-/* build device Tree  */
-static void usb_scan_devices(void)
-{
-	int i;
-	struct usb_device *dev;
-
-	/* first make all devices unknown */
-	for (i = 0; i < USB_MAX_DEVICE; i++) {
-		memset(&usb_dev[i], 0, sizeof(struct usb_device));
-		usb_dev[i].devnum = -1;
-	}
-	dev_index = 0;
-	/* device 0 is always present (root hub, so let it analyze) */
-	dev = usb_alloc_new_device(ctrl);
-	if (usb_new_device(dev))
-		printf("No USB Device found\n");
-	else
-		printf("%d USB Device(s) found\n", dev_index);
-	/* insert "driver" if possible */
-#ifdef CONFIG_USB_KEYBOARD
-	drv_usb_kbd_init();
-#endif
-	USB_PRINTF("scan end\n");
-}
-
 /* EOF */
diff --git a/common/usb_storage.c b/common/usb_storage.c
index 4aeed82..950451e 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -244,7 +244,7 @@ int usb_stor_scan(int mode)
 	struct usb_device *dev;
 
 	if (mode == 1)
-		printf("       scanning bus for storage devices... ");
+		printf("       scanning usb for storage devices... ");
 
 	usb_disable_asynch(1); /* asynch transfer not allowed */
 
diff --git a/drivers/usb/eth/usb_ether.c b/drivers/usb/eth/usb_ether.c
index 6cad6c8..f361e8b 100644
--- a/drivers/usb/eth/usb_ether.c
+++ b/drivers/usb/eth/usb_ether.c
@@ -123,7 +123,7 @@ int usb_host_eth_scan(int mode)
 
 
 	if (mode == 1)
-		printf("       scanning bus for ethernet devices... ");
+		printf("       scanning usb for ethernet devices... ");
 
 	old_async = usb_disable_asynch(1); /* asynch transfer not allowed */
 
-- 
1.7.11.4

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH 1/4] usb: lowlevel interface change to support multiple controllers
  2012-08-30 16:03 ` [U-Boot] [PATCH 1/4] usb: lowlevel interface change to support multiple controllers Lucas Stach
@ 2012-08-30 21:03   ` Marek Vasut
  0 siblings, 0 replies; 18+ messages in thread
From: Marek Vasut @ 2012-08-30 21:03 UTC (permalink / raw)
  To: u-boot

Dear Lucas Stach,

> Carry an index in the lowlevel usb functions to make specify the
> respective usb controller.
> 
> Also pass through an controller struct from lowlevel_init to the
> creation of the root usb device of this controller.
> 
> Signed-off-by: Lucas Stach <dev@lynxeye.de>
[...]

WFM,

Reviewed-by: Marek Vasut <marex@denx.de>

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH 2/4] usb: ehci: rework to take advantage of new lowlevel interface
  2012-08-30 16:03 ` [U-Boot] [PATCH 2/4] usb: ehci: rework to take advantage of new lowlevel interface Lucas Stach
@ 2012-08-30 21:09   ` Marek Vasut
  2012-08-30 21:51     ` Lucas Stach
  0 siblings, 1 reply; 18+ messages in thread
From: Marek Vasut @ 2012-08-30 21:09 UTC (permalink / raw)
  To: u-boot

Dear Lucas Stach,

> 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>
[...]

The omap change could be separated out, no?
Also, I'd fix all these &(*something)->somethingelse if possible.

Otherwise,

Reviewed-by: Marek Vasut <marex@denx.de>

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH 4/4] usb: add support for multiple usb controllers
  2012-08-30 16:03 ` [U-Boot] [PATCH 4/4] usb: add support for multiple usb controllers Lucas Stach
@ 2012-08-30 21:12   ` Marek Vasut
  0 siblings, 0 replies; 18+ messages in thread
From: Marek Vasut @ 2012-08-30 21:12 UTC (permalink / raw)
  To: u-boot

Dear Lucas Stach,

> Allows to initialize more than one USB controller at once.
> 
> Signed-off-by: Lucas Stach <dev@lynxeye.de>
[...]

>  int usb_stop(void)
>  {
> -	int res = 0;
> +	int i;
> 
>  	if (usb_started) {
>  		asynch_allowed = 1;
>  		usb_started = 0;
>  		usb_hub_reset();
> -		res = usb_lowlevel_stop(0);
> +
> +		for (i = 0; i < CONFIG_USB_MAX_CONTROLLER_COUNT; i++)
> +			usb_lowlevel_stop(i);

You might want to track if any failed and return it or emit warning.

Otherwise:

Reviewed-by: Marek Vasut <marex@denx.de>

>  	}
> -	return res;
> +
> +	return 0;
>  }
> 
>  /*
> @@ -751,7 +781,6 @@ struct usb_device *usb_get_dev_index(int index)
>  		return &usb_dev[index];
>  }
> 
> -
>  /* returns a pointer of a new device structure or NULL, if
>   * no device struct is available
>   */
> @@ -947,29 +976,4 @@ int usb_new_device(struct usb_device *dev)
>  	return 0;
>  }
> 
> -/* build device Tree  */
> -static void usb_scan_devices(void)
> -{
> -	int i;
> -	struct usb_device *dev;
> -
> -	/* first make all devices unknown */
> -	for (i = 0; i < USB_MAX_DEVICE; i++) {
> -		memset(&usb_dev[i], 0, sizeof(struct usb_device));
> -		usb_dev[i].devnum = -1;
> -	}
> -	dev_index = 0;
> -	/* device 0 is always present (root hub, so let it analyze) */
> -	dev = usb_alloc_new_device(ctrl);
> -	if (usb_new_device(dev))
> -		printf("No USB Device found\n");
> -	else
> -		printf("%d USB Device(s) found\n", dev_index);
> -	/* insert "driver" if possible */
> -#ifdef CONFIG_USB_KEYBOARD
> -	drv_usb_kbd_init();
> -#endif
> -	USB_PRINTF("scan end\n");
> -}
> -
>  /* EOF */
> diff --git a/common/usb_storage.c b/common/usb_storage.c
> index 4aeed82..950451e 100644
> --- a/common/usb_storage.c
> +++ b/common/usb_storage.c
> @@ -244,7 +244,7 @@ int usb_stor_scan(int mode)
>  	struct usb_device *dev;
> 
>  	if (mode == 1)
> -		printf("       scanning bus for storage devices... ");
> +		printf("       scanning usb for storage devices... ");
> 
>  	usb_disable_asynch(1); /* asynch transfer not allowed */
> 
> diff --git a/drivers/usb/eth/usb_ether.c b/drivers/usb/eth/usb_ether.c
> index 6cad6c8..f361e8b 100644
> --- a/drivers/usb/eth/usb_ether.c
> +++ b/drivers/usb/eth/usb_ether.c
> @@ -123,7 +123,7 @@ int usb_host_eth_scan(int mode)
> 
> 
>  	if (mode == 1)
> -		printf("       scanning bus for ethernet devices... ");
> +		printf("       scanning usb for ethernet devices... ");
> 
>  	old_async = usb_disable_asynch(1); /* asynch transfer not allowed */

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH 2/4] usb: ehci: rework to take advantage of new lowlevel interface
  2012-08-30 21:09   ` Marek Vasut
@ 2012-08-30 21:51     ` Lucas Stach
  2012-08-30 21:55       ` Marek Vasut
  0 siblings, 1 reply; 18+ messages in thread
From: Lucas Stach @ 2012-08-30 21:51 UTC (permalink / raw)
  To: u-boot

Am Donnerstag, den 30.08.2012, 23:09 +0200 schrieb Marek Vasut:
> Dear Lucas Stach,
> 
> > 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>
> [...]
> 
> The omap change could be separated out, no?

There is no logic change in OMAP up to now. I just had to add some
forward decls to make it work, which would not be needed if OMAP worked
like all the other platforms.

Actually fixing this would be far more invasive and I don't really want
to do this work, as I don't have a single OMAP board to test with.

> Also, I'd fix all these &(*something)->somethingelse if possible.
> 
I just did it this way to minimize the churn this change is causing.
Removing this, arguably a bit ugly, pointer construct could possibly
introduce logic errors, that are not catchable by just compile testing
this. I would rather leave this to someone who actually cares about the
specific platform.

> Otherwise,
> 
> Reviewed-by: Marek Vasut <marex@denx.de>
> 
Thanks,
Lucas

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH 2/4] usb: ehci: rework to take advantage of new lowlevel interface
  2012-08-30 21:51     ` Lucas Stach
@ 2012-08-30 21:55       ` Marek Vasut
  0 siblings, 0 replies; 18+ messages in thread
From: Marek Vasut @ 2012-08-30 21:55 UTC (permalink / raw)
  To: u-boot

Dear Lucas Stach,

> Am Donnerstag, den 30.08.2012, 23:09 +0200 schrieb Marek Vasut:
> > Dear Lucas Stach,
> > 
> > > 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>
> > 
> > [...]
> > 
> > The omap change could be separated out, no?
> 
> There is no logic change in OMAP up to now. I just had to add some
> forward decls to make it work, which would not be needed if OMAP worked
> like all the other platforms.
> 
> Actually fixing this would be far more invasive and I don't really want
> to do this work, as I don't have a single OMAP board to test with.

CCing Tom

> > Also, I'd fix all these &(*something)->somethingelse if possible.
> 
> I just did it this way to minimize the churn this change is causing.
> Removing this, arguably a bit ugly, pointer construct could possibly
> introduce logic errors, that are not catchable by just compile testing
> this. I would rather leave this to someone who actually cares about the
> specific platform.

CC these people please to review such changes.

> > Otherwise,
> > 
> > Reviewed-by: Marek Vasut <marex@denx.de>
> 
> Thanks,
> Lucas

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH 0/4] USB multi controller
  2012-08-30 16:03 [U-Boot] [PATCH 0/4] USB multi controller Lucas Stach
                   ` (3 preceding siblings ...)
  2012-08-30 16:03 ` [U-Boot] [PATCH 4/4] usb: add support for multiple usb controllers Lucas Stach
@ 2012-09-04 23:05 ` Stephen Warren
  2012-09-05  0:30   ` Marek Vasut
  2012-09-05  6:21   ` Lucas Stach
  4 siblings, 2 replies; 18+ messages in thread
From: Stephen Warren @ 2012-09-04 23:05 UTC (permalink / raw)
  To: u-boot

On 08/30/2012 10:03 AM, Lucas Stach wrote:
> Hi all,
> 
> this is a follow up on the patch "USB: EHCI: Initialize multiple
> USB controllers at once" from Jim Lin. It takes some of the
> code but has undergone some heavy reworking.
> 
> When we remove the ifdef horror from the above mentioned patch it's
> mostly a big interface change to the usb subsystem. As this creates
> a lot of churn I've split this up into a series. Every patch is self
> contained so it doesn't break compiles and *should* not regress
> any functionality on it's own. At least the series is bisectable in
> case anything goes wrong. I've compile tested all the ARM configs.
> 
> Both the lowlevel usb and ehci interface change are backward
> compatible, so implementations that only use one controller can
> choose to ignore the new interface. All implementations are
> updated to work with the new function prototypes.
> 
> For Tegra I've included a patch to actually use the new ehci
> interface. Patches are based on a Tegra tree with some relevant
> changes from u-boot-usb picked over, so they should apply to
> u-boot-usb/master.

Can you explain what this series is based on in a little more detail? I
tried applying it to Tegra's for-next today, and it wouldn't apply. I
managed to apply using plain "patch" rather then "git am", but then I
get a bunch of compile errors:-(

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH 0/4] USB multi controller
  2012-09-04 23:05 ` [U-Boot] [PATCH 0/4] USB multi controller Stephen Warren
@ 2012-09-05  0:30   ` Marek Vasut
  2012-09-05  6:21   ` Lucas Stach
  1 sibling, 0 replies; 18+ messages in thread
From: Marek Vasut @ 2012-09-05  0:30 UTC (permalink / raw)
  To: u-boot

Dear Stephen Warren,

> On 08/30/2012 10:03 AM, Lucas Stach wrote:
> > Hi all,
> > 
> > this is a follow up on the patch "USB: EHCI: Initialize multiple
> > USB controllers at once" from Jim Lin. It takes some of the
> > code but has undergone some heavy reworking.
> > 
> > When we remove the ifdef horror from the above mentioned patch it's
> > mostly a big interface change to the usb subsystem. As this creates
> > a lot of churn I've split this up into a series. Every patch is self
> > contained so it doesn't break compiles and *should* not regress
> > any functionality on it's own. At least the series is bisectable in
> > case anything goes wrong. I've compile tested all the ARM configs.
> > 
> > Both the lowlevel usb and ehci interface change are backward
> > compatible, so implementations that only use one controller can
> > choose to ignore the new interface. All implementations are
> > updated to work with the new function prototypes.
> > 
> > For Tegra I've included a patch to actually use the new ehci
> > interface. Patches are based on a Tegra tree with some relevant
> > changes from u-boot-usb picked over, so they should apply to
> > u-boot-usb/master.
> 
> Can you explain what this series is based on in a little more detail? I
> tried applying it to Tegra's for-next today, and it wouldn't apply. I
> managed to apply using plain "patch" rather then "git am", but then I
> get a bunch of compile errors:-(

U-Boot USB maybe ? I'm fighting through pile of hacking now, so didn't get to 
rebasing (!) u-boot-usb on top of master yet. But it should be safe to rebase 
this on top of master.

Are we clear on the rest of comments?

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH 0/4] USB multi controller
  2012-09-04 23:05 ` [U-Boot] [PATCH 0/4] USB multi controller Stephen Warren
  2012-09-05  0:30   ` Marek Vasut
@ 2012-09-05  6:21   ` Lucas Stach
  2012-09-05  6:30     ` Marek Vasut
  1 sibling, 1 reply; 18+ messages in thread
From: Lucas Stach @ 2012-09-05  6:21 UTC (permalink / raw)
  To: u-boot

Hi Stephen,

Am Dienstag, den 04.09.2012, 17:05 -0600 schrieb Stephen Warren:
> On 08/30/2012 10:03 AM, Lucas Stach wrote:
> > Hi all,
> > 
> > this is a follow up on the patch "USB: EHCI: Initialize multiple
> > USB controllers at once" from Jim Lin. It takes some of the
> > code but has undergone some heavy reworking.
> > 
> > When we remove the ifdef horror from the above mentioned patch it's
> > mostly a big interface change to the usb subsystem. As this creates
> > a lot of churn I've split this up into a series. Every patch is self
> > contained so it doesn't break compiles and *should* not regress
> > any functionality on it's own. At least the series is bisectable in
> > case anything goes wrong. I've compile tested all the ARM configs.
> > 
> > Both the lowlevel usb and ehci interface change are backward
> > compatible, so implementations that only use one controller can
> > choose to ignore the new interface. All implementations are
> > updated to work with the new function prototypes.
> > 
> > For Tegra I've included a patch to actually use the new ehci
> > interface. Patches are based on a Tegra tree with some relevant
> > changes from u-boot-usb picked over, so they should apply to
> > u-boot-usb/master.
> 
> Can you explain what this series is based on in a little more detail? I
> tried applying it to Tegra's for-next today, and it wouldn't apply. I
> managed to apply using plain "patch" rather then "git am", but then I
> get a bunch of compile errors:-(
> 
At the time I wrote those patches the u-boot-usb and u-boot-tegra trees
didn't merge cleanly and I wasted quite some time trying to fix up the
failed merge. In the end I ended up just picking the following over to
my tegra tree, which should be enough to avoid any conflicts with the
usb tree:

cdeb916120a4 ehci: cosmetic: Define the number of qt_buffers
44ae0be7461f ehci: Fail for multi-transaction interrupt transfers
14eb79b7a086 ehci: cosmetic: Define used constants
5cec214ecd7d ehci-hcd: Boost transfer speed
cffcc5035809 usb_storage: Restore non-EHCI support
4bee5c83ea46 usb_storage: Remove EHCI constraints
3e8581bb9589 usb_stor_BBB_transport: Do not delay when not required
db19134615dd ehci: Optimize qTD allocations

HTH,
Lucas

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH 0/4] USB multi controller
  2012-09-05  6:21   ` Lucas Stach
@ 2012-09-05  6:30     ` Marek Vasut
  2012-09-05 19:11       ` Stephen Warren
  0 siblings, 1 reply; 18+ messages in thread
From: Marek Vasut @ 2012-09-05  6:30 UTC (permalink / raw)
  To: u-boot

Dear Lucas Stach,

> Hi Stephen,
> 
> Am Dienstag, den 04.09.2012, 17:05 -0600 schrieb Stephen Warren:
> > On 08/30/2012 10:03 AM, Lucas Stach wrote:
> > > Hi all,
> > > 
> > > this is a follow up on the patch "USB: EHCI: Initialize multiple
> > > USB controllers at once" from Jim Lin. It takes some of the
> > > code but has undergone some heavy reworking.
> > > 
> > > When we remove the ifdef horror from the above mentioned patch it's
> > > mostly a big interface change to the usb subsystem. As this creates
> > > a lot of churn I've split this up into a series. Every patch is self
> > > contained so it doesn't break compiles and *should* not regress
> > > any functionality on it's own. At least the series is bisectable in
> > > case anything goes wrong. I've compile tested all the ARM configs.
> > > 
> > > Both the lowlevel usb and ehci interface change are backward
> > > compatible, so implementations that only use one controller can
> > > choose to ignore the new interface. All implementations are
> > > updated to work with the new function prototypes.
> > > 
> > > For Tegra I've included a patch to actually use the new ehci
> > > interface. Patches are based on a Tegra tree with some relevant
> > > changes from u-boot-usb picked over, so they should apply to
> > > u-boot-usb/master.
> > 
> > Can you explain what this series is based on in a little more detail? I
> > tried applying it to Tegra's for-next today, and it wouldn't apply. I
> > managed to apply using plain "patch" rather then "git am", but then I
> > get a bunch of compile errors:-(
> 
> At the time I wrote those patches the u-boot-usb and u-boot-tegra trees
> didn't merge cleanly and I wasted quite some time trying to fix up the
> failed merge. In the end I ended up just picking the following over to
> my tegra tree, which should be enough to avoid any conflicts with the
> usb tree:
> 
> cdeb916120a4 ehci: cosmetic: Define the number of qt_buffers
> 44ae0be7461f ehci: Fail for multi-transaction interrupt transfers
> 14eb79b7a086 ehci: cosmetic: Define used constants
> 5cec214ecd7d ehci-hcd: Boost transfer speed
> cffcc5035809 usb_storage: Restore non-EHCI support
> 4bee5c83ea46 usb_storage: Remove EHCI constraints
> 3e8581bb9589 usb_stor_BBB_transport: Do not delay when not required
> db19134615dd ehci: Optimize qTD allocations

u-boot-usb master is updated to master and pushed for your enjoyment.

> HTH,
> Lucas

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH 0/4] USB multi controller
  2012-09-05  6:30     ` Marek Vasut
@ 2012-09-05 19:11       ` Stephen Warren
  2012-09-05 19:27         ` Marek Vasut
  0 siblings, 1 reply; 18+ messages in thread
From: Stephen Warren @ 2012-09-05 19:11 UTC (permalink / raw)
  To: u-boot

On 09/05/2012 12:30 AM, Marek Vasut wrote:
> Dear Lucas Stach,
> 
>> Hi Stephen,
>>
>> Am Dienstag, den 04.09.2012, 17:05 -0600 schrieb Stephen Warren:
>>> On 08/30/2012 10:03 AM, Lucas Stach wrote:
>>>> Hi all,
>>>>
>>>> this is a follow up on the patch "USB: EHCI: Initialize multiple
>>>> USB controllers at once" from Jim Lin. It takes some of the
>>>> code but has undergone some heavy reworking.
>>>>
>>>> When we remove the ifdef horror from the above mentioned patch it's
>>>> mostly a big interface change to the usb subsystem. As this creates
>>>> a lot of churn I've split this up into a series. Every patch is self
>>>> contained so it doesn't break compiles and *should* not regress
>>>> any functionality on it's own. At least the series is bisectable in
>>>> case anything goes wrong. I've compile tested all the ARM configs.
>>>>
>>>> Both the lowlevel usb and ehci interface change are backward
>>>> compatible, so implementations that only use one controller can
>>>> choose to ignore the new interface. All implementations are
>>>> updated to work with the new function prototypes.
>>>>
>>>> For Tegra I've included a patch to actually use the new ehci
>>>> interface. Patches are based on a Tegra tree with some relevant
>>>> changes from u-boot-usb picked over, so they should apply to
>>>> u-boot-usb/master.
>>>
>>> Can you explain what this series is based on in a little more detail? I
>>> tried applying it to Tegra's for-next today, and it wouldn't apply. I
>>> managed to apply using plain "patch" rather then "git am", but then I
>>> get a bunch of compile errors:-(
>>
>> At the time I wrote those patches the u-boot-usb and u-boot-tegra trees
>> didn't merge cleanly and I wasted quite some time trying to fix up the
>> failed merge. In the end I ended up just picking the following over to
>> my tegra tree, which should be enough to avoid any conflicts with the
>> usb tree:
>>
>> cdeb916120a4 ehci: cosmetic: Define the number of qt_buffers
>> 44ae0be7461f ehci: Fail for multi-transaction interrupt transfers
>> 14eb79b7a086 ehci: cosmetic: Define used constants
>> 5cec214ecd7d ehci-hcd: Boost transfer speed
>> cffcc5035809 usb_storage: Restore non-EHCI support
>> 4bee5c83ea46 usb_storage: Remove EHCI constraints
>> 3e8581bb9589 usb_stor_BBB_transport: Do not delay when not required
>> db19134615dd ehci: Optimize qTD allocations
> 
> u-boot-usb master is updated to master and pushed for your enjoyment.

The series doesn't appear to apply to u-boot-usb/master, nor to
u-boot-tegra/master plus those cherry-picks listed above. Perhaps you
can rebase on something (although I'm not sure which branch it's meant
to go through) so I can apply/test it?

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH 0/4] USB multi controller
  2012-09-05 19:11       ` Stephen Warren
@ 2012-09-05 19:27         ` Marek Vasut
  2012-09-05 22:13           ` Lucas Stach
  0 siblings, 1 reply; 18+ messages in thread
From: Marek Vasut @ 2012-09-05 19:27 UTC (permalink / raw)
  To: u-boot

Dear Stephen Warren,

> On 09/05/2012 12:30 AM, Marek Vasut wrote:
> > Dear Lucas Stach,
> > 
> >> Hi Stephen,
> >> 
> >> Am Dienstag, den 04.09.2012, 17:05 -0600 schrieb Stephen Warren:
> >>> On 08/30/2012 10:03 AM, Lucas Stach wrote:
> >>>> Hi all,
> >>>> 
> >>>> this is a follow up on the patch "USB: EHCI: Initialize multiple
> >>>> USB controllers at once" from Jim Lin. It takes some of the
> >>>> code but has undergone some heavy reworking.
> >>>> 
> >>>> When we remove the ifdef horror from the above mentioned patch it's
> >>>> mostly a big interface change to the usb subsystem. As this creates
> >>>> a lot of churn I've split this up into a series. Every patch is self
> >>>> contained so it doesn't break compiles and *should* not regress
> >>>> any functionality on it's own. At least the series is bisectable in
> >>>> case anything goes wrong. I've compile tested all the ARM configs.
> >>>> 
> >>>> Both the lowlevel usb and ehci interface change are backward
> >>>> compatible, so implementations that only use one controller can
> >>>> choose to ignore the new interface. All implementations are
> >>>> updated to work with the new function prototypes.
> >>>> 
> >>>> For Tegra I've included a patch to actually use the new ehci
> >>>> interface. Patches are based on a Tegra tree with some relevant
> >>>> changes from u-boot-usb picked over, so they should apply to
> >>>> u-boot-usb/master.
> >>> 
> >>> Can you explain what this series is based on in a little more detail? I
> >>> tried applying it to Tegra's for-next today, and it wouldn't apply. I
> >>> managed to apply using plain "patch" rather then "git am", but then I
> >>> get a bunch of compile errors:-(
> >> 
> >> At the time I wrote those patches the u-boot-usb and u-boot-tegra trees
> >> didn't merge cleanly and I wasted quite some time trying to fix up the
> >> failed merge. In the end I ended up just picking the following over to
> >> my tegra tree, which should be enough to avoid any conflicts with the
> >> usb tree:
> >> 
> >> cdeb916120a4 ehci: cosmetic: Define the number of qt_buffers
> >> 44ae0be7461f ehci: Fail for multi-transaction interrupt transfers
> >> 14eb79b7a086 ehci: cosmetic: Define used constants
> >> 5cec214ecd7d ehci-hcd: Boost transfer speed
> >> cffcc5035809 usb_storage: Restore non-EHCI support
> >> 4bee5c83ea46 usb_storage: Remove EHCI constraints
> >> 3e8581bb9589 usb_stor_BBB_transport: Do not delay when not required
> >> db19134615dd ehci: Optimize qTD allocations
> > 
> > u-boot-usb master is updated to master and pushed for your enjoyment.
> 
> The series doesn't appear to apply to u-boot-usb/master, nor to
> u-boot-tegra/master plus those cherry-picks listed above. Perhaps you
> can rebase on something (although I'm not sure which branch it's meant
> to go through) so I can apply/test it?

I'd say reorder 3/4 and 4/4 (swap them) and then repost the rebased result. I'll 
pick it all.

That leads me to a question, why is the tegra usb driver goo still in arch/arm/ 
and not in drivers/ as it should be?

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH 0/4] USB multi controller
  2012-09-05 19:27         ` Marek Vasut
@ 2012-09-05 22:13           ` Lucas Stach
  0 siblings, 0 replies; 18+ messages in thread
From: Lucas Stach @ 2012-09-05 22:13 UTC (permalink / raw)
  To: u-boot

Hi Marek, Stephen, Tom,

Am Mittwoch, den 05.09.2012, 21:27 +0200 schrieb Marek Vasut:
> Dear Stephen Warren,
> 
> > On 09/05/2012 12:30 AM, Marek Vasut wrote:
[...]
> > > 
> > > u-boot-usb master is updated to master and pushed for your enjoyment.
> > 
> > The series doesn't appear to apply to u-boot-usb/master, nor to
> > u-boot-tegra/master plus those cherry-picks listed above. Perhaps you
> > can rebase on something (although I'm not sure which branch it's meant
> > to go through) so I can apply/test it?
> 
> I'd say reorder 3/4 and 4/4 (swap them) and then repost the rebased result. I'll 
> pick it all.
> 
I've just posted rebased patches to the list.

> That leads me to a question, why is the tegra usb driver goo still in arch/arm/ 
> and not in drivers/ as it should be?

Just because I like doing one thing at a time. Getting all the USB
related changes integrated so far seemed to be enough work for me to
keep up with. Moving the Tegra USB implementation is still somewhere on
my list of things to do.

Maybe it would be better to also take the whole Tegra ULPI patchset
through the USB tree. This would minimize the dependencies of both trees
and would allow to easily move the implementation in a follow-on
patchset. But for this to work out we would have to agree to base all
further Tegra USB patches for this cycle (if there are any) on the
u-boot-usb tree.

Thanks,
Lucas

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [U-Boot] [PATCH 1/4] usb: lowlevel interface change to support multiple controllers
  2012-09-25 22:14 Lucas Stach
@ 2012-09-25 22:14 ` Lucas Stach
  0 siblings, 0 replies; 18+ messages in thread
From: Lucas Stach @ 2012-09-25 22:14 UTC (permalink / raw)
  To: u-boot

Carry an index in the lowlevel usb functions to make specify the
respective usb controller.

Also pass through an controller struct from lowlevel_init to the
creation of the root usb device of this controller.

Signed-off-by: Lucas Stach <dev@lynxeye.de>
Reviewed-by: Marek Vasut <marex@denx.de>
---
 arch/arm/cpu/arm920t/s3c24x0/usb_ohci.c       |  4 ++--
 arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c |  4 ++--
 arch/powerpc/cpu/mpc5xxx/usb_ohci.c           |  4 ++--
 arch/powerpc/cpu/ppc4xx/usb_ohci.c            |  4 ++--
 arch/sparc/cpu/leon3/usb_uhci.c               |  4 ++--
 arch/sparc/lib/bootm.c                        |  2 +-
 board/mpl/common/usb_uhci.c                   |  4 ++--
 common/usb.c                                  | 10 ++++++----
 common/usb_hub.c                              |  2 +-
 drivers/usb/host/ehci-hcd.c                   |  4 ++--
 drivers/usb/host/isp116x-hcd.c                |  4 ++--
 drivers/usb/host/ohci-hcd.c                   |  4 ++--
 drivers/usb/host/r8a66597-hcd.c               |  4 ++--
 drivers/usb/host/sl811-hcd.c                  |  4 ++--
 drivers/usb/musb/musb_hcd.c                   |  4 ++--
 include/usb.h                                 | 10 +++++++---
 include/usb/mv_udc.h                          |  2 +-
 17 Dateien ge?ndert, 40 Zeilen hinzugef?gt(+), 34 Zeilen entfernt(-)

diff --git a/arch/arm/cpu/arm920t/s3c24x0/usb_ohci.c b/arch/arm/cpu/arm920t/s3c24x0/usb_ohci.c
index cf0335c..944bb32 100644
--- a/arch/arm/cpu/arm920t/s3c24x0/usb_ohci.c
+++ b/arch/arm/cpu/arm920t/s3c24x0/usb_ohci.c
@@ -1659,7 +1659,7 @@ static void hc_release_ohci(struct ohci *ohci)
  */
 static char ohci_inited = 0;
 
-int usb_lowlevel_init(void)
+int usb_lowlevel_init(int index, void **controller)
 {
 	struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
 	struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio();
@@ -1738,7 +1738,7 @@ int usb_lowlevel_init(void)
 	return 0;
 }
 
-int usb_lowlevel_stop(void)
+int usb_lowlevel_stop(int index)
 {
 	struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
 
diff --git a/arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c b/arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c
index 7647e11..c747767 100644
--- a/arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c
+++ b/arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c
@@ -1565,7 +1565,7 @@ static void hc_release_ohci (ohci_t *ohci)
  */
 static char ohci_inited = 0;
 
-int usb_lowlevel_init(void)
+int usb_lowlevel_init(int index, void **controller)
 {
 	u32 pin_func;
 	u32 sys_freqctrl, sys_clksrc;
@@ -1707,7 +1707,7 @@ int usb_lowlevel_init(void)
 	return -1;
 }
 
-int usb_lowlevel_stop(void)
+int usb_lowlevel_stop(int index)
 {
 	/* this gets called really early - before the controller has */
 	/* even been initialized! */
diff --git a/arch/powerpc/cpu/mpc5xxx/usb_ohci.c b/arch/powerpc/cpu/mpc5xxx/usb_ohci.c
index 6d91525..607034b 100644
--- a/arch/powerpc/cpu/mpc5xxx/usb_ohci.c
+++ b/arch/powerpc/cpu/mpc5xxx/usb_ohci.c
@@ -1561,7 +1561,7 @@ static void hc_release_ohci (ohci_t *ohci)
  */
 static char ohci_inited = 0;
 
-int usb_lowlevel_init(void)
+int usb_lowlevel_init(int index, void **controller)
 {
 
 	/* Set the USB Clock						     */
@@ -1629,7 +1629,7 @@ int usb_lowlevel_init(void)
 	return 0;
 }
 
-int usb_lowlevel_stop(void)
+int usb_lowlevel_stop(int index)
 {
 	/* this gets called really early - before the controller has */
 	/* even been initialized! */
diff --git a/arch/powerpc/cpu/ppc4xx/usb_ohci.c b/arch/powerpc/cpu/ppc4xx/usb_ohci.c
index 14c6a28..4ce2726 100644
--- a/arch/powerpc/cpu/ppc4xx/usb_ohci.c
+++ b/arch/powerpc/cpu/ppc4xx/usb_ohci.c
@@ -1566,7 +1566,7 @@ static void hc_release_ohci (ohci_t *ohci)
  */
 static char ohci_inited = 0;
 
-int usb_lowlevel_init(void)
+int usb_lowlevel_init(int index, void **controller)
 {
 	memset (&gohci, 0, sizeof (ohci_t));
 	memset (&urb_priv, 0, sizeof (urb_priv_t));
@@ -1624,7 +1624,7 @@ int usb_lowlevel_init(void)
 	return 0;
 }
 
-int usb_lowlevel_stop(void)
+int usb_lowlevel_stop(int index)
 {
 	/* this gets called really early - before the controller has */
 	/* even been initialized! */
diff --git a/arch/sparc/cpu/leon3/usb_uhci.c b/arch/sparc/cpu/leon3/usb_uhci.c
index 62cc25d..b3b8a4d 100644
--- a/arch/sparc/cpu/leon3/usb_uhci.c
+++ b/arch/sparc/cpu/leon3/usb_uhci.c
@@ -706,7 +706,7 @@ void handle_usb_interrupt(void)
 
 /* init uhci
  */
-int usb_lowlevel_init(void)
+int usb_lowlevel_init(int index, void **controller)
 {
 	unsigned char temp;
 	ambapp_ahbdev ahbdev;
@@ -745,7 +745,7 @@ int usb_lowlevel_init(void)
 
 /* stop uhci
  */
-int usb_lowlevel_stop(void)
+int usb_lowlevel_stop(int index)
 {
 	if (grusb_irq == -1)
 		return 1;
diff --git a/arch/sparc/lib/bootm.c b/arch/sparc/lib/bootm.c
index e5b933d..bcc6358 100644
--- a/arch/sparc/lib/bootm.c
+++ b/arch/sparc/lib/bootm.c
@@ -36,7 +36,7 @@ extern void srmmu_init_cpu(unsigned int entry);
 extern void prepare_bootargs(char *bootargs);
 
 #ifdef CONFIG_USB_UHCI
-extern int usb_lowlevel_stop(void);
+extern int usb_lowlevel_stop(int index);
 #endif
 
 /* sparc kernel argument (the ROM vector) */
diff --git a/board/mpl/common/usb_uhci.c b/board/mpl/common/usb_uhci.c
index ddca587..254f263 100644
--- a/board/mpl/common/usb_uhci.c
+++ b/board/mpl/common/usb_uhci.c
@@ -602,7 +602,7 @@ void handle_usb_interrupt(void)
 
 /* init uhci
  */
-int usb_lowlevel_init(void)
+int usb_lowlevel_init(int index, void **controller)
 {
 	unsigned char temp;
 	int	busdevfunc;
@@ -632,7 +632,7 @@ int usb_lowlevel_init(void)
 
 /* stop uhci
  */
-int usb_lowlevel_stop(void)
+int usb_lowlevel_stop(int index)
 {
 	if(irqvec==-1)
 		return 1;
diff --git a/common/usb.c b/common/usb.c
index 1b40228..e58b6f4 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -76,6 +76,7 @@ static int running;
 static int asynch_allowed;
 
 char usb_started; /* flag for the started/stopped USB status */
+void *ctrl; /* goes away in a following commit, but don't break bisect */
 
 /**********************************************************************
  * some forward declerations...
@@ -96,7 +97,7 @@ int usb_init(void)
 	usb_hub_reset();
 	/* init low_level USB */
 	printf("USB:   ");
-	result = usb_lowlevel_init();
+	result = usb_lowlevel_init(0, &ctrl);
 	/* if lowlevel init is OK, scan the bus for devices
 	 * i.e. search HUBs and configure them */
 	if (result == 0) {
@@ -123,7 +124,7 @@ int usb_stop(void)
 		asynch_allowed = 1;
 		usb_started = 0;
 		usb_hub_reset();
-		res = usb_lowlevel_stop();
+		res = usb_lowlevel_stop(0);
 	}
 	return res;
 }
@@ -754,7 +755,7 @@ struct usb_device *usb_get_dev_index(int index)
 /* returns a pointer of a new device structure or NULL, if
  * no device struct is available
  */
-struct usb_device *usb_alloc_new_device(void)
+struct usb_device *usb_alloc_new_device(void *controller)
 {
 	int i;
 	USB_PRINTF("New Device %d\n", dev_index);
@@ -768,6 +769,7 @@ struct usb_device *usb_alloc_new_device(void)
 	for (i = 0; i < USB_MAXCHILDREN; i++)
 		usb_dev[dev_index].children[i] = NULL;
 	usb_dev[dev_index].parent = NULL;
+	usb_dev[dev_index].controller = controller;
 	dev_index++;
 	return &usb_dev[dev_index - 1];
 }
@@ -958,7 +960,7 @@ static void usb_scan_devices(void)
 	}
 	dev_index = 0;
 	/* device 0 is always present (root hub, so let it analyze) */
-	dev = usb_alloc_new_device();
+	dev = usb_alloc_new_device(ctrl);
 	if (usb_new_device(dev))
 		printf("No USB Device found\n");
 	else
diff --git a/common/usb_hub.c b/common/usb_hub.c
index 32750e8..e4a1201 100644
--- a/common/usb_hub.c
+++ b/common/usb_hub.c
@@ -244,7 +244,7 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
 	mdelay(200);
 
 	/* Allocate a new device struct for it */
-	usb = usb_alloc_new_device();
+	usb = usb_alloc_new_device(dev->controller);
 
 	if (portstatus & USB_PORT_STAT_HIGH_SPEED)
 		usb->speed = USB_SPEED_HIGH;
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 392e286..5d8714e 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -829,12 +829,12 @@ unknown:
 	return -1;
 }
 
-int usb_lowlevel_stop(void)
+int usb_lowlevel_stop(int index)
 {
 	return ehci_hcd_stop();
 }
 
-int usb_lowlevel_init(void)
+int usb_lowlevel_init(int index, void **controller)
 {
 	uint32_t reg;
 	uint32_t cmd;
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
index 5ef34c3..19e16a4 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -1391,7 +1391,7 @@ int isp116x_check_id(struct isp116x *isp116x)
 	return 0;
 }
 
-int usb_lowlevel_init(void)
+int usb_lowlevel_init(int index, void **controller))
 {
 	struct isp116x *isp116x = &isp116x_dev;
 
@@ -1428,7 +1428,7 @@ int usb_lowlevel_init(void)
 	return 0;
 }
 
-int usb_lowlevel_stop(void)
+int usb_lowlevel_stop(int index)
 {
 	struct isp116x *isp116x = &isp116x_dev;
 
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 9f47351..c2106ad 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1865,7 +1865,7 @@ static void hc_release_ohci(ohci_t *ohci)
  */
 static char ohci_inited = 0;
 
-int usb_lowlevel_init(void)
+int usb_lowlevel_init(int index, void **controller)
 {
 #ifdef CONFIG_PCI_OHCI
 	pci_dev_t pdev;
@@ -1971,7 +1971,7 @@ int usb_lowlevel_init(void)
 	return 0;
 }
 
-int usb_lowlevel_stop(void)
+int usb_lowlevel_stop(int index)
 {
 	/* this gets called really early - before the controller has */
 	/* even been initialized! */
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index ab1b8d0..2a4e7ff 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -908,7 +908,7 @@ int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 	return 0;
 }
 
-int usb_lowlevel_init(void)
+int usb_lowlevel_init(int index, void **controller))
 {
 	struct r8a66597 *r8a66597 = &gr8a66597;
 
@@ -931,7 +931,7 @@ int usb_lowlevel_init(void)
 	return 0;
 }
 
-int usb_lowlevel_stop(void)
+int usb_lowlevel_stop(int index)
 {
 	disable_controller(&gr8a66597);
 
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
index bb27dd5..2830616 100644
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -210,14 +210,14 @@ static int sl811_hc_reset(void)
 	return 1;
 }
 
-int usb_lowlevel_init(void)
+int usb_lowlevel_init(int index, void **controller)
 {
 	root_hub_devnum = 0;
 	sl811_hc_reset();
 	return 0;
 }
 
-int usb_lowlevel_stop(void)
+int usb_lowlevel_stop(int index)
 {
 	sl811_hc_reset();
 	return 0;
diff --git a/drivers/usb/musb/musb_hcd.c b/drivers/usb/musb/musb_hcd.c
index 8d44c46..06be38d 100644
--- a/drivers/usb/musb/musb_hcd.c
+++ b/drivers/usb/musb/musb_hcd.c
@@ -1092,7 +1092,7 @@ int submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
 /*
  * This function initializes the usb controller module.
  */
-int usb_lowlevel_init(void)
+int usb_lowlevel_init(int index, void **controller)
 {
 	u8  power;
 	u32 timeout;
@@ -1144,7 +1144,7 @@ int usb_lowlevel_init(void)
 /*
  * This function stops the operation of the davinci usb module.
  */
-int usb_lowlevel_stop(void)
+int usb_lowlevel_stop(int index)
 {
 	/* Reset the USB module */
 	musb_platform_deinit();
diff --git a/include/usb.h b/include/usb.h
index ba3d169..292a042 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -140,6 +140,8 @@ struct usb_device {
 	int portnr;
 	struct usb_device *parent;
 	struct usb_device *children[USB_MAXCHILDREN];
+
+	void *controller;		/* hardware controller private data */
 };
 
 /**********************************************************************
@@ -153,8 +155,9 @@ struct usb_device {
 	defined(CONFIG_USB_OMAP3) || defined(CONFIG_USB_DA8XX) || \
 	defined(CONFIG_USB_BLACKFIN) || defined(CONFIG_USB_AM35X)
 
-int usb_lowlevel_init(void);
-int usb_lowlevel_stop(void);
+int usb_lowlevel_init(int index, void **controller);
+int usb_lowlevel_stop(int index);
+
 int submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
 			void *buffer, int transfer_len);
 int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
@@ -382,7 +385,8 @@ void usb_hub_reset(void);
 int hub_port_reset(struct usb_device *dev, int port,
 			  unsigned short *portstat);
 
-struct usb_device *usb_alloc_new_device(void);
+struct usb_device *usb_alloc_new_device(void *controller);
+
 int usb_new_device(struct usb_device *dev);
 
 #endif /*_USB_H_ */
diff --git a/include/usb/mv_udc.h b/include/usb/mv_udc.h
index 51d36c3..221e626 100644
--- a/include/usb/mv_udc.h
+++ b/include/usb/mv_udc.h
@@ -147,5 +147,5 @@ struct ept_queue_item {
 #define INFO_BUFFER_ERROR     (1 << 5)
 #define INFO_TX_ERROR         (1 << 3)
 
-extern int usb_lowlevel_init(void);
+extern int usb_lowlevel_init(int index, void **controller);
 #endif /* __MV_UDC_H__ */
-- 
1.7.11.4

^ permalink raw reply related	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2012-09-25 22:14 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-30 16:03 [U-Boot] [PATCH 0/4] USB multi controller Lucas Stach
2012-08-30 16:03 ` [U-Boot] [PATCH 1/4] usb: lowlevel interface change to support multiple controllers Lucas Stach
2012-08-30 21:03   ` Marek Vasut
2012-08-30 16:03 ` [U-Boot] [PATCH 2/4] usb: ehci: rework to take advantage of new lowlevel interface Lucas Stach
2012-08-30 21:09   ` Marek Vasut
2012-08-30 21:51     ` Lucas Stach
2012-08-30 21:55       ` Marek Vasut
2012-08-30 16:03 ` [U-Boot] [PATCH 3/4] tegra20: port to new ehci interface Lucas Stach
2012-08-30 16:03 ` [U-Boot] [PATCH 4/4] usb: add support for multiple usb controllers Lucas Stach
2012-08-30 21:12   ` Marek Vasut
2012-09-04 23:05 ` [U-Boot] [PATCH 0/4] USB multi controller Stephen Warren
2012-09-05  0:30   ` Marek Vasut
2012-09-05  6:21   ` Lucas Stach
2012-09-05  6:30     ` Marek Vasut
2012-09-05 19:11       ` Stephen Warren
2012-09-05 19:27         ` Marek Vasut
2012-09-05 22:13           ` Lucas Stach
2012-09-25 22:14 Lucas Stach
2012-09-25 22:14 ` [U-Boot] [PATCH 1/4] usb: lowlevel interface change to support multiple controllers Lucas Stach

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.