diff --git a/common/aboot.c b/common/aboot.c
index c8556d9b23f4..18ff30ee6d11 100644
--- a/common/aboot.c
+++ b/common/aboot.c
@@ -42,6 +42,13 @@
 #include <part.h>
 #include <sparse_format.h>
 
+typedef struct sparse_buffer {
+	void	*data;
+	u32	length;
+	u32	repeat;
+	u16	type;
+} sparse_buffer_t;
+
 static unsigned int sparse_get_chunk_data_size(sparse_header_t *sparse,
 					       chunk_header_t *chunk)
 {
@@ -247,13 +254,11 @@ static void sparse_put_data_buffer(sparse_buffer_t *buffer)
 	free(buffer);
 }
 
-void write_sparse_image(block_dev_desc_t *dev_desc,
-		disk_partition_t *info, const char *part_name,
-		void *data, unsigned sz)
+void store_sparse_image(sparse_storage_t *storage,
+			void *storage_priv, void *data)
 {
-	lbaint_t blk;
-	lbaint_t blkcnt;
-	lbaint_t blks;
+	uint32_t blk;
+	uint32_t blkcnt;
 	uint32_t bytes_written = 0;
 	unsigned int chunk;
 	sparse_header_t *sparse_header;
@@ -262,14 +267,25 @@ void write_sparse_image(block_dev_desc_t *dev_desc,
 	uint32_t total_blocks = 0;
 	int i;
 
+	debug("=== Storage ===\n");
+	debug("name: %s\n", storage->name);
+	debug("block_size: 0x%x\n", storage->block_sz);
+	debug("start: 0x%x\n", storage->start);
+	debug("size: 0x%x\n", storage->size);
+	debug("write: 0x%p\n", storage->write);
+	debug("priv: 0x%p\n", storage_priv);
+
 	sparse_header = sparse_parse_header(&data);
 	if (!sparse_header) {
 		fastboot_fail("sparse header issue\n");
 		return;
 	}
 
-	/* verify sparse_header->blk_sz is an exact multiple of info->blksz */
-	if (sparse_header->blk_sz % info->blksz) {
+	/*
+	 * Verify that the sparse block size is a multiple of our
+	 * storage backend block size
+	 */
+	if (sparse_header->blk_sz % storage->block_sz) {
 		printf("%s: Sparse image block size issue [%u]\n",
 		       __func__, sparse_header->blk_sz);
 		fastboot_fail("sparse image block size issue");
@@ -279,7 +295,7 @@ void write_sparse_image(block_dev_desc_t *dev_desc,
 	puts("Flashing Sparse Image\n");
 
 	/* Start processing chunks */
-	blk = info->start;
+	blk = storage->start;
 	for (chunk = 0; chunk < sparse_header->total_chunks; chunk++) {
 		chunk_header = sparse_parse_chunk(sparse_header, &data);
 		if (!chunk_header) {
@@ -289,13 +305,13 @@ void write_sparse_image(block_dev_desc_t *dev_desc,
 
 		/* Retrieve the buffer we're going to write */
 		buffer = sparse_get_data_buffer(sparse_header, chunk_header,
-						info->blksz, &data);
+						storage->block_sz, &data);
 		if (!buffer)
 			continue;
 
-		blkcnt = (buffer->length / info->blksz) * buffer->repeat;
+		blkcnt = (buffer->length / storage->block_sz) * buffer->repeat;
 
-		if (blk + blkcnt > info->start + info->size) {
+		if (blk + blkcnt > storage->start + storage->size) {
 			printf("%s: Request would exceed partition size!\n",
 			       __func__);
 			fastboot_fail("Request would exceed partition size!");
@@ -308,10 +324,12 @@ void write_sparse_image(block_dev_desc_t *dev_desc,
 
 			buffer_blk_cnt = buffer->length / storage->block_sz;
 
-			buffer_blks = dev_desc->block_write(dev_desc->dev, blk,
-							    buffer_blk_cnt, buffer->data);
+			buffer_blks = storage->write(storage,
+						     storage_priv,
+						     blk, buffer_blk_cnt,
+						     buffer->data);
 			if (buffer_blks != buffer_blk_cnt) {
-				printf("%s: Write %d failed " LBAFU "\n",
+				printf("%s: Write %d failed %d\n",
 				       __func__, i, buffer_blks);
 				fastboot_fail("flash write failure");
 				return;
@@ -327,7 +345,8 @@ void write_sparse_image(block_dev_desc_t *dev_desc,
 
 	debug("Wrote %d blocks, expected to write %d blocks\n",
 	      total_blocks, sparse_header->total_blks);
-	printf("........ wrote %u bytes to '%s'\n", bytes_written, part_name);
+	printf("........ wrote %u bytes to '%s'\n", bytes_written,
+	       storage->name);
 
 	if (total_blocks != sparse_header->total_blks)
 		fastboot_fail("sparse image write failure");
diff --git a/common/fb_mmc.c b/common/fb_mmc.c
index 0c48cf929f8f..a44627c00060 100644
--- a/common/fb_mmc.c
+++ b/common/fb_mmc.c
@@ -33,6 +33,10 @@ void fastboot_okay(const char *s)
 	strncat(response_str, s, RESPONSE_LEN - 4 - 1);
 }
 
+struct fb_mmc_sparse {
+	block_dev_desc_t	*dev_desc;
+};
+
 static int get_partition_info_efi_by_name_or_alias(block_dev_desc_t *dev_desc,
 		const char *name, disk_partition_t *info)
 {
@@ -55,6 +59,19 @@ static int get_partition_info_efi_by_name_or_alias(block_dev_desc_t *dev_desc,
 	return ret;
 }
 
+
+static unsigned int fb_mmc_sparse_write(struct sparse_storage *storage,
+					void *priv,
+					unsigned int offset,
+					unsigned int size,
+					char *data)
+{
+	struct fb_mmc_sparse *sparse = priv;
+	block_dev_desc_t *dev_desc = sparse->dev_desc;
+
+	return dev_desc->block_write(dev_desc->dev, offset, size, data);
+}
+
 static void write_raw_image(block_dev_desc_t *dev_desc, disk_partition_t *info,
 		const char *part_name, void *buffer,
 		unsigned int download_bytes)
@@ -126,12 +143,26 @@ void fb_mmc_flash_write(const char *cmd, void *download_buffer,
 		return;
 	}
 
-	if (is_sparse_image(download_buffer))
-		write_sparse_image(dev_desc, &info, cmd, download_buffer,
-				   download_bytes);
-	else
+	if (is_sparse_image(download_buffer)) {
+		struct fb_mmc_sparse sparse_priv;
+		sparse_storage_t sparse;
+
+		sparse_priv.dev_desc = dev_desc;
+
+		sparse.block_sz = info.blksz;
+		sparse.start = info.start;
+		sparse.size = info.size;
+		sparse.name = cmd;
+		sparse.write = fb_mmc_sparse_write;
+
+		printf("Flashing sparse image at offset " LBAFU "\n",
+		       info.start);
+
+		store_sparse_image(&sparse, &sparse_priv, download_buffer);
+	} else {
 		write_raw_image(dev_desc, &info, cmd, download_buffer,
 				download_bytes);
+	}
 }
 
 void fb_mmc_erase(const char *cmd, char *response)
diff --git a/include/aboot.h b/include/aboot.h
index 30e4d36df8ba..162d81da6d9d 100644
--- a/include/aboot.h
+++ b/include/aboot.h
@@ -9,6 +9,17 @@
 
 #define ROUNDUP(x, y)	(((x) + ((y) - 1)) & ~((y) - 1))
 
+typedef struct sparse_storage {
+	unsigned int	block_sz;
+	unsigned int	start;
+	unsigned int	size;
+	const char	*name;
+
+	unsigned int	(*write)(struct sparse_storage *storage, void *priv,
+				 unsigned int offset, unsigned int size,
+				 char *data);
+} sparse_storage_t;
+
 void fastboot_fail(const char *s);
 void fastboot_okay(const char *s);
 
@@ -26,3 +37,6 @@ static inline int is_sparse_image(void *buf)
 void write_sparse_image(block_dev_desc_t *dev_desc,
 		disk_partition_t *info, const char *part_name,
 		void *data, unsigned sz);
+
+void store_sparse_image(sparse_storage_t *storage, void *storage_priv,
+			void *data);
