summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Warren <swarren@nvidia.com>2011-06-10 20:15:21 -0700
committerTodd Poynor <toddpoynor@google.com>2011-06-16 14:55:41 -0700
commit390f202e3ac5a111fcfa326e5a99a4dcbcc2bf7a (patch)
tree1a55264eaf56bee849eed1d597377fa74ca3ec12
parent170372e4abeddda05fc078e1ae0f01e26a8a7b43 (diff)
ASoC: core: Don't schedule deferred_resume_work twice
For cards that have two or more DAIs, snd_soc_resume's loop over all DAIs ends up calling schedule_work(deferred_resume_work) once per DAI. Since this is the same work item each time, the 2nd and subsequent calls return 0 (work item already queued), and trigger the dev_err message below stating that a work item may have been lost. Solve this by adjusting the loop to simply calculate whether to run the resume work immediately or defer it, and then call schedule work (or not) one time based on that. Note: This has not been tested in mainline, but only in chromeos-2.6.38; mainline doesn't support suspend/resume on Tegra, nor does the mainline Tegra ASoC driver contain multiple DAIs. It has been compile-checked in mainline. Signed-off-by: Stephen Warren <swarren@nvidia.com> Acked-by: Liam Girdwood <lrg@ti.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Change-Id: I9c29b6c310a94108d81ab6506eb64ee9f30d846a Signed-off-by: Todd Poynor <toddpoynor@google.com>
-rw-r--r--sound/soc/soc-core.c19
1 files changed, 10 insertions, 9 deletions
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index d75043ed7fc..13a40fc78d3 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1256,7 +1256,7 @@ static void soc_resume_deferred(struct work_struct *work)
int snd_soc_resume(struct device *dev)
{
struct snd_soc_card *card = dev_get_drvdata(dev);
- int i;
+ int i, ac97_control = 0;
/* AC97 devices might have other drivers hanging off them so
* need to resume immediately. Other drivers don't have that
@@ -1265,14 +1265,15 @@ int snd_soc_resume(struct device *dev)
*/
for (i = 0; i < card->num_rtd; i++) {
struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai;
- if (cpu_dai->driver->ac97_control) {
- dev_dbg(dev, "Resuming AC97 immediately\n");
- soc_resume_deferred(&card->deferred_resume_work);
- } else {
- dev_dbg(dev, "Scheduling resume work\n");
- if (!schedule_work(&card->deferred_resume_work))
- dev_err(dev, "resume work item may be lost\n");
- }
+ ac97_control |= cpu_dai->driver->ac97_control;
+ }
+ if (ac97_control) {
+ dev_dbg(dev, "Resuming AC97 immediately\n");
+ soc_resume_deferred(&card->deferred_resume_work);
+ } else {
+ dev_dbg(dev, "Scheduling resume work\n");
+ if (!schedule_work(&card->deferred_resume_work))
+ dev_err(dev, "resume work item may be lost\n");
}
return 0;