diff options
author | Takashi Iwai <tiwai@suse.de> | 2014-09-09 11:17:20 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2014-09-15 09:52:03 -0400 |
commit | db0a5214b8d6cc7a90ce3336d24a85b90cbb4e67 (patch) | |
tree | fdfcfaee149e83613d9854a763bbe3fe95f60292 /sound/drivers | |
parent | e7e69265b6269763799a5de9c263fbbce32cd3a3 (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.c | 49 | ||||
-rw-r--r-- | sound/drivers/vx/vx_mixer.c | 12 | ||||
-rw-r--r-- | sound/drivers/vx/vx_pcm.c | 68 | ||||
-rw-r--r-- | sound/drivers/vx/vx_uer.c | 23 |
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 | */ |
122 | static int vx_transfer_end(struct vx_core *chip, int cmd) | 122 | static 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 | */ |
160 | static int vx_read_status(struct vx_core *chip, struct vx_rmh *rmh) | 160 | static 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 | */ |
241 | int vx_send_msg_nolock(struct vx_core *chip, struct vx_rmh *rmh) | 241 | int 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 | */ |
346 | int vx_send_msg(struct vx_core *chip, struct vx_rmh *rmh) | 346 | int 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 | */ |
406 | int vx_send_rih(struct vx_core *chip, int cmd) | 405 | int 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 | */ |
499 | static void vx_interrupt(unsigned long private_data) | 497 | irqreturn_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 | 537 | EXPORT_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 | ||
555 | EXPORT_SYMBOL(snd_vx_irq_handler); | 554 | EXPORT_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 | */ |
33 | static void vx_write_codec_reg(struct vx_core *chip, int codec, unsigned int data) | 33 | static 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 | */ |
179 | static void vx_change_audio_source(struct vx_core *chip, int src) | 177 | static 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 | ||
523 | static 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 | */ | ||
735 | static 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 | */ |
758 | static int vx_pcm_trigger(struct snd_pcm_substream *subs, int cmd) | 730 | static 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 | */ |
61 | static int vx_read_one_cbit(struct vx_core *chip, int index) | 61 | static 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 | */ |
84 | static void vx_write_one_cbit(struct vx_core *chip, int index, int val) | 84 | static 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 | */ |
191 | static void vx_change_clock_source(struct vx_core *chip, int source) | 190 | static 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) | |||
209 | void vx_set_internal_clock(struct vx_core *chip, unsigned int freq) | 206 | void 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 | ||