diff --git a/common/cmd_fastboot.c b/common/cmd_fastboot.c
index 83fa7bd..7c91415 100644
--- a/common/cmd_fastboot.c
+++ b/common/cmd_fastboot.c
@@ -10,11 +10,16 @@
 #include <common.h>
 #include <command.h>
 #include <g_dnl.h>
+extern int board_partition_init(void);
+extern int dfu_init_env_entities(char *interface, int dev);
+extern void dfu_free_entities(void);
 
 static int do_fastboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 {
 	int ret;
 
+	board_partition_init();
+	dfu_init_env_entities("mmc", CONFIG_MMC_FASTBOOT_DEV);
 	ret = g_dnl_register("usb_dnl_fastboot");
 	if (ret)
 		return ret;
@@ -26,6 +31,7 @@ static int do_fastboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 	}
 
 	g_dnl_unregister();
+	dfu_free_entities();
 	return CMD_RET_SUCCESS;
 }
 
diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c
index 1e40983..dd7170d 100644
--- a/common/cmd_mmc.c
+++ b/common/cmd_mmc.c
@@ -612,7 +612,7 @@ static cmd_tbl_t cmd_mmc[] = {
 	U_BOOT_CMD_MKENT(setdsr, 2, 0, do_mmc_setdsr, "", ""),
 };
 
-static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
 	cmd_tbl_t *cp;
 
diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c
index 855808c..a100109 100644
--- a/common/cmd_nvedit.c
+++ b/common/cmd_nvedit.c
@@ -686,7 +686,7 @@ ulong getenv_ulong(const char *name, int base, ulong default_val)
 
 #ifndef CONFIG_SPL_BUILD
 #if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE)
