提交 95a771ca 编写于 作者: L Lars-Peter Clausen 提交者: Mark Brown

ASoC: mxs-pcm: Request DMA channel early

Request the DMA channel in the PCM open callback instead of the hwparams
callback, this allows us to let open fail if no dma channel is available. This
also fixes a bug where the channel will be requested multiple times if hwparams
is called multiple times.
Signed-off-by: NLars-Peter Clausen <lars@metafoo.de>
Tested-by: NShawn Guo <shawn.guo@linaro.org>
Signed-off-by: NMark Brown <broonie@opensource.wolfsonmicro.com>
上级 4564d10f
...@@ -85,8 +85,7 @@ static bool filter(struct dma_chan *chan, void *param) ...@@ -85,8 +85,7 @@ static bool filter(struct dma_chan *chan, void *param)
return true; return true;
} }
static int mxs_dma_alloc(struct snd_pcm_substream *substream, static int mxs_dma_alloc(struct snd_pcm_substream *substream)
struct snd_pcm_hw_params *params)
{ {
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
...@@ -112,11 +111,7 @@ static int snd_mxs_pcm_hw_params(struct snd_pcm_substream *substream, ...@@ -112,11 +111,7 @@ static int snd_mxs_pcm_hw_params(struct snd_pcm_substream *substream,
struct mxs_pcm_runtime_data *iprtd = runtime->private_data; struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
unsigned long dma_addr; unsigned long dma_addr;
struct dma_chan *chan; struct dma_chan *chan;
int ret;
ret = mxs_dma_alloc(substream, params);
if (ret)
return ret;
chan = iprtd->dma_chan; chan = iprtd->dma_chan;
iprtd->periods = params_periods(params); iprtd->periods = params_periods(params);
...@@ -143,19 +138,6 @@ static int snd_mxs_pcm_hw_params(struct snd_pcm_substream *substream, ...@@ -143,19 +138,6 @@ static int snd_mxs_pcm_hw_params(struct snd_pcm_substream *substream,
return 0; return 0;
} }
static int snd_mxs_pcm_hw_free(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
if (iprtd->dma_chan) {
dma_release_channel(iprtd->dma_chan);
iprtd->dma_chan = NULL;
}
return 0;
}
static int snd_mxs_pcm_trigger(struct snd_pcm_substream *substream, int cmd) static int snd_mxs_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
...@@ -208,6 +190,12 @@ static int snd_mxs_open(struct snd_pcm_substream *substream) ...@@ -208,6 +190,12 @@ static int snd_mxs_open(struct snd_pcm_substream *substream)
return ret; return ret;
} }
ret = mxs_dma_alloc(substream);
if (ret) {
kfree(iprtd);
return ret;
}
snd_soc_set_runtime_hwparams(substream, &snd_mxs_hardware); snd_soc_set_runtime_hwparams(substream, &snd_mxs_hardware);
return 0; return 0;
...@@ -218,6 +206,7 @@ static int snd_mxs_close(struct snd_pcm_substream *substream) ...@@ -218,6 +206,7 @@ static int snd_mxs_close(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
struct mxs_pcm_runtime_data *iprtd = runtime->private_data; struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
dma_release_channel(iprtd->dma_chan);
kfree(iprtd); kfree(iprtd);
return 0; return 0;
...@@ -239,7 +228,6 @@ static struct snd_pcm_ops mxs_pcm_ops = { ...@@ -239,7 +228,6 @@ static struct snd_pcm_ops mxs_pcm_ops = {
.close = snd_mxs_close, .close = snd_mxs_close,
.ioctl = snd_pcm_lib_ioctl, .ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_mxs_pcm_hw_params, .hw_params = snd_mxs_pcm_hw_params,
.hw_free = snd_mxs_pcm_hw_free,
.trigger = snd_mxs_pcm_trigger, .trigger = snd_mxs_pcm_trigger,
.pointer = snd_mxs_pcm_pointer, .pointer = snd_mxs_pcm_pointer,
.mmap = snd_mxs_pcm_mmap, .mmap = snd_mxs_pcm_mmap,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册