]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
MUSB: Miscellaneous updates
authorDavid Brownell <dbrownell@users.sourceforge.net>
Tue, 12 Sep 2006 11:46:20 +0000 (14:46 +0300)
committerTony Lindgren <tony@atomide.com>
Tue, 12 Sep 2006 11:46:20 +0000 (14:46 +0300)
Lots of miscellaneous updates:

  - bugfixes
     * flag hcd-framework "got irq" state earlier
     * reject urb submission if port is suspended
     * linkage fix: unbind became optional
     * initialize vbus error retry count earlier
     * tusb init removes diagnostic-only settings
  - procfs updates
     * always show otg state info in procfs
     * show some TUSB-specific registers in procfs
  - cleanups
     * remove pointless MUSB_ERR stuff (handled better now)
     * tusb init removes dead code
     * more informative vbus error debug message
     * comment fixes
     * etc

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
drivers/usb/musb/musb_gadget.c
drivers/usb/musb/musb_host.c
drivers/usb/musb/musb_procfs.c
drivers/usb/musb/musbdefs.h
drivers/usb/musb/otg.c
drivers/usb/musb/plat_uds.c
drivers/usb/musb/tusb6010.c
drivers/usb/musb/tusb6010.h
drivers/usb/musb/virthub.c

index df9d2245f1f23ecc0f29a0b94030a57791e77b25..6aac44d3d22c2b67e2c8c23f22dfb965e34d3260 100644 (file)
@@ -1708,7 +1708,6 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
        if (!driver
                        || driver->speed != USB_SPEED_HIGH
                        || !driver->bind
-                       || !driver->unbind
                        || !driver->setup)
                return -EINVAL;
 
@@ -1847,7 +1846,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
        int             retval = 0;
        struct musb     *musb = the_gadget;
 
-       if (!driver || !musb)
+       if (!driver || !driver->unbind || !musb)
                return -EINVAL;
 
        /* REVISIT always use otg_set_peripheral() here too;
index 6cf568058d10b473d4ee8409771d0ddadafb568a..e7f22d048e6a30c71c154ec0669f90f887e5e740 100644 (file)
@@ -1176,7 +1176,6 @@ irqreturn_t musb_h_ep0_irq(struct musb *pThis)
        if (bComplete)
                musb_advance_schedule(pThis, pUrb, pEnd, 1);
 done:
-       set_bit(HCD_FLAG_SAW_IRQ, &musb_to_hcd(pThis)->flags);
        return retval;
 }
 
@@ -1812,7 +1811,7 @@ static int musb_urb_enqueue(
        unsigned                        interval;
 
        /* host role must be active */
-       if (!is_host_active(musb))
+       if (!is_host_active(musb) || !musb->is_active)
                return -ENODEV;
 
        /* DMA mapping was already done, if needed, and this urb is on
@@ -2154,6 +2153,9 @@ static int musb_h_get_frame_number(struct usb_hcd *hcd)
 
 static int musb_h_start(struct usb_hcd *hcd)
 {
+       /* NOTE: musb_start() is called when the hub driver turns
+        * on port power, or when (OTG) peripheral starts.
+        */
        hcd->state = HC_STATE_RUNNING;
        return 0;
 }
index eae8c5b9b7026e5c546b570f37032329d41b26ae..7b687e34f7b10e7fffc76e886e057c6231e41fe6 100644 (file)
@@ -48,8 +48,6 @@
 #include "davinci.h"
 
 
-#ifdef CONFIG_USB_MUSB_OTG
-
 static const char *state_string(enum usb_otg_state state)
 {
        switch (state) {
@@ -70,8 +68,6 @@ static const char *state_string(enum usb_otg_state state)
        }
 }
 
-#endif
-
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
 
 static int dump_qh(struct musb_qh *qh, char *buf, unsigned max)
@@ -489,15 +485,12 @@ static int dump_header_stats(struct musb *pThis, char *buffer)
                return count;
        buffer += count;
 
