diff --git a/common/bouncebuf.c b/common/bouncebuf.c
index ffd3c90..210d70d 100644
--- a/common/bouncebuf.c
+++ b/common/bouncebuf.c
@@ -50,44 +50,35 @@ static int addr_aligned(void *data, size_t len)
 	return 1;
 }
 
-int bounce_buffer_start(void **data, size_t len, void **backup, uint8_t flags)
+int bounce_buffer_start(struct bounce_buffer_state *state, void *data,
+			size_t len, uint8_t flags)
 {
-	void *tmp;
-	size_t alen;
+	state->user_buffer = data;
+	state->bounce_buffer = data;
+	state->len = len;
+	state->len_aligned = roundup(len, ARCH_DMA_MINALIGN);
+	state->flags = flags;
 
-	if (addr_aligned(*data, len)) {
-		*backup = NULL;
+	if (addr_aligned(data, len))
 		return 0;
-	}
-
-	alen = roundup(len, ARCH_DMA_MINALIGN);
-	tmp = memalign(ARCH_DMA_MINALIGN, alen);
 
-	if (!tmp)
+	state->bounce_buffer = memalign(ARCH_DMA_MINALIGN, state->len_aligned);
+	if (!state->bounce_buffer)
 		return -ENOMEM;
 
-	if (flags & GEN_BB_READ)
-		memcpy(tmp, *data, len);
-
-	*backup = *data;
-	*data = tmp;
+	if (state->flags & GEN_BB_READ)
+		memcpy(state->bounce_buffer, state->user_buffer, state->len);
 
 	return 0;
 }
 
-int bounce_buffer_stop(void **data, size_t len, void **backup, uint8_t flags)
+int bounce_buffer_stop(struct bounce_buffer_state *state)
 {
-	void *tmp = *data;
-
-	/* The buffer was already aligned, since "backup" is NULL. */
-	if (!*backup)
+	if (state->bounce_buffer == state->user_buffer)
 		return 0;
 
-	if (flags & GEN_BB_WRITE)
-		memcpy(*backup, *data, len);
-
-	*data = *backup;
-	free(tmp);
+	if (state->flags & GEN_BB_WRITE)
+		memcpy(state->user_buffer, state->bounce_buffer, state->len);
 
 	return 0;
 }
diff --git a/drivers/mmc/mxsmmc.c b/drivers/mmc/mxsmmc.c
index 109acbf..d314d7d 100644
--- a/drivers/mmc/mxsmmc.c
+++ b/drivers/mmc/mxsmmc.c
@@ -96,11 +96,11 @@ static int mxsmmc_send_cmd_pio(struct mxsmmc_priv *priv, struct mmc_data *data)
 static int mxsmmc_send_cmd_dma(struct mxsmmc_priv *priv, struct mmc_data *data)
 {
 	uint32_t data_count = data->blocksize * data->blocks;
-	uint32_t cache_data_count = roundup(data_count, ARCH_DMA_MINALIGN);
 	int dmach;
 	struct mxs_dma_desc *desc = priv->desc;
-	void *addr, *backup;
+	void *addr;
 	uint8_t flags;
+	struct bounce_buffer_state bbstate;
 
 	memset(desc, 0, sizeof(struct mxs_dma_desc));
 	desc->address = (dma_addr_t)desc;
@@ -115,19 +115,21 @@ static int mxsmmc_send_cmd_dma(struct mxsmmc_priv *priv, struct mmc_data *data)
 		flags = GEN_BB_READ;
 	}
 
-	bounce_buffer_start(&addr, data_count, &backup, flags);
+	bounce_buffer_start(&bbstate, addr, data_count, flags);
 
-	priv->desc->cmd.address = (dma_addr_t)addr;
+	priv->desc->cmd.address = (dma_addr_t)bbstate.bounce_buffer;
 
 	if (data->flags & MMC_DATA_WRITE) {
 		/* Flush data to DRAM so DMA can pick them up */
-		flush_dcache_range((uint32_t)addr,
-			(uint32_t)(addr) + cache_data_count);
+		flush_dcache_range((uint32_t)bbstate.bounce_buffer,
+					(uint32_t)(bbstate.bounce_buffer) +
+						bbstate.len_aligned);
 	}
 
 	/* Invalidate the area, so no writeback into the RAM races with DMA */
 	invalidate_dcache_range((uint32_t)priv->desc->cmd.address,
-			(uint32_t)(priv->desc->cmd.address + cache_data_count));
+				(uint32_t)(priv->desc->cmd.address +
+					bbstate.len_aligned));
 
 	priv->desc->cmd.data |= MXS_DMA_DESC_IRQ | MXS_DMA_DESC_DEC_SEM |
 				(data_count << MXS_DMA_DESC_BYTES_OFFSET);
@@ -135,17 +137,18 @@ static int mxsmmc_send_cmd_dma(struct mxsmmc_priv *priv, struct mmc_data *data)
 	dmach = MXS_DMA_CHANNEL_AHB_APBH_SSP0 + priv->id;
 	mxs_dma_desc_append(dmach, priv->desc);
 	if (mxs_dma_go(dmach)) {
-		bounce_buffer_stop(&addr, data_count, &backup, flags);
+		bounce_buffer_stop(&bbstate);
 		return COMM_ERR;
 	}
 
 	/* The data arrived into DRAM, invalidate cache over them */
 	if (data->flags & MMC_DATA_READ) {
-		invalidate_dcache_range((uint32_t)addr,
-			(uint32_t)(addr) + cache_data_count);
+		invalidate_dcache_range((uint32_t)bbstate.bounce_buffer,
+					(uint32_t)(bbstate.bounce_buffer) +
+						bbstate.len_aligned);
 	}
 
-	bounce_buffer_stop(&addr, data_count, &backup, flags);
+	bounce_buffer_stop(&bbstate);
 
 	return 0;
 }
diff --git a/include/bouncebuf.h b/include/bouncebuf.h
index 31021c5..205a1ed 100644
--- a/include/bouncebuf.h
+++ b/include/bouncebuf.h
@@ -52,33 +52,43 @@
 #define GEN_BB_RW	(GEN_BB_READ | GEN_BB_WRITE)
 
 #ifdef CONFIG_BOUNCE_BUFFER
+struct bounce_buffer_state {
+	void *user_buffer;
+	void *bounce_buffer;
+	size_t len;
+	size_t len_aligned;
+	uint8_t flags;
+};
+
 /**
  * bounce_buffer_start() -- Start the bounce buffer session
+ * state:	stores state passed between bounce_buffer_{start,stop}
  * data:	pointer to buffer to be aligned
  * len:		length of the buffer
- * backup:	pointer to backup buffer (the original value is stored here if
- *              needed
  * flags:	flags describing the transaction, see above.
  */
-int bounce_buffer_start(void **data, size_t len, void **backup, uint8_t flags);
+int bounce_buffer_start(struct bounce_buffer_state *state, void *data,
+			size_t len, uint8_t flags);
 /**
  * bounce_buffer_stop() -- Finish the bounce buffer session
- * data:	pointer to buffer that was aligned
- * len:		length of the buffer
- * backup:	pointer to backup buffer (the original value is stored here if
- *              needed
- * flags:	flags describing the transaction, see above.
+ * state:	stores state passed between bounce_buffer_{start,stop}
  */
-int bounce_buffer_stop(void **data, size_t len, void **backup, uint8_t flags);
+int bounce_buffer_stop(struct bounce_buffer_state *state);
 #else
-static inline int bounce_buffer_start(void **data, size_t len, void **backup,
-					uint8_t flags)
+struct bounce_buffer_state {
+	void *bounce_buffer;
+	size_t len_aligned;
+};
+
+static inline int bounce_buffer_start(struct bounce_buffer_state *state,
+					void *data, size_t len, uint8_t flags)
 {
+	state->bounce_buffer = data;
+	state->len_aligned = len;
 	return 0;
 }
 
-static inline int bounce_buffer_stop(void **data, size_t len, void **backup,
-					uint8_t flags)
+static inline int bounce_buffer_stop(struct bounce_buffer_state *state)
 {
 	return 0;
 }
