diff --git a/arch/mips/include/asm/mach-jz4740/dma.h b/arch/mips/include/asm/mach-jz4740/dma.h
index 14ecc5313d2d..ece7e39cdacb 100644
--- a/arch/mips/include/asm/mach-jz4740/dma.h
+++ b/arch/mips/include/asm/mach-jz4740/dma.h
@@ -16,6 +16,13 @@
 #ifndef __ASM_MACH_JZ4740_DMA_H__
 #define __ASM_MACH_JZ4740_DMA_H__
 
+#include <linux/dmaengine.h>
+
+static inline bool jz4740_dma_filter_fn(struct dma_chan *chan, void *filter_param)
+{
+	chan->private = filter_param;
+}
+
 enum jz4740_dma_request_type {
 	JZ4740_DMA_TYPE_AUTO_REQUEST	= 8,
 	JZ4740_DMA_TYPE_UART_TRANSMIT	= 20,
diff --git a/drivers/dma/dma-jz4740.c b/drivers/dma/dma-jz4740.c
index bdeafeefa5f6..f02e60e8e5cc 100644
--- a/drivers/dma/dma-jz4740.c
+++ b/drivers/dma/dma-jz4740.c
@@ -119,6 +119,7 @@ struct jz4740_dma_desc {
 struct jz4740_dmaengine_chan {
 	struct virt_dma_chan vchan;
 	unsigned int id;
+	unsigned int slave;
 
 	dma_addr_t fifo_addr;
 	unsigned int transfer_shift;
@@ -220,6 +221,11 @@ static int jz4740_dma_slave_config(struct dma_chan *c,
 	enum jz4740_dma_flags flags;
 	uint32_t cmd;
 
+	/* deprecated: all drivers should request the channel with
+	 * the correct slave argument */
+	if (!chan->slave)
+		chan->slave = config->slave_id;
+
 	switch (config->direction) {
 	case DMA_MEM_TO_DEV:
 		flags = JZ4740_DMA_SRC_AUTOINC;
@@ -265,8 +271,7 @@ static int jz4740_dma_slave_config(struct dma_chan *c,
 
 	jz4740_dma_write(dmadev, JZ_REG_DMA_CMD(chan->id), cmd);
 	jz4740_dma_write(dmadev, JZ_REG_DMA_STATUS_CTRL(chan->id), 0);
-	jz4740_dma_write(dmadev, JZ_REG_DMA_REQ_TYPE(chan->id),
-		config->slave_id);
+	jz4740_dma_write(dmadev, JZ_REG_DMA_REQ_TYPE(chan->id), chan->slave);
 
 	return 0;
 }
@@ -513,6 +518,8 @@ static enum dma_status jz4740_dma_tx_status(struct dma_chan *c,
 
 static int jz4740_dma_alloc_chan_resources(struct dma_chan *c)
 {
+	struct jz4740_dmaengine_chan *chan = to_jz4740_dma_chan(c);
+	chan->slave = (unsigned long)c->private;
 	return 0;
 }
 
diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c
index 76e8bce6f46e..a6680959ce83 100644
--- a/drivers/mmc/host/jz4740_mmc.c
+++ b/drivers/mmc/host/jz4740_mmc.c
@@ -178,13 +178,15 @@ static int jz4740_mmc_acquire_dma_channels(struct jz4740_mmc_host *host)
 	dma_cap_zero(mask);
 	dma_cap_set(DMA_SLAVE, mask);
 
-	host->dma_tx = dma_request_channel(mask, NULL, host);
+	host->dma_tx = dma_request_channel(mask, jz4740_dma_filter_fn,
+					   (void*)JZ4740_DMA_TYPE_MMC_TRANSMIT);
 	if (!host->dma_tx) {
 		dev_err(mmc_dev(host->mmc), "Failed to get dma_tx channel\n");
 		return -ENODEV;
 	}
 
-	host->dma_rx = dma_request_channel(mask, NULL, host);
+	host->dma_rx = dma_request_channel(mask, jz4740_dma_filter_fn,
+					   (void*)JZ4740_DMA_TYPE_MMC_RECEIVE);
 	if (!host->dma_rx) {
 		dev_err(mmc_dev(host->mmc), "Failed to get dma_rx channel\n");
 		goto free_master_write;
@@ -283,12 +285,10 @@ static int jz4740_mmc_start_dma_transfer(struct jz4740_mmc_host *host,
 	if (data->flags & MMC_DATA_WRITE) {
 		conf.direction = DMA_MEM_TO_DEV;
 		conf.dst_addr = host->mem_res->start + JZ_REG_MMC_TXFIFO;
-		conf.slave_id = JZ4740_DMA_TYPE_MMC_TRANSMIT;
 		chan = host->dma_tx;
 	} else {
 		conf.direction = DMA_DEV_TO_MEM;
 		conf.src_addr = host->mem_res->start + JZ_REG_MMC_RXFIFO;
-		conf.slave_id = JZ4740_DMA_TYPE_MMC_RECEIVE;
 		chan = host->dma_rx;
 	}
 
diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index d3d45c6f064f..7a60c075bd81 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -31,10 +31,12 @@
 #include <sound/initval.h>
 #include <sound/dmaengine_pcm.h>
 
+#include <asm/mach-jz4740/dma.h>
+
 #include "jz4740-i2s.h"
 
-#define JZ4740_DMA_TYPE_AIC_TRANSMIT 24
-#define JZ4740_DMA_TYPE_AIC_RECEIVE 25
+#define JZ4740_DMA_TYPE_AIC_TRANSMIT (void *)24ul
+#define JZ4740_DMA_TYPE_AIC_RECEIVE (void *)25ul
 
 #define JZ_REG_AIC_CONF		0x00
 #define JZ_REG_AIC_CTRL		0x04
@@ -337,13 +339,13 @@ static void jz4740_i2c_init_pcm_config(struct jz4740_i2s *i2s)
 	/* Playback */
 	dma_data = &i2s->playback_dma_data;
 	dma_data->maxburst = 16;
-	dma_data->slave_id = JZ4740_DMA_TYPE_AIC_TRANSMIT;
+	dma_data->filter_data = JZ4740_DMA_TYPE_AIC_TRANSMIT;
 	dma_data->addr = i2s->phys_base + JZ_REG_AIC_FIFO;
 
 	/* Capture */
 	dma_data = &i2s->capture_dma_data;
 	dma_data->maxburst = 16;
-	dma_data->slave_id = JZ4740_DMA_TYPE_AIC_RECEIVE;
+	dma_data->filter_data = JZ4740_DMA_TYPE_AIC_RECEIVE;
 	dma_data->addr = i2s->phys_base + JZ_REG_AIC_FIFO;
 }
 
@@ -415,6 +417,10 @@ static const struct snd_soc_component_driver jz4740_i2s_component = {
 	.name		= "jz4740-i2s",
 };
 
+static struct snd_dmaengine_pcm_config jz4740_i2s_pcm_config = {
+	.filter_fn = jz4740_dma_filter_fn,
+};
+
 static int jz4740_i2s_dev_probe(struct platform_device *pdev)
 {
 	struct jz4740_i2s *i2s;
@@ -447,8 +453,8 @@ static int jz4740_i2s_dev_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL,
-		SND_DMAENGINE_PCM_FLAG_COMPAT);
+	return devm_snd_dmaengine_pcm_register(&pdev->dev,
+		jz4740_i2s_pcm_config, SND_DMAENGINE_PCM_FLAG_COMPAT);
 }
 
 static struct platform_driver jz4740_i2s_driver = {
