summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorRavindra Lokhande <rlokhande@nvidia.com>2014-05-06 19:33:11 +0530
committerRiham Haidar <rhaidar@nvidia.com>2014-05-14 15:28:13 -0700
commit6a3202ea03cba8b987a77ed4ec0010121c01dc03 (patch)
treee5e0ec0fc36db559435dcb74ef700747cd6af436 /sound
parentd1f1668ee6c4d12348caefda6504c5c5663c6f0c (diff)
ASoC: Tegra: Fix concurrent pcm and compress playback
- Added path between BE and codec stream - use atomic reference count Bug 1495249 Change-Id: I895d22e1854c53f41362ed2a1cff63d88feb397b Signed-off-by: Ravindra Lokhande <rlokhande@nvidia.com> Reviewed-on: http://git-master/r/405859 Reviewed-by: Riham Haidar <rhaidar@nvidia.com> Tested-by: Riham Haidar <rhaidar@nvidia.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/tegra/tegra30_avp.c61
-rw-r--r--sound/soc/tegra/tegra_offload.c12
-rw-r--r--sound/soc/tegra/tegra_rt5639.c6
3 files changed, 38 insertions, 41 deletions
diff --git a/sound/soc/tegra/tegra30_avp.c b/sound/soc/tegra/tegra30_avp.c
index e15b66bcff24..f18952dd714a 100644
--- a/sound/soc/tegra/tegra30_avp.c
+++ b/sound/soc/tegra/tegra30_avp.c
@@ -105,8 +105,8 @@ struct tegra30_avp_audio_dma {
struct dma_slave_config chan_slave_config;
dma_cookie_t chan_cookie;
- int use_count;
- int active_count;
+ atomic_t is_dma_allocated;
+ atomic_t active_count;
};
struct tegra30_avp_stream {
@@ -141,7 +141,7 @@ struct tegra30_avp_audio {
unsigned int *cmd_buf;
int cmd_buf_idx;
- int stream_active_count;
+ atomic_t stream_active_count;
struct tegra30_avp_audio_dma audio_dma;
spinlock_t lock;
};
@@ -438,11 +438,10 @@ static int tegra30_avp_audio_alloc_dma(struct tegra_offload_dma_params *params)
dma_cap_mask_t mask;
int ret = 0;
- dev_vdbg(audio_avp->dev, "%s : use %d",
- __func__, dma->use_count);
+ dev_vdbg(audio_avp->dev, "%s: is_dma_allocated %d",
+ __func__, atomic_read(&dma->is_dma_allocated));
- dma->use_count++;
- if (dma->use_count > 1)
+ if (atomic_read(&dma->is_dma_allocated) == 1)
return 0;
memcpy(&dma->params, params, sizeof(struct tegra_offload_dma_params));
@@ -469,6 +468,8 @@ static int tegra30_avp_audio_alloc_dma(struct tegra_offload_dma_params *params)
return ret;
}
audio_engine->apb_channel_handle = dma->chan->chan_id;
+ atomic_set(&dma->is_dma_allocated, 1);
+
return 0;
}
@@ -477,17 +478,15 @@ static void tegra30_avp_audio_free_dma(void)
struct tegra30_avp_audio *audio_avp = avp_audio_ctx;
struct tegra30_avp_audio_dma *dma = &audio_avp->audio_dma;
- dev_vdbg(audio_avp->dev, "%s : use %d",
- __func__, dma->use_count);
-
- if (dma->use_count <= 0)
- return;
+ dev_vdbg(audio_avp->dev, "%s: is_dma_allocated %d",
+ __func__, atomic_read(&dma->is_dma_allocated));
- dma->use_count--;
- if (dma->use_count)
- return;
+ if (atomic_read(&dma->is_dma_allocated) == 1) {
+ dma_release_channel(dma->chan);
+ atomic_set(&dma->is_dma_allocated, 0);
+ }
- dma_release_channel(dma->chan);
+ return;
}
static int tegra30_avp_audio_start_dma(void)
@@ -496,10 +495,10 @@ static int tegra30_avp_audio_start_dma(void)
struct tegra30_avp_audio_dma *dma = &audio_avp->audio_dma;
struct audio_engine_data *audio_engine = audio_avp->audio_engine;
- dev_vdbg(audio_avp->dev, "%s: active %d.", __func__, dma->active_count);
+ dev_vdbg(audio_avp->dev, "%s: active %d", __func__,
+ atomic_read(&dma->active_count));
- dma->active_count++;
- if (dma->active_count > 1)
+ if (atomic_inc_return(&dma->active_count) > 1)
return 0;
dma->chan_desc = dmaengine_prep_dma_cyclic(dma->chan,
@@ -522,14 +521,12 @@ static int tegra30_avp_audio_stop_dma(void)
struct tegra30_avp_audio *audio_avp = avp_audio_ctx;
struct tegra30_avp_audio_dma *dma = &audio_avp->audio_dma;
- dev_vdbg(audio_avp->dev, "%s : active %d",
- __func__, dma->active_count);
+ dev_vdbg(audio_avp->dev, "%s: active %d.", __func__,
+ atomic_read(&dma->active_count));
- dma->active_count--;
- if (dma->active_count > 0)
- return 0;
+ if (atomic_dec_and_test(&dma->active_count))
+ dmaengine_terminate_all(dma->chan);
- dmaengine_terminate_all(dma->chan);
return 0;
}
@@ -765,8 +762,11 @@ static int tegra30_avp_pcm_open(int *id)
return -EBUSY;
}
- audio_avp->stream_active_count++;
+ audio_engine->stream[*id].stream_allocated = 1;
+
+ atomic_inc(&audio_avp->stream_active_count);
tegra30_avp_audio_set_state(KSSTATE_RUN);
+
return 0;
}
@@ -917,8 +917,9 @@ static int tegra30_avp_compr_open(int *id)
}
audio_avp->avp_stream[*id].is_drain_called = 0;
- audio_avp->stream_active_count++;
+ atomic_inc(&audio_avp->stream_active_count);
tegra30_avp_audio_set_state(KSSTATE_RUN);
+
return 0;
}
@@ -1255,13 +1256,13 @@ static void tegra30_avp_stream_close(int id)
return;
}
tegra30_avp_mem_free(&avp_stream->source_buf);
- tegra30_avp_audio_free_dma();
stream->stream_allocated = 0;
tegra30_avp_stream_set_state(id, KSSTATE_STOP);
- audio_avp->stream_active_count--;
- if (!(audio_avp->stream_active_count))
+ if (atomic_dec_and_test(&audio_avp->stream_active_count)) {
+ tegra30_avp_audio_free_dma();
tegra30_avp_audio_set_state(KSSTATE_STOP);
+ }
}
static struct tegra_offload_ops avp_audio_platform = {
diff --git a/sound/soc/tegra/tegra_offload.c b/sound/soc/tegra/tegra_offload.c
index 3940f42c44ea..fbe766e4342c 100644
--- a/sound/soc/tegra/tegra_offload.c
+++ b/sound/soc/tegra/tegra_offload.c
@@ -416,7 +416,7 @@ static int tegra_offload_pcm_open(struct snd_pcm_substream *substream)
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data) {
- dev_vdbg(dev, "Failed to allocate tegra_offload_pcm_data.");
+ dev_err(dev, "Failed to allocate tegra_offload_pcm_data.");
return -ENOMEM;
}
@@ -579,12 +579,6 @@ static int tegra_offload_pcm_ack(struct snd_pcm_substream *substream)
static const struct snd_soc_dapm_widget tegra_offload_widgets[] = {
- /* FrontEnd DAIs */
- SND_SOC_DAPM_AIF_IN("offload-pcm-playback", "pcm-playback", 0,
- 0/*wreg*/, 0/*wshift*/, 0/*winvert*/),
- SND_SOC_DAPM_AIF_IN("offload-compr-playback", "compr-playback", 0,
- 0/*wreg*/, 0/*wshift*/, 0/*winvert*/),
-
/* BackEnd DAIs */
SND_SOC_DAPM_AIF_OUT("I2S0_OUT", "tegra30-i2s.0 Playback", 0,
0/*wreg*/, 0/*wshift*/, 0/*winvert*/),
@@ -718,7 +712,7 @@ static struct snd_soc_dai_driver tegra_offload_dai[] = {
.name = "tegra-offload-pcm",
.id = 0,
.playback = {
- .stream_name = "pcm-playback",
+ .stream_name = "offload-pcm-playback",
.channels_min = 2,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
@@ -730,7 +724,7 @@ static struct snd_soc_dai_driver tegra_offload_dai[] = {
.id = 0,
.compress_dai = 1,
.playback = {
- .stream_name = "compr-playback",
+ .stream_name = "offload-compr-playback",
.channels_min = 2,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
diff --git a/sound/soc/tegra/tegra_rt5639.c b/sound/soc/tegra/tegra_rt5639.c
index 0493b2987862..ae16793491f5 100644
--- a/sound/soc/tegra/tegra_rt5639.c
+++ b/sound/soc/tegra/tegra_rt5639.c
@@ -928,10 +928,10 @@ static const struct snd_soc_dapm_route ardbeg_audio_map[] = {
/*{"IN1P", NULL, "micbias1"},*/
/*{"IN1N", NULL, "micbias1"},*/
/* AHUB BE connections */
- {"tegra30-i2s.1 Playback", NULL, "I2S1_OUT"},
-
{"I2S1_OUT", NULL, "offload-pcm-playback"},
{"I2S1_OUT", NULL, "offload-compr-playback"},
+
+ {"AIF1 Playback", NULL, "I2S1_OUT"},
};
@@ -1072,6 +1072,8 @@ static struct snd_soc_dai_link tegra_rt5639_dai[NUM_DAI_LINKS] = {
.cpu_dai_name = "tegra30-i2s.1",
.codec_dai_name = "rt5639-aif1",
.ops = &tegra_rt5639_ops,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
.no_pcm = 1,