--- /dev/null
+--- kernel-power-2.6.28.orig/arch/arm/mach-omap2/usb-musb.c
++++ kernel-power-2.6.28/arch/arm/mach-omap2/usb-musb.c
+@@ -141,10 +141,13 @@
+ .config = &musb_config,
+
+ /* REVISIT charge pump on TWL4030 can supply up to
+- * 100 mA ... but this value is board-specific, like
++ * 200 mA ... but this value is board-specific, like
+ * "mode", and should be passed to usb_musb_init().
++ *
++ * Since the power can come from a Y-cable, let the user
++ * decide on power constraints and not limit anything here.
+ */
+- .power = 50, /* up to 100 mA */
++ .power = 0, /* use default of 500 mA */
+ };
+
+ static u64 musb_dmamask = DMA_32BIT_MASK;
+--- kernel-power-2.6.28.orig/drivers/usb/core/otg_whitelist.h
++++ kernel-power-2.6.28/drivers/usb/core/otg_whitelist.h
+@@ -14,7 +14,7 @@
+ #else
+ static inline int is_targeted(struct usb_device *d)
+ {
+- return 0;
++ return 1;
+ }
+ #endif
+
+--- kernel-power-2.6.28.orig/drivers/usb/musb/musb_core.c
++++ kernel-power-2.6.28/drivers/usb/musb/musb_core.c
+@@ -230,6 +230,8 @@
+ * change it unless you really know what you're doing
+ */
+
++ DBG(4, "Some asshole called musb_charger_detect!");
++
+ switch(musb->xceiv->state) {
+ case OTG_STATE_B_IDLE:
+ /* we always reset transceiver */
+@@ -349,7 +351,7 @@
+
+ prefetch((u8 *)src);
+
+- DBG(4, "%cX ep%d fifo %p count %d buf %p\n",
++ DBG_nonverb(4, "%cX ep%d fifo %p count %d buf %p\n",
+ 'T', hw_ep->epnum, fifo, len, src);
+
+ /* we can't assume unaligned reads work */
+@@ -387,7 +389,7 @@
+ {
+ void __iomem *fifo = hw_ep->fifo;
+
+- DBG(4, "%cX ep%d fifo %p count %d buf %p\n",
++ DBG_nonverb(4, "%cX ep%d fifo %p count %d buf %p\n",
+ 'R', hw_ep->epnum, fifo, len, dst);
+
+ /* we can't assume unaligned writes work */
+@@ -576,8 +578,8 @@
+ void __iomem *mbase = musb->mregs;
+ u8 r;
+
+- DBG(3, "<== Power=%02x, DevCtl=%02x, int_usb=0x%x\n", power, devctl,
+- int_usb);
++ DBG(3, "<== State=%s Power=%02x, DevCtl=%02x, int_usb=0x%x\n",
++ otg_state_string(musb), power, devctl, int_usb);
+
+ /* in host mode, the peripheral may issue remote wakeup.
+ * in peripheral mode, the host may resume the link.
+@@ -2028,12 +2030,16 @@
+ int status;
+
+ mutex_lock(&musb->mutex);
+- if (sysfs_streq(buf, "host"))
+- status = musb_platform_set_mode(musb, MUSB_HOST);
++ if (sysfs_streq(buf, "hostl"))
++ status = musb_platform_set_mode(musb, MUSB_HOST, 0);
++ else if (sysfs_streq(buf, "hostf"))
++ status = musb_platform_set_mode(musb, MUSB_HOST, 1);
++ else if (sysfs_streq(buf, "hosth"))
++ status = musb_platform_set_mode(musb, MUSB_HOST, 2);
+ else if (sysfs_streq(buf, "peripheral"))
+- status = musb_platform_set_mode(musb, MUSB_PERIPHERAL);
++ status = musb_platform_set_mode(musb, MUSB_PERIPHERAL, 0);
+ else if (sysfs_streq(buf, "otg"))
+- status = musb_platform_set_mode(musb, MUSB_OTG);
++ status = musb_platform_set_mode(musb, MUSB_OTG, 0);
+ else
+ status = -EINVAL;
+ mutex_unlock(&musb->mutex);
+--- kernel-power-2.6.28.orig/drivers/usb/musb/musb_core.h
++++ kernel-power-2.6.28/drivers/usb/musb/musb_core.h
+@@ -63,6 +63,9 @@
+ #include "../core/hcd.h"
+ #include "musb_host.h"
+
++/* This is the version of forced hostmode userspace<->kernelspace API.
++ * Do not update to the build date, bump only on API changes */
++#define MUSB_VERSION_HOSTMODE "20101110"
+
+ #ifdef CONFIG_USB_MUSB_OTG
+
+@@ -591,7 +594,7 @@
+
+ extern void musb_hnp_stop(struct musb *musb);
+
+-extern int musb_platform_set_mode(struct musb *musb, u8 musb_mode);
++extern int musb_platform_set_mode(struct musb *musb, u8 musb_mode, u8 hostspeed);
+
+ #if defined(CONFIG_USB_TUSB6010) || defined(CONFIG_BLACKFIN) || \
+ defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX)
+--- kernel-power-2.6.28.orig/drivers/usb/musb/musb_debug.h
++++ kernel-power-2.6.28/drivers/usb/musb/musb_debug.h
+@@ -46,6 +46,21 @@
+
+ #ifdef CONFIG_USB_MUSB_DEBUG
+
++#define xprintk_verb(level, facility, format, args...) do { \
++ if (_dbg_level(level)) { \
++ u8 testmode, devctl, power/*, otg_ctrl, func_ctrl, isp_debug*/; \
++ testmode = musb_readb(musb->mregs, MUSB_TESTMODE); \
++ devctl = musb_readb(musb->mregs, MUSB_DEVCTL); \
++ power = musb_readb(musb->mregs, MUSB_POWER); \
++ /*otg_ctrl = musb_ulpi_readb(musb->mregs, ISP1704_OTG_CTRL); \
++ func_ctrl = musb_ulpi_readb(musb->mregs, ISP1704_FUNC_CTRL); \
++ isp_debug = musb_ulpi_readb(musb->mregs, ISP1704_DEBUG); */ \
++ printk(facility "State=%s Testmode=%02x Power=%02x, DevCtl=%02x\n", \
++ otg_state_string(musb), testmode, power, devctl/*, otg_ctrl, func_ctrl, isp_debug*/); \
++ printk(facility "%-20s %4d: " format , \
++ __func__, __LINE__ , ## args); \
++ } } while (0)
++
+ #define xprintk(level, facility, format, args...) do { \
+ if (_dbg_level(level)) { \
+ printk(facility "%-20s %4d: " format , \
+@@ -58,7 +73,8 @@
+ {
+ return musb_debug >= l;
+ }
+-#define DBG(level, fmt, args...) xprintk(level, KERN_DEBUG, fmt, ## args)
++#define DBG(level, fmt, args...) xprintk_verb(level, KERN_DEBUG, fmt, ## args)
++#define DBG_nonverb(level, fmt, args...) xprintk(level, KERN_DEBUG, fmt, ## args)
+ #else
+ #define DBG(level, fmt, args...) do {} while(0)
+ #endif /* CONFIG_USB_MUSB_DEBUG */
+--- kernel-power-2.6.28.orig/drivers/usb/musb/musb_gadget.c
++++ kernel-power-2.6.28/drivers/usb/musb/musb_gadget.c
+@@ -816,12 +816,12 @@
+ if (!ep || !desc)
+ return -EINVAL;
+
++ musb_ep = to_musb_ep(ep);
++ musb = musb_ep->musb;
+ DBG(1, "===> enabling %s\n", ep->name);
+
+- musb_ep = to_musb_ep(ep);
+ hw_ep = musb_ep->hw_ep;
+ regs = hw_ep->regs;
+- musb = musb_ep->musb;
+ mbase = musb->mregs;
+ epnum = musb_ep->current_epnum;
+
+@@ -949,8 +949,8 @@
+ int status = 0;
+
+ musb_ep = to_musb_ep(ep);
+- DBG(4, "disabling %s\n", musb_ep->name);
+ musb = musb_ep->musb;
++ DBG(4, "disabling %s\n", musb_ep->name);
+ epnum = musb_ep->current_epnum;
+ epio = musb->endpoints[epnum].regs;
+
+--- kernel-power-2.6.28.orig/drivers/usb/musb/musb_host.c
++++ kernel-power-2.6.28/drivers/usb/musb/musb_host.c
+@@ -118,7 +118,7 @@
+ csr = musb_readw(epio, MUSB_TXCSR);
+ while (csr & MUSB_TXCSR_FIFONOTEMPTY) {
+ if (csr != lastcsr)
+- DBG(3, "Host TX FIFONOTEMPTY csr: %02x\n", csr);
++ DBG_nonverb(3, "Host TX FIFONOTEMPTY csr: %02x\n", csr);
+ lastcsr = csr;
+ csr |= MUSB_TXCSR_FLUSHFIFO;
+ musb_writew(epio, MUSB_TXCSR, csr);
+@@ -2036,7 +2036,7 @@
+ dma = is_in ? ep->rx_channel : ep->tx_channel;
+ if (dma) {
+ status = ep->musb->dma_controller->channel_abort(dma);
+- DBG(status ? 1 : 3,
++ DBG_nonverb(status ? 1 : 3,
+ "abort %cX%d DMA for urb %p --> %d\n",
+ is_in ? 'R' : 'T', ep->epnum,
+ urb, status);
+--- kernel-power-2.6.28.orig/drivers/usb/musb/musb_procfs.c
++++ kernel-power-2.6.28/drivers/usb/musb/musb_procfs.c
+@@ -479,7 +479,8 @@
+ #elif defined(CONFIG_USB_MUSB_HDRC_HCD)
+ "host"
+ #endif
+- ", debug=%d [eps=%d]\n",
++ ", debug=%d [eps=%d]"
++ ", version_hostmode=" MUSB_VERSION_HOSTMODE "\n",
+ musb_debug,
+ musb->nr_endpoints);
+ if (code <= 0)
+@@ -651,6 +652,75 @@
+ reg = musb_readb(mbase, MUSB_DEVCTL);
+ reg |= MUSB_DEVCTL_SESSION;
+ musb_writeb(mbase, MUSB_DEVCTL, reg);
++
++ /* Pretend there's a session request */
++ musb->ep0_stage = MUSB_EP0_START;
++ musb->xceiv->state = OTG_STATE_A_IDLE;
++ MUSB_HST_MODE(musb);
++ musb_set_vbus(musb, 1);
++
++ /* Connect request */
++ {
++ struct usb_hcd *hcd = musb_to_hcd(musb);
++ u8 testmode, line;
++
++ musb->is_active = 1;
++ set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);
++
++ musb->ep0_stage = MUSB_EP0_START;
++
++#ifdef CONFIG_USB_MUSB_OTG
++ /* flush endpoints when transitioning from Device Mode */
++ if (is_peripheral_active(musb)) {
++ /* REVISIT HNP; just force disconnect */
++ }
++ musb_writew(mbase, MUSB_INTRTXE, musb->epmask);
++ musb_writew(mbase, MUSB_INTRRXE, musb->epmask & 0xfffe);
++ musb_writeb(mbase, MUSB_INTRUSBE, 0xf7);
++#endif
++ musb->port1_status &= ~(USB_PORT_STAT_LOW_SPEED
++ |USB_PORT_STAT_HIGH_SPEED
++ |USB_PORT_STAT_ENABLE
++ );
++ musb->port1_status |= USB_PORT_STAT_CONNECTION
++ |(USB_PORT_STAT_C_CONNECTION << 16);
++
++ line = musb_ulpi_readb(mbase, ISP1704_DEBUG);
++ testmode = musb_readb(mbase, MUSB_TESTMODE);
++
++ switch (line) {
++ case 1: /* pullup indicates a full/high-speed device */
++ if (!(testmode & (MUSB_TEST_FORCE_FS | MUSB_TEST_FORCE_HS)))
++ pr_err("Forced hostmode error: a full/high-speed device attached but low-speed mode selected\n");
++ break;
++ case 2: /* pullup indicates a low-speed device */
++ if (testmode & (MUSB_TEST_FORCE_FS | MUSB_TEST_FORCE_HS))
++ pr_err("Forced hostmode error: a low-speed device attached but full/high-speed mode selected\n");
++ break;
++ default:
++ pr_err("Forced hostmode error: no device attached\n");
++ }
++
++ if (!(testmode & (MUSB_TEST_FORCE_FS | MUSB_TEST_FORCE_HS)))
++ musb->port1_status |= USB_PORT_STAT_LOW_SPEED;
++
++ if (hcd->status_urb)
++ usb_hcd_poll_rh_status(hcd);
++ else
++ usb_hcd_resume_root_hub(hcd);
++
++ MUSB_HST_MODE(musb);
++
++ /* indicate new connection to OTG machine */
++ switch (musb->xceiv->state) {
++ default:
++ musb->xceiv->state = OTG_STATE_A_HOST;
++ hcd->self.is_b_host = 0;
++ break;
++ }
++ DBG(1, "CONNECT (%s) devctl %02x\n",
++ otg_state_string(musb), devctl);
++ }
+ break;
+
+ case 'H':
+--- kernel-power-2.6.28.orig/drivers/usb/musb/musb_regs.h
++++ kernel-power-2.6.28/drivers/usb/musb/musb_regs.h
+@@ -330,7 +330,7 @@
+ while (!(musb_readb(addr, ULPI_REG_CONTROL) & ULPI_REG_CMPLT)) {
+ i++;
+ if (i == 10000) {
+- DBG(3, "ULPI read timed out\n");
++ DBG_nonverb(3, "ULPI read timed out\n");
+ return 0;
+ }
+
+@@ -355,7 +355,7 @@
+ while(!(musb_readb(addr, ULPI_REG_CONTROL) & ULPI_REG_CMPLT)) {
+ i++;
+ if (i == 10000) {
+- DBG(3, "ULPI write timed out\n");
++ DBG_nonverb(3, "ULPI write timed out\n");
+ return;
+ }
+ }
+--- kernel-power-2.6.28.orig/drivers/usb/musb/musbhsdma.c
++++ kernel-power-2.6.28/drivers/usb/musb/musbhsdma.c
+@@ -131,7 +131,7 @@
+ u8 bchannel = musb_channel->idx;
+ u16 csr = 0;
+
+- DBG(4, "%p, pkt_sz %d, addr 0x%x, len %d, mode %d\n",
++ DBG_nonverb(4, "%p, pkt_sz %d, addr 0x%x, len %d, mode %d\n",
+ channel, packet_sz, dma_addr, len, mode);
+
+ if (mode)
+@@ -167,7 +167,7 @@
+ {
+ struct musb_dma_channel *musb_channel = channel->private_data;
+
+- DBG(2, "ep%d-%s pkt_sz %d, dma_addr 0x%x length %d, mode %d\n",
++ DBG_nonverb(2, "ep%d-%s pkt_sz %d, dma_addr 0x%x length %d, mode %d\n",
+ musb_channel->epnum,
+ musb_channel->transmit ? "Tx" : "Rx",
+ packet_sz, dma_addr, len, mode);
+--- kernel-power-2.6.28.orig/drivers/usb/musb/omap2430.c
++++ kernel-power-2.6.28/drivers/usb/musb/omap2430.c
+@@ -73,6 +73,8 @@
+
+ spin_lock_irqsave(&musb->lock, flags);
+
++ DBG(3, "%s\n", otg_state_string(musb));
++
+ devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
+
+ switch (musb->xceiv->state) {
+@@ -211,15 +213,12 @@
+
+ static int musb_platform_resume(struct musb *musb);
+
+-int musb_platform_set_mode(struct musb *musb, u8 musb_mode)
++int musb_platform_set_mode(struct musb *musb, u8 musb_mode, u8 hostspeed)
+ {
+ struct usb_hcd *hcd;
+ struct usb_bus *host;
+ u8 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
+
+- devctl |= MUSB_DEVCTL_SESSION;
+- musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
+-
+ switch (musb_mode) {
+ #ifdef CONFIG_USB_MUSB_HDRC_HCD
+ case MUSB_HOST:
+@@ -227,10 +226,36 @@
+ host = hcd_to_bus(hcd);
+
+ otg_set_host(musb->xceiv, host);
++
++ if (machine_is_nokia_rx51()) {
++ u8 testmode;
++
++ musb_platform_resume(musb);
++
++ devctl |= MUSB_DEVCTL_SESSION;
++ musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
++
++ testmode = MUSB_TEST_FORCE_HOST;
++ if (hostspeed == 1)
++ testmode |= MUSB_TEST_FORCE_FS;
++ else if (hostspeed == 2)
++ testmode |= MUSB_TEST_FORCE_HS;
++ musb_writeb(musb->mregs, MUSB_TESTMODE, testmode);
++ }
+ break;
+ #endif
+ #ifdef CONFIG_USB_GADGET_MUSB_HDRC
+ case MUSB_PERIPHERAL:
++ if (machine_is_nokia_rx51()) {
++ musb_platform_resume(musb);
++ musb_set_vbus(musb, 0);
++
++ devctl &= ~MUSB_DEVCTL_SESSION;
++ musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
++
++ musb_writeb(musb->mregs, MUSB_TESTMODE, 0);
++ }
++
+ otg_set_peripheral(musb->xceiv, &musb->g);
+ break;
+ #endif
+--- kernel-power-2.6.28.orig/drivers/usb/otg/twl4030-usb.c
++++ kernel-power-2.6.28/drivers/usb/otg/twl4030-usb.c
+@@ -371,6 +371,7 @@
+
+ spin_lock_irq(&twl->lock);
+ twl->linkstat = linkstat;
++#if 0
+ if (linkstat == USB_LINK_ID) {
+ twl->otg.default_a = true;
+ twl->otg.state = OTG_STATE_A_IDLE;
+@@ -378,6 +379,7 @@
+ twl->otg.default_a = false;
+ twl->otg.state = OTG_STATE_B_IDLE;
+ }
++#endif
+ spin_unlock_irq(&twl->lock);
+
+ return linkstat;
+--- kernel-power-2.6.28.orig/drivers/usb/musb/musb_virthub.c
++++ kernel-power-2.6.28/drivers/usb/musb/musb_virthub.c
+@@ -112,7 +112,7 @@
+
+ static void musb_port_reset(struct musb *musb, bool do_reset)
+ {
+- u8 power;
++ u8 power, testmode;
+ void __iomem *mbase = musb->mregs;
+
+ #ifdef CONFIG_USB_MUSB_OTG
+@@ -162,10 +162,16 @@
+
+ musb->ignore_disconnect = false;
+
++ testmode = musb_readb(mbase, MUSB_TESTMODE);
+ power = musb_readb(mbase, MUSB_POWER);
+ if (power & MUSB_POWER_HSMODE) {
+ DBG(4, "high-speed device connected\n");
+ musb->port1_status |= USB_PORT_STAT_HIGH_SPEED;
++ if (!(testmode & MUSB_TEST_FORCE_HS))
++ pr_err("Forced hostmode error: a high-speed device attached but not high-speed mode selected\n");
++ } else {
++ if (testmode & MUSB_TEST_FORCE_HS)
++ pr_err("Forced hostmode error: a full/low-speed device attached but high-speed mode selected\n");
+ }
+
+ musb->port1_status &= ~USB_PORT_STAT_RESET;