summaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2012-02-22 10:49:07 +0100
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-02-22 13:21:49 +0000
commit95a771ca16ad63cfd665bebadbc543857db6fa4e (patch)
tree1d7b2eb1d8f02a3528dd47619bc8436b001e7a3a /sound/soc
parent4564d10f3066a1abf5053936684e2c8495163def (diff)
downloadlinux-95a771ca16ad63cfd665bebadbc543857db6fa4e.tar.bz2
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: Lars-Peter Clausen <lars@metafoo.de> Tested-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/mxs/mxs-pcm.c28
1 files changed, 8 insertions, 20 deletions
diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c
index 06c18ecffbb4..5b8c8d314060 100644
--- a/sound/soc/mxs/mxs-pcm.c
+++ b/sound/soc/mxs/mxs-pcm.c
@@ -85,8 +85,7 @@ static bool filter(struct dma_chan *chan, void *param)
return true;
}
-static int mxs_dma_alloc(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
+static int mxs_dma_alloc(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_pcm_runtime *runtime = substream->runtime;
@@ -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;
unsigned long dma_addr;
struct dma_chan *chan;
- int ret;
- ret = mxs_dma_alloc(substream, params);
- if (ret)
- return ret;
chan = iprtd->dma_chan;
iprtd->periods = params_periods(params);
@@ -143,19 +138,6 @@ static int snd_mxs_pcm_hw_params(struct snd_pcm_substream *substream,
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)
{
struct snd_pcm_runtime *runtime = substream->runtime;
@@ -208,6 +190,12 @@ static int snd_mxs_open(struct snd_pcm_substream *substream)
return ret;
}
+ ret = mxs_dma_alloc(substream);
+ if (ret) {
+ kfree(iprtd);
+ return ret;
+ }
+
snd_soc_set_runtime_hwparams(substream, &snd_mxs_hardware);
return 0;
@@ -218,6 +206,7 @@ static int snd_mxs_close(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
+ dma_release_channel(iprtd->dma_chan);
kfree(iprtd);
return 0;
@@ -239,7 +228,6 @@ static struct snd_pcm_ops mxs_pcm_ops = {
.close = snd_mxs_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_mxs_pcm_hw_params,
- .hw_free = snd_mxs_pcm_hw_free,
.trigger = snd_mxs_pcm_trigger,
.pointer = snd_mxs_pcm_pointer,
.mmap = snd_mxs_pcm_mmap,