-static int do_env_save(cmd_tbl_t *cmdtp, int flag, int argc,
+int do_env_save(cmd_tbl_t *cmdtp, int flag, int argc,
 		       char * const argv[])
 {
 	printf("Saving Environment to %s...\n", env_name_spec);
diff --git a/disk/Makefile b/disk/Makefile
index 6970cec..4b7a9ef 100644
--- a/disk/Makefile
+++ b/disk/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_DOS_PARTITION)   += part_dos.o
 obj-$(CONFIG_ISO_PARTITION)   += part_iso.o
 obj-$(CONFIG_AMIGA_PARTITION) += part_amiga.o
 obj-$(CONFIG_EFI_PARTITION)   += part_efi.o
+obj-$(CONFIG_CMD_FASTBOOT)    += part_fastboot.o
diff --git a/disk/part_fastboot.c b/disk/part_fastboot.c
new file mode 100644
index 0000000..681f3da
--- /dev/null
+++ b/disk/part_fastboot.c
@@ -0,0 +1,383 @@
+/*
+ * Copyright (C) 2013 Texas Instruments
+ *
+ * Author : Pankaj Bharadiya <pankaj.bharadiya@ti.com>
+ *
+ * Tom Rix <Tom.Rix@windriver.com> and Sitara 2011 u-boot by
+ * Mohammed Afzal M A <afzal@ti.com>
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Copyright 2014 Linaro, Ltd.
+ * Dileep Katta <dileep.katta@linaro.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <usb/fastboot.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+#include <environment.h>
+#include <mmc.h>
+#include <dfu.h>
+
+#define EFI_VERSION 0x00010000
+#define EFI_ENTRIES 128
+#define EFI_NAMELEN 36
+
+struct partition_emmc {
+	const char *name;
+	unsigned size_kb;
+};
+
+/* eMMC partition layout (All sizes are in kB)
+ * Modify the below partition table to change the GPT configuration.
+ * The entry for each partition can be modified as per the requirement.
+ */
+static struct partition_emmc partitions[] = {
+	{ "-", 128 },			/* Master Boot Record and GUID Partition Table */
+	{ "spl", 128 },			/* First stage bootloader */
+	{ "bootloader", 512 },		/* Second stage bootloader */
+	{ "misc", 128 },		/* Rserved for internal purpose */
+	{ "-", 128 },			/* Reserved */
+	{ "recovery", 8*1024 },		/* Recovery partition  */
+	{ "boot", 8*1024 },		/* Partition contains kernel + ramdisk images */
+	{ "system", 256*1024 },		/* Android file system */
+	{ "cache", 256*1024 },		/* Store Application Cache */
+	{ "userdata", 256*1024 },	/* User data */
+	{ "media", 0 },			/* Media files */
+	{ 0, 0 },
+};
+
+
+static const u8 partition_type[16] = {
+	0xa2, 0xa0, 0xd0, 0xeb, 0xe5, 0xb9, 0x33, 0x44,
+	0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7,
+};
+
+static const u8 random_uuid[16] = {
+	0xff, 0x1f, 0xf2, 0xf9, 0xd4, 0xa8, 0x0e, 0x5f,
+	0x97, 0x46, 0x59, 0x48, 0x69, 0xae, 0xc3, 0x4e,
+};
+
+struct efi_entry {
+	u8 type_uuid[16];
+	u8 uniq_uuid[16];
+	u64 first_lba;
+	u64 last_lba;
+	u64 attr;
+	u16 name[EFI_NAMELEN];
+};
+
+struct efi_header {
+	u8 magic[8];
+
+	u32 version;
+	u32 header_sz;
+
+	u32 crc32;
+	u32 reserved;
+
+	u64 header_lba;
+	u64 backup_lba;
+	u64 first_lba;
+	u64 last_lba;
+
+	u8 volume_uuid[16];
+
+	u64 entries_lba;
+
+	u32 entries_count;
+	u32 entries_size;
+	u32 entries_crc32;
+} __attribute__((packed));
+
+struct ptable {
+	u8 mbr[512];
+	union {
+		struct efi_header header;
+		u8 block[512];
+	};
+	struct efi_entry entry[EFI_ENTRIES];
+};
+
+static void init_mbr(u8 *mbr, u32 blocks)
+{
+	mbr[0x1be] = 0x00; /* nonbootable */
+	mbr[0x1bf] = 0xFF; /* bogus CHS */
+	mbr[0x1c0] = 0xFF;
+	mbr[0x1c1] = 0xFF;
+
+	mbr[0x1c2] = 0xEE; /* GPT partition */
+	mbr[0x1c3] = 0xFF; /* bogus CHS */
+	mbr[0x1c4] = 0xFF;
+	mbr[0x1c5] = 0xFF;
+
+	mbr[0x1c6] = 0x01; /* start */
+	mbr[0x1c7] = 0x00;
+	mbr[0x1c8] = 0x00;
+	mbr[0x1c9] = 0x00;
+
+	memcpy(mbr + 0x1ca, &blocks, sizeof(u32));
+
+	mbr[0x1fe] = 0x55;
+	mbr[0x1ff] = 0xaa;
+}
+
+extern int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+
+static void start_ptbl(struct ptable *ptbl, unsigned blocks)
+{
+	struct efi_header *hdr = &ptbl->header;
+
+	memset(ptbl, 0, sizeof(*ptbl));
+
+	init_mbr(ptbl->mbr, blocks - 1);
+
+	memcpy(hdr->magic, "EFI PART", 8);
+	hdr->version = EFI_VERSION;
+	hdr->header_sz = sizeof(struct efi_header);
+	hdr->header_lba = 1;
+	hdr->backup_lba = blocks - 1;
+	hdr->first_lba = 34;
+	hdr->last_lba = blocks - 1;
+	memcpy(hdr->volume_uuid, random_uuid, 16);
+	hdr->entries_lba = 2;
+	hdr->entries_count = EFI_ENTRIES;
+	hdr->entries_size = sizeof(struct efi_entry);
+}
+
+static void end_ptbl(struct ptable *ptbl)
+{
+	struct efi_header *hdr = &ptbl->header;
+	u32 n;
+
+	n = crc32(0, 0, 0);
+	n = crc32(n, (void *) ptbl->entry, sizeof(ptbl->entry));
+	hdr->entries_crc32 = n;
+
+	n = crc32(0, 0, 0);
+	n = crc32(0, (void *) &ptbl->header, sizeof(ptbl->header));
+	hdr->crc32 = n;
+}
+
+int add_ptn(struct ptable *ptbl, u64 first, u64 last, const char *name)
+{
+	struct efi_header *hdr = &ptbl->header;
+	struct efi_entry *entry = ptbl->entry;
+	unsigned n;
+
+	if (first < 34) {
+		printf("partition '%s' overlaps partition table\n", name);
+		return -1;
+	}
+
+	if (last > hdr->last_lba) {
+		printf("partition '%s' does not fit\n", name);
+		return -1;
+	}
+	for (n = 0; n < EFI_ENTRIES; n++, entry++) {
+		if (entry->last_lba)
+			continue;
+		memcpy(entry->type_uuid, partition_type, 16);
+		memcpy(entry->uniq_uuid, random_uuid, 16);
+		entry->uniq_uuid[0] = n;
+		entry->first_lba = first;
+		entry->last_lba = last;
+		for (n = 0; (n < EFI_NAMELEN) && *name; n++)
+			entry->name[n] = *name++;
+		return 0;
+	}
+	printf("out of partition table entries\n");
+	return -1;
+}
+
+void import_efi_partition(struct efi_entry *entry)
+{
+	struct fastboot_ptentry e;
+	int n;
+	if (memcmp(entry->type_uuid, partition_type, sizeof(partition_type)))
+		return;
+	for (n = 0; n < (sizeof(e.name)-1); n++)
+		e.name[n] = entry->name[n];
+	e.name[n] = 0;
+	e.start = entry->first_lba;
+	e.length = (entry->last_lba - entry->first_lba + 1) * 512;
+	e.flags = 0;
+
+	if (!strcmp(e.name, "environment"))
+		e.flags |= FASTBOOT_PTENTRY_FLAGS_WRITE_ENV;
+	fastboot_flash_add_ptn(&e);
+
+	if (e.length > 0x100000)
+		printf("%8d %7dM %s\n", e.start, e.length/0x100000, e.name);
+	else
+		printf("%8d %7dK %s\n", e.start, e.length/0x400, e.name);
+}
+
+static int load_ptbl(void)
+{
+	static unsigned char data[512];
+	static struct efi_entry entry[4];
+	int n, m;
+	char source[32], dest[32], length[32];
+
+	char *mmc_read[5]  = {"mmc", "read", NULL, NULL, NULL};
+
+	/* read mbr */
+	mmc_read[2] = source;
+	mmc_read[3] = dest;
+	mmc_read[4] = length;
+
+	sprintf(source, "%p", data);
+	sprintf(dest, "0x%x", 0x1);
+	sprintf(length, "0x%x", 1);
+
+	if (do_mmcops(NULL, 0, 5, mmc_read)) {
+		printf("Reading boot magic FAILED!\n");
+		return -1;
+	}
+
+	if (memcmp(data, "EFI PART", 8)) {
+		printf("efi partition table not found\n");
+		return -1;
+	}
+	for (n = 0; n < (128/4); n++) {
+
+		/* read partition */
+		source[0] = '\0';
+		dest[0] = '\0';
+		length[0] = '\0';
+		mmc_read[2] = source;
+		mmc_read[3] = dest;
+		mmc_read[4] = length;
+
+		sprintf(source, "%p", entry);
+		sprintf(dest, "0x%x", 0x1+n);
+		sprintf(length, "0x%x", 1);
+
+		if (do_mmcops(NULL, 0, 5, mmc_read)) {
+			printf("Reading boot magic FAILED!\n");
+			return -1;
+		}
+		for (m = 0; m < 4; m++)
+			import_efi_partition(entry + m);
+	}
+	return 0;
+}
+
+int board_mmc_fbtptn_init(void)
+{
+        char *mmc_init[2] = {"mmc", "rescan",};
+	char dev[2];
+	char *mmc_dev[3] = {"mmc", "dev", NULL};
+
+	mmc_dev[2] = dev;
+	sprintf(dev,"0x%x", CONFIG_MMC_FASTBOOT_DEV);
+
+	if (do_mmcops(NULL, 0, 3, mmc_dev)) {
+		printf("MMC DEV: %d selection FAILED!\n", CONFIG_MMC_FASTBOOT_DEV);
+		return -1;
+	}
+
+        if (do_mmcops(NULL, 0, 2, mmc_init)) {
+                printf("FAIL:Init of MMC card\n");
+                return 1;
+        }
+
+        printf("Loading efi partition table:\n");
+        return load_ptbl();
+}
+
+
+static struct ptable the_ptable;
+extern void fastboot_flash_reset_ptn(void);
+
+int do_format(void)
+{
+	struct ptable *ptbl = &the_ptable;
+	/* unsigned sector_sz; */
+	unsigned blocks;
+	unsigned next;
+	int n;
+
+	printf("\ndo_format ..!!");
+	/* get mmc info */
+	struct mmc *mmc = find_mmc_device(CONFIG_MMC_FASTBOOT_DEV);
+	if (mmc == 0) {
+		printf("no mmc device at slot %d", CONFIG_MMC_FASTBOOT_DEV);
+		return -1;
+	}
+
+	mmc->has_init = 0;
+	if (mmc_init(mmc)) {
+
+		printf("\n mmc init FAILED");
+		return -1;
+	} else{
+		printf("\nmmc capacity is: %llu", mmc->capacity);
+		printf("\nmmc: number of blocks:0x%lx", mmc->block_dev.lba);
+		printf("\nmmc: block size:0x%lx", mmc->block_dev.blksz);
+	}
+
+	blocks = mmc->block_dev.lba;
+	/* sector_sz = mmc->block_dev.blksz; */
+
+	start_ptbl(ptbl, blocks);
+	n = 0;
+	next = 0;
+	for (n = 0, next = 0; partitions[n].name; n++) {
+		/* 10/11 : below line change size from KB to no of blocks */
+		unsigned sz = partitions[n].size_kb*2 ;
+		if (!strcmp(partitions[n].name, "-")) {
+			next += sz;
+			continue;
+		}
+		if (sz == 0)
+			sz = blocks - next;
+		if (add_ptn(ptbl, next, next + sz - 1, partitions[n].name))
+			return -1;
+		next += sz;
+	}
+	end_ptbl(ptbl);
+
+	fastboot_flash_reset_ptn();
+
+	/* 10/11:modified as per PSP release support */
+	char *mmc_write[5]  = {"mmc", "write", NULL, NULL, NULL};
+	char source[32], dest[32], length[32];
+
+	char dev[2];
+	char *mmc_dev[3] = {"mmc", "dev", NULL};
+
+	mmc_dev[2] = dev;
+	sprintf(dev,"0x%x", CONFIG_MMC_FASTBOOT_DEV);
+
+	if (do_mmcops(NULL, 0, 3, mmc_dev)) {
+		printf("MMC DEV: %d selection FAILED!\n", CONFIG_MMC_FASTBOOT_DEV);
+		return -1;
+	}
+
+	mmc_write[2] = source;
+	mmc_write[3] = dest;
+	mmc_write[4] = length;
+
+	sprintf(source, "%p", (void *)ptbl);
+	sprintf(dest, "0x%x", 0x00);
+	sprintf(length, "0x%x", (sizeof(struct ptable)/512)+1);
+
+	if (do_mmcops(NULL, 0, 5, mmc_write)) {
+		printf("Writing mbr is FAILED!\n");
+		return -1;
+	} else {
+		printf("Writing mbr is DONE!\n");
+	}
+
+	printf("\nnew partition table:\n");
+	load_ptbl();
+
+	return 0;
+}
diff --git a/doc/README.android-fastboot b/doc/README.android-fastboot
index f1d128c..e2a330a 100644
--- a/doc/README.android-fastboot
+++ b/doc/README.android-fastboot
@@ -46,6 +46,14 @@ buffer should be as large as possible for a platform. The location of the
 buffer and size are set with CONFIG_USB_FASTBOOT_BUF_ADDR and
 CONFIG_USB_FASTBOOT_BUF_SIZE.
 
+Fastboot flash command uses DFU and storage(NAND/MMC) specific
+functionality, and hence related definitions needs to be defined:
+
+DFU_ALT_INFO
+CONFIG_STORAGE_EMMC
+CONFIG_MMC_FASTBOOT_DEV
+
+
 In Action
 =========
 Enter into fastboot by executing the fastboot command in u-boot and you
@@ -89,3 +97,21 @@ and on the gadget side you should see:
 |OK
 |
 |Starting kernel ...
+
+Flash command in action, on the client side:
+
+|>fastboot flash bootloader u-boot.img
+|target reported max download size of 1835008 bytes
+|sending 'bootloader' (395 KB)...
+|OKAY [  0.144s]
+|writing 'bootloader'...
+|OKAY [  0.009s]
+|finished. total time: 0.153s
+
+and on the gadget side you should see:
+|Starting download of 405019 bytes
+|...
+|downloading of 405019 bytes finished
+|download_bytes: 0x62e1b
+|Writing 'bootloader'
+|Writing 'bootloader' DONE!
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index 7a1acb9..f4b9a62 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -19,6 +19,10 @@
 #include <linux/compiler.h>
 #include <version.h>
 #include <g_dnl.h>
+#include <usb/fastboot.h>
+#include <command.h>
+#include <environment.h>
+#include <dfu.h>
 
 #define FASTBOOT_VERSION		"0.4"
 
@@ -35,6 +39,15 @@
 
 #define EP_BUFFER_SIZE			4096
 
+static struct fastboot_config *fb_cfg;
+static char *transfer_buffer = (void *)CONFIG_USB_FASTBOOT_BUF_ADDR;
+
+/* To support the Android-style naming of flash */
+#define MAX_PTN 16
+static fastboot_ptentry ptable[MAX_PTN];
+static unsigned int pcount;
+/* static int static_pcount = -1; */
+
 struct f_fastboot {
 	struct usb_function usb_function;
 
@@ -118,6 +131,40 @@ static struct usb_gadget_strings *fastboot_strings[] = {
 };
 
 static void rx_handler_command(struct usb_ep *ep, struct usb_request *req);
+int handle_flash(char *part_name, char *response, char *transfer_buffer);
+
+void set_fb_config (struct fastboot_config *cfg)
+{
+	fb_cfg = cfg;
+}
+
+/*
+ * Android style flash utilties */
+void fastboot_flash_reset_ptn(void)
+{
+#ifdef DEBUG
+       printf("fastboot flash reset partition..!!");
+#endif
+       pcount = 0;
+}
+
+void fastboot_flash_add_ptn(fastboot_ptentry *ptn)
+{
+       if(pcount < MAX_PTN){
+               memcpy(ptable + pcount, ptn, sizeof(*ptn));
+               pcount++;
+       }
+}
+
+void fastboot_flash_dump_ptn(void)
+{
+       unsigned int n;
+       for(n = 0; n < pcount; n++) {
+               fastboot_ptentry *ptn = ptable + n;
+               printf("ptn %d name='%s' start=%d len=%d\n",
+                               n, ptn->name, ptn->start, ptn->length);
+       }
+}
 
 static void fastboot_complete(struct usb_ep *ep, struct usb_request *req)
 {
@@ -308,6 +355,22 @@ static int fastboot_tx_write_str(const char *buffer)
 	return fastboot_tx_write(buffer, strlen(buffer));
 }
 
+fastboot_ptentry *fastboot_flash_find_ptn(const char *name)
+{
+       unsigned int n;
+
+       for(n = 0; n < pcount; n++) {
+               /* Make sure a substring is not accepted */
+               if (strlen(name) == strlen(ptable[n].name))
+               {
+                       if(0 == strcmp(ptable[n].name, name))
+                               return ptable + n;
+               }
+       }
+       return 0;
+}
+
+
 static void compl_do_reset(struct usb_ep *ep, struct usb_request *req)
 {
 	do_reset(NULL, 0, 0, NULL);
@@ -346,7 +409,7 @@ static void cb_getvar(struct usb_ep *ep, struct usb_request *req)
 		strncat(response, FASTBOOT_VERSION, chars_left);
 	} else if (!strcmp_l1("bootloader-version", cmd)) {
 		strncat(response, U_BOOT_VERSION, chars_left);
-	} else if (!strcmp_l1("downloadsize", cmd)) {
+	} else if (!strcmp_l1("max-download-size", cmd)) {
 		char str_num[12];
 
 		sprintf(str_num, "%08x", CONFIG_USB_FASTBOOT_BUF_SIZE);
@@ -380,6 +443,7 @@ static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req)
 	unsigned int transfer_size = download_size - download_bytes;
 	const unsigned char *buffer = req->buf;
 	unsigned int buffer_size = req->actual;
+	int dnl_complete = 0;
 
 	if (req->status != 0) {
 		printf("Bad status: %d\n", req->status);
@@ -389,7 +453,7 @@ static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req)
 	if (buffer_size < transfer_size)
 		transfer_size = buffer_size;
 
-	memcpy((void *)CONFIG_USB_FASTBOOT_BUF_ADDR + download_bytes,
+	memcpy((void *)transfer_buffer + download_bytes,
 	       buffer, transfer_size);
 
 	download_bytes += transfer_size;
@@ -403,9 +467,7 @@ static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req)
 		download_size = 0;
 		req->complete = rx_handler_command;
 		req->length = EP_BUFFER_SIZE;
-
-		sprintf(response, "OKAY");
-		fastboot_tx_write_str(response);
+		dnl_complete = 1;
 
 		printf("\ndownloading of %d bytes finished\n", download_bytes);
 	} else {
@@ -419,6 +481,12 @@ static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req)
 		if (!(download_bytes % (74 * BYTES_PER_DOT)))
 			putc('\n');
 	}
