Skip to content

Commit

Permalink
ALSA: Support nonatomic dmaengine PCMs
Browse files Browse the repository at this point in the history
*** possible v6.11 conflict: _snd_dmaengine_pcm_close

Signed-off-by: Martin Povišer <[email protected]>
  • Loading branch information
povik authored and herrnst committed Nov 23, 2024
1 parent 446ca72 commit ecb72fb
Showing 1 changed file with 28 additions and 1 deletion.
29 changes: 28 additions & 1 deletion sound/core/pcm_dmaengine.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
struct dmaengine_pcm_runtime_data {
struct dma_chan *dma_chan;
dma_cookie_t cookie;
struct work_struct complete_wq; /* for nonatomic PCM */
struct snd_pcm_substream *substream;

unsigned int pos;
};
Expand Down Expand Up @@ -145,6 +147,21 @@ static void dmaengine_pcm_dma_complete(void *arg)
snd_pcm_period_elapsed(substream);
}

static void dmaengine_pcm_dma_complete_nonatomic(struct work_struct *wq)
{
struct dmaengine_pcm_runtime_data *prtd = \
container_of(wq, struct dmaengine_pcm_runtime_data, complete_wq);
struct snd_pcm_substream *substream = prtd->substream;
dmaengine_pcm_dma_complete(substream);
}

static void dmaengine_pcm_dma_complete_nonatomic_callback(void *arg)
{
struct snd_pcm_substream *substream = arg;
struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
schedule_work(&prtd->complete_wq);
}

static int dmaengine_pcm_prepare_and_submit(struct snd_pcm_substream *substream)
{
struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
Expand All @@ -167,7 +184,11 @@ static int dmaengine_pcm_prepare_and_submit(struct snd_pcm_substream *substream)
if (!desc)
return -ENOMEM;

desc->callback = dmaengine_pcm_dma_complete;
if (substream->pcm->nonatomic)
desc->callback = dmaengine_pcm_dma_complete_nonatomic_callback;
else
desc->callback = dmaengine_pcm_dma_complete;

desc->callback_param = substream;
prtd->cookie = dmaengine_submit(desc);

Expand Down Expand Up @@ -320,6 +341,10 @@ int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream,
if (!prtd)
return -ENOMEM;

if (substream->pcm->nonatomic)
INIT_WORK(&prtd->complete_wq, dmaengine_pcm_dma_complete_nonatomic);

prtd->substream = substream;
prtd->dma_chan = chan;

substream->runtime->private_data = prtd;
Expand Down Expand Up @@ -380,6 +405,8 @@ static void __snd_dmaengine_pcm_close(struct snd_pcm_substream *substream,
*/
dmaengine_terminate_async(prtd->dma_chan);
dmaengine_synchronize(prtd->dma_chan);
if (substream->pcm->nonatomic)
flush_work(&prtd->complete_wq);
if (release_channel)
dma_release_channel(prtd->dma_chan);
kfree(prtd);
Expand Down

0 comments on commit ecb72fb

Please sign in to comment.