diff --git a/drivers/serial/usbtty.h b/drivers/serial/usbtty.h
index f746d6317f71dafd3970512fec06460feccaf1c3..6b6c4a162855a3645ffcf9bcafee17172446a63b 100644
--- a/drivers/serial/usbtty.h
+++ b/drivers/serial/usbtty.h
@@ -29,6 +29,8 @@
 #include <usb/mpc8xx_udc.h>
 #elif defined(CONFIG_OMAP1510)
 #include <usb/omap1510_udc.h>
+#elif defined(CONFIG_MUSB_UDC)
+#include <usb/musb_udc.h>
 #elif defined(CONFIG_PXA27X)
 #include <usb/pxa27x_udc.h>
 #endif
diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile
index 09e0a5f32fa655604aa2000092e80eddfe43cf6d..f2ccd9fe06536a0fd9e0238019e4b15619b75aa4 100644
--- a/drivers/usb/musb/Makefile
+++ b/drivers/usb/musb/Makefile
@@ -26,7 +26,9 @@ include $(TOPDIR)/config.mk
 LIB	:= $(obj)libusb_musb.a
 
 COBJS-$(CONFIG_MUSB_HCD) += musb_hcd.o musb_core.o
+COBJS-$(CONFIG_MUSB_UDC) += musb_udc.o musb_core.o
 COBJS-$(CONFIG_USB_DAVINCI) += davinci.o
