Merge branch 'master' of git://git.denx.de/u-boot-usb
diff --git a/Makefile b/Makefile
index 28eda69..ed6156f 100644
--- a/Makefile
+++ b/Makefile
@@ -241,6 +241,7 @@
 LIBS += drivers/usb/gadget/libusb_gadget.a
 LIBS += drivers/usb/host/libusb_host.a
 LIBS += drivers/usb/musb/libusb_musb.a
+LIBS += drivers/usb/phy/libusb_phy.a
 LIBS += drivers/video/libvideo.a
 LIBS += drivers/watchdog/libwatchdog.a
 LIBS += common/libcommon.a
diff --git a/board/logicpd/zoom2/zoom2_serial.c b/board/logicpd/zoom2/zoom2_serial.c
index a3d777d..ba58e39 100644
--- a/board/logicpd/zoom2/zoom2_serial.c
+++ b/board/logicpd/zoom2/zoom2_serial.c
@@ -86,6 +86,8 @@
 			quad_putc_dev (base, '\r');
 
 		NS16550_putc ((NS16550_t) base, c);
+	} else {
+		usbtty_putc(c);
 	}
 }
 
@@ -94,6 +96,8 @@
 	if (zoom2_debug_board_connected ()) {
 		while ((s != NULL) && (*s != '\0'))
 			quad_putc_dev (base, *s++);
+	} else {
+		usbtty_puts(s);
 	}
 }
 
@@ -101,16 +105,16 @@
 {
 	if (zoom2_debug_board_connected ())
 		return NS16550_getc ((NS16550_t) base);
-	else
-		return 0;
+
+	return usbtty_getc();
 }
 
 int quad_tstc_dev (unsigned long base)
 {
 	if (zoom2_debug_board_connected ())
 		return NS16550_tstc ((NS16550_t) base);
-	else
-		return 0;
+
+	return usbtty_tstc();
 }
 
 void quad_setbrg_dev (unsigned long base)
diff --git a/common/cmd_usb.c b/common/cmd_usb.c
index 7b8ee6b..9de515c 100644
--- a/common/cmd_usb.c
+++ b/common/cmd_usb.c
@@ -157,7 +157,7 @@
 {
 	if (dev->descriptor.bDescriptorType == USB_DT_DEVICE) {
 		printf("%d: %s,  USB Revision %x.%x\n", dev->devnum,
-		usb_get_class_desc(dev->config.if_desc[0].bInterfaceClass),
+		usb_get_class_desc(dev->config.if_desc[0].desc.bInterfaceClass),
 				   (dev->descriptor.bcdUSB>>8) & 0xff,
 				   dev->descriptor.bcdUSB & 0xff);
 
@@ -174,7 +174,7 @@
 		} else {
 			printf(" - Class: (from Interface) %s\n",
 			       usb_get_class_desc(
-				dev->config.if_desc[0].bInterfaceClass));
+				dev->config.if_desc[0].desc.bInterfaceClass));
 		}
 		printf(" - PacketSize: %d  Configurations: %d\n",
 			dev->descriptor.bMaxPacketSize0,
@@ -187,14 +187,14 @@
 
 }
 