+
+	if (dnl_complete)
+	{
+		sprintf(response, "OKAY");
+		fastboot_tx_write_str(response);
+	}
 	req->actual = 0;
 	usb_ep_queue(ep, req, 0);
 }
@@ -469,6 +537,39 @@ static void cb_boot(struct usb_ep *ep, struct usb_request *req)
 	fastboot_tx_write_str("OKAY");
 }
 
+static void cb_flash(struct usb_ep *ep, struct usb_request *req)
+{
+	char *cmdbuf = req->buf;
+	char response[32];
+	char part_name[20]={0,};
+	strncpy (part_name, cmdbuf + 6, req->actual - 6);
+	handle_flash(part_name, response, transfer_buffer);
+	fastboot_tx_write_str(response);
+}
+
+extern int do_format(void);
+
+int fastboot_oem(const char *cmd)
+{
+	printf("fastboot_oem:%s", cmd);
+	if (!strcmp(cmd, "format"))
+		return do_format();
+	return -1;
+}
+
+static void cb_oem(struct usb_ep *ep, struct usb_request *req)
+{
+	char *cmd = req->buf;
+
+	printf ("calling fastboot oem!! : %s\n", cmd);
+	int r = fastboot_oem(cmd + 4);
+	if (r < 0) {
+		fastboot_tx_write_str("FAIL");
+	} else {
+		fastboot_tx_write_str("OKAY");
+	}
+}
+
 struct cmd_dispatch_info {
 	char *cmd;
 	void (*cb)(struct usb_ep *ep, struct usb_request *req);
@@ -487,6 +588,12 @@ static const struct cmd_dispatch_info cmd_dispatch_info[] = {
 	}, {
 		.cmd = "boot",
 		.cb = cb_boot,
+	}, {
+		.cmd = "flash",
+		.cb = cb_flash,
+	}, {
+		.cmd = "oem",
+		.cb = cb_oem,
 	},
 };
 