+COBJS-$(CONFIG_USB_OMAP3) += omap3.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index ec57fc811c27f55988a57eb52f56a13303e0ed36..22f3dba0cfc4c1f69e58f46cb4a9398c27febf76 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -32,7 +32,9 @@ struct musb_regs *musbr;
  */
 void musb_start(void)
 {
+#if defined(CONFIG_MUSB_HCD)
 	u8 devctl;
+#endif
 
 	/* disable all interrupts */
 	writew(0, &musbr->intrtxe);
@@ -74,9 +76,10 @@ void musb_configure_ep(struct musb_epinfo *epinfo, u8 cnt)
 			/* Configure fifo size and fifo base address */
 			writeb(idx, &musbr->txfifosz);
 			writew(fifoaddr >> 3, &musbr->txfifoadd);
+
+			csr = readw(&musbr->txcsr);
 #if defined(CONFIG_MUSB_HCD)
 			/* clear the data toggle bit */
-			csr = readw(&musbr->txcsr);
 			writew(csr | MUSB_TXCSR_CLRDATATOG, &musbr->txcsr);
 #endif
 			/* Flush fifo if required */
@@ -87,9 +90,10 @@ void musb_configure_ep(struct musb_epinfo *epinfo, u8 cnt)
 			/* Configure fifo size and fifo base address */
 			writeb(idx, &musbr->rxfifosz);
 			writew(fifoaddr >> 3, &musbr->rxfifoadd);
+
+			csr = readw(&musbr->rxcsr);
 #if defined(CONFIG_MUSB_HCD)
 			/* clear the data toggle bit */
-			csr = readw(&musbr->rxcsr);
 			writew(csr | MUSB_RXCSR_CLRDATATOG, &musbr->rxcsr);
 #endif
 			/* Flush fifo if required */
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index f9da3f0b29b28766c37ee468ba917a52124d466b..15c7f49a350dbdfd70e2fb9bb20843bf3d8ca58f 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -40,6 +40,36 @@
 
 #define MUSB_EP0_FIFOSIZE	64	/* This is non-configurable */
 
+/* EP0 */
+struct musb_ep0_regs {
+	u16	reserved4;
+	u16	csr0;
+	u16	reserved5;
+	u16	reserved6;
+	u16	count0;
+	u8	host_type0;
+	u8	host_naklimit0;
+	u8	reserved7;
+	u8	reserved8;
+	u8	reserved9;
+	u8	configdata;
+};
+
+/* EP 1-15 */
+struct musb_epN_regs {
+	u16	txmaxp;
+	u16	txcsr;
+	u16	rxmaxp;
+	u16	rxcsr;
+	u16	rxcount;
+	u8	txtype;
+	u8	txinterval;
+	u8	rxtype;
+	u8	rxinterval;
+	u8	reserved0;
+	u8	fifosize;
+};
+
 /* Mentor USB core register overlay structure */
 struct musb_regs {
 	/* common registers */
@@ -97,6 +127,16 @@ struct musb_regs {
 		u8	rxhubaddr;
 		u8	rxhubport;
 	} tar[16];
+	/*
+	 * end point registers
+	 * ep0 elements are valid when array index is 0
+	 * otherwise epN is valid
+	 */
+	union musb_ep_regs {
+		struct musb_ep0_regs ep0;
+		struct musb_epN_regs epN;
+	} ep[16];
+
 } __attribute__((aligned(32)));
 
 /*
diff --git a/drivers/usb/musb/musb_debug.h b/drivers/usb/musb/musb_debug.h
new file mode 100644
index 0000000000000000000000000000000000000000..62380ffc6516a89c5ccdcb7cfca17d85a1b550dd
--- /dev/null
+++ b/drivers/usb/musb/musb_debug.h
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2009 Wind River Systems, Inc.
+ * Tom Rix <Tom.Rix@windriver.com>
+ *
+ * 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; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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
+ */
+
+/* Define MUSB_DEBUG before including this file to get debug macros */
+#ifdef MUSB_DEBUG
+
+#define MUSB_FLAGS_PRINT(v, x, y)		\
+  if (((v) & MUSB_##x##_##y))			\
+		serial_printf("\t\t"#y"\n")
+
+static inline void musb_print_pwr(u8 b)
+{
+	serial_printf("\tpower   0x%2.2x\n", b);
+	MUSB_FLAGS_PRINT(b, POWER, ISOUPDATE);
+	MUSB_FLAGS_PRINT(b, POWER, SOFTCONN);
+	MUSB_FLAGS_PRINT(b, POWER, HSENAB);
+	MUSB_FLAGS_PRINT(b, POWER, HSMODE);
+	MUSB_FLAGS_PRINT(b, POWER, RESET);
+	MUSB_FLAGS_PRINT(b, POWER, RESUME);
+	MUSB_FLAGS_PRINT(b, POWER, SUSPENDM);
+	MUSB_FLAGS_PRINT(b, POWER, ENSUSPEND);
+}
+
+static inline void musb_print_csr0(u16 w)
+{
+	serial_printf("\tcsr0    0x%4.4x\n", w);
+	MUSB_FLAGS_PRINT(w, CSR0, FLUSHFIFO);
+	MUSB_FLAGS_PRINT(w, CSR0_P, SVDSETUPEND);
+	MUSB_FLAGS_PRINT(w, CSR0_P, SVDRXPKTRDY);
+	MUSB_FLAGS_PRINT(w, CSR0_P, SENDSTALL);
+	MUSB_FLAGS_PRINT(w, CSR0_P, SETUPEND);
+	MUSB_FLAGS_PRINT(w, CSR0_P, DATAEND);
+	MUSB_FLAGS_PRINT(w, CSR0_P, SENTSTALL);
+	MUSB_FLAGS_PRINT(w, CSR0, TXPKTRDY);
+	MUSB_FLAGS_PRINT(w, CSR0, RXPKTRDY);
+}
+
+static inline void musb_print_intrusb(u8 b)
+{
+	serial_printf("\tintrusb 0x%2.2x\n", b);
+	MUSB_FLAGS_PRINT(b, INTR, VBUSERROR);
+	MUSB_FLAGS_PRINT(b, INTR, SESSREQ);
+	MUSB_FLAGS_PRINT(b, INTR, DISCONNECT);
+	MUSB_FLAGS_PRINT(b, INTR, CONNECT);
+	MUSB_FLAGS_PRINT(b, INTR, SOF);
+	MUSB_FLAGS_PRINT(b, INTR, RESUME);
+	MUSB_FLAGS_PRINT(b, INTR, SUSPEND);
+
+	if (b & MUSB_INTR_BABBLE)
+		serial_printf("\t\tMUSB_INTR_RESET or MUSB_INTR_BABBLE\n");
+
+}
+
+static inline void musb_print_intrtx(u16 w)
+{
+	serial_printf("\tintrtx 0x%4.4x\n", w);
+}
+
+static inline void musb_print_intrrx(u16 w)
+{
+	serial_printf("\tintrx 0x%4.4x\n", w);
+}
+
+static inline void musb_print_devctl(u8 b)
+{
+	serial_printf("\tdevctl  0x%2.2x\n", b);
+	if (b & MUSB_DEVCTL_BDEVICE)
+		serial_printf("\t\tB device\n");
+	else
+		serial_printf("\t\tA device\n");
+	if (b & MUSB_DEVCTL_FSDEV)
+		serial_printf("\t\tFast Device -(host mode)\n");
+	if (b & MUSB_DEVCTL_LSDEV)
+		serial_printf("\t\tSlow Device -(host mode)\n");
+	if (b & MUSB_DEVCTL_HM)
+		serial_printf("\t\tHost mode\n");
+	else
+		serial_printf("\t\tPeripherial mode\n");
+	if (b & MUSB_DEVCTL_HR)
+		serial_printf("\t\tHost request started(B device)\n");
+	else
+		serial_printf("\t\tHost request finished(B device)\n");
+	if (b & MUSB_DEVCTL_BDEVICE) {
+		if (b & MUSB_DEVCTL_SESSION)
+			serial_printf("\t\tStart of session(B device)\n");
+		else
+			serial_printf("\t\tEnd of session(B device)\n");
+	} else {
+		if (b & MUSB_DEVCTL_SESSION)
+			serial_printf("\t\tStart of session(A device)\n");
+		else
+			serial_printf("\t\tEnd of session(A device)\n");
+	}
+}
+
+static inline void musb_print_config(u8 b)
+{
+	serial_printf("\tconfig 0x%2.2x\n", b);
+	if (b & MUSB_CONFIGDATA_MPRXE)
+		serial_printf("\t\tAuto combine rx bulk packets\n");
+	if (b & MUSB_CONFIGDATA_MPTXE)
+		serial_printf("\t\tAuto split tx bulk packets\n");
+	if (b & MUSB_CONFIGDATA_BIGENDIAN)
+		serial_printf("\t\tBig Endian ordering\n");
+	else
+		serial_printf("\t\tLittle Endian ordering\n");
+	if (b & MUSB_CONFIGDATA_HBRXE)
+		serial_printf("\t\tHigh speed rx iso endpoint\n");
+	if (b & MUSB_CONFIGDATA_HBTXE)
+		serial_printf("\t\tHigh speed tx iso endpoint\n");
+	if (b & MUSB_CONFIGDATA_DYNFIFO)
+		serial_printf("\t\tDynamic fifo sizing\n");
+	if (b & MUSB_CONFIGDATA_SOFTCONE)
+		serial_printf("\t\tSoft Connect\n");
+	if (b & MUSB_CONFIGDATA_UTMIDW)
+		serial_printf("\t\t16 bit data width\n");
+	else
+		serial_printf("\t\t8 bit data width\n");
+}
+
+static inline void musb_print_rxmaxp(u16 w)
+{
+	serial_printf("\trxmaxp  0x%4.4x\n", w);
+}
+
+static inline void musb_print_rxcsr(u16 w)
+{
+	serial_printf("\trxcsr   0x%4.4x\n", w);
+	MUSB_FLAGS_PRINT(w, RXCSR, AUTOCLEAR);
+	MUSB_FLAGS_PRINT(w, RXCSR, DMAENAB);
+	MUSB_FLAGS_PRINT(w, RXCSR, DISNYET);
+	MUSB_FLAGS_PRINT(w, RXCSR, PID_ERR);
+	MUSB_FLAGS_PRINT(w, RXCSR, DMAMODE);
+	MUSB_FLAGS_PRINT(w, RXCSR, CLRDATATOG);
+	MUSB_FLAGS_PRINT(w, RXCSR, FLUSHFIFO);
+	MUSB_FLAGS_PRINT(w, RXCSR, DATAERROR);
+	MUSB_FLAGS_PRINT(w, RXCSR, FIFOFULL);
+	MUSB_FLAGS_PRINT(w, RXCSR, RXPKTRDY);
+	MUSB_FLAGS_PRINT(w, RXCSR_P, SENTSTALL);
+	MUSB_FLAGS_PRINT(w, RXCSR_P, SENDSTALL);
+	MUSB_FLAGS_PRINT(w, RXCSR_P, OVERRUN);
+
+	if (w & MUSB_RXCSR_P_ISO)
+		serial_printf("\t\tiso mode\n");
+	else
+		serial_printf("\t\tbulk mode\n");
+
+}
+
+static inline void musb_print_txmaxp(u16 w)
+{
+	serial_printf("\ttxmaxp  0x%4.4x\n", w);
+}
+
+static inline void musb_print_txcsr(u16 w)
+{
+	serial_printf("\ttxcsr   0x%4.4x\n", w);
+	MUSB_FLAGS_PRINT(w, TXCSR, TXPKTRDY);
+	MUSB_FLAGS_PRINT(w, TXCSR, FIFONOTEMPTY);
+	MUSB_FLAGS_PRINT(w, TXCSR, FLUSHFIFO);
+	MUSB_FLAGS_PRINT(w, TXCSR, CLRDATATOG);
+	MUSB_FLAGS_PRINT(w, TXCSR_P, UNDERRUN);
+	MUSB_FLAGS_PRINT(w, TXCSR_P, SENTSTALL);
+	MUSB_FLAGS_PRINT(w, TXCSR_P, SENDSTALL);
+
+	if (w & MUSB_TXCSR_MODE)
+		serial_printf("\t\tTX mode\n");
+	else
+		serial_printf("\t\tRX mode\n");
+}
+
+#else
+
+/* stubs */
+
+#define musb_print_pwr(b)
+#define musb_print_csr0(w)
+#define musb_print_intrusb(b)
+#define musb_print_intrtx(w)
+#define musb_print_intrrx(w)
+#define musb_print_devctl(b)
+#define musb_print_config(b)
+#define musb_print_rxmaxp(w)
+#define musb_print_rxcsr(w)
+#define musb_print_txmaxp(w)
+#define musb_print_txcsr(w)
+
+#endif /* MUSB_DEBUG */
diff --git a/drivers/usb/musb/musb_udc.c b/drivers/usb/musb/musb_udc.c
new file mode 100644
index 0000000000000000000000000000000000000000..fc43cf4f09d76db4d6852ee253e7eef04665f357
--- /dev/null
+++ b/drivers/usb/musb/musb_udc.c
@@ -0,0 +1,963 @@
+/*
+ * Copyright (c) 2009 Wind River Systems, Inc.
+ * Tom Rix <Tom.Rix@windriver.com>
+ *
+ * This file is a rewrite of the usb device part of
+ * repository git.omapzoom.org/repo/u-boot.git, branch master,
+ * file cpu/omap3/fastboot.c
+ *
+ * This is the unique part of its copyright :
+ *
+ * -------------------------------------------------------------------------
+ *
+ * (C) Copyright 2008 - 2009
+ * Windriver, <www.windriver.com>
+ * Tom Rix <Tom.Rix@windriver.com>
+ *
+ * -------------------------------------------------------------------------
+ *
+ * The details of connecting the device to the uboot usb device subsystem
+ * came from the old omap3 repository www.sakoman.net/u-boot-omap3.git,
+ * branch omap3-dev-usb, file drivers/usb/usbdcore_musb.c
+ *
+ * This is the unique part of its copyright :
+ *
+ * -------------------------------------------------------------------------
+ *
+ * (C) Copyright 2008 Texas Instruments Incorporated.
+ *
+ * Based on
+ * u-boot OMAP1510 USB drivers (drivers/usbdcore_omap1510.c)
+ * twl4030 init based on linux (drivers/i2c/chips/twl4030_usb.c)
+ *
+ * Author: Diego Dompe (diego.dompe@ridgerun.com)
+ *         Atin Malaviya (atin.malaviya@gmail.com)
+ *
+ * -------------------------------------------------------------------------
+ *
+ * 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; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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
+ */
+
+#include <common.h>
+#include <usb/musb_udc.h>
+#include "../gadget/ep0.h"
+#include "musb_core.h"
+#if defined(CONFIG_USB_OMAP3)
+#include "omap3.h"
+#elif defined(CONFIG_USB_DAVINCI)
+#include "davinci.h"
+#endif
+
+/* Define MUSB_DEBUG for debugging */
+/* #define MUSB_DEBUG */
+#include "musb_debug.h"
+
+#define MAX_ENDPOINT 15
+
+#define GET_ENDPOINT(dev,ep)						\
+(((struct usb_device_instance *)(dev))->bus->endpoint_array + ep)
+
+#define SET_EP0_STATE(s)						\
+do {									\
+	if ((0 <= (s)) && (SET_ADDRESS >= (s))) {			\
+		if ((s) != ep0_state) {					\
+			if ((debug_setup) && (debug_level > 1))		\
+				serial_printf("INFO : Changing state "  \
+					      "from %s to %s in %s at " \
+					      "line %d\n",		\
+					      ep0_state_strings[ep0_state],\
+					      ep0_state_strings[s],	\
+					      __PRETTY_FUNCTION__,	\
+					      __LINE__);		\
+			ep0_state = s;					\
+		}							\
+	} else {							\
+		if (debug_level > 0)					\
+			serial_printf("Error at %s %d with setting "	\
+				      "state %d is invalid\n",		\
+				      __PRETTY_FUNCTION__, __LINE__, s); \
+	}								\
+} while (0)
+
+/* static implies these initialized to 0 or NULL */
+static int debug_setup;
+static int debug_level;
+static struct musb_epinfo epinfo[MAX_ENDPOINT * 2];
+static enum ep0_state_enum {
+	IDLE = 0,
+	TX,
+	RX,
+	SET_ADDRESS
+} ep0_state = IDLE;
+static char *ep0_state_strings[4] = {
+	"IDLE",
+	"TX",
+	"RX",
+	"SET_ADDRESS",
+};
+
+static struct urb *ep0_urb;
+struct usb_endpoint_instance *ep0_endpoint;
+static struct usb_device_instance *udc_device;
+static int enabled;
+
+#ifdef MUSB_DEBUG
+static void musb_db_regs(void)
+{
+	u8 b;
+	u16 w;
+
+	b = readb(&musbr->faddr);
+	serial_printf("\tfaddr   0x%2.2x\n", b);
+
+	b = readb(&musbr->power);
+	musb_print_pwr(b);
+
+	w = readw(&musbr->ep[0].ep0.csr0);
+	musb_print_csr0(w);
+
+	b = readb(&musbr->devctl);
+	musb_print_devctl(b);
+
+	b = readb(&musbr->ep[0].ep0.configdata);
+	musb_print_config(b);
+
+	w = readw(&musbr->frame);
+	serial_printf("\tframe   0x%4.4x\n", w);
+
+	b = readb(&musbr->index);
+	serial_printf("\tindex   0x%2.2x\n", b);
+
+	w = readw(&musbr->ep[1].epN.rxmaxp);
+	musb_print_rxmaxp(w);
+
+	w = readw(&musbr->ep[1].epN.rxcsr);
+	musb_print_rxcsr(w);
+
+	w = readw(&musbr->ep[1].epN.txmaxp);
+	musb_print_txmaxp(w);
+
+	w = readw(&musbr->ep[1].epN.txcsr);
+	musb_print_txcsr(w);
+}
+#else
+#define musb_db_regs()
+#endif /* DEBUG_MUSB */
+
+static void musb_peri_softconnect(void)
+{
+	u8 power, devctl;
+	u8 intrusb;
+	u16 intrrx, intrtx;
+
+	/* Power off MUSB */
+	power = readb(&musbr->power);
+	power &= ~MUSB_POWER_SOFTCONN;
+	writeb(power, &musbr->power);
+
+	/* Read intr to clear */
+	intrusb = readb(&musbr->intrusb);
+	intrrx = readw(&musbr->intrrx);
+	intrtx = readw(&musbr->intrtx);
+
+	udelay(1000 * 1000); /* 1 sec */
+
+	/* Power on MUSB */
+	power = readb(&musbr->power);
+	power |= MUSB_POWER_SOFTCONN;
+	/*
+	 * The usb device interface is usb 1.1
+	 * Disable 2.0 high speed by clearring the hsenable bit.
+	 */
+	power &= ~MUSB_POWER_HSENAB;
+	writeb(power, &musbr->power);
+
+	/* Check if device is in b-peripheral mode */
+	devctl = readb(&musbr->devctl);
+	if (!(devctl & MUSB_DEVCTL_BDEVICE) ||
+	    (devctl & MUSB_DEVCTL_HM)) {
+		serial_printf("ERROR : Unsupport USB mode\n");
+		serial_printf("Check that mini-B USB cable is attached "
+			      "to the device\n");
+	}
+
+	if (debug_setup && (debug_level > 1))
+		musb_db_regs();
+}
+
+static void musb_peri_reset(void)
+{
+	if ((debug_setup) && (debug_level > 1))
+		serial_printf("INFO : %s reset\n", __PRETTY_FUNCTION__);
+
+	if (ep0_endpoint)
+		ep0_endpoint->endpoint_address = 0xff;
+
+	/* Sync sw and hw addresses */
+	writeb(udc_device->address, &musbr->faddr);
+
+	SET_EP0_STATE(IDLE);
+}
+
+static void musb_peri_resume(void)
+{
+	/* noop */
+}
+
+static void musb_peri_ep0_stall(void)
+{
+	u16 csr0;
+
+	csr0 = readw(&musbr->ep[0].ep0.csr0);
+	csr0 |= MUSB_CSR0_P_SENDSTALL;
+	writew(csr0, &musbr->ep[0].ep0.csr0);
+	if ((debug_setup) && (debug_level > 1))
+		serial_printf("INFO : %s stall\n", __PRETTY_FUNCTION__);
+}
+
+static void musb_peri_ep0_ack_req(void)
+{
+	u16 csr0;
+
+	csr0 = readw(&musbr->ep[0].ep0.csr0);
+	csr0 |= MUSB_CSR0_P_SVDRXPKTRDY;
+	writew(csr0, &musbr->ep[0].ep0.csr0);
+}
+
+static void musb_ep0_tx_ready(void)
+{
+	u16 csr0;
+
+	csr0 = readw(&musbr->ep[0].ep0.csr0);
+	csr0 |= MUSB_CSR0_TXPKTRDY;
+	writew(csr0, &musbr->ep[0].ep0.csr0);
+}
+
+static void musb_ep0_tx_ready_and_last(void)
+{
+	u16 csr0;
+
+	csr0 = readw(&musbr->ep[0].ep0.csr0);
+	csr0 |= (MUSB_CSR0_TXPKTRDY | MUSB_CSR0_P_DATAEND);
+	writew(csr0, &musbr->ep[0].ep0.csr0);
+}
+
+static void musb_peri_ep0_last(void)
+{
+	u16 csr0;
+
+	csr0 = readw(&musbr->ep[0].ep0.csr0);
+	csr0 |= MUSB_CSR0_P_DATAEND;
+	writew(csr0, &musbr->ep[0].ep0.csr0);
+}
+
+static void musb_peri_ep0_set_address(void)
+{
+	u8 faddr;
+	writeb(udc_device->address, &musbr->faddr);
+
+	/* Verify */
+	faddr = readb(&musbr->faddr);
+	if (udc_device->address == faddr) {
+		SET_EP0_STATE(IDLE);
+		usbd_device_event_irq(udc_device, DEVICE_ADDRESS_ASSIGNED, 0);
+		if ((debug_setup) && (debug_level > 1))
+			serial_printf("INFO : %s Address set to %d\n",
+				      __PRETTY_FUNCTION__, udc_device->address);
+	} else {
+		if (debug_level > 0)
+			serial_printf("ERROR : %s Address missmatch "
+				      "sw %d vs hw %d\n",
+				      __PRETTY_FUNCTION__,
+				      udc_device->address, faddr);
+	}
+}
+
+static void musb_peri_rx_ack(unsigned int ep)
+{
+	u16 peri_rxcsr;
+
+	peri_rxcsr = readw(&musbr->ep[ep].epN.rxcsr);
+	peri_rxcsr &= ~MUSB_RXCSR_RXPKTRDY;
+	writew(peri_rxcsr, &musbr->ep[ep].epN.rxcsr);
+}
+
+static void musb_peri_tx_ready(unsigned int ep)
+{
+	u16 peri_txcsr;
+
+	peri_txcsr = readw(&musbr->ep[ep].epN.txcsr);
+	peri_txcsr |= MUSB_TXCSR_TXPKTRDY;
+	writew(peri_txcsr, &musbr->ep[ep].epN.txcsr);
+}
+
+static void musb_peri_ep0_zero_data_request(int err)
+{
+	musb_peri_ep0_ack_req();
+
+	if (err) {
+		musb_peri_ep0_stall();
+		SET_EP0_STATE(IDLE);
+	} else {
+
+		musb_peri_ep0_last();
+
+		/* USBD state */
+		switch (ep0_urb->device_request.bRequest) {
+		case USB_REQ_SET_ADDRESS:
+			if ((debug_setup) && (debug_level > 1))
+				serial_printf("INFO : %s received set "
+					      "address\n", __PRETTY_FUNCTION__);
+			break;
+
+		case USB_REQ_SET_CONFIGURATION:
+			if ((debug_setup) && (debug_level > 1))
+				serial_printf("INFO : %s Configured\n",
+					      __PRETTY_FUNCTION__);
+			usbd_device_event_irq(udc_device, DEVICE_CONFIGURED, 0);
+			break;
+		}
+
+		/* EP0 state */
+		if (USB_REQ_SET_ADDRESS == ep0_urb->device_request.bRequest) {
+			SET_EP0_STATE(SET_ADDRESS);
+		} else {
+			SET_EP0_STATE(IDLE);
+		}
+	}
+}
+
+static void musb_peri_ep0_rx_data_request(void)
+{
+	/*
+	 * This is the completion of the data OUT / RX
+	 *
+	 * Host is sending data to ep0 that is not
+	 * part of setup.  This comes from the cdc_recv_setup
+	 * op that is device specific.
+	 *
+	 */
+	musb_peri_ep0_ack_req();
+
+	ep0_endpoint->rcv_urb = ep0_urb;
+	ep0_urb->actual_length = 0;
+	SET_EP0_STATE(RX);
+}
+
+static void musb_peri_ep0_tx_data_request(int err)
+{
+	if (err) {
+		musb_peri_ep0_stall();
+		SET_EP0_STATE(IDLE);
+	} else {
+		musb_peri_ep0_ack_req();
+
+		ep0_endpoint->tx_urb = ep0_urb;
+		ep0_endpoint->sent = 0;
+		SET_EP0_STATE(TX);
+	}
+}
+
+static void musb_peri_ep0_idle(void)
+{
+	u16 count0;
+	int err;
+	u16 csr0;
+
+	/*
+	 * Verify addresses
+	 * A lot of confusion can be caused if the address
+	 * in software, udc layer, does not agree with the
+	 * hardware.  Since the setting of the hardware address
+	 * must be set after the set address request, the
+	 * usb state machine is out of sync for a few frame.
+	 * It is a good idea to run this check when changes
+	 * are made to the state machine.
+	 */
+	if ((debug_level > 0) &&
+	    (ep0_state != SET_ADDRESS)) {
+		u8 faddr;
+
+		faddr = readb(&musbr->faddr);
+		if (udc_device->address != faddr) {
+			serial_printf("ERROR : %s addresses do not"
+				      "match sw %d vs hw %d\n",
+				      __PRETTY_FUNCTION__,
+				      udc_device->address, faddr);
+			udelay(1000 * 1000);
+			hang();
+		}
+	}
+
+	csr0 = readw(&musbr->ep[0].ep0.csr0);
+
+	if (!(MUSB_CSR0_RXPKTRDY & csr0))
+		goto end;
+
+	count0 = readw(&musbr->ep[0].ep0.count0);
+	if (count0 == 0)
+		goto end;
+
+	if (count0 != 8) {
+		if ((debug_setup) && (debug_level > 1))
+			serial_printf("WARN : %s SETUP incorrect size %d\n",
+				      __PRETTY_FUNCTION__, count0);
+		musb_peri_ep0_stall();
+		goto end;
+	}
+
+	read_fifo(0, count0, &ep0_urb->device_request);
+
+	if (debug_level > 2)
+		print_usb_device_request(&ep0_urb->device_request);
+
+	if (ep0_urb->device_request.wLength == 0) {
+		err = ep0_recv_setup(ep0_urb);
+
+		/* Zero data request */
+		musb_peri_ep0_zero_data_request(err);
+	} else {
+		/* Is data coming or going ? */
+		u8 reqType = ep0_urb->device_request.bmRequestType;
+
+		if (USB_REQ_DEVICE2HOST == (reqType & USB_REQ_DIRECTION_MASK)) {
+			err = ep0_recv_setup(ep0_urb);
+			/* Device to host */
+			musb_peri_ep0_tx_data_request(err);
+		} else {
+			/*
+			 * Host to device
+			 *
+			 * The RX routine will call ep0_recv_setup
+			 * when the data packet has arrived.
+			 */
+			musb_peri_ep0_rx_data_request();
+		}
+	}
+
+end:
+	return;
+}
+
+static void musb_peri_ep0_rx(void)
+{
+	/*
+	 * This is the completion of the data OUT / RX
+	 *
+	 * Host is sending data to ep0 that is not
+	 * part of setup.  This comes from the cdc_recv_setup
+	 * op that is device specific.
+	 *
+	 * Pass the data back to driver ep0_recv_setup which
+	 * should give the cdc_recv_setup the chance to handle
+	 * the rx
+	 */
+	u16 csr0;
+	u16 count0;
+
+	if (debug_level > 3) {
+		if (0 != ep0_urb->actual_length) {
+			serial_printf("%s finished ? %d of %d\n",
+				      __PRETTY_FUNCTION__,
+				      ep0_urb->actual_length,
+				      ep0_urb->device_request.wLength);
+		}
+	}
+
+	if (ep0_urb->device_request.wLength == ep0_urb->actual_length) {
+		musb_peri_ep0_last();
+		SET_EP0_STATE(IDLE);
+		ep0_recv_setup(ep0_urb);
+		return;
+	}
+
+	csr0 = readw(&musbr->ep[0].ep0.csr0);
+	if (!(MUSB_CSR0_RXPKTRDY & csr0))
+		return;
+
+	count0 = readw(&musbr->ep[0].ep0.count0);
+
+	if (count0) {
+		struct usb_endpoint_instance *endpoint;
+		u32 length;
+		u8 *data;
+
+		endpoint = ep0_endpoint;
+		if (endpoint && endpoint->rcv_urb) {
+			struct urb *urb = endpoint->rcv_urb;
+			unsigned int remaining_space = urb->buffer_length -
+				urb->actual_length;
+
+			if (remaining_space) {
+				int urb_bad = 0; /* urb is good */
+
+				if (count0 > remaining_space)
+					length = remaining_space;
+				else
+					length = count0;
+
+				data = (u8 *) urb->buffer_data;
+				data += urb->actual_length;
+
+				/* The common musb fifo reader */
+				read_fifo(0, length, data);
+
+				musb_peri_ep0_ack_req();
+
+				/*
+				 * urb's actual_length is updated in
+				 * usbd_rcv_complete
+				 */
+				usbd_rcv_complete(endpoint, length, urb_bad);
+
+			} else {
+				if (debug_level > 0)
+					serial_printf("ERROR : %s no space in "
+						      "rcv buffer\n",
+						      __PRETTY_FUNCTION__);
+			}
+		} else {
+			if (debug_level > 0)
+				serial_printf("ERROR : %s problem with "
+					      "endpoint\n",
+					      __PRETTY_FUNCTION__);
+		}
+	} else {
+		if (debug_level > 0)
+			serial_printf("ERROR : %s with nothing to do\n",
+				      __PRETTY_FUNCTION__);
+	}
+}
+
+static void musb_peri_ep0_tx(void)
+{
+	u16 csr0;
+	int transfer_size = 0;
+	unsigned int p, pm;
+
+	csr0 = readw(&musbr->ep[0].ep0.csr0);
+
+	/* Check for pending tx */
+	if (csr0 & MUSB_CSR0_TXPKTRDY)
+		goto end;
+
+	/* Check if this is the last packet sent */
+	if (ep0_endpoint->sent >= ep0_urb->actual_length) {
+		SET_EP0_STATE(IDLE);
+		goto end;
+	}
+
+	transfer_size = ep0_urb->actual_length - ep0_endpoint->sent;
+	/* Is the transfer size negative ? */
+	if (transfer_size <= 0) {
+		if (debug_level > 0)
+			serial_printf("ERROR : %s problem with the"
+				      " transfer size %d\n",
+				      __PRETTY_FUNCTION__,
+				      transfer_size);
+		SET_EP0_STATE(IDLE);
+		goto end;
+	}
+
+	/* Truncate large transfers to the fifo size */
+	if (transfer_size > ep0_endpoint->tx_packetSize)
+		transfer_size = ep0_endpoint->tx_packetSize;
+
+	write_fifo(0, transfer_size, &ep0_urb->buffer[ep0_endpoint->sent]);
+	ep0_endpoint->sent += transfer_size;
+
+	/* Done or more to send ? */
+	if (ep0_endpoint->sent >= ep0_urb->actual_length)
+		musb_ep0_tx_ready_and_last();
+	else
+		musb_ep0_tx_ready();
+
+	/* Wait a bit */
+	pm = 10;
+	for (p = 0; p < pm; p++) {
+		csr0 = readw(&musbr->ep[0].ep0.csr0);
+		if (!(csr0 & MUSB_CSR0_TXPKTRDY))
+			break;
+
+		/* Double the delay. */
+		udelay(1 << pm);
+	}
+
+	if ((ep0_endpoint->sent >= ep0_urb->actual_length) && (p < pm))
+		SET_EP0_STATE(IDLE);
+
+end:
+	return;
+}
+
+static void musb_peri_ep0(void)
+{
+	u16 csr0;
+
+	if (SET_ADDRESS == ep0_state)
+		return;
+
+	csr0 = readw(&musbr->ep[0].ep0.csr0);
+
+	/* Error conditions */
+	if (MUSB_CSR0_P_SENTSTALL & csr0) {
+		csr0 &= ~MUSB_CSR0_P_SENTSTALL;
+		writew(csr0, &musbr->ep[0].ep0.csr0);
+		SET_EP0_STATE(IDLE);
+	}
+	if (MUSB_CSR0_P_SETUPEND & csr0) {
+		csr0 |= MUSB_CSR0_P_SVDSETUPEND;
+		writew(csr0, &musbr->ep[0].ep0.csr0);
+		SET_EP0_STATE(IDLE);
+		if ((debug_setup) && (debug_level > 1))
+			serial_printf("WARN: %s SETUPEND\n",
+				      __PRETTY_FUNCTION__);
+	}
+
+	/* Normal states */
+	if (IDLE == ep0_state)
+		musb_peri_ep0_idle();
+
+	if (TX == ep0_state)
+		musb_peri_ep0_tx();
+
+	if (RX == ep0_state)
+		musb_peri_ep0_rx();
+}
+
+static void musb_peri_rx_ep(unsigned int ep)
+{
+	u16 peri_rxcount = readw(&musbr->ep[ep].epN.rxcount);
+
+	if (peri_rxcount) {
+		struct usb_endpoint_instance *endpoint;
+		u32 length;
+		u8 *data;
+
+		endpoint = GET_ENDPOINT(udc_device, ep);
+		if (endpoint && endpoint->rcv_urb) {
+			struct urb *urb = endpoint->rcv_urb;
+			unsigned int remaining_space = urb->buffer_length -
+				urb->actual_length;
+
+			if (remaining_space) {
+				int urb_bad = 0; /* urb is good */
+
+				if (peri_rxcount > remaining_space)
+					length = remaining_space;
+				else
+					length = peri_rxcount;
+
+				data = (u8 *) urb->buffer_data;
+				data += urb->actual_length;
+
+				/* The common musb fifo reader */
+				read_fifo(ep, length, data);
+
+				musb_peri_rx_ack(ep);
+
+				/*
+				 * urb's actual_length is updated in
+				 * usbd_rcv_complete
+				 */
+				usbd_rcv_complete(endpoint, length, urb_bad);
+
+			} else {
+				if (debug_level > 0)
+					serial_printf("ERROR : %s %d no space "
+						      "in rcv buffer\n",
+						      __PRETTY_FUNCTION__, ep);
+			}
+		} else {
+			if (debug_level > 0)
+				serial_printf("ERROR : %s %d problem with "
+					      "endpoint\n",
+					      __PRETTY_FUNCTION__, ep);
+		}
+
+	} else {
+		if (debug_level > 0)
+			serial_printf("ERROR : %s %d with nothing to do\n",
+				      __PRETTY_FUNCTION__, ep);
+	}
+}
+
+static void musb_peri_rx(u16 intr)
+{
+	unsigned int ep;
+
+	/* Check for EP0 */
+	if (0x01 & intr)
+		musb_peri_ep0();
+
+	for (ep = 1; ep < 16; ep++) {
+		if ((1 << ep) & intr)
+			musb_peri_rx_ep(ep);
+	}
+}
+
+static void musb_peri_tx(u16 intr)
+{
+	/* Check for EP0 */
+	if (0x01 & intr)
+		musb_peri_ep0_tx();
+
+	/*
+	 * Use this in the future when handling epN tx
+	 *
+	 * u8 ep;
+	 *
+	 * for (ep = 1; ep < 16; ep++) {
+	 *	if ((1 << ep) & intr) {
+	 *		/ * handle tx for this endpoint * /
+	 *	}
+	 * }
+	 */
+}
+
+void udc_irq(void)
+{
+	/* This is a high freq called function */
+	if (enabled) {
+		u8 intrusb;
+
+		intrusb = readb(&musbr->intrusb);
+
+		/*
+		 * See drivers/usb/gadget/mpc8xx_udc.c for
+		 * state diagram going from detached through
+		 * configuration.
+		 */
+		if (MUSB_INTR_RESUME & intrusb) {
+			usbd_device_event_irq(udc_device,
+					      DEVICE_BUS_ACTIVITY, 0);
+			musb_peri_resume();
+		}
+
+		musb_peri_ep0();
+
+		if (MUSB_INTR_RESET & intrusb) {
+			usbd_device_event_irq(udc_device, DEVICE_RESET, 0);
+			musb_peri_reset();
+		}
+
+		if (MUSB_INTR_DISCONNECT & intrusb) {
+			/* cable unplugged from hub/host */
+			usbd_device_event_irq(udc_device, DEVICE_RESET, 0);
+			musb_peri_reset();
+			usbd_device_event_irq(udc_device, DEVICE_HUB_RESET, 0);
+		}
+
+		if (MUSB_INTR_SOF & intrusb) {
+			usbd_device_event_irq(udc_device,
+					      DEVICE_BUS_ACTIVITY, 0);
+			musb_peri_resume();
+		}
+
+		if (MUSB_INTR_SUSPEND & intrusb) {
+			usbd_device_event_irq(udc_device,
+					      DEVICE_BUS_INACTIVE, 0);
+		}
+
+		if (ep0_state != SET_ADDRESS) {
+			u16 intrrx, intrtx;
+
+			intrrx = readw(&musbr->intrrx);
+			intrtx = readw(&musbr->intrtx);
+
+			if (intrrx)
+				musb_peri_rx(intrrx);
+
+			if (intrtx)
+				musb_peri_tx(intrtx);
+		} else {
+			if (MUSB_INTR_SOF & intrusb) {
+				u8 faddr;
+				faddr = readb(&musbr->faddr);
+				/*
+				 * Setting of the address can fail.
+				 * Normally it succeeds the second time.
+				 */
+				if (udc_device->address != faddr)
+					musb_peri_ep0_set_address();
+			}
+		}
+	}
+}
+
+void udc_set_nak(int ep_num)
+{
+	/* noop */
+}
+
+void udc_unset_nak(int ep_num)
+{
+	/* noop */
+}
+
+int udc_endpoint_write(struct usb_endpoint_instance *endpoint)
+{
+	int ret = 0;
+
+	/* Transmit only if the hardware is available */
+	if (endpoint->tx_urb && endpoint->state == 0) {
+		unsigned int ep = endpoint->endpoint_address &
+			USB_ENDPOINT_NUMBER_MASK;
+
+		u16 peri_txcsr = readw(&musbr->ep[ep].epN.txcsr);
+
+		/* Error conditions */
+		if (peri_txcsr & MUSB_TXCSR_P_UNDERRUN) {
+			peri_txcsr &= ~MUSB_TXCSR_P_UNDERRUN;
+			writew(peri_txcsr, &musbr->ep[ep].epN.txcsr);
+		}
+
+		if (debug_level > 1)
+			musb_print_txcsr(peri_txcsr);
+
+		/* Check if a packet is waiting to be sent */
+		if (!(peri_txcsr & MUSB_TXCSR_TXPKTRDY)) {
+			u32 length;
+			u8 *data;
+			struct urb *urb = endpoint->tx_urb;
+			unsigned int remaining_packet = urb->actual_length -
+				endpoint->sent;
+
+			if (endpoint->tx_packetSize < remaining_packet)
+				length = endpoint->tx_packetSize;
+			else
+				length = remaining_packet;
+
+			data = (u8 *) urb->buffer;
+			data += endpoint->sent;
+
+			/* common musb fifo function */
+			write_fifo(ep, length, data);
+
+			musb_peri_tx_ready(ep);
+
+			endpoint->last = length;
+			/* usbd_tx_complete will take care of updating 'sent' */
+			usbd_tx_complete(endpoint);
+		}
+	} else {
+		if (debug_level > 0)
+			serial_printf("ERROR : %s Problem with urb %p "
+				      "or ep state %d\n",
+				      __PRETTY_FUNCTION__,
+				      endpoint->tx_urb, endpoint->state);
+	}
+
+	return ret;
+}
+
+void udc_setup_ep(struct usb_device_instance *device, unsigned int id,
+		  struct usb_endpoint_instance *endpoint)
+{
+	if (0 == id) {
+		/* EP0 */
+		ep0_endpoint = endpoint;
+		ep0_endpoint->endpoint_address = 0xff;
+		ep0_urb = usbd_alloc_urb(device, endpoint);
+	} else if (MAX_ENDPOINT >= id) {
+		int ep_addr;
+
+		/* Check the direction */
+		ep_addr = endpoint->endpoint_address;
+		if (USB_DIR_IN == (ep_addr & USB_ENDPOINT_DIR_MASK)) {
+			/* IN */
+			epinfo[(id * 2) + 1].epsize = endpoint->tx_packetSize;
+		} else {
+			/* OUT */
+			epinfo[id * 2].epsize = endpoint->rcv_packetSize;
+		}
+
+		musb_configure_ep(&epinfo[0],
+				  sizeof(epinfo) / sizeof(struct musb_epinfo));
+	} else {
+		if (debug_level > 0)
+			serial_printf("ERROR : %s endpoint request %d "
+				      "exceeds maximum %d\n",
+				      __PRETTY_FUNCTION__, id, MAX_ENDPOINT);
+	}
+}
+
+void udc_connect(void)
+{
+	/* noop */
+}
+
+void udc_disconnect(void)
+{
+	/* noop */
+}
+
+void udc_enable(struct usb_device_instance *device)
+{
+	/* Save the device structure pointer */
+	udc_device = device;
+
+	enabled = 1;
+}
+
+void udc_disable(void)
+{
+	enabled = 0;
+}
+
+void udc_startup_events(struct usb_device_instance *device)
+{
+	/* The DEVICE_INIT event puts the USB device in the state STATE_INIT. */
+	usbd_device_event_irq(device, DEVICE_INIT, 0);
+
+	/*
+	 * The DEVICE_CREATE event puts the USB device in the state
+	 * STATE_ATTACHED.
+	 */
+	usbd_device_event_irq(device, DEVICE_CREATE, 0);
+
+	/* Resets the address to 0 */
+	usbd_device_event_irq(device, DEVICE_RESET, 0);
+
+	udc_enable(device);
+}
+
+int udc_init(void)
+{
+	int ret;
+	int ep_loop;
+
+	ret = musb_platform_init();
+	if (ret < 0)
+		goto end;
+
+	/* Configure all the endpoint FIFO's and start usb controller */
+	musbr = musb_cfg.regs;
+
+	/* Initialize the endpoints */
+	for (ep_loop = 0; ep_loop < MAX_ENDPOINT * 2; ep_loop++) {
+		epinfo[ep_loop].epnum = (ep_loop / 2) + 1;
+		epinfo[ep_loop].epdir = ep_loop % 2; /* OUT, IN */
+		epinfo[ep_loop].epsize = 0;
+	}
+
+	musb_peri_softconnect();
+
+	ret = 0;
+end:
+
+	return ret;
+}
diff --git a/drivers/usb/musb/omap3.c b/drivers/usb/musb/omap3.c
new file mode 100644
index 0000000000000000000000000000000000000000..3e502e7d853dd9e2ca9e766a28c31bbf8b7eef2e
--- /dev/null
+++ b/drivers/usb/musb/omap3.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2009 Wind River Systems, Inc.
+ * Tom Rix <Tom.Rix@windriver.com>
+ *
+ * This is file is based on
+ * repository git.gitorious.org/u-boot-omap3/mainline.git,
+ * branch omap3-dev-usb, file drivers/usb/host/omap3530_usb.c
+ *
+ * This is the unique part of its copyright :
+ *
+ * ------------------------------------------------------------------------
+ *
+ * Copyright (c) 2009 Texas Instruments
+ *
+ * ------------------------------------------------------------------------
+ *
+ * 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; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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
+ */
+
+#include <twl4030.h>
+#include "omap3.h"
+
+static int platform_needs_initialization = 1;
+
+struct musb_config musb_cfg = {
+	(struct	musb_regs *)MENTOR_USB0_BASE,
+	OMAP3_USB_TIMEOUT,
+	0
+};
+
+/*
+ * OMAP3 USB OTG registers.
+ */
+struct omap3_otg_regs {
+	u32	revision;
+	u32	sysconfig;
+	u32	sysstatus;
+	u32	interfsel;
+	u32	simenable;
+	u32	forcestdby;
+};
+
+static struct omap3_otg_regs *otg;
+
+#define OMAP3_OTG_SYSCONFIG_SMART_STANDBY_MODE		0x2000
+#define OMAP3_OTG_SYSCONFIG_NO_STANDBY_MODE		0x1000
+#define OMAP3_OTG_SYSCONFIG_SMART_IDLE_MODE		0x0010
+#define OMAP3_OTG_SYSCONFIG_NO_IDLE_MODE		0x0008
+#define OMAP3_OTG_SYSCONFIG_ENABLEWAKEUP		0x0004
+#define OMAP3_OTG_SYSCONFIG_SOFTRESET			0x0002
+#define OMAP3_OTG_SYSCONFIG_AUTOIDLE			0x0001
+
+#define OMAP3_OTG_SYSSTATUS_RESETDONE			0x0001
+
+#define OMAP3_OTG_INTERFSEL_OMAP			0x0001
+
+#define OMAP3_OTG_FORCESTDBY_STANDBY			0x0001
+
+
+#ifdef DEBUG_MUSB_OMAP3
+static void musb_db_otg_regs(void)
+{
+	u32 l;
+	l = readl(&otg->revision);
+	serial_printf("OTG_REVISION 0x%x\n", l);
+	l = readl(&otg->sysconfig);
+	serial_printf("OTG_SYSCONFIG 0x%x\n", l);
+	l = readl(&otg->sysstatus);
+	serial_printf("OTG_SYSSTATUS 0x%x\n", l);
+	l = readl(&otg->interfsel);
+	serial_printf("OTG_INTERFSEL 0x%x\n", l);
+	l = readl(&otg->forcestdby);
+	serial_printf("OTG_FORCESTDBY 0x%x\n", l);
+}
+#endif
+
+int musb_platform_init(void)
+{
+	int ret = -1;
+
+	if (platform_needs_initialization) {
+		u32 stdby;
+
+		if (twl4030_usb_ulpi_init()) {
+			serial_printf("ERROR: %s Could not initialize PHY\n",
+				__PRETTY_FUNCTION__);
+			goto end;
+		}
+
+		otg = (struct omap3_otg_regs *)OMAP3_OTG_BASE;
+
+		/* Set OTG to always be on */
+		writel(OMAP3_OTG_SYSCONFIG_NO_STANDBY_MODE |
+		       OMAP3_OTG_SYSCONFIG_NO_IDLE_MODE, &otg->sysconfig);
+
+		/* Set the interface */
+		writel(OMAP3_OTG_INTERFSEL_OMAP, &otg->interfsel);
+
+		/* Clear force standby */
+		stdby = readl(&otg->forcestdby);
+		stdby &= ~OMAP3_OTG_FORCESTDBY_STANDBY;
+		writel(stdby, &otg->forcestdby);
+
+		platform_needs_initialization = 0;
+	}
+
+	ret = platform_needs_initialization;
+end:
+	return ret;
+
+}
+
+void musb_platform_deinit(void)
+{
+	/* noop */
+}
diff --git a/drivers/usb/musb/omap3.h b/drivers/usb/musb/omap3.h
new file mode 100644
index 0000000000000000000000000000000000000000..20fc9d294a291978d55eb10a0e999070f8c3026a
--- /dev/null
+++ b/drivers/usb/musb/omap3.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2009 Wind River Systems, Inc.
+ * Tom Rix <Tom.Rix@windriver.com>
+ *
+ * This file is based on the file drivers/usb/musb/davinci.h
+ *
+ * This is the unique part of its copyright:
+ *
+ * --------------------------------------------------------------------
+ *
+ * Copyright (c) 2008 Texas Instruments
+ * Author: Thomas Abraham t-abraham@ti.com, Texas Instruments
+ *
+ * --------------------------------------------------------------------
+ *
+ * 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; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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 _MUSB_OMAP3_H_
+#define _MUSB_OMAP3_H_
+
+#include "musb_core.h"
+
+/* Base address of MUSB registers */
+#define MENTOR_USB0_BASE (OMAP34XX_CORE_L4_IO_BASE + 0xAB000)
+
+/* Base address of OTG registers */
+#define OMAP3_OTG_BASE (MENTOR_USB0_BASE + 0x400)
+
+/* Timeout for USB module */
+#define OMAP3_USB_TIMEOUT 0x3FFFFFF
+
+int musb_platform_init(void);
+
+#endif /* _MUSB_OMAP3_H */
+
diff --git a/include/usb.h b/include/usb.h
index 4148d67e121261df0e50ff7b9f1fb83d6dc74afd..1cc3e4229daed2c528da4e16d73e601a616a15ea 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -131,7 +131,8 @@ struct usb_device {
 #if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || \
 	defined(CONFIG_USB_EHCI) || defined(CONFIG_USB_OHCI_NEW) || \
 	defined(CONFIG_USB_SL811HS) || defined(CONFIG_USB_ISP116X_HCD) || \
-	defined(CONFIG_USB_R8A66597_HCD) || defined(CONFIG_USB_DAVINCI)
+	defined(CONFIG_USB_R8A66597_HCD) || defined(CONFIG_USB_DAVINCI) || \
+	defined(CONFIG_USB_OMAP3)
 
 int usb_lowlevel_init(void);
 int usb_lowlevel_stop(void);
diff --git a/include/usb/musb_udc.h b/include/usb/musb_udc.h
new file mode 100644
index 0000000000000000000000000000000000000000..ef37dbbcc4ad63367585b2f057412db5769d29aa
--- /dev/null
+++ b/include/usb/musb_udc.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2009 Wind River Systems, Inc.
+ * Tom Rix <Tom.Rix@windriver.com>
+ *
+ * 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; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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 __MUSB_UDC_H__
+#define __MUSB_UDC_H__
+
+#include <usbdevice.h>
+
+/* UDC level routines */
+void udc_irq(void);
+void udc_set_nak(int ep_num);
+void udc_unset_nak(int ep_num);
+int udc_endpoint_write(struct usb_endpoint_instance *endpoint);
+void udc_setup_ep(struct usb_device_instance *device, unsigned int id,
+		  struct usb_endpoint_instance *endpoint);
+void udc_connect(void);
+void udc_disconnect(void);
+void udc_enable(struct usb_device_instance *device);
+void udc_disable(void);
+void udc_startup_events(struct usb_device_instance *device);
+int udc_init(void);
+
+/* usbtty */
+#ifdef CONFIG_USB_TTY
+
+#define EP0_MAX_PACKET_SIZE	64 /* MUSB_EP0_FIFOSIZE */
+#define UDC_INT_ENDPOINT	1
+#define UDC_INT_PACKET_SIZE	64
+#define UDC_OUT_ENDPOINT	2
+#define UDC_OUT_PACKET_SIZE	64
+#define UDC_IN_ENDPOINT		3
+#define UDC_IN_PACKET_SIZE	64
+#define UDC_BULK_PACKET_SIZE	64
+
+#endif /* CONFIG_USB_TTY */
+
+#endif /* __MUSB_UDC_H__ */
+