aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/cs5535audio/cs5535audio_pcm.c
diff options
context:
space:
mode:
authorAndres Salomon <dilinger@debian.org>2007-09-03 09:42:16 -0400
committerJaroslav Kysela <perex@perex.cz>2007-10-16 09:59:52 -0400
commit222fa0b0d2fdb2373a71d532c2cabd2ec920b3b3 (patch)
treefff88e0f8be8540b1fd74cc7f7d7b9fec783a8f4 /sound/pci/cs5535audio/cs5535audio_pcm.c
parent7abcacb09ac0f9c6848f1e7d86b284427fa83cee (diff)
[ALSA] cs5535audio: fix PRD register save/restore power management race
In the suspend path, we currently save the PRD registers and then disable DMA. This is racy; the sound hardware might update the PRD register as it finishes processing some DMA pages between when we've saved the PRD registers and when DMA actually gets disabled. Furthermore, we actively check whether or not DMA is enabled before saving PRD registers; there's no reason to do that, as the PRD registers should not update when we twiddle the ACC_BM[x]_CMD register(s). Worst case, we save the PRD registers twice; even powering down the ACC shouldn't mess with the PRD registers (according to the 5536 data sheet, section 5.3.7.4, power-down procedure). This patch reworks all that to first disable DMA, and then save PRD registers. Signed-off-by: Andres Salomon <dilinger@debian.org> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/pci/cs5535audio/cs5535audio_pcm.c')
-rw-r--r--sound/pci/cs5535audio/cs5535audio_pcm.c2
1 files changed, 0 insertions, 2 deletions
diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c
index 9a1e87fd4815..21df0634af32 100644
--- a/sound/pci/cs5535audio/cs5535audio_pcm.c
+++ b/sound/pci/cs5535audio/cs5535audio_pcm.c
@@ -297,14 +297,12 @@ static int snd_cs5535audio_trigger(struct snd_pcm_substream *substream, int cmd)
297 break; 297 break;
298 case SNDRV_PCM_TRIGGER_RESUME: 298 case SNDRV_PCM_TRIGGER_RESUME:
299 dma->ops->enable_dma(cs5535au); 299 dma->ops->enable_dma(cs5535au);
300 dma->suspended = 0;
301 break; 300 break;
302 case SNDRV_PCM_TRIGGER_STOP: 301 case SNDRV_PCM_TRIGGER_STOP:
303 dma->ops->disable_dma(cs5535au); 302 dma->ops->disable_dma(cs5535au);
304 break; 303 break;
305 case SNDRV_PCM_TRIGGER_SUSPEND: 304 case SNDRV_PCM_TRIGGER_SUSPEND:
306 dma->ops->disable_dma(cs5535au); 305 dma->ops->disable_dma(cs5535au);
307 dma->suspended = 1;
308 break; 306 break;
309 default: 307 default:
310 snd_printk(KERN_ERR "unhandled trigger\n"); 308 snd_printk(KERN_ERR "unhandled trigger\n");