-void usb_display_conf_desc(struct usb_config_descriptor *config,
+void usb_display_conf_desc(struct usb_configuration_descriptor *config,
 			   struct usb_device *dev)
 {
 	printf("   Configuration: %d\n", config->bConfigurationValue);
 	printf("   - Interfaces: %d %s%s%dmA\n", config->bNumInterfaces,
 	       (config->bmAttributes & 0x40) ? "Self Powered " : "Bus Powered ",
 	       (config->bmAttributes & 0x20) ? "Remote Wakeup " : "",
-		config->MaxPower*2);
+		config->bMaxPower*2);
 	if (config->iConfiguration) {
 		printf("   - ");
 		usb_display_string(dev, config->iConfiguration);
@@ -246,16 +246,16 @@
 /* main routine to diasplay the configs, interfaces and endpoints */
 void usb_display_config(struct usb_device *dev)
 {
-	struct usb_config_descriptor *config;
-	struct usb_interface_descriptor *ifdesc;
+	struct usb_config *config;
+	struct usb_interface *ifdesc;
 	struct usb_endpoint_descriptor *epdesc;
 	int i, ii;
 
 	config = &dev->config;
-	usb_display_conf_desc(config, dev);
+	usb_display_conf_desc(&config->desc, dev);
 	for (i = 0; i < config->no_of_if; i++) {
 		ifdesc = &config->if_desc[i];
-		usb_display_if_desc(ifdesc, dev);
+		usb_display_if_desc(&ifdesc->desc, dev);
 		for (ii = 0; ii < ifdesc->no_of_ep; ii++) {
 			epdesc = &ifdesc->ep_desc[ii];
 			usb_display_ep_desc(epdesc);
@@ -319,9 +319,9 @@
 	pre[index++] = has_child ? '|' : ' ';
 	pre[index] = 0;
 	printf(" %s (%s, %dmA)\n", usb_get_class_desc(
-					dev->config.if_desc[0].bInterfaceClass),
+					dev->config.if_desc[0].desc.bInterfaceClass),
 					portspeed(dev->speed),
-					dev->config.MaxPower * 2);
+					dev->config.desc.bMaxPower * 2);
 	if (strlen(dev->mf) || strlen(dev->prod) || strlen(dev->serial))
 		printf(" %s  %s %s %s\n", pre, dev->mf, dev->prod, dev->serial);
 	printf(" %s\n", pre);
@@ -642,6 +642,28 @@
 			return 1;
 		}
 	}
+	if (strcmp(argv[1], "write") == 0) {
+		if (usb_stor_curr_dev < 0) {
+			printf("no current device selected\n");
+			return 1;
+		}
+		if (argc == 5) {
+			unsigned long addr = simple_strtoul(argv[2], NULL, 16);
+			unsigned long blk  = simple_strtoul(argv[3], NULL, 16);
+			unsigned long cnt  = simple_strtoul(argv[4], NULL, 16);
+			unsigned long n;
+			printf("\nUSB write: device %d block # %ld, count %ld"
+				" ... ", usb_stor_curr_dev, blk, cnt);
+			stor_dev = usb_stor_get_dev(usb_stor_curr_dev);
+			n = stor_dev->block_write(usb_stor_curr_dev, blk, cnt,
+						(ulong *)addr);
+			printf("%ld blocks write: %s\n", n,
+				(n == cnt) ? "OK" : "ERROR");
+			if (n == cnt)
+				return 0;
+			return 1;
+		}
+	}
 	if (strncmp(argv[1], "dev", 3) == 0) {
 		if (argc == 3) {
 			int dev = (int)simple_strtoul(argv[2], NULL, 10);
@@ -687,6 +709,8 @@
 	" devices\n"
 	"usb read addr blk# cnt - read `cnt' blocks starting at block `blk#'\n"
 	"    to memory address `addr'"
+	"usb write addr blk# cnt - write `cnt' blocks starting at block `blk#'\n"
+	"    from memory address `addr'"
 );
 
 
diff --git a/common/usb.c b/common/usb.c
index 87fca70..eef4b34 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -299,8 +299,8 @@
 {
 	int i, ii;
 
-	for (i = 0; i < dev->config.bNumInterfaces; i++)
-		for (ii = 0; ii < dev->config.if_desc[i].bNumEndpoints; ii++)
+	for (i = 0; i < dev->config.desc.bNumInterfaces; i++)
+		for (ii = 0; ii < dev->config.if_desc[i].desc.bNumEndpoints; ii++)
 			usb_set_maxpacket_ep(dev,
 					  &dev->config.if_desc[i].ep_desc[ii]);
 
@@ -330,14 +330,14 @@
 		return -1;
 	}
 	memcpy(&dev->config, buffer, buffer[0]);
-	le16_to_cpus(&(dev->config.wTotalLength));
+	le16_to_cpus(&(dev->config.desc.wTotalLength));
 	dev->config.no_of_if = 0;
 
-	index = dev->config.bLength;
+	index = dev->config.desc.bLength;
 	/* Ok the first entry must be a configuration entry,
 	 * now process the others */
 	head = (struct usb_descriptor_header *) &buffer[index];
-	while (index + 1 < dev->config.wTotalLength) {
+	while (index + 1 < dev->config.desc.wTotalLength) {
 		switch (head->bDescriptorType) {
 		case USB_DT_INTERFACE:
 			if (((struct usb_interface_descriptor *) \
@@ -350,7 +350,7 @@
 				dev->config.if_desc[ifno].no_of_ep = 0;
 				dev->config.if_desc[ifno].num_altsetting = 1;
 				curr_if_num =
-				     dev->config.if_desc[ifno].bInterfaceNumber;
+				     dev->config.if_desc[ifno].desc.bInterfaceNumber;
 			} else {
 				/* found alternate setting for the interface */
 				dev->config.if_desc[ifno].num_altsetting++;
@@ -440,10 +440,9 @@
 {
 	int result;
 	unsigned int tmp;
-	struct usb_config_descriptor *config;
+	struct usb_configuration_descriptor *config;
 
-
-	config = (struct usb_config_descriptor *)&buffer[0];
+	config = (struct usb_configuration_descriptor *)&buffer[0];
 	result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, 9);
 	if (result < 9) {
 		if (result < 0)
@@ -489,11 +488,11 @@
  */
 int usb_set_interface(struct usb_device *dev, int interface, int alternate)
 {
-	struct usb_interface_descriptor *if_face = NULL;
+	struct usb_interface *if_face = NULL;
 	int ret, i;
 
-	for (i = 0; i < dev->config.bNumInterfaces; i++) {
-		if (dev->config.if_desc[i].bInterfaceNumber == interface) {
+	for (i = 0; i < dev->config.desc.bNumInterfaces; i++) {
+		if (dev->config.if_desc[i].desc.bInterfaceNumber == interface) {
 			if_face = &dev->config.if_desc[i];
 			break;
 		}
@@ -897,7 +896,7 @@
 	usb_parse_config(dev, &tmpbuf[0], 0);
 	usb_set_maxpacket(dev);
 	/* we set the default configuration here */
-	if (usb_set_configuration(dev, dev->config.bConfigurationValue)) {
+	if (usb_set_configuration(dev, dev->config.desc.bConfigurationValue)) {
 		printf("failed to set default configuration " \
 			"len %d, status %lX\n", dev->act_len, dev->status);
 		return -1;
@@ -1347,21 +1346,21 @@
 
 int usb_hub_probe(struct usb_device *dev, int ifnum)
 {
-	struct usb_interface_descriptor *iface;
+	struct usb_interface *iface;
 	struct usb_endpoint_descriptor *ep;
 	int ret;
 
 	iface = &dev->config.if_desc[ifnum];
 	/* Is it a hub? */
-	if (iface->bInterfaceClass != USB_CLASS_HUB)
+	if (iface->desc.bInterfaceClass != USB_CLASS_HUB)
 		return 0;
 	/* Some hubs have a subclass of 1, which AFAICT according to the */
 	/*  specs is not defined, but it works */
-	if ((iface->bInterfaceSubClass != 0) &&
-	    (iface->bInterfaceSubClass != 1))
+	if ((iface->desc.bInterfaceSubClass != 0) &&
+	    (iface->desc.bInterfaceSubClass != 1))
 		return 0;
 	/* Multiple endpoints? What kind of mutant ninja-hub is this? */
-	if (iface->bNumEndpoints != 1)
+	if (iface->desc.bNumEndpoints != 1)
 		return 0;
 	ep = &iface->ep_desc[0];
 	/* Output endpoint? Curiousier and curiousier.. */
diff --git a/common/usb_kbd.c b/common/usb_kbd.c
index b458d77..9957dcc 100644
--- a/common/usb_kbd.c
+++ b/common/usb_kbd.c
@@ -229,7 +229,7 @@
 
 static void usb_kbd_setled(struct usb_device *dev)
 {
-	struct usb_interface_descriptor *iface;
+	struct usb_interface *iface;
 	iface = &dev->config.if_desc[0];
 	leds=0;
 	if(scroll_lock!=0)
@@ -242,7 +242,7 @@
 		leds|=1;
 	usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
 		USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
-		0x200, iface->bInterfaceNumber,(void *)&leds, 1, 0);
+		0x200, iface->desc.bInterfaceNumber, (void *)&leds, 1, 0);
 
 }
 
@@ -348,17 +348,21 @@
 /* probes the USB device dev for keyboard type */
 static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum)
 {
-	struct usb_interface_descriptor *iface;
+	struct usb_interface *iface;
 	struct usb_endpoint_descriptor *ep;
 	int pipe,maxp;
 
 	if (dev->descriptor.bNumConfigurations != 1) return 0;
 	iface = &dev->config.if_desc[ifnum];
 
-	if (iface->bInterfaceClass != 3) return 0;
-	if (iface->bInterfaceSubClass != 1) return 0;
-	if (iface->bInterfaceProtocol != 1) return 0;
-	if (iface->bNumEndpoints != 1) return 0;
+	if (iface->desc.bInterfaceClass != 3)
+		return 0;
+	if (iface->desc.bInterfaceSubClass != 1)
+		return 0;
+	if (iface->desc.bInterfaceProtocol != 1)
+		return 0;
+	if (iface->desc.bNumEndpoints != 1)
+		return 0;
 
 	ep = &iface->ep_desc[0];
 
@@ -367,9 +371,9 @@
 	USB_KBD_PRINTF("USB KBD found set protocol...\n");
 	/* ok, we found a USB Keyboard, install it */
 	/* usb_kbd_get_hid_desc(dev); */
-	usb_set_protocol(dev, iface->bInterfaceNumber, 0);
+	usb_set_protocol(dev, iface->desc.bInterfaceNumber, 0);
 	USB_KBD_PRINTF("USB KBD found set idle...\n");
-	usb_set_idle(dev, iface->bInterfaceNumber, REPEAT_RATE, 0);
+	usb_set_idle(dev, iface->desc.bInterfaceNumber, REPEAT_RATE, 0);
 	memset(&new[0], 0, 8);
 	memset(&old[0], 0, 8);
 	repeat_delay=0;
diff --git a/common/usb_storage.c b/common/usb_storage.c
index 19613f2..a8642c9 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -168,6 +168,8 @@
 		      struct us_data *ss);
 unsigned long usb_stor_read(int device, unsigned long blknr,
 			    unsigned long blkcnt, void *buffer);
+unsigned long usb_stor_write(int device, unsigned long blknr,
+			     unsigned long blkcnt, const void *buffer);
 struct usb_device * usb_get_dev_index(int index);
 void uhci_show_temp_int_td(void);
 
@@ -227,6 +229,7 @@
 		usb_dev_desc[i].dev = i;
 		usb_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
 		usb_dev_desc[i].block_read = usb_stor_read;
+		usb_dev_desc[i].block_write = usb_stor_write;
 	}
 
 	usb_max_devs = 0;
@@ -964,6 +967,22 @@
 	return ss->transport(srb, ss);
 }
 
+static int usb_write_10(ccb *srb, struct us_data *ss, unsigned long start,
+			unsigned short blocks)
+{
+	memset(&srb->cmd[0], 0, 12);
+	srb->cmd[0] = SCSI_WRITE10;
+	srb->cmd[2] = ((unsigned char) (start >> 24)) & 0xff;
+	srb->cmd[3] = ((unsigned char) (start >> 16)) & 0xff;
+	srb->cmd[4] = ((unsigned char) (start >> 8)) & 0xff;
+	srb->cmd[5] = ((unsigned char) (start)) & 0xff;
+	srb->cmd[7] = ((unsigned char) (blocks >> 8)) & 0xff;
+	srb->cmd[8] = (unsigned char) blocks & 0xff;
+	srb->cmdlen = 12;
+	USB_STOR_PRINTF("write10: start %lx blocks %x\n", start, blocks);
+	return ss->transport(srb, ss);
+}
+
 
 #ifdef CONFIG_USB_BIN_FIXUP
 /*
@@ -1065,12 +1084,92 @@
 	return blkcnt;
 }
 
+#define USB_MAX_WRITE_BLK 20
+
+unsigned long usb_stor_write(int device, unsigned long blknr,
+				unsigned long blkcnt, const void *buffer)
+{
+	unsigned long start, blks, buf_addr;
+	unsigned short smallblks;
+	struct usb_device *dev;
+	int retry, i;
+	ccb *srb = &usb_ccb;
+
+	if (blkcnt == 0)
+		return 0;
+
+	device &= 0xff;
+	/* Setup  device */
+	USB_STOR_PRINTF("\nusb_write: dev %d \n", device);
+	dev = NULL;
+	for (i = 0; i < USB_MAX_DEVICE; i++) {
+		dev = usb_get_dev_index(i);
+		if (dev == NULL)
+			return 0;
+		if (dev->devnum == usb_dev_desc[device].target)
+			break;
+	}
+
+	usb_disable_asynch(1); /* asynch transfer not allowed */
+
+	srb->lun = usb_dev_desc[device].lun;
+	buf_addr = (unsigned long)buffer;
+	start = blknr;
+	blks = blkcnt;
+	if (usb_test_unit_ready(srb, (struct us_data *)dev->privptr)) {
+		printf("Device NOT ready\n   Request Sense returned %02X %02X"
+		       " %02X\n", srb->sense_buf[2], srb->sense_buf[12],
+			srb->sense_buf[13]);
+		return 0;
+	}
+
+	USB_STOR_PRINTF("\nusb_write: dev %d startblk %lx, blccnt %lx"
+			" buffer %lx\n", device, start, blks, buf_addr);
+
+	do {
+		/* If write fails retry for max retry count else
+		 * return with number of blocks written successfully.
+		 */
+		retry = 2;
+		srb->pdata = (unsigned char *)buf_addr;
+		if (blks > USB_MAX_WRITE_BLK)
+			smallblks = USB_MAX_WRITE_BLK;
+		else
+			smallblks = (unsigned short) blks;
+retry_it:
+		if (smallblks == USB_MAX_WRITE_BLK)
+			usb_show_progress();
+		srb->datalen = usb_dev_desc[device].blksz * smallblks;
+		srb->pdata = (unsigned char *)buf_addr;
+		if (usb_write_10(srb, (struct us_data *)dev->privptr, start,
+		    smallblks)) {
+			USB_STOR_PRINTF("Write ERROR\n");
+			usb_request_sense(srb, (struct us_data *)dev->privptr);
+			if (retry--)
+				goto retry_it;
+			blkcnt -= blks;
+			break;
+		}
+		start += smallblks;
+		blks -= smallblks;
+		buf_addr += srb->datalen;
+	} while (blks != 0);
+
+	USB_STOR_PRINTF("usb_write: end startblk %lx, blccnt %x buffer %lx\n",
+			start, smallblks, buf_addr);
+
+	usb_disable_asynch(0); /* asynch transfer allowed */
+	if (blkcnt >= USB_MAX_WRITE_BLK)
+		printf("\n");
+	return blkcnt;
+
+}
 
 /* Probe to see if a new device is actually a Storage device */
 int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,
 		      struct us_data *ss)
 {
-	struct usb_interface_descriptor *iface;
+	struct usb_interface *iface;
 	int i;
 	unsigned int flags = 0;
 
@@ -1094,9 +1193,9 @@
 #endif
 
 	if (dev->descriptor.bDeviceClass != 0 ||
-			iface->bInterfaceClass != USB_CLASS_MASS_STORAGE ||
-			iface->bInterfaceSubClass < US_SC_MIN ||
-			iface->bInterfaceSubClass > US_SC_MAX) {
+			iface->desc.bInterfaceClass != USB_CLASS_MASS_STORAGE ||
+			iface->desc.bInterfaceSubClass < US_SC_MIN ||
+			iface->desc.bInterfaceSubClass > US_SC_MAX) {
 		/* if it's not a mass storage, we go no further */
 		return 0;
 	}
@@ -1119,8 +1218,8 @@
 		ss->subclass = subclass;
 		ss->protocol = protocol;
 	} else {
-		ss->subclass = iface->bInterfaceSubClass;
-		ss->protocol = iface->bInterfaceProtocol;
+		ss->subclass = iface->desc.bInterfaceSubClass;
+		ss->protocol = iface->desc.bInterfaceProtocol;
 	}
 
 	/* set the handler pointers based on the protocol */
@@ -1153,7 +1252,7 @@
 	 * An optional interrupt is OK (necessary for CBI protocol).
 	 * We will ignore any others.
 	 */
-	for (i = 0; i < iface->bNumEndpoints; i++) {
+	for (i = 0; i < iface->desc.bNumEndpoints; i++) {
 		/* is it an BULK endpoint? */
 		if ((iface->ep_desc[i].bmAttributes &
 		     USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) {
@@ -1178,7 +1277,7 @@
 		  ss->ep_in, ss->ep_out, ss->ep_int);
 
 	/* Do some basic sanity checks, and bail if we find a problem */
-	if (usb_set_interface(dev, iface->bInterfaceNumber, 0) ||
+	if (usb_set_interface(dev, iface->desc.bInterfaceNumber, 0) ||
 	    !ss->ep_in || !ss->ep_out ||
 	    (ss->protocol == US_PR_CBI && ss->ep_int == 0)) {
 		USB_STOR_PRINTF("Problems with device\n");
diff --git a/cpu/ppc4xx/usbdev.c b/cpu/ppc4xx/usbdev.c
index 5bb4f3c..fe398af 100644
--- a/cpu/ppc4xx/usbdev.c
+++ b/cpu/ppc4xx/usbdev.c
@@ -21,7 +21,7 @@
 {
 	/*will hold the packet received */
 	struct usb_device_descriptor usb_device_packet;
-	struct usb_config_descriptor usb_config_packet;
+	struct usb_configuration_descriptor usb_config_packet;
 	struct usb_string_descriptor usb_string_packet;
 	struct devrequest setup_packet;
 	unsigned int *setup_packet_pt;
@@ -99,7 +99,7 @@
 				usb_config_packet.bConfigurationValue = 1;
 				usb_config_packet.iConfiguration = 0;
 				usb_config_packet.bmAttributes = 0x40;
-				usb_config_packet.MaxPower = 0;
+				usb_config_packet.bMaxPower = 0;
 
 				/*put packet in fifo */
 				packet_pt = (unsigned char *)&usb_config_packet;
diff --git a/drivers/serial/usbtty.h b/drivers/serial/usbtty.h
index f746d63..6b6c4a1 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/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 324c308..ba85991 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -96,7 +96,7 @@
 				 * UE_DIR_IN | EHCI_INTR_ENDPT
 				 */
 		3,		/* bmAttributes: UE_INTERRUPT */
-		8, 0,		/* wMaxPacketSize */
+		8,		/* wMaxPacketSize */
 		255		/* bInterval */
 	},
 };
diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile
index 09e0a5f..f2ccd9f 100644
--- a/drivers/usb/musb/Makefile
+++ b/drivers/usb/musb/Makefile
@@ -26,7 +26,9 @@
 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 ec57fc8..22f3dba 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -32,7 +32,9 @@
  */
 void musb_start(void)
 {
+#if defined(CONFIG_MUSB_HCD)
 	u8 devctl;
+#endif
 
 	/* disable all interrupts */
 	writew(0, &musbr->intrtxe);
@@ -74,9 +76,10 @@
 			/* 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 @@
 			/* 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 f9da3f0..15c7f49 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 @@
 		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 0000000..62380ff
--- /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_hcd.c b/drivers/usb/musb/musb_hcd.c
index 4ca94cb..555d2dc 100644
--- a/drivers/usb/musb/musb_hcd.c
+++ b/drivers/usb/musb/musb_hcd.c
@@ -803,7 +803,7 @@
 {
 	struct stdio_dev *dev;
 	struct usb_device *usb_kbd_dev;
-	struct usb_interface_descriptor *iface;
+	struct usb_interface *iface;
 	struct usb_endpoint_descriptor *ep;
 	int pipe;
 	int maxp;
diff --git a/drivers/usb/musb/musb_udc.c b/drivers/usb/musb/musb_udc.c
new file mode 100644
index 0000000..fc43cf4
--- /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 0000000..ea98c3c
--- /dev/null
+++ b/drivers/usb/musb/omap3.c
@@ -0,0 +1,134 @@
+/*
+ * 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;
+
+		/*
+		 * OMAP3EVM uses ISP1504 phy and so
+		 * twl4030 related init is not required.
+		 */
+#ifdef CONFIG_TWL4030_USB
+		if (twl4030_usb_ulpi_init()) {
+			serial_printf("ERROR: %s Could not initialize PHY\n",
+				__PRETTY_FUNCTION__);
+			goto end;
+		}
+#endif
+		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 0000000..20fc9d2
--- /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/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
new file mode 100644
index 0000000..200b907
--- /dev/null
+++ b/drivers/usb/phy/Makefile
@@ -0,0 +1,44 @@
+#
+# 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
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	:= $(obj)libusb_phy.a
+
+COBJS-$(CONFIG_TWL4030_USB) += twl4030.o
+COBJS-y := twl4030.o
+
+COBJS	:= $(COBJS-y)
+SRCS	:= $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+
+all:	$(LIB)
+
+$(LIB):	$(obj).depend $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/drivers/usb/phy/twl4030.c b/drivers/usb/phy/twl4030.c
new file mode 100644
index 0000000..54d2e61
--- /dev/null
+++ b/drivers/usb/phy/twl4030.c
@@ -0,0 +1,189 @@
+/*
+ * 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/gadget/twl4030_usb.c
+ *
+ * This is the unique part of its copyright :
+ *
+ * ------------------------------------------------------------------------
+ *
+ *  * (C) Copyright 2009 Atin Malaviya (atin.malaviya@gmail.com)
+ *
+ * Based on: twl4030_usb.c in linux 2.6 (drivers/i2c/chips/twl4030_usb.c)
+ * Copyright (C) 2004-2007 Texas Instruments
+ * Copyright (C) 2008 Nokia Corporation
+ * Contact: Felipe Balbi <felipe.balbi@nokia.com>
+ *
+ * Author: 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 <twl4030.h>
+
+/* Defines for bits in registers */
+#define OPMODE_MASK		(3 << 3)
+#define XCVRSELECT_MASK		(3 << 0)
+#define CARKITMODE		(1 << 2)
+#define OTG_ENAB		(1 << 5)
+#define PHYPWD			(1 << 0)
+#define CLOCKGATING_EN		(1 << 2)
+#define CLK32K_EN		(1 << 1)
+#define REQ_PHY_DPLL_CLK	(1 << 0)
+#define PHY_DPLL_CLK		(1 << 0)
+
+static int twl4030_usb_write(u8 address, u8 data)
+{
+	int ret;
+
+	ret = twl4030_i2c_write_u8(TWL4030_CHIP_USB, data, address);
+	if (ret != 0)
+		printf("TWL4030:USB:Write[0x%x] Error %d\n", address, ret);
+
+	return ret;
+}
+
+static int twl4030_usb_read(u8 address)
+{
+	u8 data;
+	int ret;
+
+	ret = twl4030_i2c_read_u8(TWL4030_CHIP_USB, &data, address);
+	if (ret == 0)
+		ret = data;
+	else
+		printf("TWL4030:USB:Read[0x%x] Error %d\n", address, ret);
+
+	return ret;
+}
+
+static void twl4030_usb_ldo_init(void)
+{
+	/* Enable writing to power configuration registers */
+	twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, 0xC0,
+			     TWL4030_PM_MASTER_PROTECT_KEY);
+	twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, 0x0C,
+			     TWL4030_PM_MASTER_PROTECT_KEY);
+
+	/* put VUSB3V1 LDO in active state */
+	twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x00,
+			     TWL4030_PM_RECEIVER_VUSB_DEDICATED2);
+
+	/* input to VUSB3V1 LDO is from VBAT, not VBUS */
+	twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x14,
+			     TWL4030_PM_RECEIVER_VUSB_DEDICATED1);
+
+	/* turn on 3.1V regulator */
+	twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x20,
+			     TWL4030_PM_RECEIVER_VUSB3V1_DEV_GRP);
+	twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x00,
+			     TWL4030_PM_RECEIVER_VUSB3V1_TYPE);
+
+	/* turn on 1.5V regulator */
+	twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x20,
+			     TWL4030_PM_RECEIVER_VUSB1V5_DEV_GRP);
+	twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x00,
+			     TWL4030_PM_RECEIVER_VUSB1V5_TYPE);
+
+	/* turn on 1.8V regulator */
+	twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x20,
+			     TWL4030_PM_RECEIVER_VUSB1V8_DEV_GRP);
+	twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x00,
+			     TWL4030_PM_RECEIVER_VUSB1V8_TYPE);
+
+	/* disable access to power configuration registers */
+	twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, 0x00,
+			     TWL4030_PM_MASTER_PROTECT_KEY);
+}
+
+static void twl4030_phy_power(void)
+{
+	u8 pwr, clk;
+
+	/* Power the PHY */
+	pwr = twl4030_usb_read(TWL4030_USB_PHY_PWR_CTRL);
+	pwr &= ~PHYPWD;
+	twl4030_usb_write(TWL4030_USB_PHY_PWR_CTRL, pwr);
+	/* Enable clocks */
+	clk = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL);
+	clk |= CLOCKGATING_EN | CLK32K_EN;
+	twl4030_usb_write(TWL4030_USB_PHY_CLK_CTRL, clk);
+}
+
+/*
+ * Initiaze the ULPI interface
+ * ULPI : Universal Transceiver Macrocell Low Pin Interface
+ * An interface between the USB link controller like musb and the
+ * the PHY or transceiver that drives the actual bus.
+ */
+int twl4030_usb_ulpi_init(void)
+{
+	long timeout = 1000 * 1000; /* 1 sec */;
+	u8 clk, sts, pwr;
+
+	/* twl4030 ldo init */
+	twl4030_usb_ldo_init();
+
+	/* Enable the twl4030 phy */
+	twl4030_phy_power();
+
+	/* Enable DPLL to access PHY registers over I2C */
+	clk = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL);
+	clk |= REQ_PHY_DPLL_CLK;
+	twl4030_usb_write(TWL4030_USB_PHY_CLK_CTRL, clk);
+
+	/* Check if the PHY DPLL is locked */
+	sts = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL_STS);
+	while (!(sts & PHY_DPLL_CLK) && 0 < timeout) {
+		udelay(10);
+		sts = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL_STS);
+		timeout -= 10;
+	}
+
+	/* Final check */
+	sts = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL_STS);
+	if (!(sts & PHY_DPLL_CLK)) {
+		printf("Error:TWL4030:USB Timeout setting PHY DPLL clock\n");
+		return -1;
+	}
+
+	/*
+	 * There are two circuit blocks attached to the PHY,
+	 * Carkit and USB OTG.  Disable Carkit and enable USB OTG
+	 */
+	twl4030_usb_write(TWL4030_USB_IFC_CTRL_CLR, CARKITMODE);
+	pwr = twl4030_usb_read(TWL4030_USB_POWER_CTRL);
+	pwr |= OTG_ENAB;
+	twl4030_usb_write(TWL4030_USB_POWER_CTRL_SET, pwr);
+
+	/* Clear the opmode bits to ensure normal encode */
+	twl4030_usb_write(TWL4030_USB_FUNC_CTRL_CLR, OPMODE_MASK);
+
+	/* Clear the xcvrselect bits to enable the high speed transeiver */
+	twl4030_usb_write(TWL4030_USB_FUNC_CTRL_CLR, XCVRSELECT_MASK);
+
+	/* Let ULPI control the DPLL clock */
+	clk = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL);
+	clk &= ~REQ_PHY_DPLL_CLK;
+	twl4030_usb_write(TWL4030_USB_PHY_CLK_CTRL, clk);
+
+	return 0;
+}
diff --git a/include/configs/omap3_beagle.h b/include/configs/omap3_beagle.h
index a6fe5e1..4fe3bd8 100644
--- a/include/configs/omap3_beagle.h
+++ b/include/configs/omap3_beagle.h
@@ -100,6 +100,21 @@
 /* DDR - I use Micron DDR */
 #define CONFIG_OMAP3_MICRON_DDR		1
 
