Commit 6afda7f5 authored by Peter Ujfalusi's avatar Peter Ujfalusi Committed by Mark Brown

ASoC: davinci-mcasp: Allow complete shutdown of McASP when not in use

Rearrange the pm_runtime_get/put_sync calls so the IP will be turned off
when it is not in use.
Signed-off-by: default avatarPeter Ujfalusi <peter.ujfalusi@ti.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 4da4608c
...@@ -62,6 +62,7 @@ struct davinci_mcasp_context { ...@@ -62,6 +62,7 @@ struct davinci_mcasp_context {
u32 config_regs[ARRAY_SIZE(context_regs)]; u32 config_regs[ARRAY_SIZE(context_regs)];
u32 afifo_regs[2]; /* for read/write fifo control registers */ u32 afifo_regs[2]; /* for read/write fifo control registers */
u32 *xrsr_regs; /* for serializer configuration */ u32 *xrsr_regs; /* for serializer configuration */
bool pm_state;
}; };
struct davinci_mcasp { struct davinci_mcasp {
...@@ -519,7 +520,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, ...@@ -519,7 +520,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
} }
out: out:
pm_runtime_put_sync(mcasp->dev); pm_runtime_put(mcasp->dev);
return ret; return ret;
} }
...@@ -528,6 +529,7 @@ static int __davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, ...@@ -528,6 +529,7 @@ static int __davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id,
{ {
struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
pm_runtime_get_sync(mcasp->dev);
switch (div_id) { switch (div_id) {
case 0: /* MCLK divider */ case 0: /* MCLK divider */
mcasp_mod_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, mcasp_mod_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG,
...@@ -553,6 +555,7 @@ static int __davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, ...@@ -553,6 +555,7 @@ static int __davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id,
return -EINVAL; return -EINVAL;
} }
pm_runtime_put(mcasp->dev);
return 0; return 0;
} }
...@@ -567,6 +570,7 @@ static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id, ...@@ -567,6 +570,7 @@ static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id,
{ {
struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
pm_runtime_get_sync(mcasp->dev);
if (dir == SND_SOC_CLOCK_OUT) { if (dir == SND_SOC_CLOCK_OUT) {
mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE); mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE);
mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE); mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE);
...@@ -579,6 +583,7 @@ static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id, ...@@ -579,6 +583,7 @@ static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id,
mcasp->sysclk_freq = freq; mcasp->sysclk_freq = freq;
pm_runtime_put(mcasp->dev);
return 0; return 0;
} }
...@@ -1053,6 +1058,10 @@ static int davinci_mcasp_suspend(struct snd_soc_dai *dai) ...@@ -1053,6 +1058,10 @@ static int davinci_mcasp_suspend(struct snd_soc_dai *dai)
u32 reg; u32 reg;
int i; int i;
context->pm_state = pm_runtime_enabled(mcasp->dev)
if (!context->pm_state)
pm_runtime_get_sync(mcasp->dev);
for (i = 0; i < ARRAY_SIZE(context_regs); i++) for (i = 0; i < ARRAY_SIZE(context_regs); i++)
context->config_regs[i] = mcasp_get_reg(mcasp, context_regs[i]); context->config_regs[i] = mcasp_get_reg(mcasp, context_regs[i]);
...@@ -1069,6 +1078,8 @@ static int davinci_mcasp_suspend(struct snd_soc_dai *dai) ...@@ -1069,6 +1078,8 @@ static int davinci_mcasp_suspend(struct snd_soc_dai *dai)
context->xrsr_regs[i] = mcasp_get_reg(mcasp, context->xrsr_regs[i] = mcasp_get_reg(mcasp,
DAVINCI_MCASP_XRSRCTL_REG(i)); DAVINCI_MCASP_XRSRCTL_REG(i));
pm_runtime_put_sync(mcasp->dev);
return 0; return 0;
} }
...@@ -1079,6 +1090,8 @@ static int davinci_mcasp_resume(struct snd_soc_dai *dai) ...@@ -1079,6 +1090,8 @@ static int davinci_mcasp_resume(struct snd_soc_dai *dai)
u32 reg; u32 reg;
int i; int i;
pm_runtime_get_sync(mcasp->dev);
for (i = 0; i < ARRAY_SIZE(context_regs); i++) for (i = 0; i < ARRAY_SIZE(context_regs); i++)
mcasp_set_reg(mcasp, context_regs[i], context->config_regs[i]); mcasp_set_reg(mcasp, context_regs[i], context->config_regs[i]);
...@@ -1095,6 +1108,9 @@ static int davinci_mcasp_resume(struct snd_soc_dai *dai) ...@@ -1095,6 +1108,9 @@ static int davinci_mcasp_resume(struct snd_soc_dai *dai)
mcasp_set_reg(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i), mcasp_set_reg(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i),
context->xrsr_regs[i]); context->xrsr_regs[i]);
if (!context->pm_state)
pm_runtime_put_sync(mcasp->dev);
return 0; return 0;
} }
#else #else
...@@ -1398,13 +1414,6 @@ static int davinci_mcasp_probe(struct platform_device *pdev) ...@@ -1398,13 +1414,6 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
ret = pm_runtime_get_sync(&pdev->dev);
if (IS_ERR_VALUE(ret)) {
dev_err(&pdev->dev, "pm_runtime_get_sync() failed\n");
pm_runtime_disable(&pdev->dev);
return ret;
}
mcasp->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); mcasp->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
if (!mcasp->base) { if (!mcasp->base) {
dev_err(&pdev->dev, "ioremap failed\n"); dev_err(&pdev->dev, "ioremap failed\n");
...@@ -1584,14 +1593,12 @@ static int davinci_mcasp_probe(struct platform_device *pdev) ...@@ -1584,14 +1593,12 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
return 0; return 0;
err: err:
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev); 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)
{ {
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