@@ -496,6 +603,8 @@ static void rx_handler_command(struct usb_ep *ep, struct usb_request *req)
 	void (*func_cb)(struct usb_ep *ep, struct usb_request *req) = NULL;
 	int i;
 
+	*(cmdbuf + req->actual) = '\0';
+
 	for (i = 0; i < ARRAY_SIZE(cmd_dispatch_info); i++) {
 		if (!strcmp_l1(cmd_dispatch_info[i].cmd, cmdbuf)) {
 			func_cb = cmd_dispatch_info[i].cb;
@@ -514,3 +623,69 @@ static void rx_handler_command(struct usb_ep *ep, struct usb_request *req)
 		usb_ep_queue(ep, req, 0);
 	}
 }
+extern env_t *env_ptr;
+extern int do_env_save (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+static int alt_setting_num;
+
+int handle_flash(char *part_name, char *response, char *transfer_buffer)
+{
+        int status = 0;
+        printf("download_bytes: 0x%x \n", download_bytes);
+        if (download_bytes) {
+                struct fastboot_ptentry *ptn;
+
+                /* Next is the partition name */
+                ptn = fastboot_flash_find_ptn(part_name);
+
+                if (ptn == 0) {
+                        printf("Partition:[%s] does not exist\n", part_name);
+                        sprintf(response, "FAILpartition does not exist");
+                } else if ((download_bytes > ptn->length) &&
+                                        !(ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_ENV)) {
+                        printf("Image too large for the partition\n");
+                        sprintf(response, "FAILimage too large for partition");
+                } else if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_ENV) {
+                        /* Check if this is not really a flash write,
+                         * but instead a saveenv
+                         */
+                        unsigned int i = 0;
+                        /* Env file is expected with a NULL delimeter between
+                         * env variables So replace New line Feeds (0x0a) with
+                         * NULL (0x00)
+                         */
+                        for (i = 0; i < download_bytes; i++) {
+                                if (transfer_buffer[i] == 0x0a)
+                                        transfer_buffer[i] = 0x00;
+                        }
+                        memset(env_ptr->data, 0, ENV_SIZE);
+                        memcpy(env_ptr->data, transfer_buffer, download_bytes);
+                        do_env_save(NULL, 0, 1, NULL);
+                        printf("saveenv to '%s' DONE!\n", ptn->name);
+                        sprintf(response, "OKAY");
+                } else {
+                        /* Normal case */
+                        alt_setting_num = dfu_get_alt(part_name);
+						status = dfu_write(dfu_get_entity(alt_setting_num),
+										transfer_buffer, download_bytes, 0);
+                        printf("Writing '%s'\n", ptn->name);
+                        if (status) {
+                                printf("Writing '%s' FAILED!\n", ptn->name);
+                                sprintf(response, "FAIL: Write partition");
+                        } else {
+                                printf("Writing '%s' DONE!\n", ptn->name);
+                                sprintf(response, "OKAY");
+                        }
+                }
+        } else {
+                sprintf(response, "FAILno image downloaded");
+        }
+        return status;
+}
+
+extern int board_mmc_fbtptn_init(void);
+
+int board_partition_init(void)
+{
+	board_mmc_fbtptn_init();
+	return 1;
+}
diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h
index 3999405..8856276 100644
--- a/include/configs/am335x_evm.h
+++ b/include/configs/am335x_evm.h
@@ -87,6 +87,7 @@
 		"uuid_disk=${uuid_gpt_disk};" \
 		"name=rootfs,start=2MiB,size=-,uuid=${uuid_gpt_rootfs}\0" \
 	"optargs=\0" \
+	"dfu_alt_info=" DFU_ALT_INFO "\0" \
 	"mmcdev=0\0" \
 	"mmcroot=/dev/mmcblk0p2 ro\0" \
 	"mmcrootfstype=ext4 rootwait\0" \
@@ -303,6 +304,16 @@
 #endif
 
 #ifdef CONFIG_MUSB_GADGET
+
+#define CONFIG_MMC_FASTBOOT_DEV			1
+
+/*Uncomment this to enable NAND fastboot*/
+/*#define CONFIG_NAND */
+
+/*Uncomment this to support eMMC booting*/
+#define CONFIG_STORAGE_EMMC
+
+
 #define CONFIG_USB_ETHER
 #define CONFIG_USB_ETH_RNDIS
 #define CONFIG_USBNET_HOST_ADDR	"de:ad:be:af:00:00"
@@ -336,14 +347,13 @@
 #define CONFIG_DFU_MMC
 #define CONFIG_CMD_DFU
 #define DFU_ALT_INFO_MMC \
-	"dfu_alt_info_mmc=" \
 	"boot part 0 1;" \
 	"rootfs part 0 2;" \
 	"MLO fat 0 1;" \
-	"MLO.raw mmc 0x100 0x100;" \
-	"u-boot.img.raw mmc 0x300 0x400;" \
-	"spl-os-args.raw mmc 0x80 0x80;" \
-	"spl-os-image.raw mmc 0x900 0x2000;" \
+	"MLO.raw raw 0x100 0x100;" \
+	"u-boot.img.raw raw 0x300 0x400;" \
+	"spl-os-args.raw raw 0x80 0x80;" \
+	"spl-os-image.raw raw 0x900 0x2000;" \
 	"spl-os-args fat 0 1;" \
 	"spl-os-image fat 0 1;" \
 	"u-boot.img fat 0 1;" \
