summaryrefslogtreecommitdiffstats
path: root/sound/soc/sof
diff options
context:
space:
mode:
authorRanjani Sridharan <ranjani.sridharan@linux.intel.com>2019-06-12 12:23:37 -0500
committerMark Brown <broonie@kernel.org>2019-06-17 13:43:22 +0100
commit6b2239e3337b4c46b850078a6fc8f1a70ebe1c1f (patch)
tree773c2d06381effbb14e680fdb94f56774ddef4f3 /sound/soc/sof
parentbdf4ad3fd01f5dc53c5d6d3b17afc98cd76d8988 (diff)
downloadlinux-stable-6b2239e3337b4c46b850078a6fc8f1a70ebe1c1f.tar.gz
linux-stable-6b2239e3337b4c46b850078a6fc8f1a70ebe1c1f.tar.bz2
linux-stable-6b2239e3337b4c46b850078a6fc8f1a70ebe1c1f.zip
ASoC: SOF: Intel: hda: reserve host DMA channel for hostless streams
Due to the HW programming sequence requirement that the host and link DMA channels need to be coupled/decoupled during pcm hw_params, the host DMA channel corresponding to the link DMA channel in use for hostless streams needs to be reserved. This is achieved by adding a host_reserved flag in the sof_intel_hda_stream structure which is checked when assigning a host DMA channel. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/sof')
-rw-r--r--sound/soc/sof/intel/hda-dai.c11
-rw-r--r--sound/soc/sof/intel/hda-stream.c10
-rw-r--r--sound/soc/sof/intel/hda.h1
3 files changed, 20 insertions, 2 deletions
diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c
index c270fd7a0878..a514f9cf5c9a 100644
--- a/sound/soc/sof/intel/hda-dai.c
+++ b/sound/soc/sof/intel/hda-dai.c
@@ -75,7 +75,7 @@ static struct hdac_ext_stream *
hda_stream = hstream_to_sof_hda_stream(hstream);
- /* check if available */
+ /* check if link is available */
if (!hstream->link_locked) {
if (stream->opened) {
/*
@@ -89,6 +89,12 @@ static struct hdac_ext_stream *
}
} else {
res = hstream;
+
+ /*
+ * This must be a hostless stream.
+ * So reserve the host DMA channel.
+ */
+ hda_stream->host_reserved = 1;
break;
}
}
@@ -368,6 +374,9 @@ static int hda_link_hw_free(struct snd_pcm_substream *substream,
snd_hdac_ext_stream_release(link_dev, HDAC_EXT_STREAM_TYPE_LINK);
link_dev->link_prepared = 0;
+ /* free the host DMA channel reserved by hostless streams */
+ hda_stream->host_reserved = 0;
+
return 0;
}
diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c
index 1cd94e7631a8..a3f7c91469ec 100644
--- a/sound/soc/sof/intel/hda-stream.c
+++ b/sound/soc/sof/intel/hda-stream.c
@@ -155,6 +155,7 @@ struct hdac_ext_stream *
hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction)
{
struct hdac_bus *bus = sof_to_bus(sdev);
+ struct sof_intel_hda_stream *hda_stream;
struct hdac_ext_stream *stream = NULL;
struct hdac_stream *s;
@@ -163,8 +164,15 @@ hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction)
/* get an unused stream */
list_for_each_entry(s, &bus->stream_list, list) {
if (s->direction == direction && !s->opened) {
- s->opened = true;
stream = stream_to_hdac_ext_stream(s);
+ hda_stream = container_of(stream,
+ struct sof_intel_hda_stream,
+ hda_stream);
+ /* check if the host DMA channel is reserved */
+ if (hda_stream->host_reserved)
+ continue;
+
+ s->opened = true;
break;
}
}
diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h
index 376b1ca51e2b..2862b4b3b07c 100644
--- a/sound/soc/sof/intel/hda.h
+++ b/sound/soc/sof/intel/hda.h
@@ -413,6 +413,7 @@ struct sof_intel_hda_stream {
struct hdac_ext_stream hda_stream;
struct sof_intel_stream stream;
int hw_params_upon_resume; /* set up hw_params upon resume */
+ int host_reserved; /* reserve host DMA channel */
};
#define hstream_to_sof_hda_stream(hstream) \