diff options
author | Takashi Iwai <tiwai@suse.de> | 2014-09-10 08:01:05 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2014-09-15 09:52:10 -0400 |
commit | 6336c20cdaee1dd13d01dfa8c07ce3b18bbc846f (patch) | |
tree | c974b279979eadaa0ace3768d7e231a59f62f3bd /sound/pci/lx6464es/lx6464es.c | |
parent | 9bef72bdb26e291d6dffb04768741a0e49582666 (diff) |
ALSA: lx6464es: Use nonatomic PCM ops
Like the other previous changes, this patch for lx6464es takes the
same strategy for converting to nonatomic PCM ops: replacing spinlock
with mutex, converting the irq tasklet to the threaded irq, and
merging the trigger tasklets back to the trigger callback.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/lx6464es/lx6464es.c')
-rw-r--r-- | sound/pci/lx6464es/lx6464es.c | 43 |
1 files changed, 14 insertions, 29 deletions
diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c index a671f0865f71..601315a1f58f 100644 --- a/sound/pci/lx6464es/lx6464es.c +++ b/sound/pci/lx6464es/lx6464es.c | |||
@@ -279,7 +279,6 @@ static snd_pcm_uframes_t lx_pcm_stream_pointer(struct snd_pcm_substream | |||
279 | { | 279 | { |
280 | struct lx6464es *chip = snd_pcm_substream_chip(substream); | 280 | struct lx6464es *chip = snd_pcm_substream_chip(substream); |
281 | snd_pcm_uframes_t pos; | 281 | snd_pcm_uframes_t pos; |
282 | unsigned long flags; | ||
283 | int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); | 282 | int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); |
284 | 283 | ||
285 | struct lx_stream *lx_stream = is_capture ? &chip->capture_stream : | 284 | struct lx_stream *lx_stream = is_capture ? &chip->capture_stream : |
@@ -287,9 +286,9 @@ static snd_pcm_uframes_t lx_pcm_stream_pointer(struct snd_pcm_substream | |||
287 | 286 | ||
288 | dev_dbg(chip->card->dev, "->lx_pcm_stream_pointer\n"); | 287 | dev_dbg(chip->card->dev, "->lx_pcm_stream_pointer\n"); |
289 | 288 | ||
290 | spin_lock_irqsave(&chip->lock, flags); | 289 | mutex_lock(&chip->lock); |
291 | pos = lx_stream->frame_pos * substream->runtime->period_size; | 290 | pos = lx_stream->frame_pos * substream->runtime->period_size; |
292 | spin_unlock_irqrestore(&chip->lock, flags); | 291 | mutex_unlock(&chip->lock); |
293 | 292 | ||
294 | dev_dbg(chip->card->dev, "stream_pointer at %ld\n", pos); | 293 | dev_dbg(chip->card->dev, "stream_pointer at %ld\n", pos); |
295 | return pos; | 294 | return pos; |
@@ -485,8 +484,8 @@ static void lx_trigger_stop(struct lx6464es *chip, struct lx_stream *lx_stream) | |||
485 | 484 | ||
486 | } | 485 | } |
487 | 486 | ||
488 | static void lx_trigger_tasklet_dispatch_stream(struct lx6464es *chip, | 487 | static void lx_trigger_dispatch_stream(struct lx6464es *chip, |
489 | struct lx_stream *lx_stream) | 488 | struct lx_stream *lx_stream) |
490 | { | 489 | { |
491 | switch (lx_stream->status) { | 490 | switch (lx_stream->status) { |
492 | case LX_STREAM_STATUS_SCHEDULE_RUN: | 491 | case LX_STREAM_STATUS_SCHEDULE_RUN: |
@@ -502,24 +501,12 @@ static void lx_trigger_tasklet_dispatch_stream(struct lx6464es *chip, | |||
502 | } | 501 | } |
503 | } | 502 | } |
504 | 503 | ||
505 | static void lx_trigger_tasklet(unsigned long data) | ||
506 | { | ||
507 | struct lx6464es *chip = (struct lx6464es *)data; | ||
508 | unsigned long flags; | ||
509 | |||
510 | dev_dbg(chip->card->dev, "->lx_trigger_tasklet\n"); | ||
511 | |||
512 | spin_lock_irqsave(&chip->lock, flags); | ||
513 | lx_trigger_tasklet_dispatch_stream(chip, &chip->capture_stream); | ||
514 | lx_trigger_tasklet_dispatch_stream(chip, &chip->playback_stream); | ||
515 | spin_unlock_irqrestore(&chip->lock, flags); | ||
516 | } | ||
517 | |||
518 | static int lx_pcm_trigger_dispatch(struct lx6464es *chip, | 504 | static int lx_pcm_trigger_dispatch(struct lx6464es *chip, |
519 | struct lx_stream *lx_stream, int cmd) | 505 | struct lx_stream *lx_stream, int cmd) |
520 | { | 506 | { |
521 | int err = 0; | 507 | int err = 0; |
522 | 508 | ||
509 | mutex_lock(&chip->lock); | ||
523 | switch (cmd) { | 510 | switch (cmd) { |
524 | case SNDRV_PCM_TRIGGER_START: | 511 | case SNDRV_PCM_TRIGGER_START: |
525 | lx_stream->status = LX_STREAM_STATUS_SCHEDULE_RUN; | 512 | lx_stream->status = LX_STREAM_STATUS_SCHEDULE_RUN; |
@@ -533,9 +520,12 @@ static int lx_pcm_trigger_dispatch(struct lx6464es *chip, | |||
533 | err = -EINVAL; | 520 | err = -EINVAL; |
534 | goto exit; | 521 | goto exit; |
535 | } | 522 | } |
536 | tasklet_schedule(&chip->trigger_tasklet); | 523 | |
524 | lx_trigger_dispatch_stream(chip, &chip->capture_stream); | ||
525 | lx_trigger_dispatch_stream(chip, &chip->playback_stream); | ||
537 | 526 | ||
538 | exit: | 527 | exit: |
528 | mutex_unlock(&chip->lock); | ||
539 | return err; | 529 | return err; |
540 | } | 530 | } |
541 | 531 | ||
@@ -861,6 +851,7 @@ static int lx_pcm_create(struct lx6464es *chip) | |||
861 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &lx_ops_capture); | 851 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &lx_ops_capture); |
862 | 852 | ||
863 | pcm->info_flags = 0; | 853 | pcm->info_flags = 0; |
854 | pcm->nonatomic = true; | ||
864 | strcpy(pcm->name, card_name); | 855 | strcpy(pcm->name, card_name); |
865 | 856 | ||
866 | err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | 857 | err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
@@ -1009,15 +1000,9 @@ static int snd_lx6464es_create(struct snd_card *card, | |||
1009 | chip->irq = -1; | 1000 | chip->irq = -1; |
1010 | 1001 | ||
1011 | /* initialize synchronization structs */ | 1002 | /* initialize synchronization structs */ |
1012 | spin_lock_init(&chip->lock); | 1003 | mutex_init(&chip->lock); |
1013 | spin_lock_init(&chip->msg_lock); | 1004 | mutex_init(&chip->msg_lock); |
1014 | mutex_init(&chip->setup_mutex); | 1005 | mutex_init(&chip->setup_mutex); |
1015 | tasklet_init(&chip->trigger_tasklet, lx_trigger_tasklet, | ||
1016 | (unsigned long)chip); | ||
1017 | tasklet_init(&chip->tasklet_capture, lx_tasklet_capture, | ||
1018 | (unsigned long)chip); | ||
1019 | tasklet_init(&chip->tasklet_playback, lx_tasklet_playback, | ||
1020 | (unsigned long)chip); | ||
1021 | 1006 | ||
1022 | /* request resources */ | 1007 | /* request resources */ |
1023 | err = pci_request_regions(pci, card_name); | 1008 | err = pci_request_regions(pci, card_name); |
@@ -1032,8 +1017,8 @@ static int snd_lx6464es_create(struct snd_card *card, | |||
1032 | /* dsp port */ | 1017 | /* dsp port */ |
1033 | chip->port_dsp_bar = pci_ioremap_bar(pci, 2); | 1018 | chip->port_dsp_bar = pci_ioremap_bar(pci, 2); |
1034 | 1019 | ||
1035 | err = request_irq(pci->irq, lx_interrupt, IRQF_SHARED, | 1020 | err = request_threaded_irq(pci->irq, lx_interrupt, lx_threaded_irq, |
1036 | KBUILD_MODNAME, chip); | 1021 | IRQF_SHARED, KBUILD_MODNAME, chip); |
1037 | if (err) { | 1022 | if (err) { |
1038 | dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq); | 1023 | dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq); |
1039 | goto request_irq_failed; | 1024 | goto request_irq_failed; |