]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ASoC: SOF: Intel: add hda_dsp_stream_pair_get/put helpers
authorBard Liao <yung-chuan.liao@linux.intel.com>
Tue, 3 Feb 2026 11:40:25 +0000 (19:40 +0800)
committerMark Brown <broonie@kernel.org>
Tue, 3 Feb 2026 13:47:19 +0000 (13:47 +0000)
Currently, hda_dsp_stream_get/put are used to get/put the host dma.
However, we may want to use a hda stream that both host and link dma are
available. Add helper to find the hda stream and reserve/release it.

Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>
Link: https://patch.msgid.link/20260203114027.3742558-2-yung-chuan.liao@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sof/intel/hda-stream.c
sound/soc/sof/intel/hda.h

index 8fdaf1fdc338d74558e3ce432ba2b7f2b5723dde..36b647d987fc75ff3e0e6213ec9f2cc7af96f5cc 100644 (file)
@@ -210,8 +210,8 @@ int hda_dsp_stream_spib_config(struct snd_sof_dev *sdev,
 }
 
 /* get next unused stream */
-struct hdac_ext_stream *
-hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction, u32 flags)
+static struct hdac_ext_stream *
+_hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction, u32 flags, bool pair)
 {
        const struct sof_intel_dsp_desc *chip_info =  get_chip_info(sdev->pdata);
        struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
@@ -233,7 +233,14 @@ hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction, u32 flags)
                        if (hda_stream->host_reserved)
                                continue;
 
+                       if (pair && hext_stream->link_locked)
+                               continue;
+
                        s->opened = true;
+
+                       if (pair)
+                               hext_stream->link_locked = true;
+
                        break;
                }
        }
@@ -264,14 +271,27 @@ hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction, u32 flags)
        return hext_stream;
 }
 
+struct hdac_ext_stream *
+hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction, u32 flags)
+{
+       return _hda_dsp_stream_get(sdev, direction, flags, false);
+}
+
+struct hdac_ext_stream *
+hda_dsp_stream_pair_get(struct snd_sof_dev *sdev, int direction, u32 flags)
+{
+       return _hda_dsp_stream_get(sdev, direction, flags, true);
+}
+
 /* free a stream */
-int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag)
+static int _hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag, bool pair)
 {
        const struct sof_intel_dsp_desc *chip_info =  get_chip_info(sdev->pdata);
        struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
        struct hdac_bus *bus = sof_to_bus(sdev);
        struct sof_intel_hda_stream *hda_stream;
        struct hdac_ext_stream *hext_stream;
+       struct hdac_ext_stream *link_stream;
        struct hdac_stream *s;
        bool dmi_l1_enable = true;
        bool found = false;
@@ -292,6 +312,8 @@ int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag)
                if (s->direction == direction && s->stream_tag == stream_tag) {
                        s->opened = false;
                        found = true;
+                       if (pair)
+                               link_stream = hext_stream;
                } else if (!(hda_stream->flags & SOF_HDA_STREAM_DMI_L1_COMPATIBLE)) {
                        dmi_l1_enable = false;
                }
@@ -312,9 +334,22 @@ int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag)
                return -ENODEV;
        }
 
+       if (pair)
+               snd_hdac_ext_stream_release(link_stream, HDAC_EXT_STREAM_TYPE_LINK);
+
        return 0;
 }
 
+int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag)
+{
+       return _hda_dsp_stream_put(sdev, direction, stream_tag, false);
+}
+
+int hda_dsp_stream_pair_put(struct snd_sof_dev *sdev, int direction, int stream_tag)
+{
+       return _hda_dsp_stream_put(sdev, direction, stream_tag, true);
+}
+
 static int hda_dsp_stream_reset(struct snd_sof_dev *sdev, struct hdac_stream *hstream)
 {
        int sd_offset = SOF_STREAM_SD_OFFSET(hstream);
index 3be39c229c9f84be00a102bd9133d8f89103e503..9234e73f30fbd6a1a9338542fa892317eb8d4817 100644 (file)
@@ -694,7 +694,10 @@ u64 hda_dsp_get_stream_ldp(struct snd_sof_dev *sdev,
 
 struct hdac_ext_stream *
        hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction, u32 flags);
+struct hdac_ext_stream *
+       hda_dsp_stream_pair_get(struct snd_sof_dev *sdev, int direction, u32 flags);
 int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag);
+int hda_dsp_stream_pair_put(struct snd_sof_dev *sdev, int direction, int stream_tag);
 int hda_dsp_stream_spib_config(struct snd_sof_dev *sdev,
                               struct hdac_ext_stream *hext_stream,
                               int enable, u32 size);