diff --git a/arch/arm/cpu/arm926ejs/mx28/mx28.c b/arch/arm/cpu/arm926ejs/mx28/mx28.c
index cf6d4e9bd4..dc0338dfb5 100644
--- a/arch/arm/cpu/arm926ejs/mx28/mx28.c
+++ b/arch/arm/cpu/arm926ejs/mx28/mx28.c
@@ -30,6 +30,7 @@
 #include <asm/errno.h>
 #include <asm/io.h>
 #include <asm/arch/clock.h>
+#include <asm/arch/dma.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/iomux.h>
 #include <asm/arch/imx-regs.h>
@@ -172,6 +173,11 @@ int arch_cpu_init(void)
 	 */
 	mxs_gpio_init();
 
+#ifdef	CONFIG_APBH_DMA
+	/* Start APBH DMA */
+	mxs_dma_init();
+#endif
+
 	return 0;
 }
 #endif
diff --git a/arch/arm/include/asm/arch-mx28/dma.h b/arch/arm/include/asm/arch-mx28/dma.h
index 52747e2fbf..4a1820bdee 100644
--- a/arch/arm/include/asm/arch-mx28/dma.h
+++ b/arch/arm/include/asm/arch-mx28/dma.h
@@ -140,6 +140,8 @@ void mxs_dma_desc_free(struct mxs_dma_desc *);
 int mxs_dma_desc_append(int channel, struct mxs_dma_desc *pdesc);
 
 int mxs_dma_go(int chan);
-int mxs_dma_init(void);
+void mxs_dma_init(void);
+int mxs_dma_init_channel(int chan);
+int mxs_dma_release(int chan);
 
 #endif	/* __DMA_H__ */
diff --git a/drivers/dma/apbh_dma.c b/drivers/dma/apbh_dma.c
index c086629b0a..cb2193ec55 100644
--- a/drivers/dma/apbh_dma.c
+++ b/drivers/dma/apbh_dma.c
@@ -316,7 +316,7 @@ static int mxs_dma_request(int channel)
  * The channel will NOT be released if it's marked "busy" (see
  * mxs_dma_enable()).
  */
-static int mxs_dma_release(int channel)
+int mxs_dma_release(int channel)
 {
 	struct mxs_dma_chan *pchan;
 	int ret;
@@ -552,12 +552,10 @@ int mxs_dma_go(int chan)
 /*
  * Initialize the DMA hardware
  */
-int mxs_dma_init(void)
+void mxs_dma_init(void)
 {
 	struct mx28_apbh_regs *apbh_regs =
 		(struct mx28_apbh_regs *)MXS_APBH_BASE;
-	struct mxs_dma_chan *pchan;
-	int ret, channel;
 
 	mx28_reset_block(&apbh_regs->hw_apbh_ctrl0_reg);
 
@@ -576,28 +574,26 @@ int mxs_dma_init(void)
 	writel(APBH_CTRL0_APB_BURST_EN,
 		&apbh_regs->hw_apbh_ctrl0_clr);
 #endif
+}
 
-	for (channel = 0; channel < MXS_MAX_DMA_CHANNELS; channel++) {
-		pchan = mxs_dma_channels + channel;
-		pchan->flags = MXS_DMA_FLAGS_VALID;
+int mxs_dma_init_channel(int channel)
+{
+	struct mxs_dma_chan *pchan;
+	int ret;
 
-		ret = mxs_dma_request(channel);
+	pchan = mxs_dma_channels + channel;
+	pchan->flags = MXS_DMA_FLAGS_VALID;
 
-		if (ret) {
-			printf("MXS DMA: Can't acquire DMA channel %i\n",
-				channel);
+	ret = mxs_dma_request(channel);
 
-			goto err;
-		}
-
-		mxs_dma_reset(channel);
-		mxs_dma_ack_irq(channel);
+	if (ret) {
+		printf("MXS DMA: Can't acquire DMA channel %i\n",
+			channel);
+		return ret;
 	}
 
-	return 0;
+	mxs_dma_reset(channel);
+	mxs_dma_ack_irq(channel);
 
-err:
-	while (--channel >= 0)
-		mxs_dma_release(channel);
-	return ret;
+	return 0;
 }
diff --git a/drivers/mmc/mxsmmc.c b/drivers/mmc/mxsmmc.c
index dfceaef953..35c6bdabb0 100644
--- a/drivers/mmc/mxsmmc.c
+++ b/drivers/mmc/mxsmmc.c
@@ -338,6 +338,7 @@ int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int))
 		(struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
 	struct mmc *mmc = NULL;
 	struct mxsmmc_priv *priv = NULL;
+	int ret;
 
 	mmc = malloc(sizeof(struct mmc));
 	if (!mmc)
@@ -356,6 +357,10 @@ int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int))
 		return -ENOMEM;
 	}
 
+	ret = mxs_dma_init_channel(id);
+	if (ret)
+		return ret;
+
 	priv->mmc_is_wp = wp;
 	priv->id = id;
 	switch (id) {
diff --git a/drivers/mtd/nand/mxs_nand.c b/drivers/mtd/nand/mxs_nand.c
index 4b1297a2fd..9c95811054 100644
--- a/drivers/mtd/nand/mxs_nand.c
+++ b/drivers/mtd/nand/mxs_nand.c
@@ -1058,7 +1058,7 @@ int mxs_nand_init(struct mxs_nand_info *info)
 {
 	struct mx28_gpmi_regs *gpmi_regs =
 		(struct mx28_gpmi_regs *)MXS_GPMI_BASE;
-	int i = 0;
+	int i = 0, j;
 
 	info->desc = malloc(sizeof(struct mxs_dma_desc *) *
 				MXS_NAND_DMA_DESCRIPTOR_COUNT);
@@ -1073,7 +1073,11 @@ int mxs_nand_init(struct mxs_nand_info *info)
 	}
 
 	/* Init the DMA controller. */
-	mxs_dma_init();
+	for (j = MXS_DMA_CHANNEL_AHB_APBH_GPMI0;
+		j <= MXS_DMA_CHANNEL_AHB_APBH_GPMI7; j++) {
+		if (mxs_dma_init_channel(j))
+			goto err3;
+	}
 
 	/* Reset the GPMI block. */
 	mx28_reset_block(&gpmi_regs->hw_gpmi_ctrl0_reg);
@@ -1089,6 +1093,9 @@ int mxs_nand_init(struct mxs_nand_info *info)
 
 	return 0;
 
+err3:
+	for (--j; j >= 0; j--)
+		mxs_dma_release(j);
 err2:
 	free(info->desc);
 err1: