tegra: seaboard: Initialize multiple USB controllers at once
Subsystems (4)
PATCH 1/1 tegra: seaboard: Initialize multiple USB controllers at once
From: Jim Lin <[email protected]>
Add support for command line "usb reset" or "usb start" to initialize , "usb stop" to stop multiple USB controllers at once. Other commands like "usb tree" also support multiple controllers.
New added definitions in header file are:CONFIG_USB_INIT_MULTICONFIG_USB_MAX_CONTROLLER_COUNT
--- arch/arm/cpu/armv7/tegra2/usb.c | 15 +++ arch/arm/include/asm/arch-tegra2/usb.h | 4 + common/cmd_usb.c | 10 ++ common/usb.c | 108 ++++++++++++++++++ common/usb_hub.c | 4 + drivers/usb/host/ehci-hcd.c | 192 ++++++++++++++++++++++++++++++++ drivers/usb/host/ehci-tegra.c | 17 +++- drivers/usb/host/ehci.h | 5 + include/configs/seaboard.h | 2 + include/usb.h | 12 ++ 10 files changed, 368 insertions(+), 1 deletions(-)
arch/arm/cpu/armv7/tegra2/usb.c +15 -0
@@ -352,7 +352,11 @@ int tegrausb_start_port(unsigned portnum, u32 *hccr, u32 *hcor)if (portnum >= port_count)return -1 ; +#ifdef CONFIG_USB_INIT_MULTI +tegrausb_stop_port (portnum); +#else tegrausb_stop_port (); +#endif set_host_mode (&port[portnum]); usbctlr = port[portnum].reg;
@@ -362,6 +366,16 @@ int tegrausb_start_port(unsigned portnum, u32 *hccr, u32 *hcor)return 0 ; } +#ifdef CONFIG_USB_INIT_MULTI +int tegrausb_stop_port (unsigned portnum) +{ +struct usb_ctlr *usbctlr; + +if (portnum >= port_count) +return -1 ; + + usbctlr = port[portnum].reg; +#else int tegrausb_stop_port (void ) {struct usb_ctlr *usbctlr;
@@ -370,6 +384,7 @@ int tegrausb_stop_port(void)return -1 ; usbctlr = port[port_current].reg; +#endif /* Stop controller */ writel (0 , &usbctlr->usb_cmd);
arch/arm/include/asm/arch-tegra2/usb.h +4 -0
@@ -247,6 +247,10 @@ int tegrausb_start_port(unsigned portnum, u32 *hccr, u32 *hcor);* * @return 0 if ok, -1 if no port was active */ +#ifdef CONFIG_USB_INIT_MULTI +int tegrausb_stop_port (unsigned portnum); +#else int tegrausb_stop_port (void ); +#endif #endif /* _TEGRA_USB_H_ */
common/cmd_usb.c +10 -0
@@ -553,7 +553,17 @@ int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) }if (strncmp (argv[1 ],"tree" ,4 ) ==0 ) {printf ("\nDevice Tree:\n" ); +#ifdef CONFIG_USB_INIT_MULTI +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); + } +#else usb_show_tree (usb_get_dev_index (0 )); +#endif return 0 ; }if (strncmp (argv[1 ],"inf" ,3 ) ==0 ) {
common/usb.c +108 -0
144 lines not on this page · raw message
common/usb_hub.c +4 -0
@@ -243,7 +243,11 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)mdelay (200 );/* Allocate a new device struct for it */ +#ifdef CONFIG_USB_INIT_MULTI + usb =usb_alloc_new_device (dev->controller); +#else usb =usb_alloc_new_device (); +#endif if (portstatus &USB_PORT_STAT_HIGH_SPEED ) usb->speed =USB_SPEED_HIGH ;
drivers/usb/host/ehci-hcd.c +192 -0
347 lines not on this page · raw message
drivers/usb/host/ehci-tegra.c +16 -1
@@ -1,5 +1,5 @@/* -* Copyright (c) 2009 NVIDIA Corporation +* Copyright (c) 2009-2012 NVIDIA Corporation * * See file CREDITS for list of people who contributed to this * project.
@@ -34,6 +34,12 @@* Create the appropriate control structures to manage * a new EHCI host controller. */ +#ifdef CONFIG_USB_INIT_MULTI +int ehci_hcd_init (int index,struct ehci_hccr **hccr,struct ehci_hcor **hcor) +{ +return tegrausb_start_port (index, hccr, hcor); +} +#else int ehci_hcd_init (void ) {u32 our_hccr, our_hcor;
@@ -50,13 +56,22 @@ int ehci_hcd_init(void) return 0; } +#endif /* * Destroy the appropriate control structures corresponding * the the EHCI host controller. */ +#ifdef CONFIG_USB_INIT_MULTI +int ehci_hcd_stop (int index) +{ +tegrausb_stop_port (index); +return 0 ; +} +#else int ehci_hcd_stop (void ) {tegrausb_stop_port ();return 0 ; } +#endif
drivers/usb/host/ehci.h +5 -0
@@ -201,7 +201,12 @@ struct QH { };/* Low level init functions */ +#ifdef CONFIG_USB_INIT_MULTI +int ehci_hcd_init (int index,struct ehci_hccr **hccr,struct ehci_hcor **hcor); +int ehci_hcd_stop (int index); +#else int ehci_hcd_init (void );int ehci_hcd_stop (void ); +#endif #endif /* USB_EHCI_H */
include/configs/seaboard.h +2 -0
@@ -107,6 +107,8 @@#define CONFIG_USB_EHCI_TEGRA #define CONFIG_USB_STORAGE #define CONFIG_CMD_USB +#define CONFIG_USB_INIT_MULTI +#define CONFIG_USB_MAX_CONTROLLER_COUNT 3/* USB networking support */ #define CONFIG_USB_HOST_ETHER
include/usb.h +12 -0
@@ -128,6 +128,9 @@ struct usb_device {int portnr;struct usb_device *parent;struct usb_device *children[USB_MAXCHILDREN ]; +#ifdef CONFIG_USB_INIT_MULTI +void *controller;/* hardware controller private data */ +#endif };/**********************************************************************
@@ -141,8 +144,13 @@ struct usb_device {defined (CONFIG_USB_OMAP3 ) ||defined (CONFIG_USB_DA8XX ) || \ defined(CONFIG_USB_BLACKFIN) || defined(CONFIG_USB_AM35X) +#ifdef CONFIG_USB_INIT_MULTI +void *usb_lowlevel_init (int index); +int usb_lowlevel_stop (int index); +#else int usb_lowlevel_init (void );int usb_lowlevel_stop (void ); +#endif 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,
@@ -370,7 +378,11 @@ void usb_hub_reset(void);int hub_port_reset (struct usb_device *dev,int port,unsigned short *portstat); +#ifdef CONFIG_USB_INIT_MULTI +struct usb_device *usb_alloc_new_device (void *controller); +#else struct usb_device *usb_alloc_new_device (void ); +#endif int usb_new_device (struct usb_device *dev);#endif /*_USB_H_ */
--
1.7.3
nvpublic
PATCH 1/1 tegra: seaboard: Initialize multiple USB controllers at once
Quoted 3 lines · Jim Lin
Add support for command line "usb reset" or "usb start" to initialize , "usb stop" to stop multiple USB controllers at once. Other commands like "usb tree" also support multiple controllers.
These patches also need to be sent to the USB maintainer since they touch core USB code. (Now CC'd)
Rather than one mega-patch that touch the USB core, and the Tegra driver, can't the patch be split up a bit so that one patch adds the ability to support multiple controllers, and then another patch modifies the Tegra USB driver to support this, etc. Many smaller patches are much easier to review.
This patch adds a huge number of ifdefs. I'm sure many of them can be removed completely. For example, in the following code, why not /always/ get the rootdev from dev->controller->rootdev, and remove the global variable. I would guess that the code size increase would be extremely minimal, but it would make the code a lot more maintainable by removing all the ifdefs.
Quoted 12 lines
submit_control_msg(struct
usb_device*dev, unsigned long pipe, void *buffer,
int length, struct devrequest *setup)
{drivers/usb/host/ehci-hcd.c +3
-0+#ifdef CONFIG_USB_INIT_MULTI +struct ehci_ctrl *ctrl = dev->controller; +#endif if (usb_pipetype (pipe) !=PIPE_CONTROL ) {debug ("non-control pipe (type=%lu)" ,usb_pipetype (pipe));return -1 ; }
drivers/usb/host/ehci-hcd.c int · line 1094
Quoted 10 lines
drivers/usb/host/ehci-hcd.c +5
-0+#ifdef CONFIG_USB_INIT_MULTI +if (usb_pipedevice (pipe) == ctrl->rootdev) { +if (ctrl->rootdev ==0 ) +#elseif (usb_pipedevice (pipe) == rootdev) {if (rootdev ==0 ) +#endif dev->speed =USB_SPEED_HIGH ;return ehci_submit_root (dev, pipe, buffer, length, setup); }
The patch above removes the use of the global variable "rootdev", but I don't see anywhere that ifdef's that variable out of existence. Not doing so would allow code to accidentally use the global when it should be using the per-device value; how can you be sure you've patched all the places in the code that you need to? What about future changes to the code by people who aren't aware of the USB_INIT_MULTI feature?
Similarly, why not just outright change the prototype of tegrausb_stop_port() so that it always takes a port number; the existing calls can hard-code a port ID of 0 for compatibility:
Quoted 12 lines
drivers/usb/host/ehci-tegra.c +7
-0+#ifdef CONFIG_USB_INIT_MULTI +int ehci_hcd_stop (int index) +{ +tegrausb_stop_port (index); +return 0 ; +} +#else int ehci_hcd_stop (void ) {tegrausb_stop_port ();return 0 ; }
Quoted 1 line
Quoted 1 line
+#endif
In the end, I think if you rework the patch to remove all/most of the ifdefs, the only thing that's left will be that the loop to initialize USB would loop over either just device 0 or devices 0..n-1, and even that wouldn't need to be ifdef'd...
PATCH 1/1 tegra: seaboard: Initialize multiple USB controllers at once
Dear Stephen Warren,
Quoted 7 lines · Jim Lin
Quoted 3 lines
Add support for command line "usb reset" or "usb start" to initialize , "usb stop" to stop multiple USB controllers at once. Other commands like "usb tree" also support multiple controllers.
These patches also need to be sent to the USB maintainer since they touch core USB code. (Now CC'd)
Ok, waiting for smaller patches indeed,
Best regards,
Marek Vasut