+/* USB */
+#define CONFIG_MUSB_UDC			1
+#define CONFIG_USB_OMAP3		1
+#define CONFIG_TWL4030_USB		1
+
+/* USB device configuration */
+#define CONFIG_USB_DEVICE		1
+#define CONFIG_USB_TTY			1
+#define CONFIG_SYS_CONSOLE_IS_IN_ENV	1
+/* Change these to suit your needs */
+#define CONFIG_USBD_VENDORID		0x0451
+#define CONFIG_USBD_PRODUCTID		0x5678
+#define CONFIG_USBD_MANUFACTURER	"Texas Instruments"
+#define CONFIG_USBD_PRODUCT_NAME	"Beagle"
+
 /* commands to include */
 #include <config_cmd_default.h>
 
@@ -164,6 +179,7 @@
 
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	"loadaddr=0x82000000\0" \
+	"usbtty=cdc_acm\0" \
 	"console=ttyS2,115200n8\0" \
 	"vram=12M\0" \
 	"dvimode=1024x768MR-16@60\0" \
diff --git a/include/configs/omap3_evm.h b/include/configs/omap3_evm.h
index 00093f8..630b00f 100644
--- a/include/configs/omap3_evm.h
+++ b/include/configs/omap3_evm.h
@@ -104,6 +104,44 @@
 /* DDR - I use Micron DDR */
 #define CONFIG_OMAP3_MICRON_DDR		1
 
+/* USB
+ * Enable CONFIG_MUSB_HCD for Host functionalities MSC, keyboard
+ * Enable CONFIG_MUSB_UDD for Device functionalities.
+ */
+#define CONFIG_USB_OMAP3		1
+#define CONFIG_MUSB_HCD			1
+/* #define CONFIG_MUSB_UDC		1 */
+
+#ifdef CONFIG_USB_OMAP3
+
+#ifdef CONFIG_MUSB_HCD
+#define CONFIG_CMD_USB
+
+#define CONFIG_USB_STORAGE
+#define CONGIG_CMD_STORAGE
+#define CONFIG_CMD_FAT
+
+#ifdef CONFIG_USB_KEYBOARD
+#define CONFIG_SYS_USB_EVENT_POLL
+#define CONFIG_PREBOOT "usb start"
+#endif /* CONFIG_USB_KEYBOARD */
+
+#endif /* CONFIG_MUSB_HCD */
+
+#ifdef CONFIG_MUSB_UDC
+/* USB device configuration */
+#define CONFIG_USB_DEVICE		1
+#define CONFIG_USB_TTY			1
+#define CONFIG_SYS_CONSOLE_IS_IN_ENV	1
+/* Change these to suit your needs */
+#define CONFIG_USBD_VENDORID		0x0451
+#define CONFIG_USBD_PRODUCTID		0x5678
+#define CONFIG_USBD_MANUFACTURER	"Texas Instruments"
+#define CONFIG_USBD_PRODUCT_NAME	"EVM"
+#endif /* CONFIG_MUSB_UDC */
+
+#endif /* CONFIG_USB_OMAP3 */
+
 /* commands to include */
 #include <config_cmd_default.h>
 
