aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorStephen Warren <swarren@nvidia.com>2011-05-25 16:06:41 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2011-05-26 10:06:08 -0400
commit82e14e8bdd88b69018fe757192b01dd98582905e (patch)
tree71e6380eb2b6f25f3eb80b8ead4a06d3268a8efb /sound
parentb6f7d7c8bf40800ac68e16302bb7627c59ea9168 (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>
Diffstat (limited to 'sound')
-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 a477e218aa28..c261eeb835b4 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)
1256int snd_soc_resume(struct device *dev) 1256int snd_soc_resume(struct device *dev)
1257{ 1257{
1258 struct snd_soc_card *card = dev_get_drvdata(dev); 1258 struct snd_soc_card *card = dev_get_drvdata(dev);
1259 int i; 1259 int i, ac97_control = 0;
1260 1260
1261 /* AC97 devices might have other drivers hanging off them so 1261 /* AC97 devices might have other drivers hanging off them so
1262 * need to resume immediately. Other drivers don't have that 1262 * need to resume immediately. Other drivers don't have that
@@ -1265,14 +1265,15 @@ int snd_soc_resume(struct device *dev)
1265 */ 1265 */
1266 for (i = 0; i < card->num_rtd; i++) { 1266 for (i = 0; i < card->num_rtd; i++) {
1267 struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai; 1267 struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai;
1268 if (cpu_dai->driver->ac97_control) { 1268 ac97_control |= cpu_dai->driver->ac97_control;
1269 dev_dbg(dev, "Resuming AC97 immediately\n"); 1269 }
1270 soc_resume_deferred(&card->deferred_resume_work); 1270 if (ac97_control) {
1271 } else { 1271 dev_dbg(dev, "Resuming AC97 immediately\n");
1272 dev_dbg(dev, "Scheduling resume work\n"); 1272 soc_resume_deferred(&card->deferred_resume_work);
1273 if (!schedule_work(&card->deferred_resume_work)) 1273 } else {
1274 dev_err(dev, "resume work item may be lost\n"); 1274 dev_dbg(dev, "Scheduling resume work\n");
1275 } 1275 if (!schedule_work(&card->deferred_resume_work))
1276 dev_err(dev, "resume work item may be lost\n");
1276 } 1277 }
1277 1278
1278 return 0; 1279 return 0;