Patch "ALSA: dmaengine_pcm: terminate dmaengine before synchronize" has been added to the 5.4-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    ALSA: dmaengine_pcm: terminate dmaengine before synchronize

to the 5.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     alsa-dmaengine_pcm-terminate-dmaengine-before-synchr.patch
and it can be found in the queue-5.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit caeed97d1f2c6506eaa5ac22aaf2895857cd0e4c
Author: Shengjiu Wang <shengjiu.wang@xxxxxxx>
Date:   Thu Jun 20 10:40:18 2024 +0800

    ALSA: dmaengine_pcm: terminate dmaengine before synchronize
    
    [ Upstream commit 6a7db25aad8ce6512b366d2ce1d0e60bac00a09d ]
    
    When dmaengine supports pause function, in suspend state,
    dmaengine_pause() is called instead of dmaengine_terminate_async(),
    
    In end of playback stream, the runtime->state will go to
    SNDRV_PCM_STATE_DRAINING, if system suspend & resume happen
    at this time, application will not resume playback stream, the
    stream will be closed directly, the dmaengine_terminate_async()
    will not be called before the dmaengine_synchronize(), which
    violates the call sequence for dmaengine_synchronize().
    
    This behavior also happens for capture streams, but there is no
    SNDRV_PCM_STATE_DRAINING state for capture. So use
    dmaengine_tx_status() to check the DMA status if the status is
    DMA_PAUSED, then call dmaengine_terminate_async() to terminate
    dmaengine before dmaengine_synchronize().
    
    Signed-off-by: Shengjiu Wang <shengjiu.wang@xxxxxxx>
    Link: https://patch.msgid.link/1718851218-27803-1-git-send-email-shengjiu.wang@xxxxxxx
    Signed-off-by: Takashi Iwai <tiwai@xxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/sound/core/pcm_dmaengine.c b/sound/core/pcm_dmaengine.c
index 5d9a24ca6f3ec..6c0d0a43baa11 100644
--- a/sound/core/pcm_dmaengine.c
+++ b/sound/core/pcm_dmaengine.c
@@ -345,6 +345,12 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_open_request_chan);
 int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream)
 {
 	struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
+	struct dma_tx_state state;
+	enum dma_status status;
+
+	status = dmaengine_tx_status(prtd->dma_chan, prtd->cookie, &state);
+	if (status == DMA_PAUSED)
+		dmaengine_terminate_async(prtd->dma_chan);
 
 	dmaengine_synchronize(prtd->dma_chan);
 	kfree(prtd);
@@ -362,6 +368,12 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_close);
 int snd_dmaengine_pcm_close_release_chan(struct snd_pcm_substream *substream)
 {
 	struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
+	struct dma_tx_state state;
+	enum dma_status status;
+
+	status = dmaengine_tx_status(prtd->dma_chan, prtd->cookie, &state);
+	if (status == DMA_PAUSED)
+		dmaengine_terminate_async(prtd->dma_chan);
 
 	dmaengine_synchronize(prtd->dma_chan);
 	dma_release_channel(prtd->dma_chan);




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux