usb: musb: Add PM runtime support for MUSB DSPS glue layer
authorTony Lindgren <tony@atomide.com>
Tue, 13 Sep 2016 02:48:31 +0000 (21:48 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 13 Sep 2016 15:20:02 +0000 (17:20 +0200)
We can now just use PM runtime autoidle support as musb core
keeps things enabled when the devctl session bit is set. And
there's no need for dsps_musb_try_idle() so let's just remove
it.

Note that as cppi41 dma is clocked by musb, this only makes
PM work for dsps glue layer if CONFIG_MUSB_PIO_ONLY=y and
cppi41.ko is unloaded. This will get fixed when cppi41.c has
PM runtime implemented.

Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Bin Liu <b-liu@ti.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/musb/musb_dsps.c

index ef955c7afd52751a6810975757439e0f078fd6c8..0f17d2140db6e5c36eceef43b185d2c7c183e091 100644 (file)
@@ -145,43 +145,6 @@ static const struct debugfs_reg32 dsps_musb_regs[] = {
        { "mode",               0xe8 },
 };
 
-static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout)
-{
-       struct device *dev = musb->controller;
-       struct dsps_glue *glue = dev_get_drvdata(dev->parent);
-
-       if (timeout == 0)
-               timeout = jiffies + msecs_to_jiffies(3);
-
-       /* Never idle if active, or when VBUS timeout is not set as host */
-       if (musb->is_active || (musb->a_wait_bcon == 0 &&
-                       musb->xceiv->otg->state == OTG_STATE_A_WAIT_BCON)) {
-               dev_dbg(musb->controller, "%s active, deleting timer\n",
-                               usb_otg_state_string(musb->xceiv->otg->state));
-               del_timer(&glue->timer);
-               glue->last_timer = jiffies;
-               return;
-       }
-       if (musb->port_mode != MUSB_PORT_MODE_DUAL_ROLE)
-               return;
-
-       if (!musb->g.dev.driver)
-               return;
-
-       if (time_after(glue->last_timer, timeout) &&
-                               timer_pending(&glue->timer)) {
-               dev_dbg(musb->controller,
-                       "Longer idle timer already pending, ignoring...\n");
-               return;
-       }
-       glue->last_timer = timeout;
-
-       dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n",
-               usb_otg_state_string(musb->xceiv->otg->state),
-                       jiffies_to_msecs(timeout - jiffies));
-       mod_timer(&glue->timer, timeout);
-}
-
 /**
  * dsps_musb_enable - enable interrupts
  */
@@ -206,7 +169,6 @@ static void dsps_musb_enable(struct musb *musb)
                        musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE)
                mod_timer(&glue->timer, jiffies +
                                msecs_to_jiffies(wrp->poll_timeout));
-       dsps_musb_try_idle(musb, 0);
 }
 
 /**
@@ -236,6 +198,11 @@ static void otg_timer(unsigned long _musb)
        u8 devctl;
        unsigned long flags;
        int skip_session = 0;
+       int err;
+
+       err = pm_runtime_get_sync(dev);
+       if (err < 0)
+               dev_err(dev, "Poll could not pm_runtime_get: %i\n", err);
 
        /*
         * We poll because DSPS IP's won't expose several OTG-critical
@@ -279,6 +246,9 @@ static void otg_timer(unsigned long _musb)
                break;
        }
        spin_unlock_irqrestore(&musb->lock, flags);
+
+       pm_runtime_mark_last_busy(dev);
+       pm_runtime_put_autosuspend(dev);
 }
 
 static irqreturn_t dsps_interrupt(int irq, void *hci)
@@ -634,7 +604,6 @@ static struct musb_platform_ops dsps_ops = {
        .enable         = dsps_musb_enable,
        .disable        = dsps_musb_disable,
 
-       .try_idle       = dsps_musb_try_idle,
        .set_mode       = dsps_musb_set_mode,
        .recover        = dsps_musb_recover,
 };
@@ -798,6 +767,8 @@ static int dsps_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, glue);
        pm_runtime_enable(&pdev->dev);
+       pm_runtime_use_autosuspend(&pdev->dev);
+       pm_runtime_set_autosuspend_delay(&pdev->dev, 200);
 
        ret = pm_runtime_get_sync(&pdev->dev);
        if (ret < 0) {
@@ -809,11 +780,15 @@ static int dsps_probe(struct platform_device *pdev)
        if (ret)
                goto err3;
 
+       pm_runtime_mark_last_busy(&pdev->dev);
+       pm_runtime_put_autosuspend(&pdev->dev);
+
        return 0;
 
 err3:
-       pm_runtime_put(&pdev->dev);
+       pm_runtime_put_sync(&pdev->dev);
 err2:
+       pm_runtime_dont_use_autosuspend(&pdev->dev);
        pm_runtime_disable(&pdev->dev);
        return ret;
 }
@@ -825,7 +800,8 @@ static int dsps_remove(struct platform_device *pdev)
        platform_device_unregister(glue->musb);
 
        /* disable usbss clocks */
-       pm_runtime_put(&pdev->dev);
+       pm_runtime_dont_use_autosuspend(&pdev->dev);
+       pm_runtime_put_sync(&pdev->dev);
        pm_runtime_disable(&pdev->dev);
 
        return 0;