Skip to content

Commit 654e07b

Browse files
povikjannau
authored andcommitted
ALSA: Support nonatomic dmaengine PCMs
*** possible v6.11 conflict: _snd_dmaengine_pcm_close Signed-off-by: Martin Povišer <povik+lin@cutebit.org>
1 parent 65b5d83 commit 654e07b

1 file changed

Lines changed: 28 additions & 1 deletion

File tree

sound/core/pcm_dmaengine.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
struct dmaengine_pcm_runtime_data {
2323
struct dma_chan *dma_chan;
2424
dma_cookie_t cookie;
25+
struct work_struct complete_wq; /* for nonatomic PCM */
26+
struct snd_pcm_substream *substream;
2527

2628
unsigned int pos;
2729
};
@@ -145,6 +147,21 @@ static void dmaengine_pcm_dma_complete(void *arg)
145147
snd_pcm_period_elapsed(substream);
146148
}
147149

150+
static void dmaengine_pcm_dma_complete_nonatomic(struct work_struct *wq)
151+
{
152+
struct dmaengine_pcm_runtime_data *prtd = \
153+
container_of(wq, struct dmaengine_pcm_runtime_data, complete_wq);
154+
struct snd_pcm_substream *substream = prtd->substream;
155+
dmaengine_pcm_dma_complete(substream);
156+
}
157+
158+
static void dmaengine_pcm_dma_complete_nonatomic_callback(void *arg)
159+
{
160+
struct snd_pcm_substream *substream = arg;
161+
struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
162+
schedule_work(&prtd->complete_wq);
163+
}
164+
148165
static int dmaengine_pcm_prepare_and_submit(struct snd_pcm_substream *substream)
149166
{
150167
struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
@@ -167,7 +184,11 @@ static int dmaengine_pcm_prepare_and_submit(struct snd_pcm_substream *substream)
167184
if (!desc)
168185
return -ENOMEM;
169186

170-
desc->callback = dmaengine_pcm_dma_complete;
187+
if (substream->pcm->nonatomic)
188+
desc->callback = dmaengine_pcm_dma_complete_nonatomic_callback;
189+
else
190+
desc->callback = dmaengine_pcm_dma_complete;
191+
171192
desc->callback_param = substream;
172193
prtd->cookie = dmaengine_submit(desc);
173194

@@ -320,6 +341,10 @@ int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream,
320341
if (!prtd)
321342
return -ENOMEM;
322343

344+
if (substream->pcm->nonatomic)
345+
INIT_WORK(&prtd->complete_wq, dmaengine_pcm_dma_complete_nonatomic);
346+
347+
prtd->substream = substream;
323348
prtd->dma_chan = chan;
324349

325350
substream->runtime->private_data = prtd;
@@ -380,6 +405,8 @@ static void __snd_dmaengine_pcm_close(struct snd_pcm_substream *substream,
380405
*/
381406
dmaengine_terminate_async(prtd->dma_chan);
382407
dmaengine_synchronize(prtd->dma_chan);
408+
if (substream->pcm->nonatomic)
409+
flush_work(&prtd->complete_wq);
383410
if (release_channel)
384411
dma_release_channel(prtd->dma_chan);
385412
kfree(prtd);

0 commit comments

Comments
 (0)