Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ALSA: pcm: Add snd_pcm_stop_xrun() helper

Add a new helper function snd_pcm_stop_xrun() to the standard sequnce
lock/snd_pcm_stop(XRUN)/unlock by a single call, and replace the
existing open codes with this helper.

The function checks the PCM running state to prevent setting the wrong
state, too, for more safety.

Signed-off-by: Takashi Iwai <tiwai@suse.de>

+46 -78
+1 -3
drivers/media/pci/saa7134/saa7134-alsa.c
··· 173 173 dprintk("irq: overrun [full=%d/%d] - Blocks in %d\n",dev->dmasound.read_count, 174 174 dev->dmasound.bufsize, dev->dmasound.blocks); 175 175 spin_unlock(&dev->slock); 176 - snd_pcm_stream_lock(dev->dmasound.substream); 177 - snd_pcm_stop(dev->dmasound.substream,SNDRV_PCM_STATE_XRUN); 178 - snd_pcm_stream_unlock(dev->dmasound.substream); 176 + snd_pcm_stop_xrun(dev->dmasound.substream); 179 177 return; 180 178 } 181 179
+1
include/sound/pcm.h
··· 506 506 int snd_pcm_start(struct snd_pcm_substream *substream); 507 507 int snd_pcm_stop(struct snd_pcm_substream *substream, snd_pcm_state_t status); 508 508 int snd_pcm_drain_done(struct snd_pcm_substream *substream); 509 + int snd_pcm_stop_xrun(struct snd_pcm_substream *substream); 509 510 #ifdef CONFIG_PM 510 511 int snd_pcm_suspend(struct snd_pcm_substream *substream); 511 512 int snd_pcm_suspend_all(struct snd_pcm *pcm);
+1 -3
sound/arm/pxa2xx-pcm-lib.c
··· 200 200 } else { 201 201 printk(KERN_ERR "DMA error on channel %d (DCSR=%#x)\n", 202 202 dma_ch, dcsr); 203 - snd_pcm_stream_lock(substream); 204 - snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); 205 - snd_pcm_stream_unlock(substream); 203 + snd_pcm_stop_xrun(substream); 206 204 } 207 205 } 208 206 EXPORT_SYMBOL(pxa2xx_pcm_dma_irq);
+23
sound/core/pcm_native.c
··· 1098 1098 SNDRV_PCM_STATE_SETUP); 1099 1099 } 1100 1100 1101 + /** 1102 + * snd_pcm_stop_xrun - stop the running streams as XRUN 1103 + * @substream: the PCM substream instance 1104 + * @state: PCM state after stopping the stream 1105 + * 1106 + * This stops the given running substream (and all linked substreams) as XRUN. 1107 + * Unlike snd_pcm_stop(), this function takes the substream lock by itself. 1108 + * 1109 + * Return: Zero if successful, or a negative error code. 1110 + */ 1111 + int snd_pcm_stop_xrun(struct snd_pcm_substream *substream) 1112 + { 1113 + unsigned long flags; 1114 + int ret = 0; 1115 + 1116 + snd_pcm_stream_lock_irqsave(substream, flags); 1117 + if (snd_pcm_running(substream)) 1118 + ret = snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); 1119 + snd_pcm_stream_unlock_irqrestore(substream, flags); 1120 + return ret; 1121 + } 1122 + EXPORT_SYMBOL_GPL(snd_pcm_stop_xrun); 1123 + 1101 1124 /* 1102 1125 * pause callbacks 1103 1126 */
+2 -6
sound/firewire/amdtp.c
··· 1006 1006 struct snd_pcm_substream *pcm; 1007 1007 1008 1008 pcm = ACCESS_ONCE(s->pcm); 1009 - if (pcm) { 1010 - snd_pcm_stream_lock_irq(pcm); 1011 - if (snd_pcm_running(pcm)) 1012 - snd_pcm_stop(pcm, SNDRV_PCM_STATE_XRUN); 1013 - snd_pcm_stream_unlock_irq(pcm); 1014 - } 1009 + if (pcm) 1010 + snd_pcm_stop_xrun(pcm); 1015 1011 } 1016 1012 EXPORT_SYMBOL(amdtp_stream_pcm_abort);
+2 -8
sound/firewire/isight.c
··· 131 131 132 132 static void isight_pcm_abort(struct isight *isight) 133 133 { 134 - unsigned long flags; 135 - 136 - if (ACCESS_ONCE(isight->pcm_active)) { 137 - snd_pcm_stream_lock_irqsave(isight->pcm, flags); 138 - if (snd_pcm_running(isight->pcm)) 139 - snd_pcm_stop(isight->pcm, SNDRV_PCM_STATE_XRUN); 140 - snd_pcm_stream_unlock_irqrestore(isight->pcm, flags); 141 - } 134 + if (ACCESS_ONCE(isight->pcm_active)) 135 + snd_pcm_stop_xrun(isight->pcm); 142 136 } 143 137 144 138 static void isight_dropped_samples(struct isight *isight, unsigned int total)
+1 -4
sound/pci/asihpi/asihpi.c
··· 769 769 s->number); 770 770 ds->drained_count++; 771 771 if (ds->drained_count > 20) { 772 - unsigned long flags; 773 - snd_pcm_stream_lock_irqsave(s, flags); 774 - snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN); 775 - snd_pcm_stream_unlock_irqrestore(s, flags); 772 + snd_pcm_stop_xrun(s); 776 773 continue; 777 774 } 778 775 } else {
+1 -3
sound/pci/atiixp.c
··· 688 688 if (! dma->substream || ! dma->running) 689 689 return; 690 690 dev_dbg(chip->card->dev, "XRUN detected (DMA %d)\n", dma->ops->type); 691 - snd_pcm_stream_lock(dma->substream); 692 - snd_pcm_stop(dma->substream, SNDRV_PCM_STATE_XRUN); 693 - snd_pcm_stream_unlock(dma->substream); 691 + snd_pcm_stop_xrun(dma->substream); 694 692 } 695 693 696 694 /*
+1 -3
sound/pci/atiixp_modem.c
··· 638 638 if (! dma->substream || ! dma->running) 639 639 return; 640 640 dev_dbg(chip->card->dev, "XRUN detected (DMA %d)\n", dma->ops->type); 641 - snd_pcm_stream_lock(dma->substream); 642 - snd_pcm_stop(dma->substream, SNDRV_PCM_STATE_XRUN); 643 - snd_pcm_stream_unlock(dma->substream); 641 + snd_pcm_stop_xrun(dma->substream); 644 642 } 645 643 646 644 /*
+1 -3
sound/soc/atmel/atmel-pcm-dma.c
··· 80 80 81 81 /* stop RX and capture: will be enabled again at restart */ 82 82 ssc_writex(prtd->ssc->regs, SSC_CR, prtd->mask->ssc_disable); 83 - snd_pcm_stream_lock(substream); 84 - snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); 85 - snd_pcm_stream_unlock(substream); 83 + snd_pcm_stop_xrun(substream); 86 84 87 85 /* now drain RHR and read status to remove xrun condition */ 88 86 ssc_readx(prtd->ssc->regs, SSC_RHR);
+1 -8
sound/soc/fsl/fsl_dma.c
··· 151 151 */ 152 152 static void fsl_dma_abort_stream(struct snd_pcm_substream *substream) 153 153 { 154 - unsigned long flags; 155 - 156 - snd_pcm_stream_lock_irqsave(substream, flags); 157 - 158 - if (snd_pcm_running(substream)) 159 - snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); 160 - 161 - snd_pcm_stream_unlock_irqrestore(substream, flags); 154 + snd_pcm_stop_xrun(substream); 162 155 } 163 156 164 157 /**
+4 -13
sound/usb/6fire/pcm.c
··· 679 679 void usb6fire_pcm_abort(struct sfire_chip *chip) 680 680 { 681 681 struct pcm_runtime *rt = chip->pcm; 682 - unsigned long flags; 683 682 int i; 684 683 685 684 if (rt) { 686 685 rt->panic = true; 687 686 688 - if (rt->playback.instance) { 689 - snd_pcm_stream_lock_irqsave(rt->playback.instance, flags); 690 - snd_pcm_stop(rt->playback.instance, 691 - SNDRV_PCM_STATE_XRUN); 692 - snd_pcm_stream_unlock_irqrestore(rt->playback.instance, flags); 693 - } 687 + if (rt->playback.instance) 688 + snd_pcm_stop_xrun(rt->playback.instance); 694 689 695 - if (rt->capture.instance) { 696 - snd_pcm_stream_lock_irqsave(rt->capture.instance, flags); 697 - snd_pcm_stop(rt->capture.instance, 698 - SNDRV_PCM_STATE_XRUN); 699 - snd_pcm_stream_unlock_irqrestore(rt->capture.instance, flags); 700 - } 690 + if (rt->capture.instance) 691 + snd_pcm_stop_xrun(rt->capture.instance); 701 692 702 693 for (i = 0; i < PCM_N_URBS; i++) { 703 694 usb_poison_urb(&rt->in_urbs[i].instance);
+1 -3
sound/usb/endpoint.c
··· 391 391 usb_audio_err(ep->chip, "cannot submit urb (err = %d)\n", err); 392 392 if (ep->data_subs && ep->data_subs->pcm_substream) { 393 393 substream = ep->data_subs->pcm_substream; 394 - snd_pcm_stream_lock_irqsave(substream, flags); 395 - snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); 396 - snd_pcm_stream_unlock_irqrestore(substream, flags); 394 + snd_pcm_stop_xrun(substream); 397 395 } 398 396 399 397 exit_clear:
+4 -14
sound/usb/misc/ua101.c
··· 613 613 614 614 static void abort_alsa_capture(struct ua101 *ua) 615 615 { 616 - unsigned long flags; 617 - 618 - if (test_bit(ALSA_CAPTURE_RUNNING, &ua->states)) { 619 - snd_pcm_stream_lock_irqsave(ua->capture.substream, flags); 620 - snd_pcm_stop(ua->capture.substream, SNDRV_PCM_STATE_XRUN); 621 - snd_pcm_stream_unlock_irqrestore(ua->capture.substream, flags); 622 - } 616 + if (test_bit(ALSA_CAPTURE_RUNNING, &ua->states)) 617 + snd_pcm_stop_xrun(ua->capture.substream); 623 618 } 624 619 625 620 static void abort_alsa_playback(struct ua101 *ua) 626 621 { 627 - unsigned long flags; 628 - 629 - if (test_bit(ALSA_PLAYBACK_RUNNING, &ua->states)) { 630 - snd_pcm_stream_lock_irqsave(ua->playback.substream, flags); 631 - snd_pcm_stop(ua->playback.substream, SNDRV_PCM_STATE_XRUN); 632 - snd_pcm_stream_unlock_irqrestore(ua->playback.substream, flags); 633 - } 622 + if (test_bit(ALSA_PLAYBACK_RUNNING, &ua->states)) 623 + snd_pcm_stop_xrun(ua->playback.substream); 634 624 } 635 625 636 626 static int set_stream_hw(struct ua101 *ua, struct snd_pcm_substream *substream,
+2 -7
sound/usb/usx2y/usbusx2yaudio.c
··· 272 272 for (s = 0; s < 4; s++) { 273 273 struct snd_usX2Y_substream *subs = usX2Y->subs[s]; 274 274 if (subs) { 275 - if (atomic_read(&subs->state) >= state_PRERUNNING) { 276 - unsigned long flags; 277 - 278 - snd_pcm_stream_lock_irqsave(subs->pcm_substream, flags); 279 - snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN); 280 - snd_pcm_stream_unlock_irqrestore(subs->pcm_substream, flags); 281 - } 275 + if (atomic_read(&subs->state) >= state_PRERUNNING) 276 + snd_pcm_stop_xrun(subs->pcm_substream); 282 277 for (u = 0; u < NRURBS; u++) { 283 278 struct urb *urb = subs->urb[u]; 284 279 if (NULL != urb)