summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sound/pci/als4000.c44
1 files changed, 20 insertions, 24 deletions
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index 33034e07b3d6..636f309c9424 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -421,30 +421,26 @@ static int snd_als4000_capture_trigger(struct snd_pcm_substream *substream, int
{
struct snd_sb *chip = snd_pcm_substream_chip(substream);
int result = 0;
-
- /* FIXME race condition in here!!!
- chip->mode non-atomic update gets consistently protected
- by reg_lock always, _except_ for this place!!
- Probably need to take reg_lock as outer (or inner??) lock, too.
- (or serialize both lock operations? probably not, though... - racy?)
- */
- guard(spinlock)(&chip->mixer_lock);
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- chip->mode |= SB_RATE_LOCK_CAPTURE;
- snd_als4_cr_write(chip, ALS4K_CR1E_FIFO2_CONTROL,
- capture_cmd(chip));
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- chip->mode &= ~SB_RATE_LOCK_CAPTURE;
- snd_als4_cr_write(chip, ALS4K_CR1E_FIFO2_CONTROL,
- capture_cmd(chip));
- break;
- default:
- result = -EINVAL;
- break;
+
+ guard(spinlock)(&chip->reg_lock);
+ scoped_guard(spinlock, &chip->mixer_lock) {
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ chip->mode |= SB_RATE_LOCK_CAPTURE;
+ snd_als4_cr_write(chip, ALS4K_CR1E_FIFO2_CONTROL,
+ capture_cmd(chip));
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ chip->mode &= ~SB_RATE_LOCK_CAPTURE;
+ snd_als4_cr_write(chip, ALS4K_CR1E_FIFO2_CONTROL,
+ capture_cmd(chip));
+ break;
+ default:
+ result = -EINVAL;
+ break;
+ }
}
return result;
}