diff --git a/include/sound/dmaengine_pcm.h b/include/sound/dmaengine_pcm.h
index 8c5e38180fb0..9fae56d39ae2 100644
--- a/include/sound/dmaengine_pcm.h
+++ b/include/sound/dmaengine_pcm.h
@@ -28,6 +28,9 @@ snd_pcm_substream_to_dma_direction(const struct snd_pcm_substream *substream)
 int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream,
 	const struct snd_pcm_hw_params *params, struct dma_slave_config *slave_config);
 int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd);
+int snd_dmaengine_pcm_custom_trigger(struct snd_pcm_substream *substream, int cmd,
+	int (*custom_pcm_prepare_and_submit)(struct snd_pcm_substream *substream));
+
 snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream);
 snd_pcm_uframes_t snd_dmaengine_pcm_pointer_no_residue(struct snd_pcm_substream *substream);
 
@@ -113,6 +116,8 @@ int snd_dmaengine_pcm_refine_runtime_hwparams(
  *   which do not use devicetree.
  * @process: Callback used to apply processing on samples transferred from/to
  *   user space.
+ * @custom_pcm_prepare_and_submit: Callback used to work-around DMA limitations
+ *   related to link lists.
  * @compat_filter_fn: Will be used as the filter function when requesting a
  *  channel for platforms which do not use devicetree. The filter parameter
  *  will be the DAI's DMA data.
@@ -138,6 +143,7 @@ struct snd_dmaengine_pcm_config {
 	int (*process)(struct snd_pcm_substream *substream,
 		       int channel, unsigned long hwoff,
 		       void *buf, unsigned long bytes);
+	int (*custom_pcm_prepare_and_submit)(struct snd_pcm_substream *substream);
 	dma_filter_fn compat_filter_fn;
 	struct device *dma_dev;
 	const char *chan_names[SNDRV_PCM_STREAM_LAST + 1];
diff --git a/sound/core/pcm_dmaengine.c b/sound/core/pcm_dmaengine.c
index 4d059ff2b2e4..cbd1429de509 100644
--- a/sound/core/pcm_dmaengine.c
+++ b/sound/core/pcm_dmaengine.c
@@ -170,16 +170,20 @@ static int dmaengine_pcm_prepare_and_submit(struct snd_pcm_substream *substream)
 }
 
 /**
- * snd_dmaengine_pcm_trigger - dmaengine based PCM trigger implementation
+ * snd_dmaengine_pcm_custom_trigger - customized PCM trigger implementation to
+ *  work-around DMA limitations related to link lists.
  * @substream: PCM substream
  * @cmd: Trigger command
+ * @custom_pcm_prepare_and_submit: custom function to deal with DMA limitations
  *
  * Returns 0 on success, a negative error code otherwise.
  *
- * This function can be used as the PCM trigger callback for dmaengine based PCM
- * driver implementations.
+ * This function can be used as the PCM trigger callback for customized dmaengine
+ * based PCM driver implementations.
  */
-int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+
+int snd_dmaengine_pcm_custom_trigger(struct snd_pcm_substream *substream, int cmd,
+	int (*custom_pcm_prepare_and_submit)(struct snd_pcm_substream *substream))
 {
 	struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
 	struct snd_pcm_runtime *runtime = substream->runtime;
@@ -187,7 +191,7 @@ int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
-		ret = dmaengine_pcm_prepare_and_submit(substream);
+		ret = custom_pcm_prepare_and_submit(substream);
 		if (ret)
 			return ret;
 		dma_async_issue_pending(prtd->dma_chan);
@@ -214,6 +218,22 @@ int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_custom_trigger);
+
+/**
+ * snd_dmaengine_pcm_trigger - dmaengine based PCM trigger implementation
+ * @substream: PCM substream
+ * @cmd: Trigger command
+ *
+ * Returns 0 on success, a negative error code otherwise.
+ *
+ * This function can be used as the PCM trigger callback for dmaengine based PCM
+ * driver implementations.
+ */
+int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+	return snd_dmaengine_pcm_custom_trigger(substream, cmd, dmaengine_pcm_prepare_and_submit);
+}
 EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_trigger);
 
 /**
diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c
index 9ef80a48707e..88fca6402a36 100644
--- a/sound/soc/soc-generic-dmaengine-pcm.c
+++ b/sound/soc/soc-generic-dmaengine-pcm.c
@@ -173,7 +173,13 @@ static int dmaengine_pcm_close(struct snd_soc_component *component,
 static int dmaengine_pcm_trigger(struct snd_soc_component *component,
 				 struct snd_pcm_substream *substream, int cmd)
 {
-	return snd_dmaengine_pcm_trigger(substream, cmd);
+	struct dmaengine_pcm *pcm = soc_component_to_pcm(component);
+
+	if (pcm->config && pcm->config->custom_pcm_prepare_and_submit)
+		return snd_dmaengine_pcm_custom_trigger(substream, cmd,
+							pcm->config->custom_pcm_prepare_and_submit);
+	else
+		return snd_dmaengine_pcm_trigger(substream, cmd);
 }
 
 static struct dma_chan *dmaengine_pcm_compat_request_channel(
