diff options
author | Peter Ujfalusi <peter.ujfalusi@ti.com> | 2015-03-05 09:55:21 -0500 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-03-05 11:41:25 -0500 |
commit | 6afda7f5075440f6737d953ab00fc82efb6cabae (patch) | |
tree | 53c467df9d3f311165ae1683bf0f8840c3a5a1e9 /sound/soc/davinci/davinci-mcasp.c | |
parent | 4da4608c91308d0d15dd022074724446c15710dc (diff) |
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: Peter Ujfalusi <peter.ujfalusi@ti.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/davinci/davinci-mcasp.c')
-rw-r--r-- | sound/soc/davinci/davinci-mcasp.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 0c882995a357..33cea0728cd2 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
@@ -62,6 +62,7 @@ struct davinci_mcasp_context { | |||
62 | u32 config_regs[ARRAY_SIZE(context_regs)]; | 62 | u32 config_regs[ARRAY_SIZE(context_regs)]; |
63 | u32 afifo_regs[2]; /* for read/write fifo control registers */ | 63 | u32 afifo_regs[2]; /* for read/write fifo control registers */ |
64 | u32 *xrsr_regs; /* for serializer configuration */ | 64 | u32 *xrsr_regs; /* for serializer configuration */ |
65 | bool pm_state; | ||
65 | }; | 66 | }; |
66 | 67 | ||
67 | struct davinci_mcasp { | 68 | struct davinci_mcasp { |
@@ -519,7 +520,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
519 | mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); | 520 | mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); |
520 | } | 521 | } |
521 | out: | 522 | out: |
522 | pm_runtime_put_sync(mcasp->dev); | 523 | pm_runtime_put(mcasp->dev); |
523 | return ret; | 524 | return ret; |
524 | } | 525 | } |
525 | 526 | ||
@@ -528,6 +529,7 @@ static int __davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, | |||
528 | { | 529 | { |
529 | struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); | 530 | struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); |
530 | 531 | ||
532 | pm_runtime_get_sync(mcasp->dev); | ||
531 | switch (div_id) { | 533 | switch (div_id) { |
532 | case 0: /* MCLK divider */ | 534 | case 0: /* MCLK divider */ |
533 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, | 535 | 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 | return -EINVAL; | 555 | return -EINVAL; |
554 | } | 556 | } |
555 | 557 | ||
558 | pm_runtime_put(mcasp->dev); | ||
556 | return 0; | 559 | return 0; |
557 | } | 560 | } |
558 | 561 | ||
@@ -567,6 +570,7 @@ static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id, | |||
567 | { | 570 | { |
568 | struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); | 571 | struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); |
569 | 572 | ||
573 | pm_runtime_get_sync(mcasp->dev); | ||
570 | if (dir == SND_SOC_CLOCK_OUT) { | 574 | if (dir == SND_SOC_CLOCK_OUT) { |
571 | mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE); | 575 | mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE); |
572 | mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE); | 576 | 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 | 583 | ||
580 | mcasp->sysclk_freq = freq; | 584 | mcasp->sysclk_freq = freq; |
581 | 585 | ||
586 | pm_runtime_put(mcasp->dev); | ||
582 | return 0; | 587 | return 0; |
583 | } | 588 | } |
584 | 589 | ||
@@ -1053,6 +1058,10 @@ static int davinci_mcasp_suspend(struct snd_soc_dai *dai) | |||
1053 | u32 reg; | 1058 | u32 reg; |
1054 | int i; | 1059 | int i; |
1055 | 1060 | ||
1061 | context->pm_state = pm_runtime_enabled(mcasp->dev) | ||
1062 | if (!context->pm_state) | ||
1063 | pm_runtime_get_sync(mcasp->dev); | ||
1064 | |||
1056 | for (i = 0; i < ARRAY_SIZE(context_regs); i++) | 1065 | for (i = 0; i < ARRAY_SIZE(context_regs); i++) |
1057 | context->config_regs[i] = mcasp_get_reg(mcasp, context_regs[i]); | 1066 | context->config_regs[i] = mcasp_get_reg(mcasp, context_regs[i]); |
1058 | 1067 | ||
@@ -1069,6 +1078,8 @@ static int davinci_mcasp_suspend(struct snd_soc_dai *dai) | |||
1069 | context->xrsr_regs[i] = mcasp_get_reg(mcasp, | 1078 | context->xrsr_regs[i] = mcasp_get_reg(mcasp, |
1070 | DAVINCI_MCASP_XRSRCTL_REG(i)); | 1079 | DAVINCI_MCASP_XRSRCTL_REG(i)); |
1071 | 1080 | ||
1081 | pm_runtime_put_sync(mcasp->dev); | ||
1082 | |||
1072 | return 0; | 1083 | return 0; |
1073 | } | 1084 | } |
1074 | 1085 | ||
@@ -1079,6 +1090,8 @@ static int davinci_mcasp_resume(struct snd_soc_dai *dai) | |||
1079 | u32 reg; | 1090 | u32 reg; |
1080 | int i; | 1091 | int i; |
1081 | 1092 | ||
1093 | pm_runtime_get_sync(mcasp->dev); | ||
1094 | |||
1082 | for (i = 0; i < ARRAY_SIZE(context_regs); i++) | 1095 | for (i = 0; i < ARRAY_SIZE(context_regs); i++) |
1083 | mcasp_set_reg(mcasp, context_regs[i], context->config_regs[i]); | 1096 | mcasp_set_reg(mcasp, context_regs[i], context->config_regs[i]); |
1084 | 1097 | ||
@@ -1095,6 +1108,9 @@ static int davinci_mcasp_resume(struct snd_soc_dai *dai) | |||
1095 | mcasp_set_reg(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i), | 1108 | mcasp_set_reg(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i), |
1096 | context->xrsr_regs[i]); | 1109 | context->xrsr_regs[i]); |
1097 | 1110 | ||
1111 | if (!context->pm_state) | ||
1112 | pm_runtime_put_sync(mcasp->dev); | ||
1113 | |||
1098 | return 0; | 1114 | return 0; |
1099 | } | 1115 | } |
1100 | #else | 1116 | #else |
@@ -1398,13 +1414,6 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
1398 | 1414 | ||
1399 | pm_runtime_enable(&pdev->dev); | 1415 | pm_runtime_enable(&pdev->dev); |
1400 | 1416 | ||
1401 | ret = pm_runtime_get_sync(&pdev->dev); | ||
1402 | if (IS_ERR_VALUE(ret)) { | ||
1403 | dev_err(&pdev->dev, "pm_runtime_get_sync() failed\n"); | ||
1404 | pm_runtime_disable(&pdev->dev); | ||
1405 | return ret; | ||
1406 | } | ||
1407 | |||
1408 | mcasp->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); | 1417 | mcasp->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); |
1409 | if (!mcasp->base) { | 1418 | if (!mcasp->base) { |
1410 | dev_err(&pdev->dev, "ioremap failed\n"); | 1419 | dev_err(&pdev->dev, "ioremap failed\n"); |
@@ -1584,14 +1593,12 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
1584 | return 0; | 1593 | return 0; |
1585 | 1594 | ||
1586 | err: | 1595 | err: |
1587 | pm_runtime_put_sync(&pdev->dev); | ||
1588 | pm_runtime_disable(&pdev->dev); | 1596 | pm_runtime_disable(&pdev->dev); |
1589 | return ret; | 1597 | return ret; |
1590 | } | 1598 | } |
1591 | 1599 | ||
1592 | static int davinci_mcasp_remove(struct platform_device *pdev) | 1600 | static int davinci_mcasp_remove(struct platform_device *pdev) |
1593 | { | 1601 | { |
1594 | pm_runtime_put_sync(&pdev->dev); | ||
1595 | pm_runtime_disable(&pdev->dev); | 1602 | pm_runtime_disable(&pdev->dev); |
1596 | 1603 | ||
1597 | return 0; | 1604 | return 0; |