@@ -160,6 +198,7 @@
 
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	"loadaddr=0x82000000\0" \
+	"usbtty=cdc_acm\0" \
 	"console=ttyS2,115200n8\0" \
 	"mmcargs=setenv bootargs console=${console} " \
 		"root=/dev/mmcblk0p2 rw " \
diff --git a/include/configs/omap3_zoom1.h b/include/configs/omap3_zoom1.h
index ef7a28b..fa58281 100644
--- a/include/configs/omap3_zoom1.h
+++ b/include/configs/omap3_zoom1.h
@@ -101,6 +101,21 @@
 /* DDR - I use Micron DDR */
 #define CONFIG_OMAP3_MICRON_DDR		1
 
+/* USB */
+#define CONFIG_MUSB_UDC			1
+#define CONFIG_USB_OMAP3		1
+#define CONFIG_TWL4030_USB		1
+
+/* USB device configuration */
+#define CONFIG_USB_DEVICE		1
+#define CONFIG_USB_TTY			1
+#define CONFIG_SYS_CONSOLE_IS_IN_ENV	1
+/* Change these to suit your needs */
+#define CONFIG_USBD_VENDORID		0x0451
+#define CONFIG_USBD_PRODUCTID		0x5678
+#define CONFIG_USBD_MANUFACTURER	"Texas Instruments"
+#define CONFIG_USBD_PRODUCT_NAME	"Zoom1"
+
 /* commands to include */
 #include <config_cmd_default.h>
 
@@ -160,6 +175,7 @@
 
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	"loadaddr=0x82000000\0" \
+	"usbtty=cdc_acm\0" \
 	"console=ttyS2,115200n8\0" \
 	"videomode=1024x768@60,vxres=1024,vyres=768\0" \
 	"videospec=omapfb:vram:2M,vram:4M\0" \
diff --git a/include/configs/omap3_zoom2.h b/include/configs/omap3_zoom2.h
index 2b07666..7a8beb8 100644
--- a/include/configs/omap3_zoom2.h
+++ b/include/configs/omap3_zoom2.h
@@ -125,6 +125,20 @@
 #define CONFIG_OMAP3_GPIO_3 /* board revision */
 #define CONFIG_OMAP3_GPIO_5 /* debug board detection, ZOOM2_LED_BLUE */
 
+/* USB */
+#define CONFIG_MUSB_UDC			1
+#define CONFIG_USB_OMAP3		1
+#define CONFIG_TWL4030_USB		1
+
+/* USB device configuration */
+#define CONFIG_USB_DEVICE		1
+#define CONFIG_USB_TTY			1
+/* Change these to suit your needs */
+#define CONFIG_USBD_VENDORID		0x0451
+#define CONFIG_USBD_PRODUCTID		0x5678
+#define CONFIG_USBD_MANUFACTURER	"Texas Instruments"
+#define CONFIG_USBD_PRODUCT_NAME	"Zoom2"
+
 /* commands to include */
 #include <config_cmd_default.h>
 
@@ -170,6 +184,9 @@
 /* Environment information */
 #define CONFIG_BOOTDELAY		10
 
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"usbtty=cdc_acm\0" \
+
 /*
  * Miscellaneous configurable options
  */
diff --git a/include/serial.h b/include/serial.h
index bbda3f0..f2638ec 100644
--- a/include/serial.h
+++ b/include/serial.h
@@ -66,4 +66,22 @@
 extern int serial_assign(char * name);
 extern void serial_reinit_all(void);
 
