Commit 65b3f50e authored by Tony Lindgren's avatar Tony Lindgren Committed by Greg Kroah-Hartman

usb: musb: Add PM runtime support for MUSB DSPS glue layer

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: default avatarTony Lindgren <tony@atomide.com>
Signed-off-by: default avatarBin Liu <b-liu@ti.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent ae909fe4
...@@ -145,43 +145,6 @@ static const struct debugfs_reg32 dsps_musb_regs[] = { ...@@ -145,43 +145,6 @@ static const struct debugfs_reg32 dsps_musb_regs[] = {
{ "mode", 0xe8 }, { "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 * dsps_musb_enable - enable interrupts
*/ */
...@@ -206,7 +169,6 @@ static void dsps_musb_enable(struct musb *musb) ...@@ -206,7 +169,6 @@ static void dsps_musb_enable(struct musb *musb)
musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE) musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE)
mod_timer(&glue->timer, jiffies + mod_timer(&glue->timer, jiffies +
msecs_to_jiffies(wrp->poll_timeout)); msecs_to_jiffies(wrp->poll_timeout));
dsps_musb_try_idle(musb, 0);
} }
/** /**
...@@ -236,6 +198,11 @@ static void otg_timer(unsigned long _musb) ...@@ -236,6 +198,11 @@ static void otg_timer(unsigned long _musb)
u8 devctl; u8 devctl;
unsigned long flags; unsigned long flags;
int skip_session = 0; 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 * We poll because DSPS IP's won't expose several OTG-critical
...@@ -279,6 +246,9 @@ static void otg_timer(unsigned long _musb) ...@@ -279,6 +246,9 @@ static void otg_timer(unsigned long _musb)
break; break;
} }
spin_unlock_irqrestore(&musb->lock, flags); 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) static irqreturn_t dsps_interrupt(int irq, void *hci)
...@@ -634,7 +604,6 @@ static struct musb_platform_ops dsps_ops = { ...@@ -634,7 +604,6 @@ static struct musb_platform_ops dsps_ops = {
.enable = dsps_musb_enable, .enable = dsps_musb_enable,
.disable = dsps_musb_disable, .disable = dsps_musb_disable,
.try_idle = dsps_musb_try_idle,
.set_mode = dsps_musb_set_mode, .set_mode = dsps_musb_set_mode,
.recover = dsps_musb_recover, .recover = dsps_musb_recover,
}; };
...@@ -798,6 +767,8 @@ static int dsps_probe(struct platform_device *pdev) ...@@ -798,6 +767,8 @@ static int dsps_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, glue); platform_set_drvdata(pdev, glue);
pm_runtime_enable(&pdev->dev); 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); ret = pm_runtime_get_sync(&pdev->dev);
if (ret < 0) { if (ret < 0) {
...@@ -809,11 +780,15 @@ static int dsps_probe(struct platform_device *pdev) ...@@ -809,11 +780,15 @@ static int dsps_probe(struct platform_device *pdev)
if (ret) if (ret)
goto err3; goto err3;
pm_runtime_mark_last_busy(&pdev->dev);
pm_runtime_put_autosuspend(&pdev->dev);
return 0; return 0;
err3: err3:
pm_runtime_put(&pdev->dev); pm_runtime_put_sync(&pdev->dev);
err2: err2:
pm_runtime_dont_use_autosuspend(&pdev->dev);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
return ret; return ret;
} }
...@@ -825,7 +800,8 @@ static int dsps_remove(struct platform_device *pdev) ...@@ -825,7 +800,8 @@ static int dsps_remove(struct platform_device *pdev)
platform_device_unregister(glue->musb); platform_device_unregister(glue->musb);
/* disable usbss clocks */ /* 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); pm_runtime_disable(&pdev->dev);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment