Merge branch 'master' of git://git.denx.de/u-boot-mmc
diff --git a/arch/arm/cpu/armv7/am33xx/board.c b/arch/arm/cpu/armv7/am33xx/board.c
index eaf09d1..81477aa 100644
--- a/arch/arm/cpu/armv7/am33xx/board.c
+++ b/arch/arm/cpu/armv7/am33xx/board.c
@@ -285,14 +285,6 @@
#ifdef CONFIG_NOR_BOOT
enable_norboot_pin_mux();
#endif
- /*
- * Save the boot parameters passed from romcode.
- * We cannot delay the saving further than this,
- * to prevent overwrites.
- */
-#ifdef CONFIG_SPL_BUILD
- save_omap_boot_params();
-#endif
watchdog_disable();
set_uart_mux_conf();
setup_clocks_for_console();
@@ -301,9 +293,6 @@
gd->baudrate = CONFIG_BAUDRATE;
serial_init();
gd->have_console = 1;
-#elif defined(CONFIG_SPL_BUILD)
- gd = &gdata;
- preloader_console_init();
#endif
#if defined(CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC)
/* Enable RTC32K clock */
diff --git a/arch/arm/cpu/armv7/omap-common/boot-common.c b/arch/arm/cpu/armv7/omap-common/boot-common.c
index 00a1082..17500f2 100644
--- a/arch/arm/cpu/armv7/omap-common/boot-common.c
+++ b/arch/arm/cpu/armv7/omap-common/boot-common.c
@@ -106,6 +106,16 @@
void spl_board_init(void)
{
+ /*
+ * Save the boot parameters passed from romcode.
+ * We cannot delay the saving further than this,
+ * to prevent overwrites.
+ */
+ save_omap_boot_params();
+
+ /* Prepare console output */
+ preloader_console_init();
+
#ifdef CONFIG_SPL_NAND_SUPPORT
gpmc_init();
#endif
diff --git a/arch/arm/cpu/armv7/omap-common/hwinit-common.c b/arch/arm/cpu/armv7/omap-common/hwinit-common.c
index dd52e93..cb35c19 100644
--- a/arch/arm/cpu/armv7/omap-common/hwinit-common.c
+++ b/arch/arm/cpu/armv7/omap-common/hwinit-common.c
@@ -111,14 +111,6 @@
*/
void s_init(void)
{
- /*
- * Save the boot parameters passed from romcode.
- * We cannot delay the saving further than this,
- * to prevent overwrites.
- */
-#ifdef CONFIG_SPL_BUILD
- save_omap_boot_params();
-#endif
init_omap_revision();
hw_data_init();
@@ -133,9 +125,6 @@
srcomp_enable();
setup_clocks_for_console();
- gd = &gdata;
-
- preloader_console_init();
do_io_settings();
#endif
prcm_init();
diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c
index 53a9e5d..90d6ae7 100644
--- a/arch/arm/cpu/armv7/omap3/board.c
+++ b/arch/arm/cpu/armv7/omap3/board.c
@@ -119,6 +119,7 @@
void spl_board_init(void)
{
+ preloader_console_init();
#if defined(CONFIG_SPL_NAND_SUPPORT) || defined(CONFIG_SPL_ONENAND_SUPPORT)
gpmc_init();
#endif
@@ -264,14 +265,6 @@
ehci_clocks_enable();
#endif
-#ifdef CONFIG_SPL_BUILD
- gd = &gdata;
-
- preloader_console_init();
-
- timer_init();
-#endif
-
if (!in_sdram)
mem_init();
}
diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c
index bc98c56..f4a580a 100644
--- a/arch/arm/cpu/armv7/sunxi/board.c
+++ b/arch/arm/cpu/armv7/sunxi/board.c
@@ -46,9 +46,8 @@
{
return MMCSD_MODE_RAW;
}
-#endif
-int gpio_init(void)
+static int gpio_init(void)
{
#if CONFIG_CONS_INDEX == 1 && defined(CONFIG_UART0_PORT_F)
#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I)
@@ -86,6 +85,42 @@
return 0;
}
+void board_init_f(ulong dummy)
+{
+#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I
+ /* Magic (undocmented) value taken from boot0, without this DRAM
+ * access gets messed up (seems cache related) */
+ setbits_le32(SUNXI_SRAMC_BASE + 0x44, 0x1800);
+#endif
+#if !defined CONFIG_SPL_BUILD && (defined CONFIG_MACH_SUN7I || \
+ defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I)
+ /* Enable SMP mode for CPU0, by setting bit 6 of Auxiliary Ctl reg */
+ asm volatile(
+ "mrc p15, 0, r0, c1, c0, 1\n"
+ "orr r0, r0, #1 << 6\n"
+ "mcr p15, 0, r0, c1, c0, 1\n");
+#endif
+
+ clock_init();
+ timer_init();
+ gpio_init();
+ i2c_init_board();
+
+ preloader_console_init();
+
+#ifdef CONFIG_SPL_I2C_SUPPORT
+ /* Needed early by sunxi_board_init if PMU is enabled */
+ i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+#endif
+ sunxi_board_init();
+
+ /* Clear the BSS. */
+ memset(__bss_start, 0, __bss_end - __bss_start);
+
+ board_init_r(NULL, 0);
+}
+#endif
+
void reset_cpu(ulong addr)
{
#if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN5I) || defined(CONFIG_MACH_SUN7I)
@@ -111,41 +146,6 @@
#endif
}
-/* do some early init */
-void s_init(void)
-{
-#if defined CONFIG_SPL_BUILD && \
- (defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I)
- /* Magic (undocmented) value taken from boot0, without this DRAM
- * access gets messed up (seems cache related) */
- setbits_le32(SUNXI_SRAMC_BASE + 0x44, 0x1800);
-#endif
-#if !defined CONFIG_SPL_BUILD && (defined CONFIG_MACH_SUN7I || \
- defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I)
- /* Enable SMP mode for CPU0, by setting bit 6 of Auxiliary Ctl reg */
- asm volatile(
- "mrc p15, 0, r0, c1, c0, 1\n"
- "orr r0, r0, #1 << 6\n"
- "mcr p15, 0, r0, c1, c0, 1\n");
-#endif
-
- clock_init();
- timer_init();
- gpio_init();
- i2c_init_board();
-
-#ifdef CONFIG_SPL_BUILD
- gd = &gdata;
- preloader_console_init();
-
-#ifdef CONFIG_SPL_I2C_SUPPORT
- /* Needed early by sunxi_board_init if PMU is enabled */
- i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
-#endif
- sunxi_board_init();
-#endif
-}
-
#ifndef CONFIG_SYS_DCACHE_OFF
void enable_caches(void)
{
diff --git a/arch/arm/cpu/armv7/zynq/spl.c b/arch/arm/cpu/armv7/zynq/spl.c
index 31627f9..0936bdd 100644
--- a/arch/arm/cpu/armv7/zynq/spl.c
+++ b/arch/arm/cpu/armv7/zynq/spl.c
@@ -20,9 +20,6 @@
/* Clear the BSS. */
memset(__bss_start, 0, __bss_end - __bss_start);
- /* Set global data pointer. */
- gd = &gdata;
-
preloader_console_init();
arch_cpu_init();
board_init_r(NULL, 0);
diff --git a/arch/arm/lib/spl.c b/arch/arm/lib/spl.c
index dfcc596..c41850a 100644
--- a/arch/arm/lib/spl.c
+++ b/arch/arm/lib/spl.c
@@ -15,6 +15,11 @@
/* Pointer to as well as the global data structure for SPL */
DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * WARNING: This is going away very soon. Don't use it and don't submit
+ * pafches that rely on it. The global_data area is set up in crt0.S.
+ */
gd_t gdata __attribute__ ((section(".data")));
/*
@@ -28,7 +33,7 @@
/* Clear the BSS. */
memset(__bss_start, 0, __bss_end - __bss_start);
- /* Set global data pointer. */
+ /* TODO: Remove settings of the global data pointer here */
gd = &gdata;
board_init_r(NULL, 0);
diff --git a/board/compulab/cm_fx6/spl.c b/board/compulab/cm_fx6/spl.c
index 6fe937b..5b4b76f 100644
--- a/board/compulab/cm_fx6/spl.c
+++ b/board/compulab/cm_fx6/spl.c
@@ -313,7 +313,6 @@
{
struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
- gd = &gdata;
/*
* We don't use DMA in SPL, but we do need it in U-Boot. U-Boot
* initializes DMA very early (before all board code), so the only
diff --git a/board/freescale/ls1021aqds/ls1021aqds.c b/board/freescale/ls1021aqds/ls1021aqds.c
index f08e54f..152da2d 100644
--- a/board/freescale/ls1021aqds/ls1021aqds.c
+++ b/board/freescale/ls1021aqds/ls1021aqds.c
@@ -219,9 +219,6 @@
pinctl);
#endif
- /* Set global data pointer */
- gd = &gdata;
-
/* Clear the BSS */
memset(__bss_start, 0, __bss_end - __bss_start);
diff --git a/board/freescale/ls1021atwr/ls1021atwr.c b/board/freescale/ls1021atwr/ls1021atwr.c
index 8ab229d..027b67e 100644
--- a/board/freescale/ls1021atwr/ls1021atwr.c
+++ b/board/freescale/ls1021atwr/ls1021atwr.c
@@ -287,9 +287,6 @@
#ifdef CONFIG_SPL_BUILD
void board_init_f(ulong dummy)
{
- /* Set global data pointer */
- gd = &gdata;
-
/* Clear the BSS */
memset(__bss_start, 0, __bss_end - __bss_start);
diff --git a/board/freescale/mpc837xerdb/MAINTAINERS b/board/freescale/mpc837xerdb/MAINTAINERS
index 8592a2c..81b4eed 100644
--- a/board/freescale/mpc837xerdb/MAINTAINERS
+++ b/board/freescale/mpc837xerdb/MAINTAINERS
@@ -1,6 +1,6 @@
MPC837XERDB BOARD
-#M: Joe D'Abbraccio <ljd015@freescale.com>
-S: Orphan (since 2014-06)
+M: Sinan Akman <sinan@writeme.com>
+S: Maintained
F: board/freescale/mpc837xerdb/
F: include/configs/MPC837XERDB.h
F: configs/MPC837XERDB_defconfig
diff --git a/board/woodburn/woodburn.c b/board/woodburn/woodburn.c
index 2744514..3da61a4 100644
--- a/board/woodburn/woodburn.c
+++ b/board/woodburn/woodburn.c
@@ -137,9 +137,6 @@
/* Clear the BSS. */
memset(__bss_start, 0, __bss_end - __bss_start);
- /* Set global data pointer. */
- gd = &gdata;
-
preloader_console_init();
timer_init();
diff --git a/common/cmd_usb.c b/common/cmd_usb.c
index c192498..27813f0 100644
--- a/common/cmd_usb.c
+++ b/common/cmd_usb.c
@@ -441,6 +441,26 @@
return 0;
}
+static void do_usb_start(void)
+{
+ bootstage_mark_name(BOOTSTAGE_ID_USB_START, "usb_start");
+
+ if (usb_init() < 0)
+ return;
+
+#ifdef CONFIG_USB_STORAGE
+ /* try to recognize storage devices immediately */
+ usb_stor_curr_dev = usb_stor_scan(1);
+#endif
+#ifdef CONFIG_USB_HOST_ETHER
+ /* 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
+}
+
/******************************************************************************
* usb command intepreter
*/
@@ -457,26 +477,20 @@
if (argc < 2)
return CMD_RET_USAGE;
- if ((strncmp(argv[1], "reset", 5) == 0) ||
- (strncmp(argv[1], "start", 5) == 0)) {
- bootstage_mark_name(BOOTSTAGE_ID_USB_START, "usb_start");
+ if (strncmp(argv[1], "start", 5) == 0) {
+ if (usb_started)
+ return 0; /* Already started */
+ printf("starting USB...\n");
+ do_usb_start();
+ return 0;
+ }
+
+ if (strncmp(argv[1], "reset", 5) == 0) {
+ printf("resetting USB...\n");
if (do_usb_stop_keyboard(1) != 0)
return 1;
usb_stop();
- printf("(Re)start USB...\n");
- if (usb_init() >= 0) {
-#ifdef CONFIG_USB_STORAGE
- /* try to recognize storage devices immediately */
- usb_stor_curr_dev = usb_stor_scan(1);
-#endif
-#ifdef CONFIG_USB_HOST_ETHER
- /* 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
- }
+ do_usb_start();
return 0;
}
if (strncmp(argv[1], "stop", 4) == 0) {
diff --git a/common/usb.c b/common/usb.c
index 736cd9f..32e15cd 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -59,6 +59,7 @@
void *ctrl;
struct usb_device *dev;
int i, start_index = 0;
+ int controllers_initialized = 0;
int ret;
dev_index = 0;
@@ -78,6 +79,7 @@
ret = usb_lowlevel_init(i, USB_INIT_HOST, &ctrl);
if (ret == -ENODEV) { /* No such device. */
puts("Port not available.\n");
+ controllers_initialized++;
continue;
}
@@ -89,6 +91,7 @@
* lowlevel init is OK, now scan the bus for devices
* i.e. search HUBs and configure them
*/
+ controllers_initialized++;
start_index = dev_index;
printf("scanning bus %d for devices... ", i);
dev = usb_alloc_new_device(ctrl);
@@ -110,12 +113,10 @@
debug("scan end\n");
/* if we were not able to find at least one working bus, bail out */
- if (!usb_started) {
+ if (controllers_initialized == 0)
puts("USB error: all controllers failed lowlevel init\n");
- return -1;
- }
- return 0;
+ return usb_started ? 0 : -1;
}
/******************************************************************************
@@ -969,6 +970,8 @@
printf("\n Couldn't reset port %i\n", dev->portnr);
return 1;
}
+ } else {
+ usb_reset_root_port();
}
#endif
diff --git a/common/usb_kbd.c b/common/usb_kbd.c
index bc7145e..ecc3085 100644
--- a/common/usb_kbd.c
+++ b/common/usb_kbd.c
@@ -332,7 +332,8 @@
/* We've consumed all queued int packets, create new */
destroy_int_queue(dev, data->intq);
data->intq = create_int_queue(dev, data->intpipe, 1,
- USB_KBD_BOOT_REPORT_SIZE, data->new);
+ USB_KBD_BOOT_REPORT_SIZE, data->new,
+ data->intinterval);
}
#endif
}
@@ -453,7 +454,8 @@
debug("USB KBD: enable interrupt pipe...\n");
#ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE
data->intq = create_int_queue(dev, data->intpipe, 1,
- USB_KBD_BOOT_REPORT_SIZE, data->new);
+ USB_KBD_BOOT_REPORT_SIZE, data->new,
+ data->intinterval);
if (!data->intq) {
#else
if (usb_submit_int_msg(dev, data->intpipe, data->new, data->intpktsize,
@@ -542,6 +544,10 @@
data = usb_kbd_dev->privptr;
if (stdio_deregister_dev(dev, force) != 0)
return 1;
+#ifdef CONFIG_CONSOLE_MUX
+ if (iomux_doenv(stdin, getenv("stdin")) != 0)
+ return 1;
+#endif
#ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE
destroy_int_queue(usb_kbd_dev, data->intq);
#endif
diff --git a/drivers/usb/eth/asix88179.c b/drivers/usb/eth/asix88179.c
index b8ca720..0ef85db 100644
--- a/drivers/usb/eth/asix88179.c
+++ b/drivers/usb/eth/asix88179.c
@@ -271,6 +271,19 @@
return 0;
}
+static int asix_write_mac(struct eth_device *eth)
+{
+ struct ueth_data *dev = (struct ueth_data *)eth->priv;
+ int ret;
+
+ ret = asix_write_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN,
+ ETH_ALEN, eth->enetaddr);
+ if (ret < 0)
+ debug("Failed to set MAC address: %02x\n", ret);
+
+ return ret;
+}
+
static int asix_basic_reset(struct ueth_data *dev)
{
struct asix_private *dev_priv = (struct asix_private *)dev->dev_priv;
@@ -686,6 +699,7 @@
eth->send = asix_send;
eth->recv = asix_recv;
eth->halt = asix_halt;
+ eth->write_hwaddr = asix_write_mac;
eth->priv = ss;
if (asix_basic_reset(ss))
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index a4c5606..98c2da6 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -761,6 +761,14 @@
if (value >= 0)
value = min(w_length, (u16) value);
break;
+ case USB_DT_BOS:
+ /*
+ * The USB compliance test (USB 2.0 Command Verifier)
+ * issues this request. We should not run into the
+ * default path here. But return for now until
+ * the superspeed support is added.
+ */
+ break;
default:
goto unknown;
}
diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c
index ead71eb..77a1567 100644
--- a/drivers/usb/gadget/f_dfu.c
+++ b/drivers/usb/gadget/f_dfu.c
@@ -780,6 +780,13 @@
return 0;
}
+static int __dfu_get_alt(struct usb_function *f, unsigned intf)
+{
+ struct f_dfu *f_dfu = func_to_dfu(f);
+
+ return f_dfu->altsetting;
+}
+
/* TODO: is this really what we need here? */
static void dfu_disable(struct usb_function *f)
{
@@ -806,6 +813,7 @@
f_dfu->usb_function.bind = dfu_bind;
f_dfu->usb_function.unbind = dfu_unbind;
f_dfu->usb_function.set_alt = dfu_set_alt;
+ f_dfu->usb_function.get_alt = __dfu_get_alt;
f_dfu->usb_function.disable = dfu_disable;
f_dfu->usb_function.strings = dfu_generic_strings;
f_dfu->usb_function.setup = dfu_handle;
diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c
index 8945c5b..d4460b2 100644
--- a/drivers/usb/gadget/pxa25x_udc.c
+++ b/drivers/usb/gadget/pxa25x_udc.c
@@ -1950,11 +1950,11 @@
dev->watchdog.period = 5000 * CONFIG_SYS_HZ / 1000000; /* 5 ms */
dev->watchdog.function = udc_watchdog;
+ dev->mach = &mach_info;
+
udc_disable(dev);
udc_reinit(dev);
- dev->mach = &mach_info;
-
dev->gadget.name = "pxa2xx_udc";
retval = driver->bind(&dev->gadget);
if (retval) {
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index bc76066..f1fb190 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1148,7 +1148,7 @@
struct int_queue *
create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize,
- int elementsize, void *buffer)
+ int elementsize, void *buffer, int interval)
{
struct ehci_ctrl *ctrl = dev->controller;
struct int_queue *result = NULL;
@@ -1398,7 +1398,7 @@
debug("dev=%p, pipe=%lu, buffer=%p, length=%d, interval=%d",
dev, pipe, buffer, length, interval);
- queue = create_int_queue(dev, pipe, 1, length, buffer);
+ queue = create_int_queue(dev, pipe, 1, length, buffer, interval);
if (!queue)
return -1;
diff --git a/drivers/usb/musb-new/Makefile b/drivers/usb/musb-new/Makefile
index 3facf0f..9edeece 100644
--- a/drivers/usb/musb-new/Makefile
+++ b/drivers/usb/musb-new/Makefile
@@ -8,6 +8,7 @@
obj-$(CONFIG_USB_MUSB_DSPS) += musb_dsps.o
obj-$(CONFIG_USB_MUSB_AM35X) += am35x.o
obj-$(CONFIG_USB_MUSB_OMAP2PLUS) += omap2430.o
+obj-$(CONFIG_USB_MUSB_SUNXI) += sunxi.o
ccflags-y := $(call cc-option,-Wno-unused-variable) \
$(call cc-option,-Wno-unused-but-set-variable) \
diff --git a/drivers/usb/musb-new/musb_host.c b/drivers/usb/musb-new/musb_host.c
index bbcee88..437309c 100644
--- a/drivers/usb/musb-new/musb_host.c
+++ b/drivers/usb/musb-new/musb_host.c
@@ -2130,8 +2130,6 @@
return ret;
}
-
-#ifndef __UBOOT__
/*
* abort a transfer that's at the head of a hardware queue.
* called with controller locked, irqs blocked
@@ -2195,7 +2193,14 @@
return status;
}
-static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
+#ifndef __UBOOT__
+static int musb_urb_dequeue(
+#else
+int musb_urb_dequeue(
+#endif
+ struct usb_hcd *hcd,
+ struct urb *urb,
+ int status)
{
struct musb *musb = hcd_to_musb(hcd);
struct musb_qh *qh;
@@ -2253,6 +2258,7 @@
return ret;
}
+#ifndef __UBOOT__
/* disable an endpoint */
static void
musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep)
diff --git a/drivers/usb/musb-new/musb_host.h b/drivers/usb/musb-new/musb_host.h
index ebebe0c..546b4a2 100644
--- a/drivers/usb/musb-new/musb_host.h
+++ b/drivers/usb/musb-new/musb_host.h
@@ -110,5 +110,6 @@
#ifdef __UBOOT__
int musb_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags);
+int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status);
#endif
#endif /* _MUSB_HOST_H */
diff --git a/drivers/usb/musb-new/musb_regs.h b/drivers/usb/musb-new/musb_regs.h
index 03f2655..27e4ed4 100644
--- a/drivers/usb/musb-new/musb_regs.h
+++ b/drivers/usb/musb-new/musb_regs.h
@@ -216,6 +216,9 @@
#ifndef CONFIG_BLACKFIN
+/* SUNXI has different reg addresses, but identical r/w functions */
+#ifndef CONFIG_ARCH_SUNXI
+
/*
* Common USB registers
*/
@@ -318,6 +321,85 @@
#define MUSB_BUSCTL_OFFSET(_epnum, _offset) \
(0x80 + (8*(_epnum)) + (_offset))
+#else /* CONFIG_ARCH_SUNXI */
+
+/*
+ * Common USB registers
+ */
+
+#define MUSB_FADDR 0x0098
+#define MUSB_POWER 0x0040
+
+#define MUSB_INTRTX 0x0044
+#define MUSB_INTRRX 0x0046
+#define MUSB_INTRTXE 0x0048
+#define MUSB_INTRRXE 0x004A
+#define MUSB_INTRUSB 0x004C
+#define MUSB_INTRUSBE 0x0050
+#define MUSB_FRAME 0x0054
+#define MUSB_INDEX 0x0042
+#define MUSB_TESTMODE 0x007C
+
+/* Get offset for a given FIFO from musb->mregs */
+#define MUSB_FIFO_OFFSET(epnum) (0x00 + ((epnum) * 4))
+
+/*
+ * Additional Control Registers
+ */
+
+#define MUSB_DEVCTL 0x0041
+
+/* These are always controlled through the INDEX register */
+#define MUSB_TXFIFOSZ 0x0090
+#define MUSB_RXFIFOSZ 0x0094
+#define MUSB_TXFIFOADD 0x0092
+#define MUSB_RXFIFOADD 0x0096
+
+#define MUSB_EPINFO 0x0078
+#define MUSB_RAMINFO 0x0079
+#define MUSB_LINKINFO 0x007A
+#define MUSB_VPLEN 0x007B
+#define MUSB_HS_EOF1 0x007C
+#define MUSB_FS_EOF1 0x007D
+#define MUSB_LS_EOF1 0x007E
+
+/* Offsets to endpoint registers */
+#define MUSB_TXMAXP 0x0080
+#define MUSB_TXCSR 0x0082
+#define MUSB_CSR0 0x0082
+#define MUSB_RXMAXP 0x0084
+#define MUSB_RXCSR 0x0086
+#define MUSB_RXCOUNT 0x0088
+#define MUSB_COUNT0 0x0088
+#define MUSB_TXTYPE 0x008C
+#define MUSB_TYPE0 0x008C
+#define MUSB_TXINTERVAL 0x008D
+#define MUSB_NAKLIMIT0 0x008D
+#define MUSB_RXTYPE 0x008E
+#define MUSB_RXINTERVAL 0x008F
+
+#define MUSB_CONFIGDATA 0x00b0 /* musb_read_configdata adds 0x10 ! */
+#define MUSB_FIFOSIZE 0x0090
+
+/* Offsets to endpoint registers in indexed model (using INDEX register) */
+#define MUSB_INDEXED_OFFSET(_epnum, _offset) (_offset)
+
+#define MUSB_TXCSR_MODE 0x2000
+
+/* "bus control"/target registers, for host side multipoint (external hubs) */
+#define MUSB_TXFUNCADDR 0x0098
+#define MUSB_TXHUBADDR 0x009A
+#define MUSB_TXHUBPORT 0x009B
+
+#define MUSB_RXFUNCADDR 0x009C
+#define MUSB_RXHUBADDR 0x009E
+#define MUSB_RXHUBPORT 0x009F
+
+/* Endpoint is selected with MUSB_INDEX. */
+#define MUSB_BUSCTL_OFFSET(_epnum, _offset) (_offset)
+
+#endif /* CONFIG_ARCH_SUNXI */
+
static inline void musb_write_txfifosz(void __iomem *mbase, u8 c_size)
{
musb_writeb(mbase, MUSB_TXFIFOSZ, c_size);
@@ -340,7 +422,9 @@
static inline void musb_write_ulpi_buscontrol(void __iomem *mbase, u8 val)
{
+#ifndef CONFIG_ARCH_SUNXI /* No ulpi on sunxi */
musb_writeb(mbase, MUSB_ULPI_BUSCONTROL, val);
+#endif
}
static inline u8 musb_read_txfifosz(void __iomem *mbase)
@@ -365,7 +449,11 @@
static inline u8 musb_read_ulpi_buscontrol(void __iomem *mbase)
{
+#ifdef CONFIG_ARCH_SUNXI /* No ulpi on sunxi */
+ return 0;
+#else
return musb_readb(mbase, MUSB_ULPI_BUSCONTROL);
+#endif
}
static inline u8 musb_read_configdata(void __iomem *mbase)
@@ -376,7 +464,11 @@
static inline u16 musb_read_hwvers(void __iomem *mbase)
{
+#ifdef CONFIG_ARCH_SUNXI
+ return 0; /* Unknown version */
+#else
return musb_readw(mbase, MUSB_HWVERS);
+#endif
}
static inline void __iomem *musb_read_target_reg_base(u8 i, void __iomem *mbase)
diff --git a/drivers/usb/musb-new/musb_uboot.c b/drivers/usb/musb-new/musb_uboot.c
index 2676f09..6e58ddf 100644
--- a/drivers/usb/musb-new/musb_uboot.c
+++ b/drivers/usb/musb-new/musb_uboot.c
@@ -12,6 +12,11 @@
#include "musb_gadget.h"
#ifdef CONFIG_MUSB_HOST
+struct int_queue {
+ struct usb_host_endpoint hep;
+ struct urb urb;
+};
+
static struct musb *host;
static struct usb_hcd hcd;
static enum usb_device_speed host_speed;
@@ -25,45 +30,42 @@
static struct usb_host_endpoint hep;
static struct urb urb;
-static struct urb *construct_urb(struct usb_device *dev, int endpoint_type,
- unsigned long pipe, void *buffer, int len,
- struct devrequest *setup, int interval)
+static void construct_urb(struct urb *urb, struct usb_host_endpoint *hep,
+ struct usb_device *dev, int endpoint_type,
+ unsigned long pipe, void *buffer, int len,
+ struct devrequest *setup, int interval)
{
int epnum = usb_pipeendpoint(pipe);
int is_in = usb_pipein(pipe);
- memset(&urb, 0, sizeof(struct urb));
- memset(&hep, 0, sizeof(struct usb_host_endpoint));
- INIT_LIST_HEAD(&hep.urb_list);
- INIT_LIST_HEAD(&urb.urb_list);
- urb.ep = &hep;
- urb.complete = musb_host_complete_urb;
- urb.status = -EINPROGRESS;
- urb.dev = dev;
- urb.pipe = pipe;
- urb.transfer_buffer = buffer;
- urb.transfer_dma = (unsigned long)buffer;
- urb.transfer_buffer_length = len;
- urb.setup_packet = (unsigned char *)setup;
+ memset(urb, 0, sizeof(struct urb));
+ memset(hep, 0, sizeof(struct usb_host_endpoint));
+ INIT_LIST_HEAD(&hep->urb_list);
+ INIT_LIST_HEAD(&urb->urb_list);
+ urb->ep = hep;
+ urb->complete = musb_host_complete_urb;
+ urb->status = -EINPROGRESS;
+ urb->dev = dev;
+ urb->pipe = pipe;
+ urb->transfer_buffer = buffer;
+ urb->transfer_dma = (unsigned long)buffer;
+ urb->transfer_buffer_length = len;
+ urb->setup_packet = (unsigned char *)setup;
- urb.ep->desc.wMaxPacketSize =
+ urb->ep->desc.wMaxPacketSize =
__cpu_to_le16(is_in ? dev->epmaxpacketin[epnum] :
dev->epmaxpacketout[epnum]);
- urb.ep->desc.bmAttributes = endpoint_type;
- urb.ep->desc.bEndpointAddress =
+ urb->ep->desc.bmAttributes = endpoint_type;
+ urb->ep->desc.bEndpointAddress =
(is_in ? USB_DIR_IN : USB_DIR_OUT) | epnum;
- urb.ep->desc.bInterval = interval;
-
- return &urb;
+ urb->ep->desc.bInterval = interval;
}
-#define MUSB_HOST_TIMEOUT 0x3ffffff
-
static int submit_urb(struct usb_hcd *hcd, struct urb *urb)
{
struct musb *host = hcd->hcd_priv;
int ret;
- int timeout;
+ unsigned long timeout;
ret = musb_urb_enqueue(hcd, urb, 0);
if (ret < 0) {
@@ -71,12 +73,16 @@
return ret;
}
- timeout = MUSB_HOST_TIMEOUT;
+ timeout = get_timer(0) + USB_TIMEOUT_MS(urb->pipe);
do {
if (ctrlc())
return -EIO;
host->isr(0, host);
- } while ((urb->dev->status & USB_ST_NOT_PROC) && --timeout);
+ } while (urb->status == -EINPROGRESS &&
+ get_timer(0) < timeout);
+
+ if (urb->status == -EINPROGRESS)
+ musb_urb_dequeue(hcd, urb, -ETIME);
return urb->status;
}
@@ -84,38 +90,117 @@
int submit_control_msg(struct usb_device *dev, unsigned long pipe,
void *buffer, int len, struct devrequest *setup)
{
- struct urb *urb = construct_urb(dev, USB_ENDPOINT_XFER_CONTROL, pipe,
- buffer, len, setup, 0);
+ construct_urb(&urb, &hep, dev, USB_ENDPOINT_XFER_CONTROL, pipe,
+ buffer, len, setup, 0);
/* Fix speed for non hub-attached devices */
if (!dev->parent)
dev->speed = host_speed;
- return submit_urb(&hcd, urb);
+ return submit_urb(&hcd, &urb);
}
int submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
void *buffer, int len)
{
- struct urb *urb = construct_urb(dev, USB_ENDPOINT_XFER_BULK, pipe,
- buffer, len, NULL, 0);
- return submit_urb(&hcd, urb);
+ construct_urb(&urb, &hep, dev, USB_ENDPOINT_XFER_BULK, pipe,
+ buffer, len, NULL, 0);
+ return submit_urb(&hcd, &urb);
}
int submit_int_msg(struct usb_device *dev, unsigned long pipe,
void *buffer, int len, int interval)
{
- struct urb *urb = construct_urb(dev, USB_ENDPOINT_XFER_INT, pipe,
- buffer, len, NULL, interval);
- return submit_urb(&hcd, urb);
+ construct_urb(&urb, &hep, dev, USB_ENDPOINT_XFER_INT, pipe,
+ buffer, len, NULL, interval);
+ return submit_urb(&hcd, &urb);
+}
+
+struct int_queue *create_int_queue(struct usb_device *dev, unsigned long pipe,
+ int queuesize, int elementsize, void *buffer, int interval)
+{
+ struct int_queue *queue;
+ int ret, index = usb_pipein(pipe) * 16 + usb_pipeendpoint(pipe);
+
+ if (queuesize != 1) {
+ printf("ERROR musb int-queues only support queuesize 1\n");
+ return NULL;
+ }
+
+ if (dev->int_pending & (1 << index)) {
+ printf("ERROR int-urb is already pending on pipe %lx\n", pipe);
+ return NULL;
+ }
+
+ queue = malloc(sizeof(*queue));
+ if (!queue)
+ return NULL;
+
+ construct_urb(&queue->urb, &queue->hep, dev, USB_ENDPOINT_XFER_INT,
+ pipe, buffer, elementsize, NULL, interval);
+
+ ret = musb_urb_enqueue(&hcd, &queue->urb, 0);
+ if (ret < 0) {
+ printf("Failed to enqueue URB to controller\n");
+ free(queue);
+ return NULL;
+ }
+
+ dev->int_pending |= 1 << index;
+ return queue;
+}
+
+int destroy_int_queue(struct usb_device *dev, struct int_queue *queue)
+{
+ int index = usb_pipein(queue->urb.pipe) * 16 +
+ usb_pipeendpoint(queue->urb.pipe);
+
+ if (queue->urb.status == -EINPROGRESS)
+ musb_urb_dequeue(&hcd, &queue->urb, -ETIME);
+
+ dev->int_pending &= ~(1 << index);
+ free(queue);
+ return 0;
+}
+
+void *poll_int_queue(struct usb_device *dev, struct int_queue *queue)
+{
+ if (queue->urb.status != -EINPROGRESS)
+ return NULL; /* URB has already completed in a prev. poll */
+
+ host->isr(0, host);
+
+ if (queue->urb.status != -EINPROGRESS)
+ return queue->urb.transfer_buffer; /* Done */
+
+ return NULL; /* URB still pending */
+}
+
+void usb_reset_root_port(void)
+{
+ void *mbase = host->mregs;
+ u8 power;
+
+ power = musb_readb(mbase, MUSB_POWER);
+ power &= 0xf0;
+ musb_writeb(mbase, MUSB_POWER, MUSB_POWER_RESET | power);
+ mdelay(50);
+ power = musb_readb(mbase, MUSB_POWER);
+ musb_writeb(mbase, MUSB_POWER, ~MUSB_POWER_RESET & power);
+ host->isr(0, host);
+ host_speed = (musb_readb(mbase, MUSB_POWER) & MUSB_POWER_HSMODE) ?
+ USB_SPEED_HIGH :
+ (musb_readb(mbase, MUSB_DEVCTL) & MUSB_DEVCTL_FSDEV) ?
+ USB_SPEED_FULL : USB_SPEED_LOW;
+ mdelay((host_speed == USB_SPEED_LOW) ? 200 : 50);
}
int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
{
- u8 power;
void *mbase;
- int timeout = MUSB_HOST_TIMEOUT;
+ /* USB spec says it may take up to 1 second for a device to connect */
+ unsigned long timeout = get_timer(0) + 1000;
if (!host) {
printf("MUSB host is not registered\n");
@@ -127,20 +212,11 @@
do {
if (musb_readb(mbase, MUSB_DEVCTL) & MUSB_DEVCTL_HM)
break;
- } while (--timeout);
- if (!timeout)
+ } while (get_timer(0) < timeout);
+ if (get_timer(0) >= timeout)
return -ENODEV;
- power = musb_readb(mbase, MUSB_POWER);
- musb_writeb(mbase, MUSB_POWER, MUSB_POWER_RESET | power);
- udelay(30000);
- power = musb_readb(mbase, MUSB_POWER);
- musb_writeb(mbase, MUSB_POWER, ~MUSB_POWER_RESET & power);
- host->isr(0, host);
- host_speed = (musb_readb(mbase, MUSB_POWER) & MUSB_POWER_HSMODE) ?
- USB_SPEED_HIGH :
- (musb_readb(mbase, MUSB_DEVCTL) & MUSB_DEVCTL_FSDEV) ?
- USB_SPEED_FULL : USB_SPEED_LOW;
+ usb_reset_root_port();
host->is_active = 1;
hcd.hcd_priv = host;
diff --git a/drivers/usb/musb-new/sunxi.c b/drivers/usb/musb-new/sunxi.c
new file mode 100644
index 0000000..778916d
--- /dev/null
+++ b/drivers/usb/musb-new/sunxi.c
@@ -0,0 +1,279 @@
+/*
+ * Allwinner SUNXI "glue layer"
+ *
+ * Copyright © 2015 Hans de Goede <hdegoede@redhat.com>
+ * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * Based on the sw_usb "Allwinner OTG Dual Role Controller" code.
+ * Copyright 2007-2012 (C) Allwinner Technology Co., Ltd.
+ * javen <javen@allwinnertech.com>
+ *
+ * Based on the DA8xx "glue layer" code.
+ * Copyright (c) 2008-2009 MontaVista Software, Inc. <source@mvista.com>
+ * Copyright (C) 2005-2006 by Texas Instruments
+ *
+ * This file is part of the Inventra Controller Driver for Linux.
+ *
+ * The Inventra Controller Driver for Linux is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU
+ * General Public License version 2 as published by the Free Software
+ * Foundation.
+ *
+ */
+#include <common.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/usbc.h>
+#include "linux-compat.h"
+#include "musb_core.h"
+
+/******************************************************************************
+ ******************************************************************************
+ * From the Allwinner driver
+ ******************************************************************************
+ ******************************************************************************/
+
+/******************************************************************************
+ * From include/sunxi_usb_bsp.h
+ ******************************************************************************/
+
+/* reg offsets */
+#define USBC_REG_o_ISCR 0x0400
+#define USBC_REG_o_PHYCTL 0x0404
+#define USBC_REG_o_PHYBIST 0x0408
+#define USBC_REG_o_PHYTUNE 0x040c
+
+#define USBC_REG_o_VEND0 0x0043
+
+/* Interface Status and Control */
+#define USBC_BP_ISCR_VBUS_VALID_FROM_DATA 30
+#define USBC_BP_ISCR_VBUS_VALID_FROM_VBUS 29
+#define USBC_BP_ISCR_EXT_ID_STATUS 28
+#define USBC_BP_ISCR_EXT_DM_STATUS 27
+#define USBC_BP_ISCR_EXT_DP_STATUS 26
+#define USBC_BP_ISCR_MERGED_VBUS_STATUS 25
+#define USBC_BP_ISCR_MERGED_ID_STATUS 24
+
+#define USBC_BP_ISCR_ID_PULLUP_EN 17
+#define USBC_BP_ISCR_DPDM_PULLUP_EN 16
+#define USBC_BP_ISCR_FORCE_ID 14
+#define USBC_BP_ISCR_FORCE_VBUS_VALID 12
+#define USBC_BP_ISCR_VBUS_VALID_SRC 10
+
+#define USBC_BP_ISCR_HOSC_EN 7
+#define USBC_BP_ISCR_VBUS_CHANGE_DETECT 6
+#define USBC_BP_ISCR_ID_CHANGE_DETECT 5
+#define USBC_BP_ISCR_DPDM_CHANGE_DETECT 4
+#define USBC_BP_ISCR_IRQ_ENABLE 3
+#define USBC_BP_ISCR_VBUS_CHANGE_DETECT_EN 2
+#define USBC_BP_ISCR_ID_CHANGE_DETECT_EN 1
+#define USBC_BP_ISCR_DPDM_CHANGE_DETECT_EN 0
+
+/******************************************************************************
+ * From usbc/usbc.c
+ ******************************************************************************/
+
+static u32 USBC_WakeUp_ClearChangeDetect(u32 reg_val)
+{
+ u32 temp = reg_val;
+
+ temp &= ~(1 << USBC_BP_ISCR_VBUS_CHANGE_DETECT);
+ temp &= ~(1 << USBC_BP_ISCR_ID_CHANGE_DETECT);
+ temp &= ~(1 << USBC_BP_ISCR_DPDM_CHANGE_DETECT);
+
+ return temp;
+}
+
+static void USBC_EnableIdPullUp(__iomem void *base)
+{
+ u32 reg_val;
+
+ reg_val = musb_readl(base, USBC_REG_o_ISCR);
+ reg_val |= (1 << USBC_BP_ISCR_ID_PULLUP_EN);
+ reg_val = USBC_WakeUp_ClearChangeDetect(reg_val);
+ musb_writel(base, USBC_REG_o_ISCR, reg_val);
+}
+
+static void USBC_DisableIdPullUp(__iomem void *base)
+{
+ u32 reg_val;
+
+ reg_val = musb_readl(base, USBC_REG_o_ISCR);
+ reg_val &= ~(1 << USBC_BP_ISCR_ID_PULLUP_EN);
+ reg_val = USBC_WakeUp_ClearChangeDetect(reg_val);
+ musb_writel(base, USBC_REG_o_ISCR, reg_val);
+}
+
+static void USBC_EnableDpDmPullUp(__iomem void *base)
+{
+ u32 reg_val;
+
+ reg_val = musb_readl(base, USBC_REG_o_ISCR);
+ reg_val |= (1 << USBC_BP_ISCR_DPDM_PULLUP_EN);
+ reg_val = USBC_WakeUp_ClearChangeDetect(reg_val);
+ musb_writel(base, USBC_REG_o_ISCR, reg_val);
+}
+
+static void USBC_DisableDpDmPullUp(__iomem void *base)
+{
+ u32 reg_val;
+
+ reg_val = musb_readl(base, USBC_REG_o_ISCR);
+ reg_val &= ~(1 << USBC_BP_ISCR_DPDM_PULLUP_EN);
+ reg_val = USBC_WakeUp_ClearChangeDetect(reg_val);
+ musb_writel(base, USBC_REG_o_ISCR, reg_val);
+}
+
+static void USBC_ForceIdToLow(__iomem void *base)
+{
+ u32 reg_val;
+
+ reg_val = musb_readl(base, USBC_REG_o_ISCR);
+ reg_val &= ~(0x03 << USBC_BP_ISCR_FORCE_ID);
+ reg_val |= (0x02 << USBC_BP_ISCR_FORCE_ID);
+ reg_val = USBC_WakeUp_ClearChangeDetect(reg_val);
+ musb_writel(base, USBC_REG_o_ISCR, reg_val);
+}
+
+static void USBC_ForceIdToHigh(__iomem void *base)
+{
+ u32 reg_val;
+
+ reg_val = musb_readl(base, USBC_REG_o_ISCR);
+ reg_val &= ~(0x03 << USBC_BP_ISCR_FORCE_ID);
+ reg_val |= (0x03 << USBC_BP_ISCR_FORCE_ID);
+ reg_val = USBC_WakeUp_ClearChangeDetect(reg_val);
+ musb_writel(base, USBC_REG_o_ISCR, reg_val);
+}
+
+static void USBC_ForceVbusValidDisable(__iomem void *base)
+{
+ u32 reg_val;
+
+ reg_val = musb_readl(base, USBC_REG_o_ISCR);
+ reg_val &= ~(0x03 << USBC_BP_ISCR_FORCE_VBUS_VALID);
+ reg_val = USBC_WakeUp_ClearChangeDetect(reg_val);
+ musb_writel(base, USBC_REG_o_ISCR, reg_val);
+}
+
+static void USBC_ForceVbusValidToHigh(__iomem void *base)
+{
+ u32 reg_val;
+
+ reg_val = musb_readl(base, USBC_REG_o_ISCR);
+ reg_val &= ~(0x03 << USBC_BP_ISCR_FORCE_VBUS_VALID);
+ reg_val |= (0x03 << USBC_BP_ISCR_FORCE_VBUS_VALID);
+ reg_val = USBC_WakeUp_ClearChangeDetect(reg_val);
+ musb_writel(base, USBC_REG_o_ISCR, reg_val);
+}
+
+static void USBC_ConfigFIFO_Base(void)
+{
+ u32 reg_value;
+
+ /* config usb fifo, 8kb mode */
+ reg_value = readl(SUNXI_SRAMC_BASE + 0x04);
+ reg_value &= ~(0x03 << 0);
+ reg_value |= (1 << 0);
+ writel(reg_value, SUNXI_SRAMC_BASE + 0x04);
+}
+
+/******************************************************************************
+ * MUSB Glue code
+ ******************************************************************************/
+
+static irqreturn_t sunxi_musb_interrupt(int irq, void *__hci)
+{
+ struct musb *musb = __hci;
+ irqreturn_t retval = IRQ_NONE;
+
+ /* read and flush interrupts */
+ musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB);
+ if (musb->int_usb)
+ musb_writeb(musb->mregs, MUSB_INTRUSB, musb->int_usb);
+ musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX);
+ if (musb->int_tx)
+ musb_writew(musb->mregs, MUSB_INTRTX, musb->int_tx);
+ musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX);
+ if (musb->int_rx)
+ musb_writew(musb->mregs, MUSB_INTRRX, musb->int_rx);
+
+ if (musb->int_usb || musb->int_tx || musb->int_rx)
+ retval |= musb_interrupt(musb);
+
+ return retval;
+}
+
+static void sunxi_musb_enable(struct musb *musb)
+{
+ pr_debug("%s():\n", __func__);
+
+ /* select PIO mode */
+ musb_writeb(musb->mregs, USBC_REG_o_VEND0, 0);
+
+ if (is_host_enabled(musb)) {
+ /* port power on */
+ sunxi_usbc_vbus_enable(0);
+ }
+}
+
+static void sunxi_musb_disable(struct musb *musb)
+{
+ pr_debug("%s():\n", __func__);
+
+ /* Put the controller back in a pristane state for "usb reset" */
+ if (musb->is_active) {
+ sunxi_usbc_disable(0);
+ sunxi_usbc_enable(0);
+ musb->is_active = 0;
+ }
+}
+
+static int sunxi_musb_init(struct musb *musb)
+{
+ int err;
+
+ pr_debug("%s():\n", __func__);
+
+ err = sunxi_usbc_request_resources(0);
+ if (err)
+ return err;
+
+ musb->isr = sunxi_musb_interrupt;
+ sunxi_usbc_enable(0);
+
+ USBC_ConfigFIFO_Base();
+ USBC_EnableDpDmPullUp(musb->mregs);
+ USBC_EnableIdPullUp(musb->mregs);
+
+ if (is_host_enabled(musb)) {
+ /* Host mode */
+ USBC_ForceIdToLow(musb->mregs);
+ USBC_ForceVbusValidToHigh(musb->mregs);
+ } else {
+ /* Peripheral mode */
+ USBC_ForceIdToHigh(musb->mregs);
+ USBC_ForceVbusValidDisable(musb->mregs);
+ }
+
+ return 0;
+}
+
+static int sunxi_musb_exit(struct musb *musb)
+{
+ pr_debug("%s():\n", __func__);
+
+ USBC_DisableDpDmPullUp(musb->mregs);
+ USBC_DisableIdPullUp(musb->mregs);
+ sunxi_usbc_vbus_disable(0);
+ sunxi_usbc_disable(0);
+
+ return sunxi_usbc_free_resources(0);
+}
+
+const struct musb_platform_ops sunxi_musb_ops = {
+ .init = sunxi_musb_init,
+ .exit = sunxi_musb_exit,
+
+ .enable = sunxi_musb_enable,
+ .disable = sunxi_musb_disable,
+};
diff --git a/drivers/usb/musb-new/usb-compat.h b/drivers/usb/musb-new/usb-compat.h
index 27f656f..50bad37 100644
--- a/drivers/usb/musb-new/usb-compat.h
+++ b/drivers/usb/musb-new/usb-compat.h
@@ -48,6 +48,7 @@
list_add_tail(&urb->urb_list, &urb->ep->urb_list); \
ret; })
#define usb_hcd_unlink_urb_from_ep(hcd, urb) list_del_init(&urb->urb_list)
+#define usb_hcd_check_unlink_urb(hdc, urb, status) 0
static inline void usb_hcd_giveback_urb(struct usb_hcd *hcd,
struct urb *urb,
diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h
index be616e8..becbe3f 100644
--- a/include/config_distro_bootcmd.h
+++ b/include/config_distro_bootcmd.h
@@ -90,15 +90,8 @@
#endif
#ifdef CONFIG_CMD_USB
-#define BOOTENV_RUN_USB_INIT "run usb_init; "
-#define BOOTENV_SET_USB_NEED_INIT "setenv usb_need_init; "
+#define BOOTENV_RUN_USB_INIT "usb start; "
#define BOOTENV_SHARED_USB \
- "usb_init=" \
- "if ${usb_need_init}; then " \
- "setenv usb_need_init false; " \
- "usb start 0; " \
- "fi\0" \
- \
"usb_boot=" \
BOOTENV_RUN_USB_INIT \
BOOTENV_SHARED_BLKDEV_BODY(usb)
@@ -106,7 +99,6 @@
#define BOOTENV_DEV_NAME_USB BOOTENV_DEV_NAME_BLKDEV
#else
#define BOOTENV_RUN_USB_INIT
-#define BOOTENV_SET_USB_NEED_INIT
#define BOOTENV_SHARED_USB
#define BOOTENV_DEV_USB \
BOOT_TARGET_DEVICES_references_USB_without_CONFIG_CMD_USB
@@ -202,7 +194,7 @@
\
BOOT_TARGET_DEVICES(BOOTENV_DEV) \
\
- "bootcmd=" BOOTENV_SET_USB_NEED_INIT BOOTENV_SET_SCSI_NEED_INIT \
+ "bootcmd=" BOOTENV_SET_SCSI_NEED_INIT \
"for target in ${boot_targets}; do " \
"run bootcmd_${target}; " \
"done\0"
diff --git a/include/configs/MPC837XERDB.h b/include/configs/MPC837XERDB.h
index 8ed0f7c..19e0e30 100644
--- a/include/configs/MPC837XERDB.h
+++ b/include/configs/MPC837XERDB.h
@@ -15,6 +15,8 @@
#define CONFIG_E300 1 /* E300 family */
#define CONFIG_MPC837x 1 /* MPC837x CPU specific */
#define CONFIG_MPC837XERDB 1
+#define CONFIG_DISPLAY_BOARDINFO
+#define CONFIG_SYS_GENERIC_BOARD
#define CONFIG_SYS_TEXT_BASE 0xFE000000
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index e839053..647cac5 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -109,6 +109,7 @@
#define CONFIG_SYS_PBSIZE 1024 /* Print Buffer Size */
#define CONFIG_SYS_MAXARGS 16 /* max number of command args */
#define CONFIG_SYS_GENERIC_BOARD
+#define CONFIG_SKIP_LOWLEVEL_INIT
/* Boot Argument Buffer Size */
#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
diff --git a/include/usb.h b/include/usb.h
index d3c7415..a8fee0b 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -120,6 +120,7 @@
* Each instance needs its own set of data structures.
*/
unsigned long status;
+ unsigned long int_pending; /* 1 bit per ep, used by int_queue */
int act_len; /* transfered bytes */
int maxchild; /* Number of ports if hub */
int portnr;
@@ -154,11 +155,16 @@
defined(CONFIG_USB_OMAP3) || defined(CONFIG_USB_DA8XX) || \
defined(CONFIG_USB_BLACKFIN) || defined(CONFIG_USB_AM35X) || \
defined(CONFIG_USB_MUSB_DSPS) || defined(CONFIG_USB_MUSB_AM35X) || \
- defined(CONFIG_USB_MUSB_OMAP2PLUS) || defined(CONFIG_USB_XHCI) || \
- defined(CONFIG_USB_DWC2)
+ defined(CONFIG_USB_MUSB_OMAP2PLUS) || defined(CONFIG_USB_MUSB_SUNXI) || \
+ defined(CONFIG_USB_XHCI) || defined(CONFIG_USB_DWC2)
int usb_lowlevel_init(int index, enum usb_init_type init, void **controller);
int usb_lowlevel_stop(int index);
+#ifdef CONFIG_MUSB_HOST
+void usb_reset_root_port(void);
+#else
+#define usb_reset_root_port()
+#endif
int submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
void *buffer, int transfer_len);
@@ -167,9 +173,9 @@
int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
int transfer_len, int interval);
-#ifdef CONFIG_USB_EHCI /* Only the ehci code has pollable int support */
+#if defined CONFIG_USB_EHCI || defined CONFIG_MUSB_HOST
struct int_queue *create_int_queue(struct usb_device *dev, unsigned long pipe,
- int queuesize, int elementsize, void *buffer);
+ int queuesize, int elementsize, void *buffer, int interval);
int destroy_int_queue(struct usb_device *dev, struct int_queue *queue);
void *poll_int_queue(struct usb_device *dev, struct int_queue *queue);
#endif