+/* For usbtty */
+#ifdef CONFIG_USB_TTY
+
+extern int usbtty_getc(void);
+extern void usbtty_putc(const char c);
+extern void usbtty_puts(const char *str);
+extern int usbtty_tstc(void);
+
+#else
+
+/* stubs */
+#define usbtty_getc() 0
+#define usbtty_putc(a)
+#define usbtty_puts(a)
+#define usbtty_tstc() 0
+
+#endif /* CONFIG_USB_TTY */
+
 #endif
diff --git a/include/twl4030.h b/include/twl4030.h
index f260ecb..feaec47 100644
--- a/include/twl4030.h
+++ b/include/twl4030.h
@@ -342,21 +342,129 @@
 #define TWL4030_KEYPAD_CTRL_SOFT_NRST			(1 << 0)
 
 /* USB */
-#define TWL4030_USB_FUNC_CTRL				(0x04)
-#define TWL4030_USB_OPMODE_MASK				(3 << 3)
-#define TWL4030_USB_XCVRSELECT_MASK			(3 << 0)
-#define TWL4030_USB_IFC_CTRL				(0x07)
-#define TWL4030_USB_CARKITMODE				(1 << 2)
-#define TWL4030_USB_POWER_CTRL				(0xAC)
-#define TWL4030_USB_OTG_ENAB				(1 << 5)
-#define TWL4030_USB_PHY_PWR_CTRL			(0xFD)
-#define TWL4030_USB_PHYPWD				(1 << 0)
-#define TWL4030_USB_PHY_CLK_CTRL			(0xFE)
-#define TWL4030_USB_CLOCKGATING_EN			(1 << 2)
-#define TWL4030_USB_CLK32K_EN				(1 << 1)
-#define TWL4030_USB_REQ_PHY_DPLL_CLK			(1 << 0)
-#define TWL4030_USB_PHY_CLK_CTRL_STS			(0xFF)
-#define TWL4030_USB_PHY_DPLL_CLK			(1 << 0)
+#define TWL4030_USB_VENDOR_ID_LO			0x00
+#define TWL4030_USB_VENDOR_ID_HI			0x01
+#define TWL4030_USB_PRODUCT_ID_LO			0x02
+#define TWL4030_USB_PRODUCT_ID_HI			0x03
+#define TWL4030_USB_FUNC_CTRL				0x04
+#define TWL4030_USB_FUNC_CTRL_SET			0x05
+#define TWL4030_USB_FUNC_CTRL_CLR			0x06
+#define TWL4030_USB_IFC_CTRL				0x07
+#define TWL4030_USB_IFC_CTRL_SET			0x08
+#define TWL4030_USB_IFC_CTRL_CLR			0x09
+#define TWL4030_USB_OTG_CTRL				0x0A
+#define TWL4030_USB_OTG_CTRL_SET			0x0B
+#define TWL4030_USB_OTG_CTRL_CLR			0x0C
+#define TWL4030_USB_USB_INT_EN_RISE			0x0D
+#define TWL4030_USB_USB_INT_EN_RISE_SET			0x0E
+#define TWL4030_USB_USB_INT_EN_RISE_CLR			0x0F
+#define TWL4030_USB_USB_INT_EN_FALL			0x10
+#define TWL4030_USB_USB_INT_EN_FALL_SET			0x11
+#define TWL4030_USB_USB_INT_EN_FALL_CLR			0x12
+#define TWL4030_USB_USB_INT_STS				0x13
+#define TWL4030_USB_USB_INT_LATCH			0x14
+#define TWL4030_USB_DEBUG				0x15
+#define TWL4030_USB_SCRATCH_REG				0x16
+#define TWL4030_USB_SCRATCH_REG_SET			0x17
+#define TWL4030_USB_SCRATCH_REG_CLR			0x18
+#define TWL4030_USB_CARKIT_CTRL				0x19
+#define TWL4030_USB_CARKIT_CTRL_SET			0x1A
+#define TWL4030_USB_CARKIT_CTRL_CLR			0x1B
+#define TWL4030_USB_CARKIT_INT_DELAY			0x1C
+#define TWL4030_USB_CARKIT_INT_EN			0x1D
+#define TWL4030_USB_CARKIT_INT_EN_SET			0x1E
+#define TWL4030_USB_CARKIT_INT_EN_CLR			0x1F
+#define TWL4030_USB_CARKIT_INT_STS			0x20
+#define TWL4030_USB_CARKIT_INT_LATCH			0x21
+#define TWL4030_USB_CARKIT_PLS_CTRL			0x22
+#define TWL4030_USB_CARKIT_PLS_CTRL_SET			0x23
+#define TWL4030_USB_CARKIT_PLS_CTRL_CLR			0x24
+#define TWL4030_USB_TRANS_POS_WIDTH			0x25
+#define TWL4030_USB_TRANS_NEG_WIDTH			0x26
+#define TWL4030_USB_RCV_PLTY_RECOVERY			0x27
+#define TWL4030_USB_MCPC_CTRL				0x30
+#define TWL4030_USB_MCPC_CTRL_SET			0x31
+#define TWL4030_USB_MCPC_CTRL_CLR			0x32
+#define TWL4030_USB_MCPC_IO_CTRL			0x33
+#define TWL4030_USB_MCPC_IO_CTRL_SET			0x34
+#define TWL4030_USB_MCPC_IO_CTRL_CLR			0x35
+#define TWL4030_USB_MCPC_CTRL2				0x36
+#define TWL4030_USB_MCPC_CTRL2_SET			0x37
+#define TWL4030_USB_MCPC_CTRL2_CLR			0x38
+#define TWL4030_USB_OTHER_FUNC_CTRL			0x80
+#define TWL4030_USB_OTHER_FUNC_CTRL_SET			0x81
+#define TWL4030_USB_OTHER_FUNC_CTRL_CLR			0x82
+#define TWL4030_USB_OTHER_IFC_CTRL			0x83
+#define TWL4030_USB_OTHER_IFC_CTRL_SET			0x84
+#define TWL4030_USB_OTHER_IFC_CTRL_CLR			0x85
+#define TWL4030_USB_OTHER_INT_EN_RISE_SET		0x87
+#define TWL4030_USB_OTHER_INT_EN_RISE_CLR		0x88
+#define TWL4030_USB_OTHER_INT_EN_FALL			0x89
+#define TWL4030_USB_OTHER_INT_EN_FALL_SET		0x8A
+#define TWL4030_USB_OTHER_INT_EN_FALL_CLR		0x8B
+#define TWL4030_USB_OTHER_INT_STS			0x8C
+#define TWL4030_USB_OTHER_INT_LATCH			0x8D
+#define TWL4030_USB_ID_STATUS				0x96
+#define TWL4030_USB_CARKIT_SM_1_INT_EN			0x97
+#define TWL4030_USB_CARKIT_SM_1_INT_EN_SET		0x98
+#define TWL4030_USB_CARKIT_SM_1_INT_EN_CLR		0x99
+#define TWL4030_USB_CARKIT_SM_1_INT_STS			0x9A
+#define TWL4030_USB_CARKIT_SM_1_INT_LATCH		0x9B
+#define TWL4030_USB_CARKIT_SM_2_INT_EN			0x9C
+#define TWL4030_USB_CARKIT_SM_2_INT_EN_SET		0x9D
+#define TWL4030_USB_CARKIT_SM_2_INT_EN_CLR		0x9E
+#define TWL4030_USB_CARKIT_SM_2_INT_STS			0x9F
+#define TWL4030_USB_CARKIT_SM_2_INT_LATCH		0xA0
+#define TWL4030_USB_CARKIT_SM_CTRL			0xA1
+#define TWL4030_USB_CARKIT_SM_CTRL_SET			0xA2
+#define TWL4030_USB_CARKIT_SM_CTRL_CLR			0xA3
+#define TWL4030_USB_CARKIT_SM_CMD			0xA4
+#define TWL4030_USB_CARKIT_SM_CMD_SET			0xA5
+#define TWL4030_USB_CARKIT_SM_CMD_CLR			0xA6
+#define TWL4030_USB_CARKIT_SM_CMD_STS			0xA7
+#define TWL4030_USB_CARKIT_SM_STATUS			0xA8
+#define TWL4030_USB_CARKIT_SM_ERR_STATUS		0xAA
+#define TWL4030_USB_CARKIT_SM_CTRL_STATE		0xAB
+#define TWL4030_USB_POWER_CTRL				0xAC
+#define TWL4030_USB_POWER_CTRL_SET			0xAD
+#define TWL4030_USB_POWER_CTRL_CLR			0xAE
+#define TWL4030_USB_OTHER_IFC_CTRL2			0xAF
+#define TWL4030_USB_OTHER_IFC_CTRL2_SET			0xB0
+#define TWL4030_USB_OTHER_IFC_CTRL2_CLR			0xB1
+#define TWL4030_USB_REG_CTRL_EN				0xB2
+#define TWL4030_USB_REG_CTRL_EN_SET			0xB3
+#define TWL4030_USB_REG_CTRL_EN_CLR			0xB4
+#define TWL4030_USB_REG_CTRL_ERROR			0xB5
+#define TWL4030_USB_OTHER_FUNC_CTRL2			0xB8
+#define TWL4030_USB_OTHER_FUNC_CTRL2_SET		0xB9
+#define TWL4030_USB_OTHER_FUNC_CTRL2_CLR		0xBA
+#define TWL4030_USB_CARKIT_ANA_CTRL			0xBB
+#define TWL4030_USB_CARKIT_ANA_CTRL_SET			0xBC
+#define TWL4030_USB_CARKIT_ANA_CTRL_CLR			0xBD
+#define TWL4030_USB_VBUS_DEBOUNCE			0xC0
+#define TWL4030_USB_ID_DEBOUNCE				0xC1
+#define TWL4030_USB_TPH_DP_CON_MIN			0xC2
+#define TWL4030_USB_TPH_DP_CON_MAX			0xC3
+#define TWL4030_USB_TCR_DP_CON_MIN			0xC4
+#define TWL4030_USB_TCR_DP_CON_MAX			0xC5
+#define TWL4030_USB_TPH_DP_PD_SHORT			0xC6
+#define TWL4030_USB_TPH_CMD_DLY				0xC7
+#define TWL4030_USB_TPH_DET_RST				0xC8
+#define TWL4030_USB_TPH_AUD_BIAS			0xC9
+#define TWL4030_USB_TCR_UART_DET_MIN			0xCA
+#define TWL4030_USB_TCR_UART_DET_MAX			0xCB
+#define TWL4030_USB_TPH_ID_INT_PW			0xCD
+#define TWL4030_USB_TACC_ID_INT_WAIT			0xCE
+#define TWL4030_USB_TACC_ID_INT_PW			0xCF
+#define TWL4030_USB_TPH_CMD_WAIT			0xD0
+#define TWL4030_USB_TPH_ACK_WAIT			0xD1
+#define TWL4030_USB_TPH_DP_DISC_DET			0xD2
+#define TWL4030_USB_VBAT_TIMER				0xD3
+#define TWL4030_USB_CARKIT_4W_DEBUG			0xE0
+#define TWL4030_USB_CARKIT_5W_DEBUG			0xE1
+#define TWL4030_USB_PHY_PWR_CTRL			0xFD
+#define TWL4030_USB_PHY_CLK_CTRL			0xFE
+#define TWL4030_USB_PHY_CLK_CTRL_STS			0xFF
 
 /*
  * Convience functions to read and write from TWL4030
@@ -398,4 +506,9 @@
  */
 void twl4030_led_init(void);
 
