diff options
Diffstat (limited to 'target/linux/s3c24xx/patches-2.6.24/1182-ASoC-Don-t-block-system-resume.patch')
-rw-r--r-- | target/linux/s3c24xx/patches-2.6.24/1182-ASoC-Don-t-block-system-resume.patch | 125 |
1 files changed, 0 insertions, 125 deletions
diff --git a/target/linux/s3c24xx/patches-2.6.24/1182-ASoC-Don-t-block-system-resume.patch b/target/linux/s3c24xx/patches-2.6.24/1182-ASoC-Don-t-block-system-resume.patch deleted file mode 100644 index 347dbfb879..0000000000 --- a/target/linux/s3c24xx/patches-2.6.24/1182-ASoC-Don-t-block-system-resume.patch +++ /dev/null @@ -1,125 +0,0 @@ -From 2219855aa7835e082ec134fafd9ddba84589d345 Mon Sep 17 00:00:00 2001 -From: Andy Green <andy@openmoko.com> -Date: Wed, 2 Jul 2008 22:39:33 +0100 -Subject: [PATCH] ASoC: Don't block system resume - -On OpenMoko soc-audio resume is taking 700ms of the whole resume time of -1.3s, dominated by writes to the codec over I2C. This patch shunts the -resume guts into a workqueue which then is done asynchronously. - -The "card" is locked using the ALSA power state APIs as suggested by -Mark Brown. - -[Added fix for race with resume to suspend and fixed a couple of nits -from checkpatch -- broonie.] - -Signed-off-by: Andy Green <andy@openmoko.com> -Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> ---- - include/sound/soc.h | 1 + - sound/soc/soc-core.c | 52 ++++++++++++++++++++++++++++++++++++++++++++----- - 2 files changed, 47 insertions(+), 6 deletions(-) - -diff --git a/include/sound/soc.h b/include/sound/soc.h -index aedb348..2d6c0eb 100644 ---- a/include/sound/soc.h -+++ b/include/sound/soc.h -@@ -442,6 +442,7 @@ struct snd_soc_device { - struct snd_soc_codec *codec; - struct snd_soc_codec_device *codec_dev; - struct delayed_work delayed_work; -+ struct work_struct deferred_resume_work; - void *codec_data; - }; - -diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c -index 9e20333..e96930e 100644 ---- a/sound/soc/soc-core.c -+++ b/sound/soc/soc-core.c -@@ -632,6 +632,16 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state) - struct snd_soc_codec *codec = socdev->codec; - int i; - -+ /* Due to the resume being scheduled into a workqueue we could -+ * suspend before that's finished - wait for it to complete. -+ */ -+ snd_power_lock(codec->card); -+ snd_power_wait(codec->card, SNDRV_CTL_POWER_D0); -+ snd_power_unlock(codec->card); -+ -+ /* we're going to block userspace touching us until resume completes */ -+ snd_power_change_state(codec->card, SNDRV_CTL_POWER_D3hot); -+ - /* mute any active DAC's */ - for(i = 0; i < machine->num_links; i++) { - struct snd_soc_codec_dai *dai = machine->dai_link[i].codec_dai; -@@ -684,16 +694,27 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state) - return 0; - } - --/* powers up audio subsystem after a suspend */ --static int soc_resume(struct platform_device *pdev) -+/* deferred resume work, so resume can complete before we finished -+ * setting our codec back up, which can be very slow on I2C -+ */ -+static void soc_resume_deferred(struct work_struct *work) - { -- struct snd_soc_device *socdev = platform_get_drvdata(pdev); -- struct snd_soc_machine *machine = socdev->machine; -- struct snd_soc_platform *platform = socdev->platform; -- struct snd_soc_codec_device *codec_dev = socdev->codec_dev; -+ struct snd_soc_device *socdev = container_of(work, -+ struct snd_soc_device, -+ deferred_resume_work); -+ struct snd_soc_machine *machine = socdev->machine; -+ struct snd_soc_platform *platform = socdev->platform; -+ struct snd_soc_codec_device *codec_dev = socdev->codec_dev; - struct snd_soc_codec *codec = socdev->codec; -+ struct platform_device *pdev = to_platform_device(socdev->dev); - int i; - -+ /* our power state is still SNDRV_CTL_POWER_D3hot from suspend time, -+ * so userspace apps are blocked from touching us -+ */ -+ -+ dev_info(socdev->dev, "starting resume work\n"); -+ - if (machine->resume_pre) - machine->resume_pre(pdev); - -@@ -735,6 +756,22 @@ static int soc_resume(struct platform_device *pdev) - if (machine->resume_post) - machine->resume_post(pdev); - -+ dev_info(socdev->dev, "resume work completed\n"); -+ -+ /* userspace can access us now we are back as we were before */ -+ snd_power_change_state(codec->card, SNDRV_CTL_POWER_D0); -+} -+ -+/* powers up audio subsystem after a suspend */ -+static int soc_resume(struct platform_device *pdev) -+{ -+ struct snd_soc_device *socdev = platform_get_drvdata(pdev); -+ -+ dev_info(socdev->dev, "scheduling resume work\n"); -+ -+ if (!schedule_work(&socdev->deferred_resume_work)) -+ dev_err(socdev->dev, "work item may be lost\n"); -+ - return 0; - } - -@@ -781,6 +818,9 @@ static int soc_probe(struct platform_device *pdev) - - /* DAPM stream work */ - INIT_DELAYED_WORK(&socdev->delayed_work, close_delayed_work); -+ /* deferred resume work */ -+ INIT_WORK(&socdev->deferred_resume_work, soc_resume_deferred); -+ - return 0; - - platform_err: --- -1.5.6.5 - |