hda_stream = hstream_to_sof_hda_stream(hstream);
- /* check if available */
+ /* check if link is available */
if (!hstream->link_locked) {
if (stream->opened) {
/*
}
} else {
res = hstream;
+
+ /*
+ * This must be a hostless stream.
+ * So reserve the host DMA channel.
+ */
+ hda_stream->host_reserved = 1;
break;
}
}
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;
}
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;
/* 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;
}
}
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) \