@@ -374,6 +384,9 @@
 	DFU_ALT_INFO_MMC \
 	DFU_ALT_INFO_RAM \
 	DFU_ALT_INFO_NAND
+#ifdef CONFIG_DFU_MMC
+#define DFU_ALT_INFO DFU_ALT_INFO_MMC
+#endif
 #endif
 
 /*
diff --git a/include/configs/omap3_beagle.h b/include/configs/omap3_beagle.h
index 644e97f..2935208 100644
--- a/include/configs/omap3_beagle.h
+++ b/include/configs/omap3_beagle.h
@@ -77,6 +77,18 @@
 #define CONFIG_USB_FASTBOOT_BUF_ADDR	CONFIG_SYS_LOAD_ADDR
 #define CONFIG_USB_FASTBOOT_BUF_SIZE	0x07000000
 
+#ifdef CONFIG_CMD_FASTBOOT
+#define CONFIG_MMC_FASTBOOT_DEV			1
+#define CONFIG_DFU_FUNCTION
+#define CONFIG_DFU_MMC
+#define CONFIG_CMD_DFU
+#define DFU_ALT_INFO_MMC ""
+#endif
+
+#ifdef CONFIG_DFU_MMC
+#define DFU_ALT_INFO DFU_ALT_INFO_MMC
+#endif
+
 /* USB EHCI */
 #define CONFIG_CMD_USB
 #define CONFIG_USB_EHCI
