--- /dev/null
+From 82e14e8bdd88b69018fe757192b01dd98582905e Mon Sep 17 00:00:00 2001
+From: Stephen Warren <swarren@nvidia.com>
+Date: Wed, 25 May 2011 14:06:41 -0600
+Subject: ASoC: core: Don't schedule deferred_resume_work twice
+
+From: Stephen Warren <swarren@nvidia.com>
+
+commit 82e14e8bdd88b69018fe757192b01dd98582905e upstream.
+
+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>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ sound/soc/soc-core.c | 19 ++++++++++---------
+ 1 file changed, 10 insertions(+), 9 deletions(-)
+
+--- a/sound/soc/soc-core.c
++++ b/sound/soc/soc-core.c
+@@ -1257,7 +1257,7 @@ static void soc_resume_deferred(struct w
+ 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
+@@ -1266,14 +1266,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;