[U-Boot] [PATCH 0/4] USB multi controller

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

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__ */

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

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 */

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

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

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

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); }

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 at 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 */

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 */

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:-(

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

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

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

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?

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

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
participants (4)
-
Lucas Stach
-
Marek Vasut
-
Marek Vasut
-
Stephen Warren