diff --git a/include/usb/fastboot.h b/include/usb/fastboot.h
new file mode 100644
index 0000000..8079c53
--- /dev/null
+++ b/include/usb/fastboot.h
@@ -0,0 +1,175 @@
+/*
+ * (C) Copyright 2008 - 2009
+ * Windriver, <www.windriver.com>
+ * Tom Rix <Tom.Rix at windriver.com>
+ *
+ * Copyright (c) 2011 Sebastian Andrzej Siewior <bigeasy at linutronix.de>
+ *
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Copyright 2014 Linaro, Ltd.
+ * Dileep Katta <dileep.katta@linaro.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef FASTBOOT_H
+#define FASTBOOT_H
+
+#include <common.h>
+#include <command.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+
+#ifdef DEBUG
+#define FBTDBG(fmt,args...)\
+        printf("DEBUG: [%s]: %d: \n"fmt, __FUNCTION__, __LINE__,##args)
+#else
+#define FBTDBG(fmt,args...) do{}while(0)
+#endif
+
+#ifdef INFO
+#define FBTINFO(fmt,args...)\
+        printf("INFO: [%s]: "fmt, __FUNCTION__, ##args)
+#else
+#define FBTINFO(fmt,args...) do{}while(0)
+#endif
+
+#ifdef WARN
+#define FBTWARN(fmt,args...)\
+        printf("WARNING: [%s]: "fmt, __FUNCTION__, ##args)
+#else
+#define FBTWARN(fmt,args...) do{}while(0)
+#endif
+
+#ifdef ERR
+#define FBTERR(fmt,args...)\
+        printf("ERROR: [%s]: "fmt, __FUNCTION__, ##args)
+#else
+#define FBTERR(fmt,args...) do{}while(0)
+#endif
+
+struct fastboot_config {
+
+	/*
+	 * Transfer buffer for storing data sent by the client. It should be
+	 * able to hold a kernel image and flash partitions. Care should be
+	 * take so it does not overrun bootloader memory
+	 */
+	unsigned char *transfer_buffer;
+
+	/* Size of the buffer mentioned above */
+	unsigned int transfer_buffer_size;
+
+	/* Total data to be downloaded */
+	unsigned int download_size;
+
+	/* Data downloaded so far */
+	unsigned int download_bytes;
+
+	unsigned int nand_block_size;
+
+	unsigned int nand_oob_size;
+
+	unsigned int download_bytes_unpadded;
+};
+
+#define FB_STR_PRODUCT_IDX      1
+#define FB_STR_SERIAL_IDX       2
+#define FB_STR_CONFIG_IDX       3
+#define FB_STR_INTERFACE_IDX    4
+#define FB_STR_MANUFACTURER_IDX 5
+#define FB_STR_PROC_REV_IDX     6
+#define FB_STR_PROC_TYPE_IDX    7
+
+#ifdef CONFIG_CMD_FASTBOOT
+
+int fastboot_init(void);
+void fastboot_shutdown(void);
+int fastboot_poll(void);
+
+int fastboot_board_init(struct fastboot_config *interface,
+		struct usb_gadget_strings **str);
+
+
+/* Android-style flash naming */
+typedef struct fastboot_ptentry fastboot_ptentry;
+
+/* flash partitions are defined in terms of blocks
+ ** (flash erase units)
+ */
+struct fastboot_ptentry{
+
+	/* The logical name for this partition, null terminated */
+	char name[16];
+	/* The start wrt the nand part, must be multiple of nand block size */
+	unsigned int start;
+	/* The length of the partition, must be multiple of nand block size */
+	unsigned int length;
+	/* Controls the details of how operations are done on the partition
+	   See the FASTBOOT_PTENTRY_FLAGS_*'s defined below */
+	unsigned int flags;
+};
+
+/* Lower byte shows if the read/write/erase operation in
+   repeated.  The base address is incremented.
+   Either 0 or 1 is ok for a default */
+
+#define FASTBOOT_PTENTRY_FLAGS_REPEAT_MASK(n)   (n & 0x0f)
+#define FASTBOOT_PTENTRY_FLAGS_REPEAT_4         0x00000004
+
+/* Writes happen a block at a time.
+   If the write fails, go to next block
+   NEXT_GOOD_BLOCK and CONTIGOUS_BLOCK can not both be set */
+#define FASTBOOT_PTENTRY_FLAGS_WRITE_NEXT_GOOD_BLOCK  0x00000010
+
+/* Find a contiguous block big enough for a the whole file
+   NEXT_GOOD_BLOCK and CONTIGOUS_BLOCK can not both be set */
+#define FASTBOOT_PTENTRY_FLAGS_WRITE_CONTIGUOUS_BLOCK 0x00000020
+
+/* Sets the ECC to software before writing
+   HW and SW ECC should not both be set. */
+#define FASTBOOT_PTENTRY_FLAGS_WRITE_SW_ECC           0x00000040
+
+/* Sets the ECC to hardware before writing
+   HW and SW ECC should not both be set. */
+#define FASTBOOT_PTENTRY_FLAGS_WRITE_HW_ECC           0x00000080
+
+/* Sets the ECC to hardware before writing
+   HW and SW ECC should not both be set. */
+#define FASTBOOT_PTENTRY_FLAGS_WRITE_HW_BCH4_ECC      0x00000100
+
+/* Sets the ECC to hardware before writing
+   HW and SW ECC should not both be set. */
+#define FASTBOOT_PTENTRY_FLAGS_WRITE_HW_BCH8_ECC      0x00000200
+
+/* Sets the ECC to hardware before writing
+   HW and SW ECC should not both be set. */
+#define FASTBOOT_PTENTRY_FLAGS_WRITE_HW_BCH16_ECC     0x00000400
+
+/* Write the file with write.i */
+#define FASTBOOT_PTENTRY_FLAGS_WRITE_I                0x00000800
+
+/* Write the file with write.jffs2 */
+#define FASTBOOT_PTENTRY_FLAGS_WRITE_JFFS2            0x00001000
+
+/* Write the file as a series of variable/value pairs
+   using the setenv and saveenv commands */
+#define FASTBOOT_PTENTRY_FLAGS_WRITE_ENV              0x00002000
+
+
+/* The Android-style flash handling */
+
+/* tools to populate and query the partition table */
+extern void fastboot_flash_add_ptn(fastboot_ptentry *ptn);
+extern fastboot_ptentry *fastboot_flash_find_ptn(const char *name);
+extern fastboot_ptentry *fastboot_flash_get_ptn(unsigned n);
+extern unsigned int fastboot_flash_get_ptn_count(void);
+extern void fastboot_flash_dump_ptn(void);
+extern int fastboot_oem(const char *cmd);
+
+
+#endif
+#endif
