Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1fb8510c authored by Takashi Iwai's avatar Takashi Iwai
Browse files

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: default avatarTakashi Iwai <tiwai@suse.de>
parent 31584ed1
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -173,9 +173,7 @@ static void saa7134_irq_alsa_done(struct saa7134_dev *dev,
		dprintk("irq: overrun [full=%d/%d] - Blocks in %d\n",dev->dmasound.read_count,
			dev->dmasound.bufsize, dev->dmasound.blocks);
		spin_unlock(&dev->slock);
		snd_pcm_stream_lock(dev->dmasound.substream);
		snd_pcm_stop(dev->dmasound.substream,SNDRV_PCM_STATE_XRUN);
		snd_pcm_stream_unlock(dev->dmasound.substream);
		snd_pcm_stop_xrun(dev->dmasound.substream);
		return;
	}

+1 −0
Original line number Diff line number Diff line
@@ -506,6 +506,7 @@ int snd_pcm_status(struct snd_pcm_substream *substream,
int snd_pcm_start(struct snd_pcm_substream *substream);
int snd_pcm_stop(struct snd_pcm_substream *substream, snd_pcm_state_t status);
int snd_pcm_drain_done(struct snd_pcm_substream *substream);
int snd_pcm_stop_xrun(struct snd_pcm_substream *substream);
#ifdef CONFIG_PM
int snd_pcm_suspend(struct snd_pcm_substream *substream);
int snd_pcm_suspend_all(struct snd_pcm *pcm);
+1 −3
Original line number Diff line number Diff line
@@ -200,9 +200,7 @@ void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id)
	} else {
		printk(KERN_ERR "DMA error on channel %d (DCSR=%#x)\n",
			dma_ch, dcsr);
		snd_pcm_stream_lock(substream);
		snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
		snd_pcm_stream_unlock(substream);
		snd_pcm_stop_xrun(substream);
	}
}
EXPORT_SYMBOL(pxa2xx_pcm_dma_irq);
+23 −0
Original line number Diff line number Diff line
@@ -1098,6 +1098,29 @@ int snd_pcm_drain_done(struct snd_pcm_substream *substream)
				     SNDRV_PCM_STATE_SETUP);
}

/**
 * snd_pcm_stop_xrun - stop the running streams as XRUN
 * @substream: the PCM substream instance
 * @state: PCM state after stopping the stream
 *
 * This stops the given running substream (and all linked substreams) as XRUN.
 * Unlike snd_pcm_stop(), this function takes the substream lock by itself.
 *
 * Return: Zero if successful, or a negative error code.
 */
int snd_pcm_stop_xrun(struct snd_pcm_substream *substream)
{
	unsigned long flags;
	int ret = 0;

	snd_pcm_stream_lock_irqsave(substream, flags);
	if (snd_pcm_running(substream))
		ret = snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
	snd_pcm_stream_unlock_irqrestore(substream, flags);
	return ret;
}
EXPORT_SYMBOL_GPL(snd_pcm_stop_xrun);

/*
 * pause callbacks
 */
+2 −6
Original line number Diff line number Diff line
@@ -1006,11 +1006,7 @@ void amdtp_stream_pcm_abort(struct amdtp_stream *s)
	struct snd_pcm_substream *pcm;

	pcm = ACCESS_ONCE(s->pcm);
	if (pcm) {
		snd_pcm_stream_lock_irq(pcm);
		if (snd_pcm_running(pcm))
			snd_pcm_stop(pcm, SNDRV_PCM_STATE_XRUN);
		snd_pcm_stream_unlock_irq(pcm);
	}
	if (pcm)
		snd_pcm_stop_xrun(pcm);
}
EXPORT_SYMBOL(amdtp_stream_pcm_abort);
Loading