aboutsummaryrefslogtreecommitdiffstats
path: root/sound/drivers
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2014-09-09 11:17:20 -0400
committerTakashi Iwai <tiwai@suse.de>2014-09-15 09:52:03 -0400
commitdb0a5214b8d6cc7a90ce3336d24a85b90cbb4e67 (patch)
treefdfcfaee149e83613d9854a763bbe3fe95f60292 /sound/drivers
parente7e69265b6269763799a5de9c263fbbce32cd3a3 (diff)
ALSA: vx: Use nonatomic PCM ops
Rewrite VXpocket and VX222 drivers to use the new PCM nonatomic ops. The former irq tasklet is replaced with a threaded irq handler, and the tasklet for the PCM delayed start is simply merged into the normal PCM trigger, as well as the replacement of spinlock with mutex. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/drivers')
-rw-r--r--sound/drivers/vx/vx_core.c49
-rw-r--r--sound/drivers/vx/vx_mixer.c12
-rw-r--r--sound/drivers/vx/vx_pcm.c68
-rw-r--r--sound/drivers/vx/vx_uer.c23
4 files changed, 60 insertions, 92 deletions
diff --git a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c
index 83596891cde4..e8cc16993903 100644
--- a/sound/drivers/vx/vx_core.c
+++ b/sound/drivers/vx/vx_core.c
@@ -117,7 +117,7 @@ static int vx_reset_chk(struct vx_core *chip)
117 * 117 *
118 * returns 0 if successful, or a negative error code. 118 * returns 0 if successful, or a negative error code.
119 * the error code can be VX-specific, retrieved via vx_get_error(). 119 * the error code can be VX-specific, retrieved via vx_get_error().
120 * NB: call with spinlock held! 120 * NB: call with mutex held!
121 */ 121 */
122static int vx_transfer_end(struct vx_core *chip, int cmd) 122static int vx_transfer_end(struct vx_core *chip, int cmd)
123{ 123{
@@ -155,7 +155,7 @@ static int vx_transfer_end(struct vx_core *chip, int cmd)
155 * 155 *
156 * returns 0 if successful, or a negative error code. 156 * returns 0 if successful, or a negative error code.
157 * the error code can be VX-specific, retrieved via vx_get_error(). 157 * the error code can be VX-specific, retrieved via vx_get_error().
158 * NB: call with spinlock held! 158 * NB: call with mutex held!
159 */ 159 */
160static int vx_read_status(struct vx_core *chip, struct vx_rmh *rmh) 160static int vx_read_status(struct vx_core *chip, struct vx_rmh *rmh)
161{ 161{
@@ -236,7 +236,7 @@ static int vx_read_status(struct vx_core *chip, struct vx_rmh *rmh)
236 * returns 0 if successful, or a negative error code. 236 * returns 0 if successful, or a negative error code.
237 * the error code can be VX-specific, retrieved via vx_get_error(). 237 * the error code can be VX-specific, retrieved via vx_get_error().
238 * 238 *
239 * this function doesn't call spinlock at all. 239 * this function doesn't call mutex lock at all.
240 */ 240 */
241int vx_send_msg_nolock(struct vx_core *chip, struct vx_rmh *rmh) 241int vx_send_msg_nolock(struct vx_core *chip, struct vx_rmh *rmh)
242{ 242{
@@ -337,7 +337,7 @@ int vx_send_msg_nolock(struct vx_core *chip, struct vx_rmh *rmh)
337 337
338 338
339/* 339/*
340 * vx_send_msg - send a DSP message with spinlock 340 * vx_send_msg - send a DSP message with mutex
341 * @rmh: the rmh record to send and receive 341 * @rmh: the rmh record to send and receive
342 * 342 *
343 * returns 0 if successful, or a negative error code. 343 * returns 0 if successful, or a negative error code.
@@ -345,12 +345,11 @@ int vx_send_msg_nolock(struct vx_core *chip, struct vx_rmh *rmh)
345 */ 345 */
346int vx_send_msg(struct vx_core *chip, struct vx_rmh *rmh) 346int vx_send_msg(struct vx_core *chip, struct vx_rmh *rmh)
347{ 347{
348 unsigned long flags;
349 int err; 348 int err;
350 349
351 spin_lock_irqsave(&chip->lock, flags); 350 mutex_lock(&chip->lock);
352 err = vx_send_msg_nolock(chip, rmh); 351 err = vx_send_msg_nolock(chip, rmh);
353 spin_unlock_irqrestore(&chip->lock, flags); 352 mutex_unlock(&chip->lock);
354 return err; 353 return err;
355} 354}
356 355
@@ -362,7 +361,7 @@ int vx_send_msg(struct vx_core *chip, struct vx_rmh *rmh)
362 * returns 0 if successful, or a negative error code. 361 * returns 0 if successful, or a negative error code.
363 * the error code can be VX-specific, retrieved via vx_get_error(). 362 * the error code can be VX-specific, retrieved via vx_get_error().
364 * 363 *
365 * this function doesn't call spinlock at all. 364 * this function doesn't call mutex at all.
366 * 365 *
367 * unlike RMH, no command is sent to DSP. 366 * unlike RMH, no command is sent to DSP.
368 */ 367 */
@@ -398,19 +397,18 @@ int vx_send_rih_nolock(struct vx_core *chip, int cmd)
398 397
399 398
400/* 399/*
401 * vx_send_rih - send an RIH with spinlock 400 * vx_send_rih - send an RIH with mutex
402 * @cmd: the command to send 401 * @cmd: the command to send
403 * 402 *
404 * see vx_send_rih_nolock(). 403 * see vx_send_rih_nolock().
405 */ 404 */
406int vx_send_rih(struct vx_core *chip, int cmd) 405int vx_send_rih(struct vx_core *chip, int cmd)
407{ 406{
408 unsigned long flags;
409 int err; 407 int err;
410 408
411 spin_lock_irqsave(&chip->lock, flags); 409 mutex_lock(&chip->lock);
412 err = vx_send_rih_nolock(chip, cmd); 410 err = vx_send_rih_nolock(chip, cmd);
413 spin_unlock_irqrestore(&chip->lock, flags); 411 mutex_unlock(&chip->lock);
414 return err; 412 return err;
415} 413}
416 414
@@ -482,30 +480,30 @@ static int vx_test_irq_src(struct vx_core *chip, unsigned int *ret)
482 int err; 480 int err;
483 481
484 vx_init_rmh(&chip->irq_rmh, CMD_TEST_IT); 482 vx_init_rmh(&chip->irq_rmh, CMD_TEST_IT);
485 spin_lock(&chip->lock); 483 mutex_lock(&chip->lock);
486 err = vx_send_msg_nolock(chip, &chip->irq_rmh); 484 err = vx_send_msg_nolock(chip, &chip->irq_rmh);
487 if (err < 0) 485 if (err < 0)
488 *ret = 0; 486 *ret = 0;
489 else 487 else
490 *ret = chip->irq_rmh.Stat[0]; 488 *ret = chip->irq_rmh.Stat[0];
491 spin_unlock(&chip->lock); 489 mutex_unlock(&chip->lock);
492 return err; 490 return err;
493} 491}
494 492
495 493
496/* 494/*
497 * vx_interrupt - soft irq handler 495 * snd_vx_threaded_irq_handler - threaded irq handler
498 */ 496 */
499static void vx_interrupt(unsigned long private_data) 497irqreturn_t snd_vx_threaded_irq_handler(int irq, void *dev)
500{ 498{
501 struct vx_core *chip = (struct vx_core *) private_data; 499 struct vx_core *chip = dev;
502 unsigned int events; 500 unsigned int events;
503 501
504 if (chip->chip_status & VX_STAT_IS_STALE) 502 if (chip->chip_status & VX_STAT_IS_STALE)
505 return; 503 return IRQ_HANDLED;
506 504
507 if (vx_test_irq_src(chip, &events) < 0) 505 if (vx_test_irq_src(chip, &events) < 0)
508 return; 506 return IRQ_HANDLED;
509 507
510#if 0 508#if 0
511 if (events & 0x000800) 509 if (events & 0x000800)
@@ -519,7 +517,7 @@ static void vx_interrupt(unsigned long private_data)
519 */ 517 */
520 if (events & FATAL_DSP_ERROR) { 518 if (events & FATAL_DSP_ERROR) {
521 snd_printk(KERN_ERR "vx_core: fatal DSP error!!\n"); 519 snd_printk(KERN_ERR "vx_core: fatal DSP error!!\n");
522 return; 520 return IRQ_HANDLED;
523 } 521 }
524 522
525 /* The start on time code conditions are filled (ie the time code 523 /* The start on time code conditions are filled (ie the time code
@@ -534,8 +532,9 @@ static void vx_interrupt(unsigned long private_data)
534 532
535 /* update the pcm streams */ 533 /* update the pcm streams */
536 vx_pcm_update_intr(chip, events); 534 vx_pcm_update_intr(chip, events);
535 return IRQ_HANDLED;
537} 536}
538 537EXPORT_SYMBOL(snd_vx_threaded_irq_handler);
539 538
540/** 539/**
541 * snd_vx_irq_handler - interrupt handler 540 * snd_vx_irq_handler - interrupt handler
@@ -548,8 +547,8 @@ irqreturn_t snd_vx_irq_handler(int irq, void *dev)
548 (chip->chip_status & VX_STAT_IS_STALE)) 547 (chip->chip_status & VX_STAT_IS_STALE))
549 return IRQ_NONE; 548 return IRQ_NONE;
550 if (! vx_test_and_ack(chip)) 549 if (! vx_test_and_ack(chip))
551 tasklet_schedule(&chip->tq); 550 return IRQ_WAKE_THREAD;
552 return IRQ_HANDLED; 551 return IRQ_NONE;
553} 552}
554 553
555EXPORT_SYMBOL(snd_vx_irq_handler); 554EXPORT_SYMBOL(snd_vx_irq_handler);
@@ -790,13 +789,11 @@ struct vx_core *snd_vx_create(struct snd_card *card, struct snd_vx_hardware *hw,
790 snd_printk(KERN_ERR "vx_core: no memory\n"); 789 snd_printk(KERN_ERR "vx_core: no memory\n");
791 return NULL; 790 return NULL;
792 } 791 }
793 spin_lock_init(&chip->lock); 792 mutex_init(&chip->lock);
794 spin_lock_init(&chip->irq_lock);
795 chip->irq = -1; 793 chip->irq = -1;
796 chip->hw = hw; 794 chip->hw = hw;
797 chip->type = hw->type; 795 chip->type = hw->type;
798 chip->ops = ops; 796 chip->ops = ops;
799 tasklet_init(&chip->tq, vx_interrupt, (unsigned long)chip);
800 mutex_init(&chip->mixer_mutex); 797 mutex_init(&chip->mixer_mutex);
801 798
802 chip->card = card; 799 chip->card = card;
diff --git a/sound/drivers/vx/vx_mixer.c b/sound/drivers/vx/vx_mixer.c
index c71b8d148d7f..3b6823fc0606 100644
--- a/sound/drivers/vx/vx_mixer.c
+++ b/sound/drivers/vx/vx_mixer.c
@@ -32,17 +32,15 @@
32 */ 32 */
33static void vx_write_codec_reg(struct vx_core *chip, int codec, unsigned int data) 33static void vx_write_codec_reg(struct vx_core *chip, int codec, unsigned int data)
34{ 34{
35 unsigned long flags;
36
37 if (snd_BUG_ON(!chip->ops->write_codec)) 35 if (snd_BUG_ON(!chip->ops->write_codec))
38 return; 36 return;
39 37
40 if (chip->chip_status & VX_STAT_IS_STALE) 38 if (chip->chip_status & VX_STAT_IS_STALE)
41 return; 39 return;
42 40
43 spin_lock_irqsave(&chip->lock, flags); 41 mutex_lock(&chip->lock);
44 chip->ops->write_codec(chip, codec, data); 42 chip->ops->write_codec(chip, codec, data);
45 spin_unlock_irqrestore(&chip->lock, flags); 43 mutex_unlock(&chip->lock);
46} 44}
47 45
48/* 46/*
@@ -178,14 +176,12 @@ void vx_reset_codec(struct vx_core *chip, int cold_reset)
178 */ 176 */
179static void vx_change_audio_source(struct vx_core *chip, int src) 177static void vx_change_audio_source(struct vx_core *chip, int src)
180{ 178{
181 unsigned long flags;
182
183 if (chip->chip_status & VX_STAT_IS_STALE) 179 if (chip->chip_status & VX_STAT_IS_STALE)
184 return; 180 return;
185 181
186 spin_lock_irqsave(&chip->lock, flags); 182 mutex_lock(&chip->lock);
187 chip->ops->change_audio_source(chip, src); 183 chip->ops->change_audio_source(chip, src);
188 spin_unlock_irqrestore(&chip->lock, flags); 184 mutex_unlock(&chip->lock);
189} 185}
190 186
191 187
diff --git a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c
index deed5efff33c..11467272089e 100644
--- a/sound/drivers/vx/vx_pcm.c
+++ b/sound/drivers/vx/vx_pcm.c
@@ -229,7 +229,7 @@ static int vx_get_pipe_state(struct vx_core *chip, struct vx_pipe *pipe, int *st
229 229
230 vx_init_rmh(&rmh, CMD_PIPE_STATE); 230 vx_init_rmh(&rmh, CMD_PIPE_STATE);
231 vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0); 231 vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
232 err = vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ 232 err = vx_send_msg(chip, &rmh);
233 if (! err) 233 if (! err)
234 *state = (rmh.Stat[0] & (1 << pipe->number)) ? 1 : 0; 234 *state = (rmh.Stat[0] & (1 << pipe->number)) ? 1 : 0;
235 return err; 235 return err;
@@ -280,7 +280,7 @@ static int vx_pipe_can_start(struct vx_core *chip, struct vx_pipe *pipe)
280 vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0); 280 vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
281 rmh.Cmd[0] |= 1; 281 rmh.Cmd[0] |= 1;
282 282
283 err = vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ 283 err = vx_send_msg(chip, &rmh);
284 if (! err) { 284 if (! err) {
285 if (rmh.Stat[0]) 285 if (rmh.Stat[0])
286 err = 1; 286 err = 1;
@@ -300,7 +300,7 @@ static int vx_conf_pipe(struct vx_core *chip, struct vx_pipe *pipe)
300 if (pipe->is_capture) 300 if (pipe->is_capture)
301 rmh.Cmd[0] |= COMMAND_RECORD_MASK; 301 rmh.Cmd[0] |= COMMAND_RECORD_MASK;
302 rmh.Cmd[1] = 1 << pipe->number; 302 rmh.Cmd[1] = 1 << pipe->number;
303 return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ 303 return vx_send_msg(chip, &rmh);
304} 304}
305 305
306/* 306/*
@@ -311,7 +311,7 @@ static int vx_send_irqa(struct vx_core *chip)
311 struct vx_rmh rmh; 311 struct vx_rmh rmh;
312 312
313 vx_init_rmh(&rmh, CMD_SEND_IRQA); 313 vx_init_rmh(&rmh, CMD_SEND_IRQA);
314 return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ 314 return vx_send_msg(chip, &rmh);
315} 315}
316 316
317 317
@@ -389,7 +389,7 @@ static int vx_stop_pipe(struct vx_core *chip, struct vx_pipe *pipe)
389 struct vx_rmh rmh; 389 struct vx_rmh rmh;
390 vx_init_rmh(&rmh, CMD_STOP_PIPE); 390 vx_init_rmh(&rmh, CMD_STOP_PIPE);
391 vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0); 391 vx_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->number, 0);
392 return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ 392 return vx_send_msg(chip, &rmh);
393} 393}
394 394
395 395
@@ -477,7 +477,7 @@ static int vx_start_stream(struct vx_core *chip, struct vx_pipe *pipe)
477 vx_init_rmh(&rmh, CMD_START_ONE_STREAM); 477 vx_init_rmh(&rmh, CMD_START_ONE_STREAM);
478 vx_set_stream_cmd_params(&rmh, pipe->is_capture, pipe->number); 478 vx_set_stream_cmd_params(&rmh, pipe->is_capture, pipe->number);
479 vx_set_differed_time(chip, &rmh, pipe); 479 vx_set_differed_time(chip, &rmh, pipe);
480 return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ 480 return vx_send_msg(chip, &rmh);
481} 481}
482 482
483 483
@@ -492,7 +492,7 @@ static int vx_stop_stream(struct vx_core *chip, struct vx_pipe *pipe)
492 492
493 vx_init_rmh(&rmh, CMD_STOP_STREAM); 493 vx_init_rmh(&rmh, CMD_STOP_STREAM);
494 vx_set_stream_cmd_params(&rmh, pipe->is_capture, pipe->number); 494 vx_set_stream_cmd_params(&rmh, pipe->is_capture, pipe->number);
495 return vx_send_msg_nolock(chip, &rmh); /* no lock needed for trigger */ 495 return vx_send_msg(chip, &rmh);
496} 496}
497 497
498 498
@@ -520,8 +520,6 @@ static struct snd_pcm_hardware vx_pcm_playback_hw = {
520}; 520};
521 521
522 522
523static void vx_pcm_delayed_start(unsigned long arg);
524
525/* 523/*
526 * vx_pcm_playback_open - open callback for playback 524 * vx_pcm_playback_open - open callback for playback
527 */ 525 */
@@ -553,7 +551,6 @@ static int vx_pcm_playback_open(struct snd_pcm_substream *subs)
553 pipe->references++; 551 pipe->references++;
554 552
555 pipe->substream = subs; 553 pipe->substream = subs;
556 tasklet_init(&pipe->start_tq, vx_pcm_delayed_start, (unsigned long)subs);
557 chip->playback_pipes[audio] = pipe; 554 chip->playback_pipes[audio] = pipe;
558 555
559 runtime->hw = vx_pcm_playback_hw; 556 runtime->hw = vx_pcm_playback_hw;
@@ -646,12 +643,12 @@ static int vx_pcm_playback_transfer_chunk(struct vx_core *chip,
646 /* we don't need irqsave here, because this function 643 /* we don't need irqsave here, because this function
647 * is called from either trigger callback or irq handler 644 * is called from either trigger callback or irq handler
648 */ 645 */
649 spin_lock(&chip->lock); 646 mutex_lock(&chip->lock);
650 vx_pseudo_dma_write(chip, runtime, pipe, size); 647 vx_pseudo_dma_write(chip, runtime, pipe, size);
651 err = vx_notify_end_of_buffer(chip, pipe); 648 err = vx_notify_end_of_buffer(chip, pipe);
652 /* disconnect the host, SIZE_HBUF command always switches to the stream mode */ 649 /* disconnect the host, SIZE_HBUF command always switches to the stream mode */
653 vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT); 650 vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT);
654 spin_unlock(&chip->lock); 651 mutex_unlock(&chip->lock);
655 return err; 652 return err;
656} 653}
657 654
@@ -728,31 +725,6 @@ static void vx_pcm_playback_update(struct vx_core *chip,
728} 725}
729 726
730/* 727/*
731 * start the stream and pipe.
732 * this function is called from tasklet, which is invoked by the trigger
733 * START callback.
734 */
735static void vx_pcm_delayed_start(unsigned long arg)
736{
737 struct snd_pcm_substream *subs = (struct snd_pcm_substream *)arg;
738 struct vx_core *chip = subs->pcm->private_data;
739 struct vx_pipe *pipe = subs->runtime->private_data;
740 int err;
741
742 /* printk( KERN_DEBUG "DDDD tasklet delayed start jiffies = %ld\n", jiffies);*/
743
744 if ((err = vx_start_stream(chip, pipe)) < 0) {
745 snd_printk(KERN_ERR "vx: cannot start stream\n");
746 return;
747 }
748 if ((err = vx_toggle_pipe(chip, pipe, 1)) < 0) {
749 snd_printk(KERN_ERR "vx: cannot start pipe\n");
750 return;
751 }
752 /* printk( KERN_DEBUG "dddd tasklet delayed start jiffies = %ld \n", jiffies);*/
753}
754
755/*
756 * vx_pcm_playback_trigger - trigger callback for playback 728 * vx_pcm_playback_trigger - trigger callback for playback
757 */ 729 */
758static int vx_pcm_trigger(struct snd_pcm_substream *subs, int cmd) 730static int vx_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
@@ -769,11 +741,17 @@ static int vx_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
769 case SNDRV_PCM_TRIGGER_RESUME: 741 case SNDRV_PCM_TRIGGER_RESUME:
770 if (! pipe->is_capture) 742 if (! pipe->is_capture)
771 vx_pcm_playback_transfer(chip, subs, pipe, 2); 743 vx_pcm_playback_transfer(chip, subs, pipe, 2);
772 /* FIXME: 744 err = vx_start_stream(chip, pipe);
773 * we trigger the pipe using tasklet, so that the interrupts are 745 if (err < 0) {
774 * issued surely after the trigger is completed. 746 pr_debug("vx: cannot start stream\n");
775 */ 747 return err;
776 tasklet_schedule(&pipe->start_tq); 748 }
749 err = vx_toggle_pipe(chip, pipe, 1);
750 if (err < 0) {
751 pr_debug("vx: cannot start pipe\n");
752 vx_stop_stream(chip, pipe);
753 return err;
754 }
777 chip->pcm_running++; 755 chip->pcm_running++;
778 pipe->running = 1; 756 pipe->running = 1;
779 break; 757 break;
@@ -955,7 +933,6 @@ static int vx_pcm_capture_open(struct snd_pcm_substream *subs)
955 if (err < 0) 933 if (err < 0)
956 return err; 934 return err;
957 pipe->substream = subs; 935 pipe->substream = subs;
958 tasklet_init(&pipe->start_tq, vx_pcm_delayed_start, (unsigned long)subs);
959 chip->capture_pipes[audio] = pipe; 936 chip->capture_pipes[audio] = pipe;
960 937
961 /* check if monitoring is needed */ 938 /* check if monitoring is needed */
@@ -1082,7 +1059,7 @@ static void vx_pcm_capture_update(struct vx_core *chip, struct snd_pcm_substream
1082 count -= 3; 1059 count -= 3;
1083 } 1060 }
1084 /* disconnect the host, SIZE_HBUF command always switches to the stream mode */ 1061 /* disconnect the host, SIZE_HBUF command always switches to the stream mode */
1085 vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT); 1062 vx_send_rih(chip, IRQ_CONNECT_STREAM_NEXT);
1086 /* read the last pending 6 bytes */ 1063 /* read the last pending 6 bytes */
1087 count = DMA_READ_ALIGN; 1064 count = DMA_READ_ALIGN;
1088 while (count > 0) { 1065 while (count > 0) {
@@ -1099,7 +1076,7 @@ static void vx_pcm_capture_update(struct vx_core *chip, struct snd_pcm_substream
1099 1076
1100 _error: 1077 _error:
1101 /* disconnect the host, SIZE_HBUF command always switches to the stream mode */ 1078 /* disconnect the host, SIZE_HBUF command always switches to the stream mode */
1102 vx_send_rih_nolock(chip, IRQ_CONNECT_STREAM_NEXT); 1079 vx_send_rih(chip, IRQ_CONNECT_STREAM_NEXT);
1103 return; 1080 return;
1104} 1081}
1105 1082
@@ -1275,6 +1252,7 @@ int snd_vx_pcm_new(struct vx_core *chip)
1275 pcm->private_data = chip; 1252 pcm->private_data = chip;
1276 pcm->private_free = snd_vx_pcm_free; 1253 pcm->private_free = snd_vx_pcm_free;
1277 pcm->info_flags = 0; 1254 pcm->info_flags = 0;
1255 pcm->nonatomic = true;
1278 strcpy(pcm->name, chip->card->shortname); 1256 strcpy(pcm->name, chip->card->shortname);
1279 chip->pcm[i] = pcm; 1257 chip->pcm[i] = pcm;
1280 } 1258 }
diff --git a/sound/drivers/vx/vx_uer.c b/sound/drivers/vx/vx_uer.c
index b0560fec6bba..ef0b40c0a594 100644
--- a/sound/drivers/vx/vx_uer.c
+++ b/sound/drivers/vx/vx_uer.c
@@ -60,9 +60,9 @@ static int vx_modify_board_inputs(struct vx_core *chip)
60 */ 60 */
61static int vx_read_one_cbit(struct vx_core *chip, int index) 61static int vx_read_one_cbit(struct vx_core *chip, int index)
62{ 62{
63 unsigned long flags;
64 int val; 63 int val;
65 spin_lock_irqsave(&chip->lock, flags); 64
65 mutex_lock(&chip->lock);
66 if (chip->type >= VX_TYPE_VXPOCKET) { 66 if (chip->type >= VX_TYPE_VXPOCKET) {
67 vx_outb(chip, CSUER, 1); /* read */ 67 vx_outb(chip, CSUER, 1); /* read */
68 vx_outb(chip, RUER, index & XX_UER_CBITS_OFFSET_MASK); 68 vx_outb(chip, RUER, index & XX_UER_CBITS_OFFSET_MASK);
@@ -72,7 +72,7 @@ static int vx_read_one_cbit(struct vx_core *chip, int index)
72 vx_outl(chip, RUER, index & XX_UER_CBITS_OFFSET_MASK); 72 vx_outl(chip, RUER, index & XX_UER_CBITS_OFFSET_MASK);
73 val = (vx_inl(chip, RUER) >> 7) & 0x01; 73 val = (vx_inl(chip, RUER) >> 7) & 0x01;
74 } 74 }
75 spin_unlock_irqrestore(&chip->lock, flags); 75 mutex_unlock(&chip->lock);
76 return val; 76 return val;
77} 77}
78 78
@@ -83,9 +83,8 @@ static int vx_read_one_cbit(struct vx_core *chip, int index)
83 */ 83 */
84static void vx_write_one_cbit(struct vx_core *chip, int index, int val) 84static void vx_write_one_cbit(struct vx_core *chip, int index, int val)
85{ 85{
86 unsigned long flags;
87 val = !!val; /* 0 or 1 */ 86 val = !!val; /* 0 or 1 */
88 spin_lock_irqsave(&chip->lock, flags); 87 mutex_lock(&chip->lock);
89 if (vx_is_pcmcia(chip)) { 88 if (vx_is_pcmcia(chip)) {
90 vx_outb(chip, CSUER, 0); /* write */ 89 vx_outb(chip, CSUER, 0); /* write */
91 vx_outb(chip, RUER, (val << 7) | (index & XX_UER_CBITS_OFFSET_MASK)); 90 vx_outb(chip, RUER, (val << 7) | (index & XX_UER_CBITS_OFFSET_MASK));
@@ -93,7 +92,7 @@ static void vx_write_one_cbit(struct vx_core *chip, int index, int val)
93 vx_outl(chip, CSUER, 0); /* write */ 92 vx_outl(chip, CSUER, 0); /* write */
94 vx_outl(chip, RUER, (val << 7) | (index & XX_UER_CBITS_OFFSET_MASK)); 93 vx_outl(chip, RUER, (val << 7) | (index & XX_UER_CBITS_OFFSET_MASK));
95 } 94 }
96 spin_unlock_irqrestore(&chip->lock, flags); 95 mutex_unlock(&chip->lock);
97} 96}
98 97
99/* 98/*
@@ -190,14 +189,12 @@ static int vx_calc_clock_from_freq(struct vx_core *chip, int freq)
190 */ 189 */
191static void vx_change_clock_source(struct vx_core *chip, int source) 190static void vx_change_clock_source(struct vx_core *chip, int source)
192{ 191{
193 unsigned long flags;
194
195 /* we mute DAC to prevent clicks */ 192 /* we mute DAC to prevent clicks */
196 vx_toggle_dac_mute(chip, 1); 193 vx_toggle_dac_mute(chip, 1);
197 spin_lock_irqsave(&chip->lock, flags); 194 mutex_lock(&chip->lock);
198 chip->ops->set_clock_source(chip, source); 195 chip->ops->set_clock_source(chip, source);
199 chip->clock_source = source; 196 chip->clock_source = source;
200 spin_unlock_irqrestore(&chip->lock, flags); 197 mutex_unlock(&chip->lock);
201 /* unmute */ 198 /* unmute */
202 vx_toggle_dac_mute(chip, 0); 199 vx_toggle_dac_mute(chip, 0);
203} 200}
@@ -209,11 +206,11 @@ static void vx_change_clock_source(struct vx_core *chip, int source)
209void vx_set_internal_clock(struct vx_core *chip, unsigned int freq) 206void vx_set_internal_clock(struct vx_core *chip, unsigned int freq)
210{ 207{
211 int clock; 208 int clock;
212 unsigned long flags; 209
213 /* Get real clock value */ 210 /* Get real clock value */
214 clock = vx_calc_clock_from_freq(chip, freq); 211 clock = vx_calc_clock_from_freq(chip, freq);
215 snd_printdd(KERN_DEBUG "set internal clock to 0x%x from freq %d\n", clock, freq); 212 snd_printdd(KERN_DEBUG "set internal clock to 0x%x from freq %d\n", clock, freq);
216 spin_lock_irqsave(&chip->lock, flags); 213 mutex_lock(&chip->lock);
217 if (vx_is_pcmcia(chip)) { 214 if (vx_is_pcmcia(chip)) {
218 vx_outb(chip, HIFREQ, (clock >> 8) & 0x0f); 215 vx_outb(chip, HIFREQ, (clock >> 8) & 0x0f);
219 vx_outb(chip, LOFREQ, clock & 0xff); 216 vx_outb(chip, LOFREQ, clock & 0xff);
@@ -221,7 +218,7 @@ void vx_set_internal_clock(struct vx_core *chip, unsigned int freq)
221 vx_outl(chip, HIFREQ, (clock >> 8) & 0x0f); 218 vx_outl(chip, HIFREQ, (clock >> 8) & 0x0f);
222 vx_outl(chip, LOFREQ, clock & 0xff); 219 vx_outl(chip, LOFREQ, clock & 0xff);
223 } 220 }
224 spin_unlock_irqrestore(&chip->lock, flags); 221 mutex_unlock(&chip->lock);
225} 222}
226 223
227 224