Patchwork [U-Boot] usb: new board-specific USB init interface

login
register
mail settings
Submitter Mateusz Zalega
Date Aug. 20, 2013, 1:35 p.m.
Message ID <1377005736-21017-1-git-send-email-m.zalega@samsung.com>
Download mbox | patch
Permalink /patch/268522/
State Superseded
Delegated to: Marek Vasut
Headers show

Comments

Mateusz Zalega - Aug. 20, 2013, 1:35 p.m.
This commit unifies board-specific USB initialization implementations
under one symbol (usb_board_init), declaration of which is available in
usb.h.

---
Changes since RFC:
- NVIDIA Tegra doesn't postpone its USB init anymore
- board_usb_init()'s sole argument name was shortened
- networking code comment style (/* blurb...) dropped
- squashed RFC changes so that patch won't break bisect

Signed-off-by: Mateusz Zalega <m.zalega@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Reviewed-by: Lukasz Majewski <l.majewski@samsung.com>
Cc: Minkyu Kang <mk7.kang@samsung.com>
Cc: Marek Vasut <marex@denx.de>
Cc: Tom Warren <twarren@nvidia.com>
Cc: Albert Aribaud <albert.u.boot@aribaud.net>
---
 arch/arm/include/asm/arch-tegra/usb.h         |  3 +--
 board/amcc/canyonlands/canyonlands.c          |  5 +++--
 board/balloon3/balloon3.c                     |  5 +++--
 board/esd/apc405/apc405.c                     |  5 +++--
 board/esd/pmc440/pmc440.c                     |  5 +++--
 board/icpdas/lp8x4x/lp8x4x.c                  |  5 +++--
 board/nvidia/common/board.c                   |  4 +++-
 board/samsung/trats/trats.c                   |  5 +++--
 board/toradex/colibri_pxa270/colibri_pxa270.c |  5 +++--
 board/trizepsiv/conxs.c                       |  5 +++--
 board/vpac270/vpac270.c                       |  5 +++--
 common/cmd_dfu.c                              |  5 ++---
 common/cmd_usb_mass_storage.c                 |  3 ++-
 common/usb.c                                  |  5 +++++
 drivers/usb/host/ehci-omap.c                  |  8 +-------
 drivers/usb/host/ehci-tegra.c                 |  2 +-
 drivers/usb/host/ohci-hcd.c                   |  4 ++--
 drivers/usb/host/ohci.h                       | 12 +++++-------
 include/g_dnl.h                               |  2 --
 include/usb.h                                 | 19 ++++++++++++++++++-
 include/usb_mass_storage.h                    | 12 +++++-------
 21 files changed, 72 insertions(+), 52 deletions(-)
Marek Vasut - Aug. 21, 2013, 3:33 a.m.
Dear Mateusz Zalega,

> This commit unifies board-specific USB initialization implementations
> under one symbol (usb_board_init), declaration of which is available in
> usb.h.
> 
> ---
> Changes since RFC:
> - NVIDIA Tegra doesn't postpone its USB init anymore
> - board_usb_init()'s sole argument name was shortened
> - networking code comment style (/* blurb...) dropped
> - squashed RFC changes so that patch won't break bisect
> 
> Signed-off-by: Mateusz Zalega <m.zalega@samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> Reviewed-by: Lukasz Majewski <l.majewski@samsung.com>
> Cc: Minkyu Kang <mk7.kang@samsung.com>
> Cc: Marek Vasut <marex@denx.de>
> Cc: Tom Warren <twarren@nvidia.com>
> Cc: Albert Aribaud <albert.u.boot@aribaud.net>
> ---
>  arch/arm/include/asm/arch-tegra/usb.h         |  3 +--
>  board/amcc/canyonlands/canyonlands.c          |  5 +++--
>  board/balloon3/balloon3.c                     |  5 +++--
>  board/esd/apc405/apc405.c                     |  5 +++--
>  board/esd/pmc440/pmc440.c                     |  5 +++--
>  board/icpdas/lp8x4x/lp8x4x.c                  |  5 +++--
>  board/nvidia/common/board.c                   |  4 +++-
>  board/samsung/trats/trats.c                   |  5 +++--
>  board/toradex/colibri_pxa270/colibri_pxa270.c |  5 +++--
>  board/trizepsiv/conxs.c                       |  5 +++--
>  board/vpac270/vpac270.c                       |  5 +++--
>  common/cmd_dfu.c                              |  5 ++---
>  common/cmd_usb_mass_storage.c                 |  3 ++-
>  common/usb.c                                  |  5 +++++
>  drivers/usb/host/ehci-omap.c                  |  8 +-------
>  drivers/usb/host/ehci-tegra.c                 |  2 +-
>  drivers/usb/host/ohci-hcd.c                   |  4 ++--
>  drivers/usb/host/ohci.h                       | 12 +++++-------
>  include/g_dnl.h                               |  2 --
>  include/usb.h                                 | 19 ++++++++++++++++++-
>  include/usb_mass_storage.h                    | 12 +++++-------
>  21 files changed, 72 insertions(+), 52 deletions(-)

The EHCI supports multi-bus thing (passing the controller *), will this be 
viable to pass in this case too, so the busses can be inited selectively in 
host/gadget functions?

Best regards,
Marek Vasut
Mateusz Zalega - Aug. 21, 2013, 10:22 a.m.
On 08/21/13 05:33, Marek Vasut wrote:
> The EHCI supports multi-bus thing (passing the controller *), will this be 
> viable to pass in this case too, so the busses can be inited selectively in 
> host/gadget functions?

Hello, Marek.
I need more context. Could you show me the part of code in which you'd
like to pass/use additional arguments?

Regards,
Marek Vasut - Aug. 21, 2013, 1:08 p.m.
Dear Mateusz Zalega,

> On 08/21/13 05:33, Marek Vasut wrote:
> > The EHCI supports multi-bus thing (passing the controller *), will this
> > be viable to pass in this case too, so the busses can be inited
> > selectively in host/gadget functions?
> 
> Hello, Marek.
> I need more context. Could you show me the part of code in which you'd
> like to pass/use additional arguments?

Please grep the 'controller' pointer that is passed to various functions at 
least in the EHCI case. It would be nice to pass that to the init functions too, 
no?

Best regards,
Marek Vasut
Mateusz Zalega - Aug. 22, 2013, 10:32 a.m.
>>> The EHCI supports multi-bus thing (passing the controller *), will this
>>> be viable to pass in this case too, so the busses can be inited
>>> selectively in host/gadget functions?
>>
>> Hello, Marek.
>> I need more context. Could you show me the part of code in which you'd
>> like to pass/use additional arguments?
> 
> Please grep the 'controller' pointer that is passed to various functions at 
> least in the EHCI case. It would be nice to pass that to the init functions too, 
> no?

It may be possible, but note that board_usb_init() is not used solely by
EHCI code (please grep or cscope function calls). In order to do that,
we would need to devise some generic interface.

Is it worth the time? Are there targets that would benefit from this change?
Marek Vasut - Aug. 22, 2013, 7:37 p.m.
Dear Mateusz Zalega,

> >>> The EHCI supports multi-bus thing (passing the controller *), will this
> >>> be viable to pass in this case too, so the busses can be inited
> >>> selectively in host/gadget functions?
> >> 
> >> Hello, Marek.
> >> I need more context. Could you show me the part of code in which you'd
> >> like to pass/use additional arguments?
> > 
> > Please grep the 'controller' pointer that is passed to various functions
> > at least in the EHCI case. It would be nice to pass that to the init
> > functions too, no?
> 
> It may be possible, but note that board_usb_init() is not used solely by
> EHCI code (please grep or cscope function calls). In order to do that,
> we would need to devise some generic interface.
> 
> Is it worth the time? Are there targets that would benefit from this
> change?

In case you want to separatelly init one port for USB peripheral mode and one 
for Host mode, yes.

Best regards,
Marek Vasut
Mateusz Zalega - Aug. 26, 2013, 10:41 a.m.
On 08/22/13 21:37, Marek Vasut wrote:
> Dear Mateusz Zalega,
> 
>>>>> The EHCI supports multi-bus thing (passing the controller *), will this
>>>>> be viable to pass in this case too, so the busses can be inited
>>>>> selectively in host/gadget functions?
>>>>
>>>> Hello, Marek.
>>>> I need more context. Could you show me the part of code in which you'd
>>>> like to pass/use additional arguments?
>>>
>>> Please grep the 'controller' pointer that is passed to various functions
>>> at least in the EHCI case. It would be nice to pass that to the init
>>> functions too, no?
>>
>> It may be possible, but note that board_usb_init() is not used solely by
>> EHCI code (please grep or cscope function calls). In order to do that,
>> we would need to devise some generic interface.
>>
>> Is it worth the time? Are there targets that would benefit from this
>> change?
> 
> In case you want to separatelly init one port for USB peripheral mode and one 
> for Host mode, yes.

We could add another argument: "int controller_index" (or maybe "const
char* controller_id"), which would correspond to node names or aliases
defined in devicetree source files (ie. see: tegra30.dtsi). List of
available controllers would be accesible via ie. "usb list" command.
Implementations of board_usb_init() would lookup applicable hardware in
gd_t.

We would need to find a way to differentiate between these controllers
in cases when it would be expected from u-boot to automatically
initialize devices it needs. It looks easy in case of ehci-tegra.c.

Devicetree-agnostic boards would have their own "usb list"
implementation, and those of them that can't initialize their
controllers selectively would be left the way they are with just one
additional, unused board_usb_init() argument.
Marek Vasut - Aug. 27, 2013, 7:50 p.m.
Dear Mateusz Zalega,

> On 08/22/13 21:37, Marek Vasut wrote:
> > Dear Mateusz Zalega,
> > 
> >>>>> The EHCI supports multi-bus thing (passing the controller *), will
> >>>>> this be viable to pass in this case too, so the busses can be inited
> >>>>> selectively in host/gadget functions?
> >>>> 
> >>>> Hello, Marek.
> >>>> I need more context. Could you show me the part of code in which you'd
> >>>> like to pass/use additional arguments?
> >>> 
> >>> Please grep the 'controller' pointer that is passed to various
> >>> functions at least in the EHCI case. It would be nice to pass that to
> >>> the init functions too, no?
> >> 
> >> It may be possible, but note that board_usb_init() is not used solely by
> >> EHCI code (please grep or cscope function calls). In order to do that,
> >> we would need to devise some generic interface.
> >> 
> >> Is it worth the time? Are there targets that would benefit from this
> >> change?
> > 
> > In case you want to separatelly init one port for USB peripheral mode and
> > one for Host mode, yes.
> 
> We could add another argument: "int controller_index" (or maybe "const
> char* controller_id"), which would correspond to node names or aliases
> defined in devicetree source files (ie. see: tegra30.dtsi).

Device tree is completely ortogonal to this. See how "int usb_lowlevel_init(int 
index, void **controller)" is declared. Pass something similar, index at least. 
Also pass the mode in which the controller should operate.

> List of
> available controllers would be accesible via ie. "usb list" command.
> Implementations of board_usb_init() would lookup applicable hardware in
> gd_t.

DT is not present on all platforms, so you _MUST_ handle the non-DT case too.

> We would need to find a way to differentiate between these controllers
> in cases when it would be expected from u-boot to automatically
> initialize devices it needs. It looks easy in case of ehci-tegra.c.
> 
> Devicetree-agnostic boards would have their own "usb list"
> implementation, and those of them that can't initialize their
> controllers selectively would be left the way they are with just one
> additional, unused board_usb_init() argument.

Best regards,
Marek Vasut

Patch

diff --git a/arch/arm/include/asm/arch-tegra/usb.h b/arch/arm/include/asm/arch-tegra/usb.h
index f66257c..a1efd07 100644
--- a/arch/arm/include/asm/arch-tegra/usb.h
+++ b/arch/arm/include/asm/arch-tegra/usb.h
@@ -131,8 +131,7 @@ 
 /* USB3_IF_USB_PHY_VBUS_SENSORS_0 */
 #define VBUS_VLD_STS			(1 << 26)
 
-
 /* Setup USB on the board */
-int board_usb_init(const void *blob);
+int usb_process_devicetree(const void *blob);
 
 #endif	/* _TEGRA_USB_H_ */
diff --git a/board/amcc/canyonlands/canyonlands.c b/board/amcc/canyonlands/canyonlands.c
index cc36f45..27ab243 100644
--- a/board/amcc/canyonlands/canyonlands.c
+++ b/board/amcc/canyonlands/canyonlands.c
@@ -16,6 +16,7 @@ 
 #include <asm/4xx_pcie.h>
 #include <asm/ppc4xx-gpio.h>
 #include <asm/errno.h>
+#include <usb.h>
 
 extern flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */
 
@@ -188,7 +189,7 @@  int board_early_init_f(void)
 }
 
 #if defined(CONFIG_USB_OHCI_NEW) && defined(CONFIG_SYS_USB_OHCI_BOARD_INIT)