-#ifdef CONFIG_USB_MUSB_OTG
-       code = sprintf(buffer, "OTG state: %s (%s)\n",
-               state_string(pThis->OtgMachine.bState),
-               state_string(pThis->xceiv.state));
+       code = sprintf(buffer, "OTG state: %s\n",
+                       state_string(pThis->xceiv.state));
        if (code < 0)
                return code;
        buffer += code;
        count += code;
-#endif
 
        code = sprintf(buffer,
                        "Options: "
@@ -548,6 +541,26 @@ static int dump_header_stats(struct musb *pThis, char *buffer)
        buffer += code;
 #endif /* DAVINCI */
 
+#ifdef CONFIG_USB_TUSB6010
+       code = sprintf(buffer,
+                       "TUSB6010: devconf %08x, phy enable %08x drive %08x"
+                       "\n\totg %08x timer %08x"
+                       "\n\tprcm conf %08x mgmt %08x; intmask %08x"
+                       "\n",
+                       musb_readl(pThis->ctrl_base, TUSB_DEV_CONF),
+                       musb_readl(pThis->ctrl_base, TUSB_PHY_OTG_CTRL_ENABLE),
+                       musb_readl(pThis->ctrl_base, TUSB_PHY_OTG_CTRL),
+                       musb_readl(pThis->ctrl_base, TUSB_DEV_OTG_STAT),
+                       musb_readl(pThis->ctrl_base, TUSB_DEV_OTG_TIMER),
+                       musb_readl(pThis->ctrl_base, TUSB_PRCM_CONF),
+                       musb_readl(pThis->ctrl_base, TUSB_PRCM_MNGMT),
+                       musb_readl(pThis->ctrl_base, TUSB_INT_MASK));
+       if (code < 0)
+               return count;
+       count += code;
+       buffer += code;
+#endif /* DAVINCI */
+
 #ifdef CONFIG_USB_TI_CPPI_DMA
        if (pThis->pDmaController) {
                code = sprintf(buffer,
index 6ec73166fadab4b9f587c4cb41785c18e2d12247..fe1803463a33a19a25f2a4b305d15ec2edc1bf06 100644 (file)
@@ -101,6 +101,7 @@ struct musb_ep;
 #define        is_host_active(musb)            is_host_capable()
 #endif
 
+
 #ifdef CONFIG_PROC_FS
 #include <linux/fs.h>
 #define MUSB_CONFIG_PROC_FS
@@ -197,15 +198,10 @@ enum musb_g_ep0_state {
        MGC_END0_STAGE_ACKWAIT,         /* after zlp, before statusin */
 } __attribute__ ((packed));
 
-/* failure codes */
-#define MUSB_ERR_WAITING       1
-#define MUSB_ERR_VBUS          -1
-#define MUSB_ERR_BABBLE                -2
-#define MUSB_ERR_CORRUPTED     -3
-#define MUSB_ERR_IRQ           -4
-#define MUSB_ERR_SHUTDOWN      -5
-#define MUSB_ERR_RESTART       -6
-
+/* OTG protocol constants */
+#define OTG_TIME_A_WAIT_VRISE  100             /* msec (max) */
+#define OTG_TIME_A_WAIT_BCON   0               /* 0=infinite; min 1000 msec */
+#define OTG_TIME_A_IDLE_BDIS   200             /* msec (min) */
 
 /*************************** REGISTER ACCESS ********************************/
 
@@ -265,25 +261,15 @@ enum musb_g_ep0_state {
 /****************************** FUNCTIONS ********************************/
 
 #define MUSB_HST_MODE(_pthis)\
-       { (_pthis)->bIsHost=TRUE; (_pthis)->bIsDevice=FALSE; \
-       (_pthis)->bFailCode=0; }
+       { (_pthis)->bIsHost=TRUE; (_pthis)->bIsDevice=FALSE; }
 #define MUSB_DEV_MODE(_pthis) \
-       { (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=TRUE; \
-       (_pthis)->bFailCode=0; }
+       { (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=TRUE; }
 #define MUSB_OTG_MODE(_pthis) \
-       { (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=FALSE; \
-       (_pthis)->bFailCode=MUSB_ERR_WAITING; }
-#define MUSB_ERR_MODE(_pthis, _cause) \
-       { (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=FALSE; \
-       (_pthis)->bFailCode=_cause; }
-
-#define MUSB_IS_ERR(_x) ( (_x)->bFailCode<0 )
-#define MUSB_IS_HST(_x) (!MUSB_IS_ERR(_x) \
-               && (_x)->bIsHost && !(_x)->bIsDevice )
-#define MUSB_IS_DEV(_x) (!MUSB_IS_ERR(_x) \
-               && !(_x)->bIsHost && (_x)->bIsDevice )
-#define MUSB_IS_OTG(_x) (!MUSB_IS_ERR(_x) \
-               && !(_x)->bIsHost && !(_x)->bIsDevice )
+       { (_pthis)->bIsHost=FALSE; (_pthis)->bIsDevice=FALSE; }
+
+#define MUSB_IS_HST(_x) ((_x)->bIsHost && !(_x)->bIsDevice)
+#define MUSB_IS_DEV(_x) (!(_x)->bIsHost && (_x)->bIsDevice)
+#define MUSB_IS_OTG(_x) (!(_x)->bIsHost && !(_x)->bIsDevice)
 
 #define test_devctl_hst_mode(_x) \
        (musb_readb((_x)->pRegs, MGC_O_HDRC_DEVCTL)&MGC_M_DEVCTL_HM)
@@ -447,8 +433,6 @@ struct musb {
        u8 board_mode;          /* enum musb_mode */
        int                     (*board_set_power)(int state);
 
-       s8 bFailCode;           /* one of MUSB_ERR_* failure code */
-
        u8                      min_power;      /* vbus for periph, in mA/2 */
 
        /* active means connected and not suspended */
index 1be6259d6ca1a9af8d19c3814c1c0807242f38d4..576c0eecf23ae4d2236a4c6b5568bdf016362f85 100644 (file)
@@ -42,6 +42,9 @@
  *
  *   - needs updating along the lines of <linux/usb_otg.h>
  *
+ *   - TUSB has a hardware OTG timer, unclear how much of this would
+ *     ever be needed for it ...
+ *
  *   - doesn't yet use all the linux 2.6.10 usbcore hooks for OTG, but
  *     some of the conversion (and consequent shrinkage) has begun.
  *
index 2b081c3c4bc1c26440979eadb34fb01362bf28f8..97c6a03b804d2b5f1e27dce7c035ef0a11fead1a 100644 (file)
  *        (And if it were to understand, there would still be limitations
  *        because of the lack of periodic endpoint scheduling.)
  *
- *  - Host-side doesn't use the HCD framework, even the older version in
- *    the 2.6.10 kernel, which doesn't provide per-endpoint URB queues.
- *
- *             +++     PARTIALLY RESOLVED      +++
- *
- *    RESULT:  code bloat, because it provides its own root hub;
- *    correctness issues.
- *
  *  - 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.)
@@ -444,9 +436,23 @@ static irqreturn_t musb_stage0_irq(struct musb * pThis, u8 bIntrUSB,
        if (bIntrUSB & MGC_M_INTR_VBUSERROR) {
 
                // MGC_OtgMachineInputsChanged(otgm, &Inputs);
+               // otg_input_changed_X(pThis, TRUE, TRUE);
                // ... may need to abort otg timer ...
 
-               DBG(1, "VBUS_ERROR (%02x)\n", devctl);
+               DBG(1, "VBUS_ERROR (%02x, %s), retry #%d\n", devctl,
+                               ({ char *s;
+                               switch (devctl & MGC_M_DEVCTL_VBUS) {
+                               case 0 << MGC_S_DEVCTL_VBUS:
+                                       s = "<SessEnd"; break;
+                               case 1 << MGC_S_DEVCTL_VBUS:
+                                       s = "<AValid"; break;
+                               case 2 << MGC_S_DEVCTL_VBUS:
+                                       s = "<VBusValid"; break;
+                               //case 3 << MGC_S_DEVCTL_VBUS:
+                               default:
+                                       s = "VALID"; break;
+                               }; s; }),
+                               pThis->vbuserr_retry);
 
                /* after hw goes to A_IDLE, try connecting again */
                pThis->xceiv.state = OTG_STATE_A_IDLE;
@@ -460,6 +466,7 @@ static irqreturn_t musb_stage0_irq(struct musb * pThis, u8 bIntrUSB,
        if (bIntrUSB & MGC_M_INTR_CONNECT) {
                handled = IRQ_HANDLED;
                pThis->is_active = 1;
+               set_bit(HCD_FLAG_SAW_IRQ, &musb_to_hcd(pThis)->flags);
 
                pThis->bEnd0Stage = MGC_END0_START;
 
@@ -514,9 +521,12 @@ static irqreturn_t musb_stage0_irq(struct musb * pThis, u8 bIntrUSB,
 
                        /* REVISIT it's unclear how to handle this.  Mentor's
                         * code stopped the whole USB host, which is clearly
-                        * very wrong.  For now, just expect the hardware is
-                        * sane, so babbling devices also trigger a normal
-                        * endpoint i/o fault (with automatic recovery).
+                        * 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...)
                         */
 
@@ -658,10 +668,10 @@ void musb_start(struct musb * pThis)
        musb_writew(pBase, MGC_O_HDRC_INTRRXE, pThis->wEndMask & 0xfffe);
        musb_writeb(pBase, MGC_O_HDRC_INTRUSBE, 0xf7);
 
-       musb_platform_enable(pThis);
-
        musb_writeb(pBase, MGC_O_HDRC_TESTMODE, 0);
 
+       musb_platform_enable(pThis);
+
        /* enable high-speed/low-power and start session */
        musb_writeb(pBase, MGC_O_HDRC_POWER,
                MGC_M_POWER_SOFTCONN | MGC_M_POWER_HSENAB);
@@ -744,8 +754,9 @@ static void musb_shutdown(struct platform_device *pdev)
        spin_lock_irqsave(&musb->Lock, flags);
        musb_platform_disable(musb);
        musb_generic_disable(musb);
-       MUSB_ERR_MODE(musb, MUSB_ERR_SHUTDOWN);
        spin_unlock_irqrestore(&musb->Lock, flags);
+
+       /* FIXME power down */
 }
 
 
@@ -1312,13 +1323,6 @@ irqreturn_t musb_interrupt(struct musb *musb)
                (devctl & MGC_M_DEVCTL_HM) ? "host" : "peripheral",
                musb->int_usb, musb->int_tx, musb->int_rx);
 
-       /* ignore requests when in error */
-       if (MUSB_IS_ERR(musb)) {
-               WARN("irq in error\n");
-               musb_platform_disable(musb);
-               return IRQ_NONE;
-       }
-
        /* the core can interrupt us for multiple reasons; docs have
         * a generic interrupt flowchart to follow
         */
@@ -1534,6 +1538,7 @@ allocate_instance(struct device *dev, void __iomem *mbase)
 
        hcd->uses_new_polling = 1;
 
+       musb->vbuserr_retry = VBUSERR_RETRY_COUNT;
 #else
        musb = kzalloc(sizeof *musb, GFP_KERNEL);
        if (!musb)
index 182711e09f58501d5f2811f552f035b13e1d4a1e..3b087d2e8b81de4bc84f3f694e2b1ba52d88d8b0 100644 (file)
@@ -463,7 +463,6 @@ static int dma_off;
  * Enables TUSB6010. Caller must take care of locking.
  * REVISIT:
  * - Check what is unnecessary in MGC_HdrcStart()
- * - Interrupt should really be IRQT_FALLING level sensitive
  */
 void musb_platform_enable(struct musb * musb)
 {
@@ -612,25 +611,9 @@ static int tusb_start(struct musb *musb)
        musb_writel(base, TUSB_PRCM_MNGMT,
                TUSB_PRCM_MNGMT_VBUS_VALID_TIMER(0xa) |
                TUSB_PRCM_MNGMT_VBUS_VALID_FLT_EN |
-               TUSB_PRCM_MNGMT_DFT_CLK_DIS |
-               TUSB_PRCM_MNGMT_VLYNQ_CLK_DIS |
                TUSB_PRCM_MNGMT_OTG_SESS_END_EN |
                TUSB_PRCM_MNGMT_OTG_VBUS_DET_EN |
                TUSB_PRCM_MNGMT_OTG_ID_PULLUP);
-#if 0
-       musb_writel(base, TUSB_PHY_OTG_CTRL_ENABLE,
-               musb_readl(base, TUSB_PHY_OTG_CTRL_ENABLE) |
-               TUSB_PHY_OTG_CTRL_WRPROTECT |
-               TUSB_PHY_OTG_CTRL_OTG_ID_PULLUP |
-               TUSB_PHY_OTG_CTRL_OTG_VBUS_DET_EN |
-               TUSB_PHY_OTG_CTRL_OTG_SESS_END_EN);
-       musb_writel(base, TUSB_PHY_OTG_CTRL,
-               musb_readl(base, TUSB_PHY_OTG_CTRL) |
-               TUSB_PHY_OTG_CTRL_WRPROTECT |
-               TUSB_PHY_OTG_CTRL_OTG_ID_PULLUP |
-               TUSB_PHY_OTG_CTRL_OTG_VBUS_DET_EN |
-               TUSB_PHY_OTG_CTRL_OTG_SESS_END_EN);
-#endif
        tusb_setup_cpu_interface(musb);
 
        spin_unlock_irqrestore(&musb->Lock, flags);
index cf30f89a00be29208d42dfff8d5bfb171806084f..cf3b250f51b3f9f11e4c32d6da63f90f19f6b354 100644 (file)
@@ -80,6 +80,8 @@
 #define                TUSB_DEV_OTG_STAT_DM_ENABLE             (1 << 0)
 
 #define TUSB_DEV_OTG_TIMER             (TUSB_SYS_REG_BASE + 0x010)
+#      define TUSB_DEV_OTG_TIMER_ENABLE                (1 << 31)
+#      define TUSB_DEV_OTG_TIMER_VAL(v)                ((v) & 0x07ffffff)
 #define TUSB_PRCM_REV                  (TUSB_SYS_REG_BASE + 0x014)
 
 /* PRCM configuration register */
 #define TUSB_PROD_TEST_RESET           (TUSB_SYS_REG_BASE + 0x1d8)
 
 /* Device System & Control register bitfields */
-#define TUSB_DEV_OTG_TIMER_ENABLE              (1 << 31)
-#define TUSB_DEV_OTG_TIMER_VAL(v)              ((v) & 0x07ffffff)
 #define TUSB_INT_CTRL_CONF_INT_RELCYC(v)       (((v) & 0x7) << 18)
 #define TUSB_INT_CTRL_CONF_INT_POLARITY                (1 << 17)
 #define TUSB_INT_CTRL_CONF_INT_MODE            (1 << 16)
index 0d0b02cd0f35878b38ab621cd3935f1c42989bd7..04d54e3bdc08ad41d00decfb4523e37006f627e2 100644 (file)
@@ -277,7 +277,6 @@ int musb_hub_control(
                         * logic relating to VBUS power-up.
                         */
                        musb_start(musb);
-                       musb->port1_status |= USB_PORT_STAT_POWER;
                        break;
                case USB_PORT_FEAT_RESET:
                        musb_port_reset(musb, TRUE);
@@ -316,12 +315,12 @@ int musb_hub_control(
                                goto error;
                        }
                        musb_writeb(musb->pRegs, MGC_O_HDRC_TESTMODE, temp);
-                       musb->port1_status |= USB_PORT_STAT_TEST;
                        break;
                default:
                        goto error;
                }
                DBG(5, "set feature %d\n", wValue);
+               musb->port1_status |= 1 << wValue;
                break;
 
        default: