/* 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_ */
 
 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_init(int index, 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_ */
 
 #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 */
 
 }
 
 #if defined(CONFIG_USB_OHCI_NEW) && defined(CONFIG_SYS_USB_OHCI_BOARD_INIT)
-int usb_board_init(void)
+int board_usb_init(int index, enum board_usb_init_type init)
 {
        struct board_bcsr *bcsr_data =
                (struct board_bcsr *)CONFIG_SYS_BCSR_BASE;
        return 0;
 }
 
-int usb_board_init_fail(void)
+int board_usb_cleanup(int index, enum board_usb_init_type init)
 {
        return usb_board_stop();
 }
 
 #include <asm/io.h>
 #include <spartan3.h>
 #include <command.h>
+#include <usb.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
 }
 
 #ifdef CONFIG_CMD_USB
-int usb_board_init(void)
+int board_usb_init(int index, enum board_usb_init_type init)
 {
        writel((readl(UHCHR) | UHCHR_PCPL | UHCHR_PSPL) &
                ~(UHCHR_SSEP0 | UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE),
        return 0;
 }
 
-void usb_board_init_fail(void)
+int board_usb_cleanup(int index, enum board_usb_init_type init)
 {
-       return;
+       return 0;
 }
 
 void usb_board_stop(void)
 
        twl4030_i2c_write_u8(TWL4030_CHIP_GPIO, offset, 0xC0);
        udelay(1);
 
-       return omap_ehci_hcd_init(&usbhs_bdata, hccr, hcor);
+       return omap_ehci_hcd_init(index, &usbhs_bdata, hccr, hcor);
 }
 
 int ehci_hcd_stop(void)
 
 #include <mtd/cfi_flash.h>
 #include <asm/4xx_pci.h>
 #include <pci.h>
+#include <usb.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
 }
 
 #if defined(CONFIG_USB_OHCI_NEW) && defined(CONFIG_SYS_USB_OHCI_BOARD_INIT)
-int usb_board_init(void)
+int board_usb_init(int index, enum board_usb_init_type init)
 {
        return 0;
 }
        return 0;
 }
 
-int usb_board_init_fail(void)
+int board_usb_cleanup(int index, enum board_usb_init_type init)
 {
-       usb_board_stop();
-       return 0;
+       return usb_board_stop();
 }
 #endif /* defined(CONFIG_USB_OHCI) && defined(CONFIG_SYS_USB_OHCI_BOARD_INIT) */
 
 #endif
 #include <serial.h>
 #include <asm/4xx_pci.h>
+#include <usb.h>
 
 #include "fpga.h"
 #include "pmc440.h"
 }
 
 #if defined(CONFIG_USB_OHCI_NEW) && defined(CONFIG_SYS_USB_OHCI_BOARD_INIT)
-int usb_board_init(void)
+int board_usb_init(int index, enum board_usb_init_type init)
 {
        char *act = getenv("usbact");
        int i;
        return 0;
 }
 
-int usb_board_init_fail(void)
+int board_usb_cleanup(int index, enum board_usb_init_type init)
 {
-       usb_board_stop();
-       return 0;
+       return usb_board_stop();
 }
 #endif /* defined(CONFIG_USB_OHCI) && defined(CONFIG_SYS_USB_OHCI_BOARD_INIT) */
 
 
 
 int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 {
-       return omap_ehci_hcd_init(&usbhs_bdata, hccr, hcor);
+       return omap_ehci_hcd_init(index, &usbhs_bdata, hccr, hcor);
 }
 
 int ehci_hcd_stop(int index)
 
 #include <netdev.h>
 #include <serial.h>
 #include <asm/io.h>
+#include <usb.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
 #endif
 
 #ifdef CONFIG_CMD_USB
-int usb_board_init(void)
+int board_usb_init(int index, enum board_usb_init_type init)
 {
        writel((UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
                ~(UHCHR_SSEP0 | UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE),
        return 0;
 }
 
-void usb_board_init_fail(void)
+int board_usb_cleanup(int index, enum board_usb_init_type init)
 {
-       return;
+       return 0;
 }
 
 void usb_board_stop(void)
 
 #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>
 
 #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
 
 #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"
        .usb_flags      = PHY0_SLEEP,
 };
 
-void board_usb_init(void)
+int board_usb_init(int index, 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
 
 
 
 int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 {
-       return omap_ehci_hcd_init(&usbhs_bdata, hccr, hcor);
+       return omap_ehci_hcd_init(index, &usbhs_bdata, hccr, hcor);
 }
 
 int ehci_hcd_stop(int index)
 
 
 int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 {
-       return omap_ehci_hcd_init(&usbhs_bdata, hccr, hcor);
+       return omap_ehci_hcd_init(index, &usbhs_bdata, hccr, hcor);
 }
 
 int ehci_hcd_stop(int index)
 
 
 int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 {
-       return omap_ehci_hcd_init(&usbhs_bdata, hccr, hcor);
+       return omap_ehci_hcd_init(index, &usbhs_bdata, hccr, hcor);
 }
 
 int ehci_hcd_stop(int index)
 
                eth_setenv_enetaddr("usbethaddr", device_mac);
        }
 
-       ret = omap_ehci_hcd_init(&usbhs_bdata, hccr, hcor);
+       ret = omap_ehci_hcd_init(index, &usbhs_bdata, hccr, hcor);
        if (ret < 0) {
                puts("Failed to initialize ehci\n");
                return ret;
 
        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, hccr, hcor);
+       ret = omap_ehci_hcd_init(index, &usbhs_bdata, hccr, hcor);
        if (ret < 0)
                return ret;
 
 
 #include <netdev.h>
 #include <asm/io.h>
 #include <serial.h>
+#include <usb.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
 }
 
 #ifdef CONFIG_CMD_USB
-int usb_board_init(void)
+int board_usb_init(int index, enum board_usb_init_type init)
 {
        writel((readl(UHCHR) | UHCHR_PCPL | UHCHR_PSPL) &
                ~(UHCHR_SSEP0 | UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE),
        return 0;
 }
 
-void usb_board_init_fail(void)
+int board_usb_cleanup(int index, enum board_usb_init_type init)
 {
-       return;
+       return 0;
 }
 
 void usb_board_stop(void)
 
 #include <asm/arch/regs-mmc.h>
 #include <netdev.h>
 #include <asm/io.h>
+#include <usb.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
  * Miscelaneous platform dependent initialisations
  */
 
-int usb_board_init(void)
+int board_usb_init(int index, enum board_usb_init_type init)
 {
        writel((readl(UHCHR) | UHCHR_PCPL | UHCHR_PSPL) &
                ~(UHCHR_SSEP0 | UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE),
        return 0;
 }
 
-void usb_board_init_fail(void)
+int board_usb_cleanup(int index, enum board_usb_init_type init)
 {
-       return;
+       return 0;
 }
 
 void usb_board_stop(void)
 
 #include <netdev.h>
 #include <serial.h>
 #include <asm/io.h>
+#include <usb.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
 #endif
 
 #ifdef CONFIG_CMD_USB
-int usb_board_init(void)
+int board_usb_init(int index, enum board_usb_init_type init)
 {
        writel((UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
                ~(UHCHR_SSEP0 | UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE),
        return 0;
 }
 
-void usb_board_init_fail(void)
+int board_usb_cleanup(int index, enum board_usb_init_type init)
 {
-       return;
+       return 0;
 }
 
 void usb_board_stop(void)
 
 #include <common.h>
 #include <dfu.h>
 #include <g_dnl.h>
+#include <usb.h>
 
 static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
+       if (argc < 4)
+               return CMD_RET_USAGE;
+
+       char *usb_controller = argv[1];
+       char *interface = argv[2];
+       char *devstring = argv[3];
+
        char *s = "dfu";
        int ret, i = 0;
 
-       if (argc < 3)
-               return CMD_RET_USAGE;
-
-       ret = dfu_init_env_entities(argv[1], simple_strtoul(argv[2], NULL, 10));
+       ret = dfu_init_env_entities(interface, simple_strtoul(devstring,
+                                                             NULL, 10));
        if (ret)
                return ret;
 
-       if (argc > 3 && strcmp(argv[3], "list") == 0) {
+       if (argc > 4 && strcmp(argv[4], "list") == 0) {
                dfu_show_entities();
                goto done;
        }
 
-#ifdef CONFIG_TRATS
-       board_usb_init();
-#endif
+       int controller_index = simple_strtoul(usb_controller, NULL, 0);
+       board_usb_init(controller_index, USB_INIT_DEVICE);
 
        g_dnl_register(s);
        while (1) {
 
 U_BOOT_CMD(dfu, CONFIG_SYS_MAXARGS, 1, do_dfu,
        "Device Firmware Upgrade",
-       "<interface> <dev> [list]\n"
-       "  - device firmware upgrade on a device <dev>\n"
-       "    attached to interface <interface>\n"
-       "    [list] - list available alt settings"
+       "<USB_controller> <interface> <dev> [list]\n"
+       "  - device firmware upgrade via <USB_controller>\n"
+       "    on device <dev>, attached to interface\n"
+       "    <interface>\n"
+       "    [list] - list available alt settings\n"
 );
 
 #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,
                               int argc, char * const argv[])
 {
-       char *ep;
-       unsigned int dev_num = 0, offset = 0, part_size = 0;
-       int rc;
+       if (argc < 3)
+               return CMD_RET_USAGE;
 
-       struct ums_board_info *ums_info;
-       static char *s = "ums";
-
-       if (argc < 2) {
-               printf("usage: ums <dev> - e.g. ums 0\n");
-               return 0;
-       }
-
-       dev_num = (int)simple_strtoul(argv[1], &ep, 16);
+       const char *usb_controller = argv[1];
+       const char *mmc_devstring  = argv[2];
 
+       unsigned int dev_num = (unsigned int)(simple_strtoul(mmc_devstring,
+                               NULL, 0));
        if (dev_num) {
-               puts("\nSet eMMC device to 0! - e.g. ums 0\n");
+               error("Set eMMC device to 0! - e.g. ums 0");
                goto fail;
        }
 
-       board_usb_init();
-       ums_info = board_ums_init(dev_num, offset, part_size);
+       unsigned int controller_index = (unsigned int)(simple_strtoul(
+                                       usb_controller, NULL, 0));
+       if (board_usb_init(controller_index, USB_INIT_DEVICE)) {
+               error("Couldn't init USB controller.");
+               goto fail;
+       }
 
+       struct ums_board_info *ums_info = board_ums_init(dev_num, 0, 0);
        if (!ums_info) {
-               printf("MMC: %d -> NOT available\n", dev_num);
+               error("MMC: %d -> NOT available", dev_num);
                goto fail;
        }
-       rc = fsg_init(ums_info);
+
+       int rc = fsg_init(ums_info);
        if (rc) {
-               printf("cmd ums: fsg_init failed\n");
+               error("fsg_init failed");
                goto fail;
        }
 
-       g_dnl_register(s);
+       g_dnl_register("ums");
 
        while (1) {
                /* Handle control-c and timeouts */
                if (ctrlc()) {
-                       printf("The remote end did not respond in time.\n");
+                       error("The remote end did not respond in time.");
                        goto exit;
                }
+
                usb_gadget_handle_interrupts();
                /* Check if USB cable has been detached */
                if (fsg_main_thread(NULL) == EIO)
 
 U_BOOT_CMD(ums, CONFIG_SYS_MAXARGS, 1, do_usb_mass_storage,
        "Use the UMS [User Mass Storage]",
-       "ums - User Mass Storage Gadget"
+       "<USB_controller> <mmc_dev>"
 );
 
 #include <linux/ctype.h>
 #include <asm/byteorder.h>
 #include <asm/unaligned.h>
+#include <compiler.h>
 
 #include <usb.h>
 #ifdef CONFIG_4xx
        return 0;
 }
 
+__weak
+int board_usb_init(int index, enum board_usb_init_type init)
+{
+       return 0;
+}
 /* EOF */
 
 }
 
 static int dfu_fill_entity(struct dfu_entity *dfu, char *s, int alt,
-                           char *interface, int num)
+                          char *interface, int num)
 {
        char *st;
 
 
 }
 #endif
 
-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) || \
        defined(CONFIG_OMAP_EHCI_PHY3_RESET_GPIO)
  * 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,
-               struct ehci_hccr **hccr, struct ehci_hcor **hcor)
+int omap_ehci_hcd_init(int index, struct omap_usbhs_board_data *usbhs_pdata,
+                      struct ehci_hccr **hccr, struct ehci_hcor **hcor)
 {
        int ret;
        unsigned int i, reg = 0, rev = 0;
 
        debug("Initializing OMAP EHCI\n");
 
-       ret = board_usb_init();
+       ret = board_usb_init(index, USB_INIT_HOST);
        if (ret < 0)
                return ret;
 
 
        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;
 
 
 #ifdef CONFIG_SYS_USB_OHCI_BOARD_INIT
        /*  board dependant init */
-       if (usb_board_init())
+       if (board_usb_init(index, USB_INIT_HOST))
                return -1;
 #endif
        memset(&gohci, 0, sizeof(ohci_t));
                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_cleanup(index, USB_INIT_HOST);
 #endif
 
 #ifdef CONFIG_SYS_USB_OHCI_CPU_INIT
 
 #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 usb_cpu_init(void);
+int usb_cpu_stop(void);
+int usb_cpu_init_fail(void);
 
 static int cc_to_error[16] = {
 
 
 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_ */
 
 
 extern void udc_disconnect(void);
 
-#else
-#error USB Lowlevel not defined
 #endif
 
+/*
+ * You can initialize platform's USB host or device
+ * ports by passing this enum as an argument to
+ * board_usb_init().
+ */
+enum board_usb_init_type {
+       USB_INIT_HOST,
+       USB_INIT_DEVICE
+};
+
+/*
+ * board-specific hardware initialization, called by
+ * usb drivers and u-boot commands
+ *
+ * @param index USB controller number
+ * @param init initializes controller as USB host or device
+ */
+int board_usb_init(int index, enum board_usb_init_type init);
+
+/*
+ * can be used to clean up after failed USB initialization attempt
+ * vide: board_usb_init()
+ *
+ * @param index USB controller number for selective cleanup
+ * @param init board_usb_init_type passed to board_usb_init()
+ */
+int board_usb_cleanup(int index, enum board_usb_init_type init);
+
 #ifdef CONFIG_USB_STORAGE
 
 #define USB_MAX_STOR_DEV 5
 
        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,
-                                            unsigned int, unsigned int);
-extern int usb_gadget_handle_interrupts(void);
-extern int fsg_main_thread(void *);
+int fsg_init(struct ums_board_info *);
+void fsg_cleanup(void);
+struct ums_board_info *board_ums_init(unsigned int, unsigned int,
+                                     unsigned int);
+int fsg_main_thread(void *);
 
 #ifdef CONFIG_USB_GADGET_MASS_STORAGE
 int fsg_add(struct usb_configuration *c);