+/*
+ * USB
+ */
+int twl4030_usb_ulpi_init(void);
+
 #endif /* TWL4030_H */
diff --git a/include/usb.h b/include/usb.h
index 7c47098..1cc3e42 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -27,6 +27,7 @@
 #define _USB_H_
 
 #include <usb_defs.h>
+#include <usbdescriptors.h>
 
 /* Everything is aribtrary */
 #define USB_ALTSETTINGALLOC		4
@@ -41,13 +42,6 @@
 
 #define USB_CNTL_TIMEOUT 100 /* 100ms timeout */
 
-/* String descriptor */
-struct usb_string_descriptor {
-	unsigned char	bLength;
-	unsigned char	bDescriptorType;
-	unsigned short	wData[1];
-} __attribute__ ((packed));
-
 /* device request (setup) */
 struct devrequest {
 	unsigned char	requesttype;
@@ -63,47 +57,9 @@
 	unsigned char	bDescriptorType;
 } __attribute__ ((packed));
 
-/* Device descriptor */
-struct usb_device_descriptor {
-	unsigned char	bLength;
-	unsigned char	bDescriptorType;
-	unsigned short	bcdUSB;
-	unsigned char	bDeviceClass;
-	unsigned char	bDeviceSubClass;
-	unsigned char	bDeviceProtocol;
-	unsigned char	bMaxPacketSize0;
-	unsigned short	idVendor;
-	unsigned short	idProduct;
-	unsigned short	bcdDevice;
-	unsigned char	iManufacturer;
-	unsigned char	iProduct;
-	unsigned char	iSerialNumber;
-	unsigned char	bNumConfigurations;
-} __attribute__ ((packed));
-
-/* Endpoint descriptor */
-struct usb_endpoint_descriptor {
-	unsigned char	bLength;
-	unsigned char	bDescriptorType;
-	unsigned char	bEndpointAddress;
-	unsigned char	bmAttributes;
-	unsigned short	wMaxPacketSize;
-	unsigned char	bInterval;
-	unsigned char	bRefresh;
-	unsigned char	bSynchAddress;
-} __attribute__ ((packed)) __attribute__ ((aligned(2)));
-
-/* Interface descriptor */
-struct usb_interface_descriptor {
-	unsigned char	bLength;
-	unsigned char	bDescriptorType;
-	unsigned char	bInterfaceNumber;
-	unsigned char	bAlternateSetting;
-	unsigned char	bNumEndpoints;
-	unsigned char	bInterfaceClass;
-	unsigned char	bInterfaceSubClass;
-	unsigned char	bInterfaceProtocol;
-	unsigned char	iInterface;
+/* Interface */
+struct usb_interface {
+	struct usb_interface_descriptor desc;
 
 	unsigned char	no_of_ep;
 	unsigned char	num_altsetting;
@@ -112,20 +68,12 @@
 	struct usb_endpoint_descriptor ep_desc[USB_MAXENDPOINTS];
 } __attribute__ ((packed));
 
-
-/* Configuration descriptor information.. */
-struct usb_config_descriptor {
-	unsigned char	bLength;
-	unsigned char	bDescriptorType;
-	unsigned short	wTotalLength;
-	unsigned char	bNumInterfaces;
-	unsigned char	bConfigurationValue;
-	unsigned char	iConfiguration;
-	unsigned char	bmAttributes;
-	unsigned char	MaxPower;
+/* Configuration information.. */
+struct usb_config {
+	struct usb_configuration_descriptor desc;
 
 	unsigned char	no_of_if;	/* number of interfaces */
-	struct usb_interface_descriptor if_desc[USB_MAXINTERFACES];
+	struct usb_interface if_desc[USB_MAXINTERFACES];
 } __attribute__ ((packed));
 
 enum {
@@ -156,7 +104,7 @@
 
 	int configno;			/* selected config number */
 	struct usb_device_descriptor descriptor; /* Device Descriptor */
-	struct usb_config_descriptor config; /* config descriptor */
+	struct usb_config config; /* config descriptor */
 
 	int have_langid;		/* whether string_langid is valid yet */
 	int string_langid;		/* language ID for strings */
@@ -183,7 +131,8 @@
 #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 0000000..ef37dbb
--- /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__ */
+
diff --git a/include/usbdescriptors.h b/include/usbdescriptors.h
index a752097..2dec3b9 100644
--- a/include/usbdescriptors.h
+++ b/include/usbdescriptors.h
@@ -504,4 +504,30 @@
 
 } __attribute__ ((packed));
 
+#ifdef DEBUG
+static inline void print_device_descriptor(struct usb_device_descriptor *d)
+{
+	serial_printf("usb device descriptor \n");
+	serial_printf("\tbLength %2.2x\n", d->bLength);
+	serial_printf("\tbDescriptorType %2.2x\n", d->bDescriptorType);
+	serial_printf("\tbcdUSB %4.4x\n", d->bcdUSB);
+	serial_printf("\tbDeviceClass %2.2x\n", d->bDeviceClass);
+	serial_printf("\tbDeviceSubClass %2.2x\n", d->bDeviceSubClass);
+	serial_printf("\tbDeviceProtocol %2.2x\n", d->bDeviceProtocol);
+	serial_printf("\tbMaxPacketSize0 %2.2x\n", d->bMaxPacketSize0);
+	serial_printf("\tidVendor %4.4x\n", d->idVendor);
+	serial_printf("\tidProduct %4.4x\n", d->idProduct);
+	serial_printf("\tbcdDevice %4.4x\n", d->bcdDevice);
+	serial_printf("\tiManufacturer %2.2x\n", d->iManufacturer);
+	serial_printf("\tiProduct %2.2x\n", d->iProduct);
+	serial_printf("\tiSerialNumber %2.2x\n", d->iSerialNumber);
+	serial_printf("\tbNumConfigurations %2.2x\n", d->bNumConfigurations);
+}
+
+#else
+
+/* stubs */
+#define print_device_descriptor(d)
+
+#endif /* DEBUG */
 #endif
diff --git a/include/usbdevice.h b/include/usbdevice.h
index 206dbbc..4171636 100644
--- a/include/usbdevice.h
+++ b/include/usbdevice.h
@@ -663,4 +663,107 @@
 void usbd_rcv_complete(struct usb_endpoint_instance *endpoint, int len, int urb_bad);
 void usbd_tx_complete (struct usb_endpoint_instance *endpoint);
 
+/* These are macros used in debugging */
+#ifdef DEBUG
+static inline void print_urb(struct urb *u)
+{
+	serial_printf("urb %p\n", (u));
+	serial_printf("\tendpoint %p\n", u->endpoint);
+	serial_printf("\tdevice %p\n", u->device);
+	serial_printf("\tbuffer %p\n", u->buffer);
+	serial_printf("\tbuffer_length %d\n", u->buffer_length);
+	serial_printf("\tactual_length %d\n", u->actual_length);
+	serial_printf("\tstatus %d\n", u->status);
+	serial_printf("\tdata %d\n", u->data);
+}
+
+static inline void print_usb_device_request(struct usb_device_request *r)
+{
+	serial_printf("usb request\n");
+	serial_printf("\tbmRequestType 0x%2.2x\n", r->bmRequestType);
+	if ((r->bmRequestType & USB_REQ_DIRECTION_MASK) == 0)
+		serial_printf("\t\tDirection : To device\n");
+	else
+		serial_printf("\t\tDirection : To host\n");
+	if ((r->bmRequestType & USB_TYPE_STANDARD) == USB_TYPE_STANDARD)
+		serial_printf("\t\tType      : Standard\n");
+	if ((r->bmRequestType & USB_TYPE_CLASS) == USB_TYPE_CLASS)
+		serial_printf("\t\tType      : Standard\n");
+	if ((r->bmRequestType & USB_TYPE_VENDOR) == USB_TYPE_VENDOR)
+		serial_printf("\t\tType      : Standard\n");
+	if ((r->bmRequestType & USB_TYPE_RESERVED) == USB_TYPE_RESERVED)
+		serial_printf("\t\tType      : Standard\n");
+	if ((r->bmRequestType & USB_REQ_RECIPIENT_MASK) ==
+	    USB_REQ_RECIPIENT_DEVICE)
+		serial_printf("\t\tRecipient : Device\n");
+	if ((r->bmRequestType & USB_REQ_RECIPIENT_MASK) ==
+	    USB_REQ_RECIPIENT_INTERFACE)
+		serial_printf("\t\tRecipient : Interface\n");
+	if ((r->bmRequestType & USB_REQ_RECIPIENT_MASK) ==
+	    USB_REQ_RECIPIENT_ENDPOINT)
+		serial_printf("\t\tRecipient : Endpoint\n");
+	if ((r->bmRequestType & USB_REQ_RECIPIENT_MASK) ==
+	    USB_REQ_RECIPIENT_OTHER)
+		serial_printf("\t\tRecipient : Other\n");
+	serial_printf("\tbRequest      0x%2.2x\n", r->bRequest);
+	if (r->bRequest == USB_REQ_GET_STATUS)
+		serial_printf("\t\tGET_STATUS\n");
+	else if (r->bRequest == USB_REQ_SET_ADDRESS)
+		serial_printf("\t\tSET_ADDRESS\n");
+	else if (r->bRequest == USB_REQ_SET_FEATURE)
+		serial_printf("\t\tSET_FEATURE\n");
+	else if (r->bRequest == USB_REQ_GET_DESCRIPTOR)
+		serial_printf("\t\tGET_DESCRIPTOR\n");
+	else if (r->bRequest == USB_REQ_SET_CONFIGURATION)
+		serial_printf("\t\tSET_CONFIGURATION\n");
+	else if (r->bRequest == USB_REQ_SET_INTERFACE)
+		serial_printf("\t\tUSB_REQ_SET_INTERFACE\n");
+	else
+		serial_printf("\tUNKNOWN %d\n", r->bRequest);
+	serial_printf("\twValue        0x%4.4x\n", r->wValue);
+	if (r->bRequest == USB_REQ_GET_DESCRIPTOR) {
+		switch (r->wValue >> 8) {
+		case USB_DESCRIPTOR_TYPE_DEVICE:
+			serial_printf("\tDEVICE\n");
+			break;
+		case USB_DESCRIPTOR_TYPE_CONFIGURATION:
+			serial_printf("\tCONFIGURATION\n");
+			break;
+		case USB_DESCRIPTOR_TYPE_STRING:
+			serial_printf("\tSTRING\n");
+			break;
+		case USB_DESCRIPTOR_TYPE_INTERFACE:
+			serial_printf("\tINTERFACE\n");
+			break;
+		case USB_DESCRIPTOR_TYPE_ENDPOINT:
+			serial_printf("\tENDPOINT\n");
+			break;
+		case USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER:
+			serial_printf("\tDEVICE_QUALIFIER\n");
+			break;
+		case USB_DESCRIPTOR_TYPE_OTHER_SPEED_CONFIGURATION:
+			serial_printf("\tOTHER_SPEED_CONFIGURATION\n");
+			break;
+		case USB_DESCRIPTOR_TYPE_INTERFACE_POWER:
+			serial_printf("\tINTERFACE_POWER\n");
+			break;
+		case USB_DESCRIPTOR_TYPE_HID:
+			serial_printf("\tHID\n");
+			break;
+		case USB_DESCRIPTOR_TYPE_REPORT:
+			serial_printf("\tREPORT\n");
+			break;
+		default:
+			serial_printf("\tUNKNOWN TYPE\n");
+			break;
+		}
+	}
+	serial_printf("\twIndex        0x%4.4x\n", r->wIndex);
+	serial_printf("\twLength       0x%4.4x\n", r->wLength);
+}
+#else
+/* stubs */
+#define print_urb(u)
+#define print_usb_device_request(r)
+#endif /* DEBUG */
 #endif