-int usb_board_init(void)
+int board_usb_init(enum board_usb_init_type init)
 {
 	struct board_bcsr *bcsr_data =
 		(struct board_bcsr *)CONFIG_SYS_BCSR_BASE;
@@ -229,7 +230,7 @@  int usb_board_stop(void)
 	return 0;
 }
 
-int usb_board_init_fail(void)
+int board_usb_init_fail(void)
 {
 	return usb_board_stop();
 }
diff --git a/board/balloon3/balloon3.c b/board/balloon3/balloon3.c
index ecbac16..b15d60f 100644
--- a/board/balloon3/balloon3.c
+++ b/board/balloon3/balloon3.c
@@ -13,6 +13,7 @@ 
 #include <asm/io.h>
 #include <spartan3.h>
 #include <command.h>
+#include <usb.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -59,7 +60,7 @@  void dram_init_banksize(void)
 }
 
 #ifdef	CONFIG_CMD_USB
-int usb_board_init(void)
+int board_usb_init(enum board_usb_init_type init)
 {
 	writel((readl(UHCHR) | UHCHR_PCPL | UHCHR_PSPL) &
 		~(UHCHR_SSEP0 | UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE),
@@ -90,7 +91,7 @@  int usb_board_init(void)
 	return 0;
 }
 
-void usb_board_init_fail(void)
+void board_usb_init_fail(void)
 {
 	return;
 }
diff --git a/board/esd/apc405/apc405.c b/board/esd/apc405/apc405.c
index f13f088..8f0fd1c 100644
--- a/board/esd/apc405/apc405.c
+++ b/board/esd/apc405/apc405.c
@@ -17,6 +17,7 @@ 
 #include <mtd/cfi_flash.h>
 #include <asm/4xx_pci.h>
 #include <pci.h>
+#include <usb.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -428,7 +429,7 @@  void reset_phy(void)
 }
 
 #if defined(CONFIG_USB_OHCI_NEW) && defined(CONFIG_SYS_USB_OHCI_BOARD_INIT)
-int usb_board_init(void)
+int board_usb_init(enum board_usb_init_type init)
 {
 	return 0;
 }
@@ -453,7 +454,7 @@  int usb_board_stop(void)
 	return 0;
 }
 
-int usb_board_init_fail(void)
+int board_usb_init_fail(void)
 {
 	usb_board_stop();
 	return 0;
diff --git a/board/esd/pmc440/pmc440.c b/board/esd/pmc440/pmc440.c
index 549b3b7..6a3b52a 100644
--- a/board/esd/pmc440/pmc440.c
+++ b/board/esd/pmc440/pmc440.c
@@ -27,6 +27,7 @@ 
 #endif
 #include <serial.h>
 #include <asm/4xx_pci.h>
+#include <usb.h>
 
 #include "fpga.h"
 #include "pmc440.h"
@@ -821,7 +822,7 @@  int bootstrap_eeprom_read (unsigned dev_addr, unsigned offset,
 }
 
 #if defined(CONFIG_USB_OHCI_NEW) && defined(CONFIG_SYS_USB_OHCI_BOARD_INIT)
-int usb_board_init(void)
+int board_usb_init(enum board_usb_init_type init)
 {
 	char *act = getenv("usbact");
 	int i;
@@ -845,7 +846,7 @@  int usb_board_stop(void)
 	return 0;
 }
 
-int usb_board_init_fail(void)
+int board_usb_init_fail(void)
 {
 	usb_board_stop();
 	return 0;
diff --git a/board/icpdas/lp8x4x/lp8x4x.c b/board/icpdas/lp8x4x/lp8x4x.c
index 1b68ef3..622ca28 100644
--- a/board/icpdas/lp8x4x/lp8x4x.c
+++ b/board/icpdas/lp8x4x/lp8x4x.c
@@ -15,6 +15,7 @@ 
 #include <netdev.h>
 #include <serial.h>
 #include <asm/io.h>
+#include <usb.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -58,7 +59,7 @@  int board_mmc_init(bd_t *bis)
 #endif
 
 #ifdef	CONFIG_CMD_USB
-int usb_board_init(void)
+int board_usb_init(enum board_usb_init_type init)
 {
 	writel((UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
 		~(UHCHR_SSEP0 | UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE),
@@ -89,7 +90,7 @@  int usb_board_init(void)
 	return 0;
 }
 
-void usb_board_init_fail(void)
+void board_usb_init_fail(void)
 {
 	return;
 }
diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c
index 126e56e..1972527 100644
--- a/board/nvidia/common/board.c
+++ b/board/nvidia/common/board.c
@@ -32,6 +32,7 @@ 
 #ifdef CONFIG_USB_EHCI_TEGRA
 #include <asm/arch-tegra/usb.h>
 #include <asm/arch/usb.h>
+#include <usb.h>
 #endif
 #ifdef CONFIG_TEGRA_MMC
 #include <asm/arch-tegra/tegra_mmc.h>
@@ -153,8 +154,9 @@  int board_init(void)
 
 #ifdef CONFIG_USB_EHCI_TEGRA
 	pin_mux_usb();
-	board_usb_init(gd->fdt_blob);
+	usb_process_devicetree(gd->fdt_blob);
 #endif
+
 #ifdef CONFIG_LCD
 	tegra_lcd_check_next_stage(gd->fdt_blob, 0);
 #endif
diff --git a/board/samsung/trats/trats.c b/board/samsung/trats/trats.c
index c8698f3..d15e1fe 100644
--- a/board/samsung/trats/trats.c
+++ b/board/samsung/trats/trats.c
@@ -26,6 +26,7 @@ 
 #include <power/max8997_muic.h>
 #include <power/battery.h>
 #include <power/max17042_fg.h>
+#include <usb.h>
 #include <usb_mass_storage.h>
 
 #include "setup.h"
@@ -488,10 +489,10 @@  struct s3c_plat_otg_data s5pc210_otg_data = {
 	.usb_flags	= PHY0_SLEEP,
 };
 
-void board_usb_init(void)
+int board_usb_init(enum board_usb_init_type init)
 {
 	debug("USB_udc_probe\n");
-	s3c_udc_probe(&s5pc210_otg_data);
+	return s3c_udc_probe(&s5pc210_otg_data);
 }
 #endif
 
diff --git a/board/toradex/colibri_pxa270/colibri_pxa270.c b/board/toradex/colibri_pxa270/colibri_pxa270.c
index c1e2562..5437290 100644
--- a/board/toradex/colibri_pxa270/colibri_pxa270.c
+++ b/board/toradex/colibri_pxa270/colibri_pxa270.c
@@ -13,6 +13,7 @@ 
 #include <netdev.h>
 #include <asm/io.h>
 #include <serial.h>
+#include <usb.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -39,7 +40,7 @@  int dram_init(void)
 }
 
 #ifdef	CONFIG_CMD_USB
-int usb_board_init(void)
+int board_usb_init(enum board_usb_init_type init)
 {
 	writel((readl(UHCHR) | UHCHR_PCPL | UHCHR_PSPL) &
 		~(UHCHR_SSEP0 | UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE),
@@ -70,7 +71,7 @@  int usb_board_init(void)
 	return 0;
 }
 
-void usb_board_init_fail(void)
+void board_usb_init_fail(void)
 {
 	return;
 }
diff --git a/board/trizepsiv/conxs.c b/board/trizepsiv/conxs.c
index c0c318f..01264b3 100644
--- a/board/trizepsiv/conxs.c
+++ b/board/trizepsiv/conxs.c
@@ -21,6 +21,7 @@ 
 #include <asm/arch/regs-mmc.h>
 #include <netdev.h>
 #include <asm/io.h>
+#include <usb.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -42,7 +43,7 @@  extern struct serial_device serial_stuart_device;
  * Miscelaneous platform dependent initialisations
  */
 
-int usb_board_init(void)
+int board_usb_init(enum board_usb_init_type init)
 {
 	writel((readl(UHCHR) | UHCHR_PCPL | UHCHR_PSPL) &
 		~(UHCHR_SSEP0 | UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE),
@@ -69,7 +70,7 @@  int usb_board_init(void)
 	return 0;
 }
 
-void usb_board_init_fail(void)
+void board_usb_init_fail(void)
 {
 	return;
 }
diff --git a/board/vpac270/vpac270.c b/board/vpac270/vpac270.c
index 616736f..3ec81f3 100644
--- a/board/vpac270/vpac270.c
+++ b/board/vpac270/vpac270.c
@@ -13,6 +13,7 @@ 
 #include <netdev.h>
 #include <serial.h>
 #include <asm/io.h>
+#include <usb.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -66,7 +67,7 @@  int board_mmc_init(bd_t *bis)
 #endif
 
 #ifdef	CONFIG_CMD_USB
-int usb_board_init(void)
+int board_usb_init(enum board_usb_init_type init)
 {
 	writel((UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
 		~(UHCHR_SSEP0 | UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE),
@@ -97,7 +98,7 @@  int usb_board_init(void)
 	return 0;
 }
 
-void usb_board_init_fail(void)
+void board_usb_init_fail(void)
 {
 	return;
 }
diff --git a/common/cmd_dfu.c b/common/cmd_dfu.c
index 793c422..7122423 100644
--- a/common/cmd_dfu.c
+++ b/common/cmd_dfu.c
@@ -14,6 +14,7 @@ 
 #include <dfu.h>
 #include <asm/errno.h>
 #include <g_dnl.h>
+#include <usb.h>
 
 static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
@@ -43,9 +44,7 @@  static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 		goto done;
 	}
 
-#ifdef CONFIG_TRATS
-	board_usb_init();
-#endif
+	board_usb_init(USB_INIT_DEVICE);
 
 	g_dnl_register(s);
 	while (1) {
diff --git a/common/cmd_usb_mass_storage.c b/common/cmd_usb_mass_storage.c
index 33a4715..86135b4 100644
--- a/common/cmd_usb_mass_storage.c
+++ b/common/cmd_usb_mass_storage.c
@@ -9,6 +9,7 @@ 
 #include <common.h>
 #include <command.h>
 #include <g_dnl.h>
+#include <usb.h>
 #include <usb_mass_storage.h>
 
 int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag,
@@ -33,7 +34,7 @@  int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag,
 		goto fail;
 	}
 
-	board_usb_init();
+	board_usb_init(USB_INIT_DEVICE);
 	ums_info = board_ums_init(dev_num, offset, part_size);
 
 	if (!ums_info) {
diff --git a/common/usb.c b/common/usb.c
index f740e5e..307e47a 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -982,4 +982,9 @@  int usb_new_device(struct usb_device *dev)
 	return 0;
 }
 
+__attribute__((weak))
+int board_usb_init(enum board_usb_init_type init)
+{
+	return 0;
+}
 /* EOF */
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index 032d5e5..fd8c4d8 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -89,12 +89,6 @@  static void omap_ehci_soft_phy_reset(int port)
 	ulpi_reset(&ulpi_vp);
 }
 
-inline int __board_usb_init(void)
-{
-	return 0;
-}
-int board_usb_init(void) __attribute__((weak, alias("__board_usb_init")));
-
 #if defined(CONFIG_OMAP_EHCI_PHY1_RESET_GPIO) || \
 	defined(CONFIG_OMAP_EHCI_PHY2_RESET_GPIO)
 /* controls PHY(s) reset signal(s) */
@@ -153,7 +147,7 @@  int omap_ehci_hcd_init(struct omap_usbhs_board_data *usbhs_pdata,
 
 	debug("Initializing OMAP EHCI\n");
 
-	ret = board_usb_init();
+	ret = board_usb_init(USB_INIT_HOST);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index c6da449..cc23133 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -699,7 +699,7 @@  static int process_usb_nodes(const void *blob, int node_list[], int count)
 	return 0;
 }
 
-int board_usb_init(const void *blob)
+int usb_process_devicetree(const void *blob)
 {
 	int node_list[USB_PORTS_MAX];
 	int count, err = 0;
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index c33c487..e6a5623 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1861,7 +1861,7 @@  int usb_lowlevel_init(int index, void **controller)
 
 #ifdef CONFIG_SYS_USB_OHCI_BOARD_INIT
 	/*  board dependant init */
-	if (usb_board_init())
+	if (board_usb_init(USB_INIT_HOST))
 		return -1;
 #endif
 	memset(&gohci, 0, sizeof(ohci_t));
@@ -1918,7 +1918,7 @@  int usb_lowlevel_init(int index, void **controller)
 		err ("can't reset usb-%s", gohci.slot_name);
 #ifdef CONFIG_SYS_USB_OHCI_BOARD_INIT
 		/* board dependant cleanup */
-		usb_board_init_fail();
+		board_usb_init_fail();
 #endif
 
 #ifdef CONFIG_SYS_USB_OHCI_CPU_INIT
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
index d977e8f..9f7f961 100644
--- a/drivers/usb/host/ohci.h
+++ b/drivers/usb/host/ohci.h
@@ -19,14 +19,12 @@ 
 #endif /* CONFIG_SYS_OHCI_SWAP_REG_ACCESS */
 
 /* functions for doing board or CPU specific setup/cleanup */
-extern int usb_board_init(void);
-extern int usb_board_stop(void);
-extern int usb_board_init_fail(void);
-
-extern int usb_cpu_init(void);
-extern int usb_cpu_stop(void);
-extern int usb_cpu_init_fail(void);
+int usb_board_stop(void);
+int board_usb_init_fail(void);
 
+int usb_cpu_init(void);
+int usb_cpu_stop(void);
+int usb_cpu_init_fail(void);
 
 static int cc_to_error[16] = {
 
diff --git a/include/g_dnl.h b/include/g_dnl.h
index 2b2f11a..b6c4dd4 100644
--- a/include/g_dnl.h
+++ b/include/g_dnl.h
@@ -14,6 +14,4 @@  int g_dnl_bind_fixup(struct usb_device_descriptor *);
 int g_dnl_register(const char *s);
 void g_dnl_unregister(void);
 
-/* USB initialization declaration - board specific */
-void board_usb_init(void);
 #endif /* __G_DOWNLOAD_H_ */
diff --git a/include/usb.h b/include/usb.h
index 60db897..2ee867f 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -165,10 +165,27 @@  int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 
 extern void udc_disconnect(void);
 
-#else
+#elif !defined(CONFIG_USB_GADGET)
 #error USB Lowlevel not defined
 #endif
 
+/*
+ * You can initialize platform's USB host, device or both
+ * capabilities by passing this enum as an argument to
+ * board_usb_init().
+ */
+enum board_usb_init_type {
+	USB_INIT_ALL,
+	USB_INIT_HOST,
+	USB_INIT_DEVICE
+};
+
+/*
+ * board-specific hardware initialization, called by
+ * usb drivers and u-boot commands
+ */
+int board_usb_init(enum board_usb_init_type init);
+
 #ifdef CONFIG_USB_STORAGE
 
 #define USB_MAX_STOR_DEV 5
diff --git a/include/usb_mass_storage.h b/include/usb_mass_storage.h
index 35cdcc3..de31b0e 100644
--- a/include/usb_mass_storage.h
+++ b/include/usb_mass_storage.h
@@ -30,13 +30,11 @@  struct ums_board_info {
 	struct ums_device ums_dev;
 };
 
-extern void board_usb_init(void);
-
-extern int fsg_init(struct ums_board_info *);
-extern void fsg_cleanup(void);
-extern struct ums_board_info *board_ums_init(unsigned int,
+int fsg_init(struct ums_board_info *);
+void fsg_cleanup(void);
+struct ums_board_info *board_ums_init(unsigned int,
 					     unsigned int, unsigned int);
-extern int usb_gadget_handle_interrupts(void);
-extern int fsg_main_thread(void *);
+int usb_gadget_handle_interrupts(void);
+int fsg_main_thread(void *);
 
 #endif /* __USB_MASS_STORAGE_H__ */