Skip to content

Commit e5e3448

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 ac9b05c commit e5e3448

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
};
@@ -147,6 +149,21 @@ static void dmaengine_pcm_dma_complete(void *arg)
147149
snd_pcm_period_elapsed(substream);
148150
}
149151

152+
static void dmaengine_pcm_dma_complete_nonatomic(struct work_struct *wq)
153+
{
154+
struct dmaengine_pcm_runtime_data *prtd = \
155+
container_of(wq, struct dmaengine_pcm_runtime_data, complete_wq);
156+
struct snd_pcm_substream *substream = prtd->substream;
157+
dmaengine_pcm_dma_complete(substream);
158+
}
159+
160+
static void dmaengine_pcm_dma_complete_nonatomic_callback(void *arg)
161+
{
162+
struct snd_pcm_substream *substream = arg;
163+
struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
164+
schedule_work(&prtd->complete_wq);
165+
}
166+
150167
static int dmaengine_pcm_prepare_and_submit(struct snd_pcm_substream *substream)
151168
{
152169
struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
@@ -169,7 +186,11 @@ static int dmaengine_pcm_prepare_and_submit(struct snd_pcm_substream *substream)
169186
if (!desc)
170187
return -ENOMEM;
171188

172-
desc->callback = dmaengine_pcm_dma_complete;
189+
if (substream->pcm->nonatomic)
190+
desc->callback = dmaengine_pcm_dma_complete_nonatomic_callback;
191+
else
192+
desc->callback = dmaengine_pcm_dma_complete;
193+
173194
desc->callback_param = substream;
174195
prtd->cookie = dmaengine_submit(desc);
175196

@@ -322,6 +343,10 @@ int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream,
322343
if (!prtd)
323344
return -ENOMEM;
324345

346+
if (substream->pcm->nonatomic)
347+
INIT_WORK(&prtd->complete_wq, dmaengine_pcm_dma_complete_nonatomic);
348+
349+
prtd->substream = substream;
325350
prtd->dma_chan = chan;
326351

327352
substream->runtime->private_data = prtd;
@@ -361,6 +386,8 @@ static void __snd_dmaengine_pcm_close(struct snd_pcm_substream *substream,
361386
*/
362387
dmaengine_terminate_async(prtd->dma_chan);
363388
dmaengine_synchronize(prtd->dma_chan);
389+
if (substream->pcm->nonatomic)
390+
flush_work(&prtd->complete_wq);
364391
if (release_channel)
365392
dma_release_channel(prtd->dma_chan);
366393
kfree(prtd);

0 commit comments

Comments
 (0)