usb: musb: dsps: use msecs_to_jiffies instead
[firefly-linux-kernel-4.4.55.git] / drivers / usb / musb / musb_dsps.c
index 53bd0e71d19f02e3582db6ac21d0e617765c0ad1..9271450ebacd5585b84f466ade142cd0ba3911a2 100644 (file)
@@ -119,7 +119,7 @@ struct dsps_musb_wrapper {
        unsigned        iddig:5;
        unsigned        iddig_mux:5;
        /* miscellaneous stuff */
-       u8              poll_seconds;
+       unsigned        poll_timeout;
 };
 
 /*
@@ -285,7 +285,8 @@ static void otg_timer(unsigned long _musb)
                }
                if (!(devctl & MUSB_DEVCTL_SESSION) && !skip_session)
                        dsps_writeb(mregs, MUSB_DEVCTL, MUSB_DEVCTL_SESSION);
-               mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ);
+               mod_timer(&glue->timer, jiffies +
+                               msecs_to_jiffies(wrp->poll_timeout));
                break;
        case OTG_STATE_A_WAIT_VFALL:
                musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
@@ -330,28 +331,6 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
 
        dev_dbg(musb->controller, "usbintr (%x) epintr(%x)\n",
                        usbintr, epintr);
-       /*
-        * DRVVBUS IRQs are the only proxy we have (a very poor one!) for
-        * DSPS IP's missing ID change IRQ.  We need an ID change IRQ to
-        * switch appropriately between halves of the OTG state machine.
-        * Managing DEVCTL.SESSION per Mentor docs requires that we know its
-        * value but DEVCTL.BDEVICE is invalid without DEVCTL.SESSION set.
-        * Also, DRVVBUS pulses for SRP (but not at 5V) ...
-        */
-       if (is_host_active(musb) && usbintr & MUSB_INTR_BABBLE) {
-               pr_info("CAUTION: musb: Babble Interrupt Occurred\n");
-
-               /*
-                * When a babble condition occurs, the musb controller removes
-                * the session and is no longer in host mode. Hence, all
-                * devices connected to its root hub get disconnected.
-                *
-                * Hand this error down to the musb core isr, so it can
-                * recover.
-                */
-               musb->int_usb = MUSB_INTR_BABBLE | MUSB_INTR_DISCONNECT;
-               musb->int_tx = musb->int_rx = 0;
-       }
 
        if (usbintr & ((1 << wrp->drvvbus) << wrp->usb_shift)) {
                int drvvbus = dsps_readl(reg_base, wrp->status);
@@ -374,8 +353,8 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
                         */
                        musb->int_usb &= ~MUSB_INTR_VBUSERROR;
                        musb->xceiv->otg->state = OTG_STATE_A_WAIT_VFALL;
-                       mod_timer(&glue->timer,
-                                       jiffies + wrp->poll_seconds * HZ);
+                       mod_timer(&glue->timer, jiffies +
+                                       msecs_to_jiffies(wrp->poll_timeout));
                        WARNING("VBUS error workaround (delay coming)\n");
                } else if (drvvbus) {
                        MUSB_HST_MODE(musb);
@@ -404,7 +383,8 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
        /* Poll for ID change in OTG port mode */
        if (musb->xceiv->otg->state == OTG_STATE_B_IDLE &&
                        musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE)
-               mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ);
+               mod_timer(&glue->timer, jiffies +
+                               msecs_to_jiffies(wrp->poll_timeout));
 out:
        spin_unlock_irqrestore(&musb->lock, flags);
 
@@ -457,12 +437,27 @@ static int dsps_musb_init(struct musb *musb)
        if (IS_ERR(musb->xceiv))
                return PTR_ERR(musb->xceiv);
 
+       musb->phy = devm_phy_get(dev->parent, "usb2-phy");
+
        /* Returns zero if e.g. not clocked */
        rev = dsps_readl(reg_base, wrp->revision);
        if (!rev)
                return -ENODEV;
 
        usb_phy_init(musb->xceiv);
+       if (IS_ERR(musb->phy))  {
+               musb->phy = NULL;
+       } else {
+               ret = phy_init(musb->phy);
+               if (ret < 0)
+                       return ret;
+               ret = phy_power_on(musb->phy);
+               if (ret) {
+                       phy_exit(musb->phy);
+                       return ret;
+               }
+       }
+
        setup_timer(&glue->timer, otg_timer, (unsigned long) musb);
 
        /* Reset the musb */
@@ -482,7 +477,7 @@ static int dsps_musb_init(struct musb *musb)
         * logic enabled.
         */
        val = dsps_readb(musb->mregs, MUSB_BABBLE_CTL);
-       if (val == MUSB_BABBLE_RCV_DISABLE) {
+       if (val & MUSB_BABBLE_RCV_DISABLE) {
                glue->sw_babble_enabled = true;
                val |= MUSB_BABBLE_SW_SESSION_CTRL;
                dsps_writeb(musb->mregs, MUSB_BABBLE_CTL, val);
@@ -502,6 +497,8 @@ static int dsps_musb_exit(struct musb *musb)
 
        del_timer_sync(&glue->timer);
        usb_phy_shutdown(musb->xceiv);
+       phy_power_off(musb->phy);
+       phy_exit(musb->phy);
        debugfs_remove_recursive(glue->dbgfs_root);
 
        return 0;
@@ -554,7 +551,7 @@ static int dsps_musb_set_mode(struct musb *musb, u8 mode)
        return 0;
 }
 
-static bool  sw_babble_control(struct musb *musb)
+static bool dsps_sw_babble_control(struct musb *musb)
 {
        u8 babble_ctl;
        bool session_restart =  false;
@@ -605,31 +602,18 @@ static bool  sw_babble_control(struct musb *musb)
        return session_restart;
 }
 
-static int dsps_musb_reset(struct musb *musb)
+static int dsps_musb_recover(struct musb *musb)
 {
        struct device *dev = musb->controller;
        struct dsps_glue *glue = dev_get_drvdata(dev->parent);
-       const struct dsps_musb_wrapper *wrp = glue->wrp;
        int session_restart = 0;
 
        if (glue->sw_babble_enabled)
-               session_restart = sw_babble_control(musb);
-       /*
-        * In case of new silicon version babble condition can be recovered
-        * without resetting the MUSB. But for older silicon versions, MUSB
-        * reset is needed
-        */
-       if (session_restart || !glue->sw_babble_enabled) {
-               dev_info(musb->controller, "Restarting MUSB to recover from Babble\n");
-               dsps_writel(musb->ctrl_base, wrp->control, (1 << wrp->reset));
-               usleep_range(100, 200);
-               usb_phy_shutdown(musb->xceiv);
-               usleep_range(100, 200);
-               usb_phy_init(musb->xceiv);
+               session_restart = dsps_sw_babble_control(musb);
+       else
                session_restart = 1;
-       }
 
-       return !session_restart;
+       return session_restart ? 0 : -EPIPE;
 }
 
 static struct musb_platform_ops dsps_ops = {
@@ -642,7 +626,7 @@ static struct musb_platform_ops dsps_ops = {
 
        .try_idle       = dsps_musb_try_idle,
        .set_mode       = dsps_musb_set_mode,
-       .reset          = dsps_musb_reset,
+       .recover        = dsps_musb_recover,
 };
 
 static u64 musb_dmamask = DMA_BIT_MASK(32);
@@ -687,7 +671,7 @@ static int dsps_create_musb_pdev(struct dsps_glue *glue,
        struct musb_hdrc_config *config;
        struct platform_device *musb;
        struct device_node *dn = parent->dev.of_node;
-       int ret;
+       int ret, val;
 
        memset(resources, 0, sizeof(resources));
        res = platform_get_resource_byname(parent, IORESOURCE_MEM, "mc");
@@ -739,7 +723,10 @@ static int dsps_create_musb_pdev(struct dsps_glue *glue,
        pdata.mode = get_musb_port_mode(dev);
        /* DT keeps this entry in mA, musb expects it as per USB spec */
        pdata.power = get_int_prop(dn, "mentor,power") / 2;
-       config->multipoint = of_property_read_bool(dn, "mentor,multipoint");
+
+       ret = of_property_read_u32(dn, "mentor,multipoint", &val);
+       if (!ret && val)
+               config->multipoint = true;
 
        ret = platform_device_add_data(musb, &pdata, sizeof(pdata));
        if (ret) {
@@ -847,7 +834,7 @@ static const struct dsps_musb_wrapper am33xx_driver_data = {
        .rxep_shift             = 16,
        .rxep_mask              = 0xfffe,
        .rxep_bitmap            = (0xfffe << 16),
-       .poll_seconds           = 2,
+       .poll_timeout           = 2000, /* ms */
 };
 
 static const struct of_device_id musb_dsps_of_match[] = {
@@ -903,7 +890,8 @@ static int dsps_resume(struct device *dev)
        dsps_writel(mbase, wrp->rx_mode, glue->context.rx_mode);
        if (musb->xceiv->otg->state == OTG_STATE_B_IDLE &&
            musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE)
-               mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ);
+               mod_timer(&glue->timer, jiffies +
+                               msecs_to_jiffies(wrp->poll_timeout));
 
        return 0;
 }