]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/usb/musb/plat_uds.c
musb_hdrc: Search and replace pPrivateData with private_data
[linux-2.6-omap-h63xx.git] / drivers / usb / musb / plat_uds.c
index e02f672113b1c95fc9ad5b133c7f58f946ecefb5..e8e41bba126cc452aa83e0a2551b07002b6bced8 100644 (file)
  *        At the other extreme, the bandwidth capabilities which do
  *        exist tend to be severely undercommitted.  You can't yet hook
  *        up both a keyboard and a mouse to an external USB hub.
- *
- *  - Provides its own OTG bits.  These are untested, and many of them
- *    seem to be superfluous code bloat given what usbcore does.  (They
- *    have now been partially removed.)
  */
 
 /*
 #include <linux/list.h>
 #include <linux/kobject.h>
 #include <linux/platform_device.h>
-#include <linux/clk.h>
 
 #include <asm/io.h>
 
 #endif
 
 #include "musbdefs.h"
-// #ifdef CONFIG_USB_MUSB_HDRC_HCD
-#define VBUSERR_RETRY_COUNT    2               /* is this too few? */
-// #endif
 
 
 #ifdef CONFIG_ARCH_DAVINCI
@@ -129,12 +121,21 @@ module_param(debug, uint, 0);
 MODULE_PARM_DESC(debug, "initial debug message level");
 
 #define MUSB_VERSION_SUFFIX    "/dbg"
+#else
+
+const char *otg_state_string(struct musb *musb)
+{
+       static char buf[8];
+
+       snprintf(buf, sizeof buf, "otg-%d", musb->xceiv.state);
+       return buf;
+}
 #endif
 
-#define DRIVER_AUTHOR "Mentor Graphics Corp. and Texas Instruments"
+#define DRIVER_AUTHOR "Mentor Graphics, Texas Instruments, Nokia"
 #define DRIVER_DESC "Inventra Dual-Role USB Controller Driver"
 
-#define MUSB_VERSION_BASE "2.2a/db-0.5.1"
+#define MUSB_VERSION_BASE "2.2a/db-0.5.2"
 
 #ifndef MUSB_VERSION_SUFFIX
 #define MUSB_VERSION_SUFFIX    ""
@@ -149,28 +150,9 @@ MODULE_DESCRIPTION(DRIVER_INFO);
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_LICENSE("GPL");
 
-/* time (millseconds) to wait before a restart */
-#define MUSB_RESTART_TIME        5000
-
-/* how many babbles to allow before giving up */
-#define MUSB_MAX_BABBLE_COUNT    10
-
 
 /*-------------------------------------------------------------------------*/
 
-#ifdef CONFIG_USB_MUSB_OTG
-
-/* For debugging/prototyping:  allow disabling host side support on boards
- * with Mini-AB (or Mini-A) connectors, making peripheral side support look
- * like pure peripherals (not reporting OTG capabilities, and able to
- * draw a full 100mA unit load).
- */
-int musb_otg = 1;
-
-module_param(musb_otg, bool, 0600);
-MODULE_PARM_DESC(musb_otg, "enable/disable OTG capabilities");
-#endif
-
 static inline struct musb *dev_to_musb(struct device *dev)
 {
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
@@ -181,129 +163,84 @@ static inline struct musb *dev_to_musb(struct device *dev)
 #endif
 }
 
-static void otg_input_changed(struct musb * pThis, u8 devctl, u8 reset,
-                       u8 connection, u8 suspend)
-{
-#ifdef CONFIG_USB_MUSB_OTG
-       struct otg_machine      *otgm = &pThis->OtgMachine;
-       MGC_OtgMachineInputs Inputs;
-
-       /* reading suspend state from Power register does NOT work */
-       memset(&Inputs, 0, sizeof(Inputs));
-
-       Inputs.bSession = (devctl & MGC_M_DEVCTL_SESSION) ? TRUE : FALSE;
-       Inputs.bSuspend = suspend;
-       Inputs.bConnection = connection;
-       Inputs.bReset = reset;
-       Inputs.bConnectorId = (devctl & MGC_M_DEVCTL_BDEVICE) ? TRUE : FALSE;
-
-       MGC_OtgMachineInputsChanged(otgm, &Inputs);
-#endif
-}
-
-static void otg_input_changed_X(struct musb * pThis, u8 bVbusError, u8 bConnect)
-{
-#ifdef CONFIG_USB_MUSB_OTG
-       MGC_OtgMachineInputs Inputs;
-       void __iomem *pBase = pThis->pRegs;
-       u8 devctl = musb_readb(pBase, MGC_O_HDRC_DEVCTL);
-       u8 power = musb_readb(pBase, MGC_O_HDRC_POWER);
-
-       DBG(2, "<== power %02x, devctl %02x%s%s\n", power, devctl,
-                       bConnect ? ", bcon" : "",
-                       bVbusError ? ", vbus_error" : "");
-
-       /* speculative */
-       memset(&Inputs, 0, sizeof(Inputs));
-       Inputs.bSession = (devctl & MGC_M_DEVCTL_SESSION) ? TRUE : FALSE;
-       Inputs.bConnectorId = (devctl & MGC_M_DEVCTL_BDEVICE) ? TRUE : FALSE;
-       Inputs.bReset = (power & MGC_M_POWER_RESET) ? TRUE : FALSE;
-       Inputs.bConnection = bConnect;
-       Inputs.bVbusError = bVbusError;
-       Inputs.bSuspend = (power & MGC_M_POWER_SUSPENDM) ? TRUE : FALSE;
-       MGC_OtgMachineInputsChanged(&(pThis->OtgMachine), &Inputs);
-#endif                         /* CONFIG_USB_MUSB_OTG */
-}
-
-
 /*-------------------------------------------------------------------------*/
 
 #ifndef CONFIG_USB_TUSB6010
 /*
  * Load an endpoint's FIFO
  */
-void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 wCount, const u8 *pSource)
+void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src)
 {
        void __iomem *fifo = hw_ep->fifo;
 
-       prefetch((u8 *)pSource);
+       prefetch((u8 *)src);
 
        DBG(4, "%cX ep%d fifo %p count %d buf %p\n",
-                       'T', hw_ep->bLocalEnd, fifo, wCount, pSource);
+                       'T', hw_ep->epnum, fifo, len, src);
 
        /* we can't assume unaligned reads work */
-       if (likely((0x01 & (unsigned long) pSource) == 0)) {
+       if (likely((0x01 & (unsigned long) src) == 0)) {
                u16     index = 0;
 
                /* best case is 32bit-aligned source address */
-               if ((0x02 & (unsigned long) pSource) == 0) {
-                       if (wCount >= 4) {
-                               writesl(fifo, pSource + index, wCount >> 2);
-                               index += wCount & ~0x03;
+               if ((0x02 & (unsigned long) src) == 0) {
+                       if (len >= 4) {
+                               writesl(fifo, src + index, len >> 2);
+                               index += len & ~0x03;
                        }
-                       if (wCount & 0x02) {
-                               musb_writew(fifo, 0, *(u16*)&pSource[index]);
+                       if (len & 0x02) {
+                               musb_writew(fifo, 0, *(u16*)&src[index]);
                                index += 2;
                        }
                } else {
-                       if (wCount >= 2) {
-                               writesw(fifo, pSource + index, wCount >> 1);
-                               index += wCount & ~0x01;
+                       if (len >= 2) {
+                               writesw(fifo, src + index, len >> 1);
+                               index += len & ~0x01;
                        }
                }
-               if (wCount & 0x01)
-                       musb_writeb(fifo, 0, pSource[index]);
+               if (len & 0x01)
+                       musb_writeb(fifo, 0, src[index]);
        } else  {
                /* byte aligned */
-               writesb(fifo, pSource, wCount);
+               writesb(fifo, src, len);
        }
 }
 
 /*
  * Unload an endpoint's FIFO
  */
-void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 wCount, u8 *pDest)
+void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst)
 {
        void __iomem *fifo = hw_ep->fifo;
 
        DBG(4, "%cX ep%d fifo %p count %d buf %p\n",
-                       'R', hw_ep->bLocalEnd, fifo, wCount, pDest);
+                       'R', hw_ep->epnum, fifo, len, dst);
 
        /* we can't assume unaligned writes work */
-       if (likely((0x01 & (unsigned long) pDest) == 0)) {
+       if (likely((0x01 & (unsigned long) dst) == 0)) {
                u16     index = 0;
 
                /* best case is 32bit-aligned destination address */
-               if ((0x02 & (unsigned long) pDest) == 0) {
-                       if (wCount >= 4) {
-                               readsl(fifo, pDest, wCount >> 2);
-                               index = wCount & ~0x03;
+               if ((0x02 & (unsigned long) dst) == 0) {
+                       if (len >= 4) {
+                               readsl(fifo, dst, len >> 2);
+                               index = len & ~0x03;
                        }
-                       if (wCount & 0x02) {
-                               *(u16*)&pDest[index] = musb_readw(fifo, 0);
+                       if (len & 0x02) {
+                               *(u16*)&dst[index] = musb_readw(fifo, 0);
                                index += 2;
                        }
                } else {
-                       if (wCount >= 2) {
-                               readsw(fifo, pDest, wCount >> 1);
-                               index = wCount & ~0x01;
+                       if (len >= 2) {
+                               readsw(fifo, dst, len >> 1);
+                               index = len & ~0x01;
                        }
                }
-               if (wCount & 0x01)
-                       pDest[index] = musb_readb(fifo, 0);
+               if (len & 0x01)
+                       dst[index] = musb_readb(fifo, 0);
        } else  {
                /* byte aligned */
-               readsb(fifo, pDest, wCount);
+               readsb(fifo, dst, len);
        }
 }
 
@@ -334,9 +271,9 @@ static const u8 musb_test_packet[53] = {
 
 void musb_load_testpacket(struct musb *musb)
 {
-       void __iomem    *regs = musb->aLocalEnd[0].regs;
+       void __iomem    *regs = musb->endpoints[0].regs;
 
-       MGC_SelectEnd(musb->pRegs, 0);
+       musb_ep_select(musb->mregs, 0);
        musb_write_fifo(musb->control_ep,
                        sizeof(musb_test_packet), musb_test_packet);
        musb_writew(regs, MGC_O_HDRC_CSR0, MGC_M_CSR0_TXPKTRDY);
@@ -344,13 +281,76 @@ void musb_load_testpacket(struct musb *musb)
 
 /*-------------------------------------------------------------------------*/
 
+#ifdef CONFIG_USB_MUSB_OTG
+
+/*
+ * See also USB_OTG_1-3.pdf 6.6.5 Timers
+ * REVISIT: Are the other timers done in the hardware?
+ */
+#define TB_ASE0_BRST           100     /* Min 3.125 ms */
+
+/*
+ * Handles OTG hnp timeouts, such as b_ase0_brst
+ */
+void musb_otg_timer_func(unsigned long data)
+{
+       struct musb     *musb = (struct musb *)data;
+       unsigned long   flags;
+
+       spin_lock_irqsave(&musb->lock, flags);
+       if (musb->xceiv.state == OTG_STATE_B_WAIT_ACON) {
+               DBG(1, "HNP: B_WAIT_ACON timeout, going back to B_PERIPHERAL\n");
+               musb_g_disconnect(musb);
+               musb->xceiv.state = OTG_STATE_B_PERIPHERAL;
+               musb->is_active = 0;
+       }
+       spin_unlock_irqrestore(&musb->lock, flags);
+}
+
+static DEFINE_TIMER(musb_otg_timer, musb_otg_timer_func, 0, 0);
+
+/*
+ * Stops the B-device HNP state. Caller must take care of locking.
+ */
+void musb_hnp_stop(struct musb *musb)
+{
+       struct usb_hcd  *hcd = musb_to_hcd(musb);
+       void __iomem    *mbase = musb->mregs;
+       u8      reg;
+
+       switch (musb->xceiv.state) {
+       case OTG_STATE_A_PERIPHERAL:
+       case OTG_STATE_A_WAIT_VFALL:
+               DBG(1, "HNP: Switching back to A-host\n");
+               musb_g_disconnect(musb);
+               musb_root_disconnect(musb);
+               musb->xceiv.state = OTG_STATE_A_IDLE;
+               musb->is_active = 0;
+               break;
+       case OTG_STATE_B_HOST:
+               DBG(1, "HNP: Disabling HR\n");
+               hcd->self.is_b_host = 0;
+               musb->xceiv.state = OTG_STATE_B_PERIPHERAL;
+               reg = musb_readb(mbase, MGC_O_HDRC_POWER);
+               reg |= MGC_M_POWER_SUSPENDM;
+               musb_writeb(mbase, MGC_O_HDRC_POWER, reg);
+               /* REVISIT: Start SESSION_REQUEST here? */
+               break;
+       default:
+               DBG(1, "HNP: Stopping in unknown state %s\n",
+                       otg_state_string(musb));
+       }
+}
+
+#endif
+
 /*
  * Interrupt Service Routine to record USB "global" interrupts.
  * Since these do not happen often and signify things of
  * paramount importance, it seems OK to check them individually;
  * the order of the tests is specified in the manual
  *
- * @param pThis instance pointer
+ * @param musb instance pointer
  * @param bIntrUSB register contents
  * @param devctl
  * @param power
@@ -360,52 +360,104 @@ void musb_load_testpacket(struct musb *musb)
                | MGC_M_INTR_VBUSERROR | MGC_M_INTR_CONNECT \
                | MGC_M_INTR_RESET )
 
-static irqreturn_t musb_stage0_irq(struct musb * pThis, u8 bIntrUSB,
+static irqreturn_t musb_stage0_irq(struct musb * musb, u8 bIntrUSB,
                                u8 devctl, u8 power)
 {
        irqreturn_t handled = IRQ_NONE;
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
-       void __iomem *pBase = pThis->pRegs;
+       void __iomem *mbase = musb->mregs;
 #endif
 
        DBG(3, "<== Power=%02x, DevCtl=%02x, bIntrUSB=0x%x\n", power, devctl,
                bIntrUSB);
 
-       /* in host mode when a device resume me (from power save)
-        * in device mode when the host resume me; it shold not change
-        * "identity".
+       /* in host mode, the peripheral may issue remote wakeup.
+        * in peripheral mode, the host may resume the link.
+        * spurious RESUME irqs happen too, paired with SUSPEND.
         */
        if (bIntrUSB & MGC_M_INTR_RESUME) {
                handled = IRQ_HANDLED;
-               DBG(3, "RESUME\n");
-               pThis->is_active = 1;
+               DBG(3, "RESUME (%s)\n", otg_state_string(musb));
 
                if (devctl & MGC_M_DEVCTL_HM) {
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
-                       /* REVISIT:  this is where SRP kicks in, yes?
-                        * host responsibility should be to CLEAR the
-                        * resume signaling after 50 msec ...
-                        */
-                       MUSB_HST_MODE(pThis);   /* unnecessary */
-                       power &= ~MGC_M_POWER_SUSPENDM;
-                       musb_writeb(pBase, MGC_O_HDRC_POWER,
-                               power | MGC_M_POWER_RESUME);
-
-                       /* should now be A_SUSPEND */
-                       pThis->xceiv.state = OTG_STATE_A_HOST;
+                       switch (musb->xceiv.state) {
+                       case OTG_STATE_A_SUSPEND:
+                               /* remote wakeup?  later, GetPortStatus
+                                * will stop RESUME signaling
+                                */
+
+                               if (power & MGC_M_POWER_SUSPENDM) {
+                                       /* spurious */
+                                       musb->int_usb &= ~MGC_M_INTR_SUSPEND;
+                                       DBG(2, "Spurious SUSPENDM\n");
+                                       break;
+                               }
+
+                               power &= ~MGC_M_POWER_SUSPENDM;
+                               musb_writeb(mbase, MGC_O_HDRC_POWER,
+                                               power | MGC_M_POWER_RESUME);
+
+                               musb->port1_status |=
+                                               (USB_PORT_STAT_C_SUSPEND << 16)
+                                               | MUSB_PORT_STAT_RESUME;
+                               musb->rh_timer = jiffies
+                                               + msecs_to_jiffies(20);
+
+                               musb->xceiv.state = OTG_STATE_A_HOST;
+                               musb->is_active = 1;
+                               usb_hcd_resume_root_hub(musb_to_hcd(musb));
+                               break;
+                       case OTG_STATE_B_WAIT_ACON:
+                               musb->xceiv.state = OTG_STATE_B_PERIPHERAL;
+                               musb->is_active = 1;
+                               MUSB_DEV_MODE(musb);
+                               break;
+                       default:
+                               WARN("bogus %s RESUME (%s)\n",
+                                       "host",
+                                       otg_state_string(musb));
+                       }
 #endif
                } else {
+                       switch (musb->xceiv.state) {
+#ifdef CONFIG_USB_MUSB_HDRC_HCD
+                       case OTG_STATE_A_SUSPEND:
+                               /* possibly DISCONNECT is upcoming */
+                               musb->xceiv.state = OTG_STATE_A_HOST;
+                               usb_hcd_resume_root_hub(musb_to_hcd(musb));
+                               break;
+#endif
 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
-                       MUSB_DEV_MODE(pThis);   /* unnecessary */
+                       case OTG_STATE_B_WAIT_ACON:
+                       case OTG_STATE_B_PERIPHERAL:
+                               /* disconnect while suspended?  we may
+                                * not get a disconnect irq...
+                                */
+                               if ((devctl & MGC_M_DEVCTL_VBUS)
+                                               != (3 << MGC_S_DEVCTL_VBUS)) {
+                                       musb->int_usb |= MGC_M_INTR_DISCONNECT;
+                                       musb->int_usb &= ~MGC_M_INTR_SUSPEND;
+                                       break;
+                               }
+                               musb_g_resume(musb);
+                               break;
+                       case OTG_STATE_B_IDLE:
+                               musb->int_usb &= ~MGC_M_INTR_SUSPEND;
+                               break;
 #endif
-                       musb_g_resume(pThis);
+                       default:
+                               WARN("bogus %s RESUME (%s)\n",
+                                       "peripheral",
+                                       otg_state_string(musb));
+                       }
                }
        }
 
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
        /* see manual for the order of the tests */
        if (bIntrUSB & MGC_M_INTR_SESSREQ) {
-               DBG(1, "SESSION_REQUEST (%s)\n", otg_state_string(pThis));
+               DBG(1, "SESSION_REQUEST (%s)\n", otg_state_string(musb));
 
                /* IRQ arrives from ID pin sense or (later, if VBUS power
                 * is removed) SRP.  responses are time critical:
@@ -414,35 +466,62 @@ static irqreturn_t musb_stage0_irq(struct musb * pThis, u8 bIntrUSB,
                 *  - ... to A_WAIT_BCON.
                 * a_wait_vrise_tmout triggers VBUS_ERROR transitions
                 */
-               musb_writeb(pBase, MGC_O_HDRC_DEVCTL, MGC_M_DEVCTL_SESSION);
-               pThis->bEnd0Stage = MGC_END0_START;
-               pThis->xceiv.state = OTG_STATE_A_IDLE;
-               MUSB_HST_MODE(pThis);
-               musb_set_vbus(pThis, 1);
+               musb_writeb(mbase, MGC_O_HDRC_DEVCTL, MGC_M_DEVCTL_SESSION);
+               musb->ep0_stage = MGC_END0_START;
+               musb->xceiv.state = OTG_STATE_A_IDLE;
+               MUSB_HST_MODE(musb);
+               musb_set_vbus(musb, 1);
 
                handled = IRQ_HANDLED;
-
-#ifdef CONFIG_USB_MUSB_OTG
-               {
-               MGC_OtgMachineInputs Inputs;
-               memset(&Inputs, 0, sizeof(Inputs));
-               Inputs.bSession = TRUE;
-               Inputs.bConnectorId = FALSE;
-               Inputs.bReset = FALSE;
-               Inputs.bConnection = FALSE;
-               Inputs.bSuspend = FALSE;
-               MGC_OtgMachineInputsChanged(&(pThis->OtgMachine), &Inputs);
-               }
-#endif
        }
 
        if (bIntrUSB & MGC_M_INTR_VBUSERROR) {
+               int     ignore = 0;
+
+               /* During connection as an A-Device, we may see a short
+                * current spikes causing voltage drop, because of cable
+                * and peripheral capacitance combined with vbus draw.
+                * (So: less common with truly self-powered devices, where
+                * vbus doesn't act like a power supply.)
+                *
+                * Such spikes are short; usually less than ~500 usec, max
+                * of ~2 msec.  That is, they're not sustained overcurrent
+                * errors, though they're reported using VBUSERROR irqs.
+                *
+                * Workarounds:  (a) hardware: use self powered devices.
+                * (b) software:  ignore non-repeated VBUS errors.
+                *
+                * REVISIT:  do delays from lots of DEBUG_KERNEL checks
+                * make trouble here, keeping VBUS < 4.4V ?
+                */
+               switch (musb->xceiv.state) {
+               case OTG_STATE_A_HOST:
+                       /* recovery is dicey once we've gotten past the
+                        * initial stages of enumeration, but if VBUS
+                        * stayed ok at the other end of the link, and
+                        * another reset is due (at least for high speed,
+                        * to redo the chirp etc), it might work OK...
+                        */
+               case OTG_STATE_A_WAIT_BCON:
+               case OTG_STATE_A_WAIT_VRISE:
+                       if (musb->vbuserr_retry) {
+                               musb->vbuserr_retry--;
+                               ignore = 1;
+                               devctl |= MGC_M_DEVCTL_SESSION;
+                               musb_writeb(mbase, MGC_O_HDRC_DEVCTL, devctl);
+                       } else {
+                               musb->port1_status |=
+                                         (1 << USB_PORT_FEAT_OVER_CURRENT)
+                                       | (1 << USB_PORT_FEAT_C_OVER_CURRENT);
+                       }
+                       break;
+               default:
+                       break;
+               }
 
-               // MGC_OtgMachineInputsChanged(otgm, &Inputs);
-               // otg_input_changed_X(pThis, TRUE, TRUE);
-               // ... may need to abort otg timer ...
-
-               DBG(1, "VBUS_ERROR (%02x, %s), retry #%d\n", devctl,
+               DBG(1, "VBUS_ERROR in %s (%02x, %s), retry #%d, port1 %08x\n",
+                               otg_state_string(musb),
+                               devctl,
                                ({ char *s;
                                switch (devctl & MGC_M_DEVCTL_VBUS) {
                                case 0 << MGC_S_DEVCTL_VBUS:
@@ -455,88 +534,95 @@ static irqreturn_t musb_stage0_irq(struct musb * pThis, u8 bIntrUSB,
                                default:
                                        s = "VALID"; break;
                                }; s; }),
-                               pThis->vbuserr_retry);
+                               VBUSERR_RETRY_COUNT - musb->vbuserr_retry,
+                               musb->port1_status);
 
                /* go through A_WAIT_VFALL then start a new session */
-               musb_set_vbus(pThis, 0);
+               if (!ignore)
+                       musb_set_vbus(musb, 0);
                handled = IRQ_HANDLED;
-       } else
-               pThis->vbuserr_retry = VBUSERR_RETRY_COUNT;
+       }
 
        if (bIntrUSB & MGC_M_INTR_CONNECT) {
+               struct usb_hcd *hcd = musb_to_hcd(musb);
+
                handled = IRQ_HANDLED;
-               pThis->is_active = 1;
-               set_bit(HCD_FLAG_SAW_IRQ, &musb_to_hcd(pThis)->flags);
+               musb->is_active = 1;
+               set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);
 
-               pThis->bEnd0Stage = MGC_END0_START;
+               musb->ep0_stage = MGC_END0_START;
 
 #ifdef CONFIG_USB_MUSB_OTG
                /* flush endpoints when transitioning from Device Mode */
-               if (is_peripheral_active(pThis)) {
+               if (is_peripheral_active(musb)) {
                        // REVISIT HNP; just force disconnect
                }
-               pThis->bDelayPortPowerOff = FALSE;
+               musb->delay_port_power_off = FALSE;
+               musb_writew(mbase, MGC_O_HDRC_INTRTXE, musb->wEndMask);
+               musb_writew(mbase, MGC_O_HDRC_INTRRXE, musb->wEndMask & 0xfffe);
+               musb_writeb(mbase, MGC_O_HDRC_INTRUSBE, 0xf7);
 #endif
-               pThis->port1_status &= ~(USB_PORT_STAT_LOW_SPEED
+               musb->port1_status &= ~(USB_PORT_STAT_LOW_SPEED
                                        |USB_PORT_STAT_HIGH_SPEED
                                        |USB_PORT_STAT_ENABLE
                                        );
-               pThis->port1_status |= USB_PORT_STAT_CONNECTION
+               musb->port1_status |= USB_PORT_STAT_CONNECTION
                                        |(USB_PORT_STAT_C_CONNECTION << 16);
 
                /* high vs full speed is just a guess until after reset */
                if (devctl & MGC_M_DEVCTL_LSDEV)
-                       pThis->port1_status |= USB_PORT_STAT_LOW_SPEED;
+                       musb->port1_status |= USB_PORT_STAT_LOW_SPEED;
 
-               usb_hcd_poll_rh_status(musb_to_hcd(pThis));
+               if (hcd->status_urb)
+                       usb_hcd_poll_rh_status(hcd);
+               else
+                       usb_hcd_resume_root_hub(hcd);
 
-               MUSB_HST_MODE(pThis);
+               MUSB_HST_MODE(musb);
 
                /* indicate new connection to OTG machine */
-               switch (pThis->xceiv.state) {
+               switch (musb->xceiv.state) {
                case OTG_STATE_B_WAIT_ACON:
-                       pThis->xceiv.state = OTG_STATE_B_HOST;
+                       DBG(1, "HNP: Waiting to switch to b_host state\n");
+                       musb->xceiv.state = OTG_STATE_B_HOST;
+                       hcd->self.is_b_host = 1;
                        break;
                default:
-                       pThis->xceiv.state = OTG_STATE_A_HOST;
+                       if ((devctl & MGC_M_DEVCTL_VBUS)
+                                       == (3 << MGC_S_DEVCTL_VBUS)) {
+                               musb->xceiv.state = OTG_STATE_A_HOST;
+                               hcd->self.is_b_host = 0;
+                       }
                        break;
                }
-               DBG(1, "CONNECT (%s)\n", otg_state_string(pThis));
-               otg_input_changed(pThis, devctl, FALSE, TRUE, FALSE);
+               DBG(1, "CONNECT (%s) devctl %02x\n",
+                               otg_state_string(musb), devctl);
        }
 #endif /* CONFIG_USB_MUSB_HDRC_HCD */
 
-       /* saved one bit: bus reset and babble share the same bit;
-        * If I am host is a babble! i must be the only one allowed
-        * to reset the bus; when in otg mode it means that I have
-        * to switch to device
+       /* mentor saves a bit: bus reset and babble share the same irq.
+        * only host sees babble; only peripheral sees bus reset.
         */
        if (bIntrUSB & MGC_M_INTR_RESET) {
                if (devctl & MGC_M_DEVCTL_HM) {
-                       DBG(1, "BABBLE\n");
-
-                       /* REVISIT it's unclear how to handle this.  Mentor's
-                        * code stopped the whole USB host, which is clearly
-                        * very wrong.  Docs say (15.1) that babble ends the
-                        * current sesssion, so shutdown _with restart_ would
-                        * be appropriate ... except that seems to be wrong,
-                        * at least some lowspeed enumerations trigger the
-                        * babbles without aborting the session!
-                        *
-                        * (A "babble" IRQ seems quite pointless...)
+                       /*
+                        * Looks like non-HS BABBLE can be ignored, but
+                        * HS BABBLE is an error condition. For HS the solution
+                        * is to avoid babble in the first place and fix whatever
+                        * causes BABBLE. When HS BABBLE happens we can only stop
+                        * the session.
                         */
-
+                       if (devctl & (MGC_M_DEVCTL_FSDEV | MGC_M_DEVCTL_LSDEV))
+                               DBG(1, "BABBLE devctl: %02x\n", devctl);
+                       else {
+                               ERR("Stopping host session because of babble\n");
+                               musb_writeb(mbase, MGC_O_HDRC_DEVCTL, 0);
+                       }
                } else {
                        DBG(1, "BUS RESET\n");
 
-                       musb_g_reset(pThis);
-
-                       /* reading state from Power register doesn't work */
-                       otg_input_changed(pThis, devctl, TRUE, FALSE,
-                                               (power & MGC_M_POWER_SUSPENDM)
-                                               ? TRUE : FALSE);
-
-                       schedule_work(&pThis->irq_work);
+                       musb_g_reset(musb);
+                       schedule_work(&musb->irq_work);
                }
 
                handled = IRQ_HANDLED;
@@ -551,12 +637,12 @@ static irqreturn_t musb_stage0_irq(struct musb * pThis, u8 bIntrUSB,
  * paramount importance, it seems OK to check them individually;
  * the order of the tests is specified in the manual
  *
- * @param pThis instance pointer
+ * @param musb instance pointer
  * @param bIntrUSB register contents
  * @param devctl
  * @param power
  */
-static irqreturn_t musb_stage2_irq(struct musb * pThis, u8 bIntrUSB,
+static irqreturn_t musb_stage2_irq(struct musb * musb, u8 bIntrUSB,
                                u8 devctl, u8 power)
 {
        irqreturn_t handled = IRQ_NONE;
@@ -574,70 +660,121 @@ static irqreturn_t musb_stage2_irq(struct musb * pThis, u8 bIntrUSB,
  * to support ISO transfers yet.
  */
        if (bIntrUSB & MGC_M_INTR_SOF) {
-               void __iomem *pBase = pThis->pRegs;
+               void __iomem *mbase = musb->mregs;
                struct musb_hw_ep       *ep;
-               u8 bEnd;
+               u8 epnum;
                u16 wFrame;
 
                DBG(6, "START_OF_FRAME\n");
                handled = IRQ_HANDLED;
 
                /* start any periodic Tx transfers waiting for current frame */
-               wFrame = musb_readw(pBase, MGC_O_HDRC_FRAME);
-               ep = pThis->aLocalEnd;
-               for (bEnd = 1; (bEnd < pThis->bEndCount)
-                                       && (pThis->wEndMask >= (1 << bEnd));
-                               bEnd++, ep++) {
+               wFrame = musb_readw(mbase, MGC_O_HDRC_FRAME);
+               ep = musb->endpoints;
+               for (epnum = 1; (epnum < musb->nr_endpoints)
+                                       && (musb->wEndMask >= (1 << epnum));
+                               epnum++, ep++) {
                        // FIXME handle framecounter wraps (12 bits)
                        // eliminate duplicated StartUrb logic
                        if (ep->dwWaitFrame >= wFrame) {
                                ep->dwWaitFrame = 0;
                                printk("SOF --> periodic TX%s on %d\n",
                                        ep->tx_channel ? " DMA" : "",
-                                       bEnd);
+                                       epnum);
                                if (!ep->tx_channel)
-                                       musb_h_tx_start(pThis, bEnd);
+                                       musb_h_tx_start(musb, epnum);
                                else
-                                       cppi_hostdma_start(pThis, bEnd);
+                                       cppi_hostdma_start(musb, epnum);
                        }
                }               /* end of for loop */
        }
 #endif
 
-       if ((bIntrUSB & MGC_M_INTR_DISCONNECT) && !pThis->bIgnoreDisconnect) {
-               DBG(1, "DISCONNECT as %s, devctl %02x\n",
-                               MUSB_MODE(pThis), devctl);
+       if ((bIntrUSB & MGC_M_INTR_DISCONNECT) && !musb->ignore_disconnect) {
+               DBG(1, "DISCONNECT (%s) as %s, devctl %02x\n",
+                               otg_state_string(musb),
+                               MUSB_MODE(musb), devctl);
                handled = IRQ_HANDLED;
-               pThis->is_active = 0;
-
-               /* need to check it against pThis, because devctl is going
-                * to report ID low as soon as the device gets disconnected
-                */
-               if (is_host_active(pThis))
-                       musb_root_disconnect(pThis);
-               else
-                       musb_g_disconnect(pThis);
 
-               /* REVISIT all OTG state machine transitions */
-               otg_input_changed_X(pThis, FALSE, FALSE);
+               switch (musb->xceiv.state) {
+#ifdef CONFIG_USB_MUSB_HDRC_HCD
+               case OTG_STATE_A_HOST:
+               case OTG_STATE_A_SUSPEND:
+                       musb_root_disconnect(musb);
+                       if (musb->a_wait_bcon != 0)
+                               musb_platform_try_idle(musb, jiffies
+                                       + msecs_to_jiffies(musb->a_wait_bcon));
+                       break;
+#endif /* HOST */
+#ifdef CONFIG_USB_MUSB_OTG
+               case OTG_STATE_B_HOST:
+                       musb_hnp_stop(musb);
+                       break;
+                       /* FALLTHROUGH */
+               case OTG_STATE_A_PERIPHERAL:
+                       musb_root_disconnect(musb);
+                       /* FALLTHROUGH */
+               case OTG_STATE_B_WAIT_ACON:
+#endif /* OTG */
+#ifdef CONFIG_USB_GADGET_MUSB_HDRC
+               case OTG_STATE_B_PERIPHERAL:
+                       musb_g_disconnect(musb);
+                       break;
+#endif /* GADGET */
+               default:
+                       WARN("unhandled DISCONNECT transition (%s)\n",
+                               otg_state_string(musb));
+                       break;
+               }
 
-               schedule_work(&pThis->irq_work);
+               schedule_work(&musb->irq_work);
        }
 
        if (bIntrUSB & MGC_M_INTR_SUSPEND) {
-               DBG(1, "SUSPEND, devctl %02x\n", devctl);
+               DBG(1, "SUSPEND (%s) devctl %02x power %02x\n",
+                               otg_state_string(musb), devctl, power);
                handled = IRQ_HANDLED;
 
-               /* peripheral suspend, may trigger HNP */
-               if (!(devctl & MGC_M_DEVCTL_HM)) {
-                       musb_g_suspend(pThis);
-                       pThis->is_active = is_otg_enabled(pThis)
-                                       && pThis->xceiv.gadget->b_hnp_enable;
-                       otg_input_changed(pThis, devctl, FALSE, FALSE, TRUE);
-               } else
-                       pThis->is_active = 0;
+               switch (musb->xceiv.state) {
+               case OTG_STATE_A_PERIPHERAL:
+                       musb_hnp_stop(musb);
+                       break;
+               case OTG_STATE_B_PERIPHERAL:
+                       musb_g_suspend(musb);
+                       musb->is_active = is_otg_enabled(musb)
+                                       && musb->xceiv.gadget->b_hnp_enable;
+                       if (musb->is_active) {
+                               musb->xceiv.state = OTG_STATE_B_WAIT_ACON;
+#ifdef CONFIG_USB_MUSB_OTG
+                               DBG(1, "HNP: Setting timer for b_ase0_brst\n");
+                               musb_otg_timer.data = (unsigned long)musb;
+                               mod_timer(&musb_otg_timer, jiffies
+                                       + msecs_to_jiffies(TB_ASE0_BRST));
+#endif
+                       }
+                       break;
+               case OTG_STATE_A_WAIT_BCON:
+                       if (musb->a_wait_bcon != 0)
+                               musb_platform_try_idle(musb, jiffies
+                                       + msecs_to_jiffies(musb->a_wait_bcon));
+                       break;
+               case OTG_STATE_A_HOST:
+                       musb->xceiv.state = OTG_STATE_A_SUSPEND;
+                       musb->is_active = is_otg_enabled(musb)
+                                       && musb->xceiv.host->b_hnp_enable;
+                       break;
+               case OTG_STATE_B_HOST:
+                       /* Transition to B_PERIPHERAL, see 6.8.2.6 p 44 */
+                       DBG(1, "REVISIT: SUSPEND as B_HOST\n");
+                       break;
+               default:
+                       /* "should not happen" */
+                       musb->is_active = 0;
+                       break;
+               }
        }
 
+
        return handled;
 }
 
@@ -648,7 +785,7 @@ static irqreturn_t musb_stage2_irq(struct musb * pThis, u8 bIntrUSB,
 */
 void musb_start(struct musb *musb)
 {
-       void __iomem    *regs = musb->pRegs;
+       void __iomem    *regs = musb->mregs;
        u8              devctl = musb_readb(regs, MGC_O_HDRC_DEVCTL);
 
        DBG(2, "<== devctl %02x\n", devctl);
@@ -660,8 +797,6 @@ void musb_start(struct musb *musb)
 
        musb_writeb(regs, MGC_O_HDRC_TESTMODE, 0);
 
-       musb_platform_enable(musb);
-
        /* put into basic highspeed mode and start session */
        musb_writeb(regs, MGC_O_HDRC_POWER, MGC_M_POWER_ISOUPDATE
                                                | MGC_M_POWER_SOFTCONN
@@ -693,27 +828,28 @@ void musb_start(struct musb *musb)
                if ((devctl & MGC_M_DEVCTL_VBUS) == MGC_M_DEVCTL_VBUS)
                        musb->is_active = 1;
        }
+       musb_platform_enable(musb);
        musb_writeb(regs, MGC_O_HDRC_DEVCTL, devctl);
 }
 
 
-static void musb_generic_disable(struct musb *pThis)
+static void musb_generic_disable(struct musb *musb)
 {
-       void __iomem    *pBase = pThis->pRegs;
+       void __iomem    *mbase = musb->mregs;
        u16     temp;
 
        /* disable interrupts */
-       musb_writeb(pBase, MGC_O_HDRC_INTRUSBE, 0);
-       musb_writew(pBase, MGC_O_HDRC_INTRTX, 0);
-       musb_writew(pBase, MGC_O_HDRC_INTRRX, 0);
+       musb_writeb(mbase, MGC_O_HDRC_INTRUSBE, 0);
+       musb_writew(mbase, MGC_O_HDRC_INTRTXE, 0);
+       musb_writew(mbase, MGC_O_HDRC_INTRRXE, 0);
 
        /* off */
-       musb_writeb(pBase, MGC_O_HDRC_DEVCTL, 0);
+       musb_writeb(mbase, MGC_O_HDRC_DEVCTL, 0);
 
        /*  flush pending interrupts */
-       temp = musb_readb(pBase, MGC_O_HDRC_INTRUSB);
-       temp = musb_readw(pBase, MGC_O_HDRC_INTRTX);
-       temp = musb_readw(pBase, MGC_O_HDRC_INTRRX);
+       temp = musb_readb(mbase, MGC_O_HDRC_INTRUSB);
+       temp = musb_readw(mbase, MGC_O_HDRC_INTRTX);
+       temp = musb_readw(mbase, MGC_O_HDRC_INTRRX);
 
 }
 
@@ -724,18 +860,13 @@ static void musb_generic_disable(struct musb *pThis)
  * with controller locked, irqs blocked
  * acts as a NOP unless some role activated the hardware
  */
-void musb_stop(struct musb * pThis)
+void musb_stop(struct musb *musb)
 {
        /* stop IRQs, timers, ... */
-       musb_platform_disable(pThis);
-       musb_generic_disable(pThis);
+       musb_platform_disable(musb);
+       musb_generic_disable(musb);
        DBG(3, "HDRC disabled\n");
 
-#ifdef CONFIG_USB_MUSB_OTG
-       if (is_otg_enabled(pThis))
-               MGC_OtgMachineDestroy(&pThis->OtgMachine);
-#endif
-
        /* FIXME
         *  - mark host and/or peripheral drivers unusable/inactive
         *  - disable DMA (and enable it in HdrcStart)
@@ -743,14 +874,7 @@ void musb_stop(struct musb * pThis)
         *    OTG mode, gadget driver module rmmod/modprobe cycles that
         *  - ...
         */
-
-#ifdef CONFIG_USB_MUSB_HDRC_HCD
-       if (is_host_enabled(pThis)) {
-               /* REVISIT aren't there some paths where this is wrong?  */
-               dev_warn(pThis->controller, "%s, root hub still active\n",
-                               __FUNCTION__);
-       }
-#endif
+       musb_platform_try_idle(musb, 0);
 }
 
 static void musb_shutdown(struct platform_device *pdev)
@@ -758,10 +882,14 @@ static void musb_shutdown(struct platform_device *pdev)
        struct musb     *musb = dev_to_musb(&pdev->dev);
        unsigned long   flags;
 
-       spin_lock_irqsave(&musb->Lock, flags);
+       spin_lock_irqsave(&musb->lock, flags);
        musb_platform_disable(musb);
        musb_generic_disable(musb);
-       spin_unlock_irqrestore(&musb->Lock, flags);
+       if (musb->clock) {
+               clk_put(musb->clock);
+               musb->clock = NULL;
+       }
+       spin_unlock_irqrestore(&musb->lock, flags);
 
        /* FIXME power down */
 }
@@ -786,9 +914,9 @@ static void musb_shutdown(struct platform_device *pdev)
 #endif
 
 #ifdef CONFIG_USB_TUSB6010
-static ushort __devinitdata fifo_mode = 4;
+static ushort __initdata fifo_mode = 4;
 #else
-static ushort __devinitdata fifo_mode = 2;
+static ushort __initdata fifo_mode = 2;
 #endif
 
 /* "modprobe ... fifo_mode=1" etc */
@@ -814,7 +942,7 @@ struct fifo_cfg {
  */
 
 /* mode 0 - fits in 2KB */
-static const struct fifo_cfg __devinitdata mode_0_cfg[] = {
+static struct fifo_cfg __initdata mode_0_cfg[] = {
 { .hw_ep_num = 1, .style = FIFO_TX,   .maxpacket = 512, },
 { .hw_ep_num = 1, .style = FIFO_RX,   .maxpacket = 512, },
 { .hw_ep_num = 2, .style = FIFO_RXTX, .maxpacket = 512, },
@@ -823,7 +951,7 @@ static const struct fifo_cfg __devinitdata mode_0_cfg[] = {
 };
 
 /* mode 1 - fits in 4KB */
-static const struct fifo_cfg __devinitdata mode_1_cfg[] = {
+static struct fifo_cfg __initdata mode_1_cfg[] = {
 { .hw_ep_num = 1, .style = FIFO_TX,   .maxpacket = 512, .mode = BUF_DOUBLE, },
 { .hw_ep_num = 1, .style = FIFO_RX,   .maxpacket = 512, .mode = BUF_DOUBLE, },
 { .hw_ep_num = 2, .style = FIFO_RXTX, .maxpacket = 512, .mode = BUF_DOUBLE, },
@@ -832,7 +960,7 @@ static const struct fifo_cfg __devinitdata mode_1_cfg[] = {
 };
 
 /* mode 2 - fits in 4KB */
-static const struct fifo_cfg __devinitdata mode_2_cfg[] = {
+static struct fifo_cfg __initdata mode_2_cfg[] = {
 { .hw_ep_num = 1, .style = FIFO_TX,   .maxpacket = 512, },
 { .hw_ep_num = 1, .style = FIFO_RX,   .maxpacket = 512, },
 { .hw_ep_num = 2, .style = FIFO_TX,   .maxpacket = 512, },
@@ -842,7 +970,7 @@ static const struct fifo_cfg __devinitdata mode_2_cfg[] = {
 };
 
 /* mode 3 - fits in 4KB */
-static const struct fifo_cfg __devinitdata mode_3_cfg[] = {
+static struct fifo_cfg __initdata mode_3_cfg[] = {
 { .hw_ep_num = 1, .style = FIFO_TX,   .maxpacket = 512, .mode = BUF_DOUBLE, },
 { .hw_ep_num = 1, .style = FIFO_RX,   .maxpacket = 512, .mode = BUF_DOUBLE, },
 { .hw_ep_num = 2, .style = FIFO_TX,   .maxpacket = 512, },
@@ -852,7 +980,7 @@ static const struct fifo_cfg __devinitdata mode_3_cfg[] = {
 };
 
 /* mode 4 - fits in 16KB */
-static const struct fifo_cfg __devinitdata mode_4_cfg[] = {
+static struct fifo_cfg __initdata mode_4_cfg[] = {
 { .hw_ep_num =  1, .style = FIFO_TX,   .maxpacket = 512, },
 { .hw_ep_num =  1, .style = FIFO_RX,   .maxpacket = 512, },
 { .hw_ep_num =  2, .style = FIFO_TX,   .maxpacket = 512, },
@@ -890,11 +1018,11 @@ static const struct fifo_cfg __devinitdata mode_4_cfg[] = {
  *
  * returns negative errno or offset for next fifo.
  */
-static int __devinit
+static int __init
 fifo_setup(struct musb *musb, struct musb_hw_ep  *hw_ep,
                const struct fifo_cfg *cfg, u16 offset)
 {
-       void __iomem    *mbase = musb->pRegs;
+       void __iomem    *mbase = musb->mregs;
        int     size = 0;
        u16     maxpacket = cfg->maxpacket;
        u16     c_off = offset >> 3;
@@ -916,13 +1044,13 @@ fifo_setup(struct musb *musb, struct musb_hw_ep  *hw_ep,
        }
 
        /* configure the FIFO */
-       musb_writeb(mbase, MGC_O_HDRC_INDEX, hw_ep->bLocalEnd);
+       musb_writeb(mbase, MGC_O_HDRC_INDEX, hw_ep->epnum);
 
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
        /* EP0 reserved endpoint for control, bidirectional;
         * EP1 reserved for bulk, two unidirection halves.
         */
-       if (hw_ep->bLocalEnd == 1)
+       if (hw_ep->epnum == 1)
                musb->bulk_ep = hw_ep;
        /* REVISIT error check:  be sure ep0 can both rx and tx ... */
 #endif
@@ -931,47 +1059,47 @@ fifo_setup(struct musb *musb, struct musb_hw_ep  *hw_ep,
                musb_writeb(mbase, MGC_O_HDRC_TXFIFOSZ, c_size);
                musb_writew(mbase, MGC_O_HDRC_TXFIFOADD, c_off);
                hw_ep->tx_double_buffered = !!(c_size & MGC_M_FIFOSZ_DPB);
-               hw_ep->wMaxPacketSizeTx = maxpacket;
+               hw_ep->max_packet_sz_tx = maxpacket;
                break;
        case FIFO_RX:
                musb_writeb(mbase, MGC_O_HDRC_RXFIFOSZ, c_size);
                musb_writew(mbase, MGC_O_HDRC_RXFIFOADD, c_off);
                hw_ep->rx_double_buffered = !!(c_size & MGC_M_FIFOSZ_DPB);
-               hw_ep->wMaxPacketSizeRx = maxpacket;
+               hw_ep->max_packet_sz_rx = maxpacket;
                break;
        case FIFO_RXTX:
                musb_writeb(mbase, MGC_O_HDRC_TXFIFOSZ, c_size);
                musb_writew(mbase, MGC_O_HDRC_TXFIFOADD, c_off);
                hw_ep->rx_double_buffered = !!(c_size & MGC_M_FIFOSZ_DPB);
-               hw_ep->wMaxPacketSizeRx = maxpacket;
+               hw_ep->max_packet_sz_rx = maxpacket;
 
                musb_writeb(mbase, MGC_O_HDRC_RXFIFOSZ, c_size);
                musb_writew(mbase, MGC_O_HDRC_RXFIFOADD, c_off);
                hw_ep->tx_double_buffered = hw_ep->rx_double_buffered;
-               hw_ep->wMaxPacketSizeTx = maxpacket;
+               hw_ep->max_packet_sz_tx = maxpacket;
 
-               hw_ep->bIsSharedFifo = TRUE;
+               hw_ep->is_shared_fifo = TRUE;
                break;
        }
 
        /* NOTE rx and tx endpoint irqs aren't managed separately,
         * which happens to be ok
         */
-       musb->wEndMask |= (1 << hw_ep->bLocalEnd);
+       musb->wEndMask |= (1 << hw_ep->epnum);
 
        return offset + (maxpacket << ((c_size & MGC_M_FIFOSZ_DPB) ? 1 : 0));
 }
 
-static const struct fifo_cfg __devinitdata ep0_cfg = {
+static struct fifo_cfg __initdata ep0_cfg = {
        .style = FIFO_RXTX, .maxpacket = 64,
 };
 
-static int __devinit ep_config_from_table(struct musb *musb)
+static int __init ep_config_from_table(struct musb *musb)
 {
        const struct fifo_cfg   *cfg;
        unsigned                i, n;
        int                     offset;
-       struct musb_hw_ep       *hw_ep = musb->aLocalEnd;
+       struct musb_hw_ep       *hw_ep = musb->endpoints;
 
        switch (fifo_mode) {
        default:
@@ -1006,6 +1134,10 @@ static int __devinit ep_config_from_table(struct musb *musb)
        offset = fifo_setup(musb, hw_ep, &ep0_cfg, 0);
        // assert(offset > 0)
 
+       /* NOTE:  for RTL versions >= 1.400 EPINFO and RAMINFO would
+        * be better than static MUSB_C_NUM_EPS and DYN_FIFO_SIZE...
+        */
+
        for (i = 0; i < n; i++) {
                u8      epn = cfg->hw_ep_num;
 
@@ -1021,7 +1153,7 @@ static int __devinit ep_config_from_table(struct musb *musb)
                        return -EINVAL;
                }
                epn++;
-               musb->bEndCount = max(epn, musb->bEndCount);
+               musb->nr_endpoints = max(epn, musb->nr_endpoints);
        }
 
        printk(KERN_DEBUG "%s: %d/%d max ep, %d/%d memory\n",
@@ -1042,49 +1174,49 @@ static int __devinit ep_config_from_table(struct musb *musb)
 
 /*
  * ep_config_from_hw - when MUSB_C_DYNFIFO_DEF is false
- * @param pThis the controller
+ * @param musb the controller
  */
-static int __devinit ep_config_from_hw(struct musb *musb)
+static int __init ep_config_from_hw(struct musb *musb)
 {
-       u8 bEnd = 0, reg;
-       struct musb_hw_ep *pEnd;
-       void *pBase = musb->pRegs;
+       u8 epnum = 0, reg;
+       struct musb_hw_ep *hw_ep;
+       void *mbase = musb->mregs;
 
        DBG(2, "<== static silicon ep config\n");
 
        /* FIXME pick up ep0 maxpacket size */
 
-       for (bEnd = 1; bEnd < MUSB_C_NUM_EPS; bEnd++) {
-               MGC_SelectEnd(pBase, bEnd);
-               pEnd = musb->aLocalEnd + bEnd;
+       for (epnum = 1; epnum < MUSB_C_NUM_EPS; epnum++) {
+               musb_ep_select(mbase, epnum);
+               hw_ep = musb->endpoints + epnum;
 
                /* read from core using indexed model */
-               reg = musb_readb(pEnd->regs, 0x10 + MGC_O_HDRC_FIFOSIZE);
+               reg = musb_readb(hw_ep->regs, 0x10 + MGC_O_HDRC_FIFOSIZE);
                if (!reg) {
                        /* 0's returned when no more endpoints */
                        break;
                }
-               musb->bEndCount++;
-               musb->wEndMask |= (1 << bEnd);
+               musb->nr_endpoints++;
+               musb->wEndMask |= (1 << epnum);
 
-               pEnd->wMaxPacketSizeTx = 1 << (reg & 0x0f);
+               hw_ep->max_packet_sz_tx = 1 << (reg & 0x0f);
 
                /* shared TX/RX FIFO? */
                if ((reg & 0xf0) == 0xf0) {
-                       pEnd->wMaxPacketSizeRx = pEnd->wMaxPacketSizeTx;
-                       pEnd->bIsSharedFifo = TRUE;
+                       hw_ep->max_packet_sz_rx = hw_ep->max_packet_sz_tx;
+                       hw_ep->is_shared_fifo = TRUE;
                        continue;
                } else {
-                       pEnd->wMaxPacketSizeRx = 1 << ((reg & 0xf0) >> 4);
-                       pEnd->bIsSharedFifo = FALSE;
+                       hw_ep->max_packet_sz_rx = 1 << ((reg & 0xf0) >> 4);
+                       hw_ep->is_shared_fifo = FALSE;
                }
 
-               /* FIXME set up pEnd->{rx,tx}_double_buffered */
+               /* FIXME set up hw_ep->{rx,tx}_double_buffered */
 
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
                /* pick an RX/TX endpoint for bulk */
-               if (pEnd->wMaxPacketSizeTx < 512
-                               || pEnd->wMaxPacketSizeRx < 512)
+               if (hw_ep->max_packet_sz_tx < 512
+                               || hw_ep->max_packet_sz_rx < 512)
                        continue;
 
                /* REVISIT:  this algorithm is lazy, we should at least
@@ -1092,7 +1224,7 @@ static int __devinit ep_config_from_hw(struct musb *musb)
                 */
                if (musb->bulk_ep)
                        continue;
-               musb->bulk_ep = pEnd;
+               musb->bulk_ep = hw_ep;
 #endif
        }
 
@@ -1111,7 +1243,7 @@ enum { MUSB_CONTROLLER_MHDRC, MUSB_CONTROLLER_HDRC, };
 /* Initialize MUSB (M)HDRC part of the USB hardware subsystem;
  * configure endpoints, or take their config from silicon
  */
-static int __devinit musb_core_init(u16 wType, struct musb *pThis)
+static int __init musb_core_init(u16 wType, struct musb *musb)
 {
 #ifdef MUSB_AHB_ID
        u32 dwData;
@@ -1120,13 +1252,13 @@ static int __devinit musb_core_init(u16 wType, struct musb *pThis)
        char *type;
        u16 wRelease, wRelMajor, wRelMinor;
        char aInfo[78], aRevision[32], aDate[12];
-       void __iomem    *pBase = pThis->pRegs;
+       void __iomem    *mbase = musb->mregs;
        int             status = 0;
        int             i;
 
        /* log core options (read using indexed model) */
-       MGC_SelectEnd(pBase, 0);
-       reg = musb_readb(pBase, 0x10 + MGC_O_HDRC_CONFIGDATA);
+       musb_ep_select(mbase, 0);
+       reg = musb_readb(mbase, 0x10 + MGC_O_HDRC_CONFIGDATA);
 
        strcpy(aInfo, (reg & MGC_M_CONFIGDATA_UTMIDW) ? "UTMI-16" : "UTMI-8");
        if (reg & MGC_M_CONFIGDATA_DYNFIFO) {
@@ -1135,7 +1267,7 @@ static int __devinit musb_core_init(u16 wType, struct musb *pThis)
        if (reg & MGC_M_CONFIGDATA_MPRXE) {
                strcat(aInfo, ", bulk combine");
 #ifdef C_MP_RX
-               pThis->bBulkCombine = TRUE;
+               musb->bulk_combine = TRUE;
 #else
                strcat(aInfo, " (X)");          /* no driver support */
 #endif
@@ -1143,7 +1275,7 @@ static int __devinit musb_core_init(u16 wType, struct musb *pThis)
        if (reg & MGC_M_CONFIGDATA_MPTXE) {
                strcat(aInfo, ", bulk split");
 #ifdef C_MP_TX
-               pThis->bBulkSplit = TRUE;
+               musb->bulk_split = TRUE;
 #else
                strcat(aInfo, " (X)");          /* no driver support */
 #endif
@@ -1164,24 +1296,24 @@ static int __devinit musb_core_init(u16 wType, struct musb *pThis)
                        musb_driver_name, reg, aInfo);
 
 #ifdef MUSB_AHB_ID
-       dwData = musb_readl(pBase, 0x404);
+       dwData = musb_readl(mbase, 0x404);
        sprintf(aDate, "%04d-%02x-%02x", (dwData & 0xffff),
                (dwData >> 16) & 0xff, (dwData >> 24) & 0xff);
        /* FIXME ID2 and ID3 are unused */
-       dwData = musb_readl(pBase, 0x408);
+       dwData = musb_readl(mbase, 0x408);
        printk("ID2=%lx\n", (long unsigned)dwData);
-       dwData = musb_readl(pBase, 0x40c);
+       dwData = musb_readl(mbase, 0x40c);
        printk("ID3=%lx\n", (long unsigned)dwData);
-       reg = musb_readb(pBase, 0x400);
+       reg = musb_readb(mbase, 0x400);
        wType = ('M' == reg) ? MUSB_CONTROLLER_MHDRC : MUSB_CONTROLLER_HDRC;
 #else
        aDate[0] = 0;
 #endif
        if (MUSB_CONTROLLER_MHDRC == wType) {
-               pThis->bIsMultipoint = 1;
+               musb->is_multipoint = 1;
                type = "M";
        } else {
-               pThis->bIsMultipoint = 0;
+               musb->is_multipoint = 0;
                type = "";
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
 #ifndef        CONFIG_USB_OTG_BLACKLIST_HUB
@@ -1193,7 +1325,7 @@ static int __devinit musb_core_init(u16 wType, struct musb *pThis)
        }
 
        /* log release info */
-       wRelease = musb_readw(pBase, MGC_O_HDRC_HWVERS);
+       wRelease = musb_readw(mbase, MGC_O_HDRC_HWVERS);
        wRelMajor = (wRelease >> 10) & 0x1f;
        wRelMinor = wRelease & 0x3ff;
        snprintf(aRevision, 32, "%d.%d%s", wRelMajor,
@@ -1202,23 +1334,23 @@ static int __devinit musb_core_init(u16 wType, struct musb *pThis)
                        musb_driver_name, type, aRevision, aDate);
 
        /* configure ep0 */
-       pThis->aLocalEnd[0].wMaxPacketSizeTx = MGC_END0_FIFOSIZE;
-       pThis->aLocalEnd[0].wMaxPacketSizeRx = MGC_END0_FIFOSIZE;
+       musb->endpoints[0].max_packet_sz_tx = MGC_END0_FIFOSIZE;
+       musb->endpoints[0].max_packet_sz_rx = MGC_END0_FIFOSIZE;
 
        /* discover endpoint configuration */
-       pThis->bEndCount = 1;
-       pThis->wEndMask = 1;
+       musb->nr_endpoints = 1;
+       musb->wEndMask = 1;
 
        if (reg & MGC_M_CONFIGDATA_DYNFIFO) {
                if (can_dynfifo())
-                       status = ep_config_from_table(pThis);
+                       status = ep_config_from_table(musb);
                else {
                        ERR("reconfigure software for Dynamic FIFOs\n");
                        status = -ENODEV;
                }
        } else {
                if (!can_dynfifo())
-                       status = ep_config_from_hw(pThis);
+                       status = ep_config_from_hw(musb);
                else {
                        ERR("reconfigure software for static FIFOs\n");
                        return -ENODEV;
@@ -1229,45 +1361,48 @@ static int __devinit musb_core_init(u16 wType, struct musb *pThis)
                return status;
 
        /* finish init, and print endpoint config */
-       for (i = 0; i < pThis->bEndCount; i++) {
-               struct musb_hw_ep       *hw_ep = pThis->aLocalEnd + i;
+       for (i = 0; i < musb->nr_endpoints; i++) {
+               struct musb_hw_ep       *hw_ep = musb->endpoints + i;
 
-               hw_ep->fifo = MUSB_FIFO_OFFSET(i) + pBase;
+               hw_ep->fifo = MUSB_FIFO_OFFSET(i) + mbase;
 #ifdef CONFIG_USB_TUSB6010
-               hw_ep->fifo_async = pThis->async + 0x400 + MUSB_FIFO_OFFSET(i);
-               hw_ep->fifo_sync = pThis->sync + 0x400 + MUSB_FIFO_OFFSET(i);
+               hw_ep->fifo_async = musb->async + 0x400 + MUSB_FIFO_OFFSET(i);
+               hw_ep->fifo_sync = musb->sync + 0x400 + MUSB_FIFO_OFFSET(i);
+               hw_ep->fifo_sync_va =
+                       musb->sync_va + 0x400 + MUSB_FIFO_OFFSET(i);
+
                if (i == 0)
-                       hw_ep->conf = pBase - 0x400 + TUSB_EP0_CONF;
+                       hw_ep->conf = mbase - 0x400 + TUSB_EP0_CONF;
                else
-                       hw_ep->conf = pBase + 0x400 + (((i - 1) & 0xf) << 2);
+                       hw_ep->conf = mbase + 0x400 + (((i - 1) & 0xf) << 2);
 #endif
 
-               hw_ep->regs = MGC_END_OFFSET(i, 0) + pBase;
+               hw_ep->regs = MGC_END_OFFSET(i, 0) + mbase;
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
-               hw_ep->target_regs = MGC_BUSCTL_OFFSET(i, 0) + pBase;
+               hw_ep->target_regs = MGC_BUSCTL_OFFSET(i, 0) + mbase;
                hw_ep->rx_reinit = 1;
                hw_ep->tx_reinit = 1;
 #endif
 
-               if (hw_ep->wMaxPacketSizeTx) {
+               if (hw_ep->max_packet_sz_tx) {
                        printk(KERN_DEBUG
                                "%s: hw_ep %d%s, %smax %d\n",
                                musb_driver_name, i,
-                               hw_ep->bIsSharedFifo ? "shared" : "tx",
+                               hw_ep->is_shared_fifo ? "shared" : "tx",
                                hw_ep->tx_double_buffered
                                        ? "doublebuffer, " : "",
-                               hw_ep->wMaxPacketSizeTx);
+                               hw_ep->max_packet_sz_tx);
                }
-               if (hw_ep->wMaxPacketSizeRx && !hw_ep->bIsSharedFifo) {
+               if (hw_ep->max_packet_sz_rx && !hw_ep->is_shared_fifo) {
                        printk(KERN_DEBUG
                                "%s: hw_ep %d%s, %smax %d\n",
                                musb_driver_name, i,
                                "rx",
                                hw_ep->rx_double_buffered
                                        ? "doublebuffer, " : "",
-                               hw_ep->wMaxPacketSizeRx);
+                               hw_ep->max_packet_sz_rx);
                }
-               if (!(hw_ep->wMaxPacketSizeTx || hw_ep->wMaxPacketSizeRx))
+               if (!(hw_ep->max_packet_sz_tx || hw_ep->max_packet_sz_rx))
                        DBG(1, "hw_ep %d not configured\n", i);
        }
 
@@ -1276,7 +1411,7 @@ static int __devinit musb_core_init(u16 wType, struct musb *pThis)
 
 /*-------------------------------------------------------------------------*/
 
-#ifdef CONFIG_ARCH_OMAP243X
+#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430)
 
 static irqreturn_t generic_interrupt(int irq, void *__hci)
 {
@@ -1284,16 +1419,16 @@ static irqreturn_t generic_interrupt(int irq, void *__hci)
        irqreturn_t     retval = IRQ_NONE;
        struct musb     *musb = __hci;
 
-       spin_lock_irqsave(&musb->Lock, flags);
+       spin_lock_irqsave(&musb->lock, flags);
 
-       musb->int_usb = musb_readb(musb->pRegs, MGC_O_HDRC_INTRUSB);
-       musb->int_tx = musb_readw(musb->pRegs, MGC_O_HDRC_INTRTX);
-       musb->int_rx = musb_readw(musb->pRegs, MGC_O_HDRC_INTRRX);
+       musb->int_usb = musb_readb(musb->mregs, MGC_O_HDRC_INTRUSB);
+       musb->int_tx = musb_readw(musb->mregs, MGC_O_HDRC_INTRTX);
+       musb->int_rx = musb_readw(musb->mregs, MGC_O_HDRC_INTRRX);
 
        if (musb->int_usb || musb->int_tx || musb->int_rx)
                retval = musb_interrupt(musb);
 
-       spin_unlock_irqrestore(&musb->Lock, flags);
+       spin_unlock_irqrestore(&musb->lock, flags);
 
        /* REVISIT we sometimes get spurious IRQs on g_ep0
         * not clear why...
@@ -1322,8 +1457,8 @@ irqreturn_t musb_interrupt(struct musb *musb)
        int             ep_num;
        u32             reg;
 
-       devctl = musb_readb(musb->pRegs, MGC_O_HDRC_DEVCTL);
-       power = musb_readb(musb->pRegs, MGC_O_HDRC_POWER);
+       devctl = musb_readb(musb->mregs, MGC_O_HDRC_DEVCTL);
+       power = musb_readb(musb->mregs, MGC_O_HDRC_POWER);
 
        DBG(4, "** IRQ %s usb%04x tx%04x rx%04x\n",
                (devctl & MGC_M_DEVCTL_HM) ? "host" : "peripheral",
@@ -1335,8 +1470,6 @@ irqreturn_t musb_interrupt(struct musb *musb)
        if (musb->int_usb & STAGE0_MASK)
                retval |= musb_stage0_irq(musb, musb->int_usb,
                                devctl, power);
-       else
-               musb->vbuserr_retry = VBUSERR_RETRY_COUNT;
 
        /* "stage 1" is handling endpoint irqs */
 
@@ -1353,7 +1486,7 @@ irqreturn_t musb_interrupt(struct musb *musb)
        ep_num = 1;
        while (reg) {
                if (reg & 1) {
-                       // MGC_SelectEnd(musb->pRegs, ep_num);
+                       // musb_ep_select(musb->mregs, ep_num);
                        /* REVISIT just retval = ep->rx_irq(...) */
                        retval = IRQ_HANDLED;
                        if (devctl & MGC_M_DEVCTL_HM) {
@@ -1374,7 +1507,7 @@ irqreturn_t musb_interrupt(struct musb *musb)
        ep_num = 1;
        while (reg) {
                if (reg & 1) {
-                       // MGC_SelectEnd(musb->pRegs, ep_num);
+                       // musb_ep_select(musb->mregs, ep_num);
                        /* REVISIT just retval |= ep->tx_irq(...) */
                        retval = IRQ_HANDLED;
                        if (devctl & MGC_M_DEVCTL_HM) {
@@ -1399,19 +1532,19 @@ irqreturn_t musb_interrupt(struct musb *musb)
 
 
 #ifndef CONFIG_USB_INVENTRA_FIFO
-static int __devinitdata use_dma = is_dma_capable();
+static int __initdata use_dma = 1;
 
 /* "modprobe ... use_dma=0" etc */
 module_param(use_dma, bool, 0);
 MODULE_PARM_DESC(use_dma, "enable/disable use of DMA");
 
-void musb_dma_completion(struct musb *musb, u8 bLocalEnd, u8 bTransmit)
+void musb_dma_completion(struct musb *musb, u8 epnum, u8 bTransmit)
 {
-       u8      devctl = musb_readb(musb->pRegs, MGC_O_HDRC_DEVCTL);
+       u8      devctl = musb_readb(musb->mregs, MGC_O_HDRC_DEVCTL);
 
        /* called with controller lock already held */
 
-       if (!bLocalEnd) {
+       if (!epnum) {
 #ifndef CONFIG_USB_TUSB_OMAP_DMA
                if (!is_cppi_enabled()) {
                        /* endpoint 0 */
@@ -1426,26 +1559,26 @@ void musb_dma_completion(struct musb *musb, u8 bLocalEnd, u8 bTransmit)
                if (bTransmit) {
                        if (devctl & MGC_M_DEVCTL_HM) {
                                if (is_host_capable())
-                                       musb_host_tx(musb, bLocalEnd);
+                                       musb_host_tx(musb, epnum);
                        } else {
                                if (is_peripheral_capable())
-                                       musb_g_tx(musb, bLocalEnd);
+                                       musb_g_tx(musb, epnum);
                        }
                } else {
                        /* receive */
                        if (devctl & MGC_M_DEVCTL_HM) {
                                if (is_host_capable())
-                                       musb_host_rx(musb, bLocalEnd);
+                                       musb_host_rx(musb, epnum);
                        } else {
                                if (is_peripheral_capable())
-                                       musb_g_rx(musb, bLocalEnd);
+                                       musb_g_rx(musb, epnum);
                        }
                }
        }
 }
 
 #else
-#define use_dma                        is_dma_capable()
+#define use_dma                        0
 #endif
 
 /*-------------------------------------------------------------------------*/
@@ -1459,23 +1592,32 @@ musb_mode_show(struct device *dev, struct device_attribute *attr, char *buf)
        unsigned long flags;
        int ret = -EINVAL;
 
-       spin_lock_irqsave(&musb->Lock, flags);
-       switch (musb->board_mode) {
-       case MUSB_HOST:
-               ret = sprintf(buf, "host\n");
-               break;
-       case MUSB_PERIPHERAL:
-               ret = sprintf(buf, "peripheral\n");
-               break;
-       case MUSB_OTG:
-               ret = sprintf(buf, "otg\n");
-               break;
-       }
-       spin_unlock_irqrestore(&musb->Lock, flags);
+       spin_lock_irqsave(&musb->lock, flags);
+       ret = sprintf(buf, "%s\n", otg_state_string(musb));
+       spin_unlock_irqrestore(&musb->lock, flags);
 
        return ret;
 }
-static DEVICE_ATTR(mode, S_IRUGO, musb_mode_show, NULL);
+
+static ssize_t
+musb_mode_store(struct device *dev, struct device_attribute *attr,
+               const char *buf, size_t n)
+{
+       struct musb     *musb = dev_to_musb(dev);
+       unsigned long   flags;
+
+       spin_lock_irqsave(&musb->lock, flags);
+       if (!strncmp(buf, "host", 4))
+               musb_platform_set_mode(musb, MUSB_HOST);
+       if (!strncmp(buf, "peripheral", 10))
+               musb_platform_set_mode(musb, MUSB_PERIPHERAL);
+       if (!strncmp(buf, "otg", 3))
+               musb_platform_set_mode(musb, MUSB_OTG);
+       spin_unlock_irqrestore(&musb->lock, flags);
+
+       return n;
+}
+static DEVICE_ATTR(mode, 0644, musb_mode_show, musb_mode_store);
 
 static ssize_t
 musb_cable_show(struct device *dev, struct device_attribute *attr, char *buf)
@@ -1485,8 +1627,8 @@ musb_cable_show(struct device *dev, struct device_attribute *attr, char *buf)
        unsigned long flags;
        int vbus;
 
-       spin_lock_irqsave(&musb->Lock, flags);
-#ifdef CONFIG_USB_TUSB6010
+       spin_lock_irqsave(&musb->lock, flags);
+#if defined(CONFIG_USB_TUSB6010) && !defined(CONFIG_USB_MUSB_OTG)
        /* REVISIT: connect-A != connect-B ... */
        vbus = musb_platform_get_vbus_status(musb);
        if (vbus)
@@ -1498,7 +1640,7 @@ musb_cable_show(struct device *dev, struct device_attribute *attr, char *buf)
         * VBUS high for a long time after power has been removed, can
         * cause temporary false indications of a connection.
         */
-       vbus = musb_readb(musb->pRegs, MGC_O_HDRC_DEVCTL);
+       vbus = musb_readb(musb->mregs, MGC_O_HDRC_DEVCTL);
        if (vbus & 0x10) {
                /* REVISIT retest on real OTG hardware */
                switch (musb->board_mode) {
@@ -1516,19 +1658,78 @@ musb_cable_show(struct device *dev, struct device_attribute *attr, char *buf)
        } else  /* VBUS level below A-Valid */
                v2 = "disconnected";
 #endif
-       musb_platform_try_idle(musb);
-       spin_unlock_irqrestore(&musb->Lock, flags);
+       musb_platform_try_idle(musb, 0);
+       spin_unlock_irqrestore(&musb->lock, flags);
 
        return sprintf(buf, "%s%s\n", v1, v2);
 }
 static DEVICE_ATTR(cable, S_IRUGO, musb_cable_show, NULL);
 
+static ssize_t
+musb_vbus_store(struct device *dev, struct device_attribute *attr,
+               const char *buf, size_t n)
+{
+       struct musb     *musb = dev_to_musb(dev);
+       unsigned long   flags;
+       unsigned long   val;
+
+       spin_lock_irqsave(&musb->lock, flags);
+       if (sscanf(buf, "%lu", &val) < 1) {
+               printk(KERN_ERR "Invalid VBUS timeout ms value\n");
+               return -EINVAL;
+       }
+       musb->a_wait_bcon = val;
+       if (musb->xceiv.state == OTG_STATE_A_WAIT_BCON)
+               musb->is_active = 0;
+       musb_platform_try_idle(musb, jiffies + msecs_to_jiffies(val));
+       spin_unlock_irqrestore(&musb->lock, flags);
+
+       return n;
+}
+
+static ssize_t
+musb_vbus_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct musb     *musb = dev_to_musb(dev);
+       unsigned long   flags;
+       unsigned long   val;
+
+       spin_lock_irqsave(&musb->lock, flags);
+       val = musb->a_wait_bcon;
+       spin_unlock_irqrestore(&musb->lock, flags);
+
+       return sprintf(buf, "%lu\n", val);
+}
+static DEVICE_ATTR(vbus, 0644, musb_vbus_show, musb_vbus_store);
+
+static ssize_t
+musb_srp_store(struct device *dev, struct device_attribute *attr,
+               const char *buf, size_t n)
+{
+       struct musb     *musb=dev_to_musb(dev);
+       unsigned long   flags;
+       unsigned short  srp;
+
+       if (sscanf(buf, "%hu", &srp) != 1
+                       || (srp != 1)) {
+               printk (KERN_ERR "SRP: Value must be 1\n");
+               return -EINVAL;
+       }
+
+       spin_lock_irqsave(&musb->lock, flags);
+       if (srp == 1)
+               musb_g_wakeup(musb);
+       spin_unlock_irqrestore(&musb->lock, flags);
+
+       return n;
+}
+static DEVICE_ATTR(srp, 0644, NULL, musb_srp_store);
 #endif
 
 /* Only used to provide cable state change events */
-static void musb_irq_work(void *data)
+static void musb_irq_work(struct work_struct *data)
 {
-       struct musb *musb = (struct musb *)data;
+       struct musb *musb = container_of(data, struct musb, irq_work);
 
        sysfs_notify(&musb->controller->kobj, NULL, "cable");
 }
@@ -1537,7 +1738,7 @@ static void musb_irq_work(void *data)
  * Init support
  */
 
-static struct musb *__devinit
+static struct musb *__init
 allocate_instance(struct device *dev, void __iomem *mbase)
 {
        struct musb             *musb;
@@ -1567,15 +1768,15 @@ allocate_instance(struct device *dev, void __iomem *mbase)
 
 #endif
 
-       musb->pRegs = mbase;
+       musb->mregs = mbase;
        musb->ctrl_base = mbase;
        musb->nIrq = -ENODEV;
-       for (epnum = 0, ep = musb->aLocalEnd;
+       for (epnum = 0, ep = musb->endpoints;
                        epnum < MUSB_C_NUM_EPS;
                        epnum++, ep++) {
 
                ep->musb = musb;
-               ep->bLocalEnd = epnum;
+               ep->epnum = epnum;
        }
 
        musb->controller = dev;
@@ -1592,6 +1793,10 @@ static void musb_free(struct musb *musb)
 #ifdef CONFIG_SYSFS
        device_remove_file(musb->controller, &dev_attr_mode);
        device_remove_file(musb->controller, &dev_attr_cable);
+       device_remove_file(musb->controller, &dev_attr_vbus);
+#ifdef CONFIG_USB_MUSB_OTG
+       device_remove_file(musb->controller, &dev_attr_srp);
+#endif
 #endif
 
 #ifdef CONFIG_USB_GADGET_MUSB_HDRC
@@ -1602,16 +1807,16 @@ static void musb_free(struct musb *musb)
                disable_irq_wake(musb->nIrq);
                free_irq(musb->nIrq, musb);
        }
-       if (is_dma_capable() && musb->pDmaController) {
-               struct dma_controller   *c = musb->pDmaController;
+       if (is_dma_capable() && musb->dma_controller) {
+               struct dma_controller   *c = musb->dma_controller;
 
-               (void) c->stop(c->pPrivateData);
-               dma_controller_factory.destroy(c);
+               (void) c->stop(c->private_data);
+               dma_controller_destroy(c);
        }
 
-       musb_writeb(musb->pRegs, MGC_O_HDRC_DEVCTL, 0);
+       musb_writeb(musb->mregs, MGC_O_HDRC_DEVCTL, 0);
        musb_platform_exit(musb);
-       musb_writeb(musb->pRegs, MGC_O_HDRC_DEVCTL, 0);
+       musb_writeb(musb->mregs, MGC_O_HDRC_DEVCTL, 0);
 
        if (musb->clock) {
                clk_disable(musb->clock);
@@ -1630,14 +1835,14 @@ static void musb_free(struct musb *musb)
  *
  * @pDevice: the controller (already clocked, etc)
  * @nIrq: irq
- * @pRegs: virtual address of controller registers,
+ * @mregs: virtual address of controller registers,
  *     not yet corrected for platform-specific offsets
  */
-static int __devinit
+static int __init
 musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
 {
        int                     status;
-       struct musb             *pThis;
+       struct musb             *musb;
        struct musb_hdrc_platform_data *plat = dev->platform_data;
 
        /* The driver might handle more features than the board; OK.
@@ -1672,26 +1877,41 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
        }
 
        /* allocate */
-       pThis = allocate_instance(dev, ctrl);
-       if (!pThis)
+       musb = allocate_instance(dev, ctrl);
+       if (!musb)
                return -ENOMEM;
 
-       spin_lock_init(&pThis->Lock);
-       pThis->board_mode = plat->mode;
-       pThis->board_set_power = plat->set_power;
-       pThis->min_power = plat->min_power;
+       spin_lock_init(&musb->lock);
+       musb->board_mode = plat->mode;
+       musb->board_set_power = plat->set_power;
+       musb->set_clock = plat->set_clock;
+       musb->min_power = plat->min_power;
+
+       /* Clock usage is chip-specific ... functional clock (DaVinci,
+        * OMAP2430), or PHY ref (some TUSB6010 boards).  All this core
+        * code does is make sure a clock handle is available; platform
+        * code manages it during start/stop and suspend/resume.
+        */
+       if (plat->clock) {
+               musb->clock = clk_get(dev, plat->clock);
+               if (IS_ERR(musb->clock)) {
+                       status = PTR_ERR(musb->clock);
+                       musb->clock = NULL;
+                       goto fail;
+               }
+       }
 
        /* assume vbus is off */
 
-       /* platform adjusts pThis->pRegs and pThis->isr if needed,
+       /* platform adjusts musb->mregs and musb->isr if needed,
         * and activates clocks
         */
-       pThis->isr = generic_interrupt;
-       status = musb_platform_init(pThis);
+       musb->isr = generic_interrupt;
+       status = musb_platform_init(musb);
 
        if (status < 0)
                goto fail;
-       if (!pThis->isr) {
+       if (!musb->isr) {
                status = -ENODEV;
                goto fail2;
        }
@@ -1700,126 +1920,122 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
        if (use_dma && dev->dma_mask) {
                struct dma_controller   *c;
 
-               c = dma_controller_factory.create(pThis, pThis->pRegs);
-               pThis->pDmaController = c;
+               c = dma_controller_create(musb, musb->mregs);
+               musb->dma_controller = c;
                if (c)
-                       (void) c->start(c->pPrivateData);
+                       (void) c->start(c->private_data);
        }
 #endif
        /* ideally this would be abstracted in platform setup */
-       if (!is_dma_capable() || !pThis->pDmaController)
+       if (!is_dma_capable() || !musb->dma_controller)
                dev->dma_mask = NULL;
 
        /* be sure interrupts are disabled before connecting ISR */
-       musb_platform_disable(pThis);
+       musb_platform_disable(musb);
+       musb_generic_disable(musb);
 
        /* setup musb parts of the core (especially endpoints) */
        status = musb_core_init(plat->multipoint
                        ? MUSB_CONTROLLER_MHDRC
-                       : MUSB_CONTROLLER_HDRC, pThis);
+                       : MUSB_CONTROLLER_HDRC, musb);
        if (status < 0)
                goto fail2;
 
        /* attach to the IRQ */
-       if (request_irq (nIrq, pThis->isr, 0, dev->bus_id, pThis)) {
+       if (request_irq (nIrq, musb->isr, 0, dev->bus_id, musb)) {
                dev_err(dev, "request_irq %d failed!\n", nIrq);
                status = -ENODEV;
                goto fail2;
        }
-       (void) enable_irq_wake(nIrq);
-       pThis->nIrq = nIrq;
-       device_init_wakeup(dev, 1);
+       musb->nIrq = nIrq;
+// FIXME this handles wakeup irqs wrong
+       if (enable_irq_wake(nIrq) == 0)
+               device_init_wakeup(dev, 1);
 
        pr_info("%s: USB %s mode controller at %p using %s, IRQ %d\n",
                        musb_driver_name,
                        ({char *s;
-                       switch (pThis->board_mode) {
+                       switch (musb->board_mode) {
                        case MUSB_HOST:         s = "Host"; break;
                        case MUSB_PERIPHERAL:   s = "Peripheral"; break;
                        default:                s = "OTG"; break;
                        }; s; }),
                        ctrl,
-                       (is_dma_capable() && pThis->pDmaController)
+                       (is_dma_capable() && musb->dma_controller)
                                ? "DMA" : "PIO",
-                       pThis->nIrq);
+                       musb->nIrq);
 
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
        /* host side needs more setup, except for no-host modes */
-       if (pThis->board_mode != MUSB_PERIPHERAL) {
-               struct usb_hcd  *hcd = musb_to_hcd(pThis);
+       if (musb->board_mode != MUSB_PERIPHERAL) {
+               struct usb_hcd  *hcd = musb_to_hcd(musb);
 
-               if (pThis->board_mode == MUSB_OTG)
+               if (musb->board_mode == MUSB_OTG)
                        hcd->self.otg_port = 1;
-               pThis->xceiv.host = &hcd->self;
+               musb->xceiv.host = &hcd->self;
                hcd->power_budget = 2 * (plat->power ? : 250);
        }
 #endif                         /* CONFIG_USB_MUSB_HDRC_HCD */
 
-#ifdef CONFIG_USB_MUSB_OTG
-       /* if present, this gets used even on non-otg boards */
-       MGC_OtgMachineInit(&pThis->OtgMachine, pThis);
-#endif
-
        /* For the host-only role, we can activate right away.
         * (We expect the ID pin to be forcibly grounded!!)
         * Otherwise, wait till the gadget driver hooks up.
         */
-       pThis->xceiv.state = OTG_STATE_B_IDLE;
-       pThis->xceiv.default_a = 0;
-
-       if (is_otg_enabled(pThis)) {
-               MUSB_OTG_MODE(pThis);
-               status = musb_gadget_setup(pThis);
+       if (!is_otg_enabled(musb) && is_host_enabled(musb)) {
+               MUSB_HST_MODE(musb);
+               musb->xceiv.default_a = 1;
+               musb->xceiv.state = OTG_STATE_A_IDLE;
 
-               DBG(1, "%s mode, status %d, dev%02x\n",
-                       "OTG", status,
-                       musb_readb(pThis->pRegs, MGC_O_HDRC_DEVCTL));
-
-       } else if (is_host_enabled(pThis)) {
-               MUSB_HST_MODE(pThis);
-               pThis->xceiv.default_a = 1;
-               pThis->xceiv.state = OTG_STATE_A_IDLE;
-
-               status = usb_add_hcd(musb_to_hcd(pThis), -1, 0);
+               status = usb_add_hcd(musb_to_hcd(musb), -1, 0);
 
                DBG(1, "%s mode, status %d, devctl %02x %c\n",
                        "HOST", status,
-                       musb_readb(pThis->pRegs, MGC_O_HDRC_DEVCTL),
-                       (musb_readb(pThis->pRegs, MGC_O_HDRC_DEVCTL)
+                       musb_readb(musb->mregs, MGC_O_HDRC_DEVCTL),
+                       (musb_readb(musb->mregs, MGC_O_HDRC_DEVCTL)
                                        & MGC_M_DEVCTL_BDEVICE
                                ? 'B' : 'A'));
 
        } else /* peripheral is enabled */ {
-               MUSB_DEV_MODE(pThis);
-               status = musb_gadget_setup(pThis);
+               MUSB_DEV_MODE(musb);
+               musb->xceiv.default_a = 0;
+               musb->xceiv.state = OTG_STATE_B_IDLE;
+
+               status = musb_gadget_setup(musb);
 
                DBG(1, "%s mode, status %d, dev%02x\n",
-                       "PERIPHERAL", status,
-                       musb_readb(pThis->pRegs, MGC_O_HDRC_DEVCTL));
+                       is_otg_enabled(musb) ? "OTG" : "PERIPHERAL",
+                       status,
+                       musb_readb(musb->mregs, MGC_O_HDRC_DEVCTL));
 
        }
 
        if (status == 0)
-               musb_debug_create("driver/musb_hdrc", pThis);
+               musb_debug_create("driver/musb_hdrc", musb);
        else {
 fail:
+               if (musb->clock)
+                       clk_put(musb->clock);
                device_init_wakeup(dev, 0);
-               musb_free(pThis);
+               musb_free(musb);
                return status;
        }
 
-       INIT_WORK(&pThis->irq_work, musb_irq_work, pThis);
+       INIT_WORK(&musb->irq_work, musb_irq_work);
 
 #ifdef CONFIG_SYSFS
        status = device_create_file(dev, &dev_attr_mode);
        status = device_create_file(dev, &dev_attr_cable);
+       status = device_create_file(dev, &dev_attr_vbus);
+#ifdef CONFIG_USB_MUSB_OTG
+       status = device_create_file(dev, &dev_attr_srp);
+#endif /* CONFIG_USB_MUSB_OTG */
        status = 0;
 #endif
 
        return status;
 
 fail2:
-       musb_platform_exit(pThis);
+       musb_platform_exit(musb);
        goto fail;
 }
 
@@ -1833,7 +2049,7 @@ fail2:
 static u64     *orig_dma_mask;
 #endif
 
-static int __devinit musb_probe(struct platform_device *pdev)
+static int __init musb_probe(struct platform_device *pdev)
 {
        struct device   *dev = &pdev->dev;
        int             irq = platform_get_irq(pdev, 0);
@@ -1859,7 +2075,6 @@ static int __devinit musb_probe(struct platform_device *pdev)
 
 static int __devexit musb_remove(struct platform_device *pdev)
 {
-       struct device   *dev = &pdev->dev;
        struct musb     *musb = dev_to_musb(&pdev->dev);
        void __iomem    *ctrl_base = musb->ctrl_base;
 
@@ -1878,7 +2093,7 @@ static int __devexit musb_remove(struct platform_device *pdev)
        iounmap(ctrl_base);
        device_init_wakeup(&pdev->dev, 0);
 #ifndef CONFIG_USB_INVENTRA_FIFO
-       dev->dma_mask = orig_dma_mask;
+       pdev->dev.dma_mask = orig_dma_mask;
 #endif
        return 0;
 }
@@ -1893,7 +2108,7 @@ static int musb_suspend(struct platform_device *pdev, pm_message_t message)
        if (!musb->clock)
                return 0;
 
-       spin_lock_irqsave(&musb->Lock, flags);
+       spin_lock_irqsave(&musb->lock, flags);
 
        if (is_peripheral_active(musb)) {
                /* FIXME force disconnect unless we know USB will wake
@@ -1905,8 +2120,11 @@ static int musb_suspend(struct platform_device *pdev, pm_message_t message)
                 */
        }
 
-       clk_disable(musb->clock);
-       spin_unlock_irqrestore(&musb->Lock, flags);
+       if (musb->set_clock)
+               musb->set_clock(musb->clock, 0);
+       else
+               clk_disable(musb->clock);
+       spin_unlock_irqrestore(&musb->lock, flags);
        return 0;
 }
 
@@ -1918,13 +2136,18 @@ static int musb_resume(struct platform_device *pdev)
        if (!musb->clock)
                return 0;
 
-       spin_lock_irqsave(&musb->Lock, flags);
-       clk_enable(musb->clock);
+       spin_lock_irqsave(&musb->lock, flags);
+
+       if (musb->set_clock)
+               musb->set_clock(musb->clock, 1);
+       else
+               clk_enable(musb->clock);
+
        /* for static cmos like DaVinci, register values were preserved
         * unless for some reason the whole soc powered down and we're
         * not treating that as a whole-system restart (e.g. swsusp)
         */
-       spin_unlock_irqrestore(&musb->Lock, flags);
+       spin_unlock_irqrestore(&musb->lock, flags);
        return 0;
 }
 
@@ -1939,7 +2162,6 @@ static struct platform_driver musb_driver = {
                .bus            = &platform_bus_type,
                .owner          = THIS_MODULE,
        },
-       .probe          = musb_probe,
        .remove         = __devexit_p(musb_remove),
        .shutdown       = musb_shutdown,
        .suspend        = musb_suspend,
@@ -1977,7 +2199,7 @@ static int __init musb_init(void)
 #endif
                ", debug=%d\n",
                musb_driver_name, debug);
-       return platform_driver_register(&musb_driver);
+       return platform_driver_probe(&musb_driver, musb_probe);
 }
 
 /* make us init after usbcore and before usb