ASoC: McASP: Convert driver to use Runtime PM API

* Add Runtime PM support to McASP host controller.
  * Use Runtime PM API to enable/disable McASP clock.

This was tested on AM18x Board using suspend/resume

Signed-off-by: Hebbar, Gururaja <gururaja.hebbar@ti.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
This commit is contained in:
Hebbar, Gururaja 2012-08-08 20:40:32 +05:30 committed by Mark Brown
parent 8f24549979
commit 10884347f1
2 changed files with 20 additions and 23 deletions

View File

@ -21,7 +21,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/clk.h> #include <linux/pm_runtime.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/pcm.h> #include <sound/pcm.h>
@ -776,20 +776,17 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
if (!dev->clk_active) { ret = pm_runtime_get_sync(dev->dev);
clk_enable(dev->clk); if (IS_ERR_VALUE(ret))
dev->clk_active = 1; dev_err(dev->dev, "pm_runtime_get_sync() failed\n");
}
davinci_mcasp_start(dev, substream->stream); davinci_mcasp_start(dev, substream->stream);
break; break;
case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_SUSPEND:
davinci_mcasp_stop(dev, substream->stream); davinci_mcasp_stop(dev, substream->stream);
if (dev->clk_active) { ret = pm_runtime_put_sync(dev->dev);
clk_disable(dev->clk); if (IS_ERR_VALUE(ret))
dev->clk_active = 0; dev_err(dev->dev, "pm_runtime_put_sync() failed\n");
}
break; break;
case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_STOP:
@ -886,12 +883,13 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
} }
pdata = pdev->dev.platform_data; pdata = pdev->dev.platform_data;
dev->clk = clk_get(&pdev->dev, NULL); pm_runtime_enable(&pdev->dev);
if (IS_ERR(dev->clk))
return -ENODEV;
clk_enable(dev->clk); ret = pm_runtime_get_sync(&pdev->dev);
dev->clk_active = 1; if (IS_ERR_VALUE(ret)) {
dev_err(&pdev->dev, "pm_runtime_get_sync() failed\n");
return ret;
}
dev->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); dev->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
if (!dev->base) { if (!dev->base) {
@ -908,6 +906,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
dev->version = pdata->version; dev->version = pdata->version;
dev->txnumevt = pdata->txnumevt; dev->txnumevt = pdata->txnumevt;
dev->rxnumevt = pdata->rxnumevt; dev->rxnumevt = pdata->rxnumevt;
dev->dev = &pdev->dev;
dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]; dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
dma_data->asp_chan_q = pdata->asp_chan_q; dma_data->asp_chan_q = pdata->asp_chan_q;
@ -949,19 +948,18 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
return 0; return 0;
err_release_clk: err_release_clk:
clk_disable(dev->clk); pm_runtime_put_sync(&pdev->dev);
clk_put(dev->clk); pm_runtime_disable(&pdev->dev);
return ret; return ret;
} }
static int davinci_mcasp_remove(struct platform_device *pdev) static int davinci_mcasp_remove(struct platform_device *pdev)
{ {
struct davinci_audio_dev *dev = dev_get_drvdata(&pdev->dev);
snd_soc_unregister_dai(&pdev->dev); snd_soc_unregister_dai(&pdev->dev);
clk_disable(dev->clk);
clk_put(dev->clk); pm_runtime_put_sync(&pdev->dev);
dev->clk = NULL; pm_runtime_disable(&pdev->dev);
return 0; return 0;
} }

View File

@ -40,9 +40,8 @@ struct davinci_audio_dev {
struct davinci_pcm_dma_params dma_params[2]; struct davinci_pcm_dma_params dma_params[2];
void __iomem *base; void __iomem *base;
int sample_rate; int sample_rate;
struct clk *clk; struct device *dev;
unsigned int codec_fmt; unsigned int codec_fmt;
u8 clk_active;
/* McASP specific data */ /* McASP specific data */
int tdm_slots; int tdm_slots;