summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2009-03-31 14:27:03 +0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-04-02 19:34:36 +0400
commit64ab9baa00fa99070da993f00173c35a8e99abfa (patch)
tree4a3f4973cca4c092c496c1eda887198f1a0ab4a7
parenta7808331f1ea6c7f89a14d1d94eafc62615b997b (diff)
downloadlinux-64ab9baa00fa99070da993f00173c35a8e99abfa.tar.xz
ASoC: Don't defer resume work for AC97 codecs
AC97 devices may have other drivers hanging off them directly so need to have resumed when the resume function returns meaning that we can't defer the resume - complete it immediately for them. Non-AC97 devices should not have other drivers hanging directly off the ASoC devices. We only really need the deferral for non-AC97 devices - it's there since some I2C buses are very slow and non-AC97 codecs often have large numbers of registers to restore and require delays to bring the codec up cleanly leading to a substantial impact on overall resume time. Reported-by: Russell King <linux@arm.linux.org.uk> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--sound/soc/soc-core.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 6e710f705a74..6c62d4a54cdf 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -767,11 +767,21 @@ static int soc_resume(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_card *card = socdev->card;
+ struct snd_soc_dai *cpu_dai = card->dai_link[0].cpu_dai;
- dev_dbg(socdev->dev, "scheduling resume work\n");
-
- if (!schedule_work(&card->deferred_resume_work))
- dev_err(socdev->dev, "resume work item may be lost\n");
+ /* AC97 devices might have other drivers hanging off them so
+ * need to resume immediately. Other drivers don't have that
+ * problem and may take a substantial amount of time to resume
+ * due to I/O costs and anti-pop so handle them out of line.
+ */
+ if (cpu_dai->ac97_control) {
+ dev_dbg(socdev->dev, "Resuming AC97 immediately\n");
+ soc_resume_deferred(&card->deferred_resume_work);
+ } else {
+ dev_dbg(socdev->dev, "Scheduling resume work\n");
+ if (!schedule_work(&card->deferred_resume_work))
+ dev_err(socdev->dev, "resume work item may be lost\n");
+ }
return 0;
}