Merge "ipq40xx: Fix for USB 3.0 detection"
diff --git a/arch/arm/cpu/armv7/qca/common/scm.c b/arch/arm/cpu/armv7/qca/common/scm.c
index ed56f69..cda0c50 100644
--- a/arch/arm/cpu/armv7/qca/common/scm.c
+++ b/arch/arm/cpu/armv7/qca/common/scm.c
@@ -518,4 +518,6 @@
 		ret = scm_call(SCM_SVC_BOOT, SCM_CMD_TZ_FORCE_DLOAD_ID, &magic_cookie,
 			sizeof(magic_cookie), NULL, 0);
 	}
+
+	return ret;
 }
diff --git a/arch/arm/cpu/armv7/qca/common/smem.c b/arch/arm/cpu/armv7/qca/common/smem.c
index 380fbff..e3a0a3c 100644
--- a/arch/arm/cpu/armv7/qca/common/smem.c
+++ b/arch/arm/cpu/armv7/qca/common/smem.c
@@ -554,26 +554,29 @@
 	return qca_smem_flash_info.flash_block_size;
 }
 
-void qca_smem_part_to_mtdparts(char *mtdid)
+void qca_smem_part_to_mtdparts(char *mtdid, int len)
 {
 	qca_smem_flash_info_t *sfi = &qca_smem_flash_info;
-	int i, l;
+	int i, ret;
 	int device_id = 0;
 	char *part = mtdid, *unit;
 	int init = 0;
 	uint32_t bsize;
 
-	part += sprintf(part, "%s:", mtdid);
+	ret = snprintf(part, len, "%s:", mtdid);
+	part += ret;
+	len -= ret;
 
-	for (i = 0; i < smem_ptable.len; i++) {
+	for (i = 0; i < smem_ptable.len && len > 0; i++) {
 		struct smem_ptn *p = &smem_ptable.parts[i];
 		loff_t psize;
 		bsize = get_part_block_size(p, sfi);
 
 		if (part_which_flash(p) && init == 0) {
 			device_id = is_spi_nand_available();
-			l = sprintf(part, ";nand%d:", device_id);
-			part += l;
+			ret = snprintf(part, len, ";nand%d:", device_id);
+			part += ret;
+			len -= ret;
 			init = 1;
 		}
 		if (p->size == (~0u)) {
@@ -597,9 +600,10 @@
 			unit = "@";
 		}
 
-		l = sprintf(part, "%lld%s0x%llx(%s),", psize, unit,
+		ret = snprintf(part, len, "%lld%s0x%llx(%s),", psize, unit,
 				((loff_t)p->start) * bsize, p->name);
-		part += l;
+		part += ret;
+		len -= ret;
 	}
 
 	if (i == 0)
diff --git a/arch/arm/dts/ipq806x-ap148.dts b/arch/arm/dts/ipq806x-ap148.dts
index 1f282e0..b2b1f34 100644
--- a/arch/arm/dts/ipq806x-ap148.dts
+++ b/arch/arm/dts/ipq806x-ap148.dts
@@ -92,4 +92,15 @@
 		};
 	};
 
+	reset_s17_gpio {
+		gpio63 {
+			gpio = <63>;
+			func = <0>;
+			out  = <GPIO_OUTPUT>;
+			pull = <GPIO_PULL_DOWN>;
+			drvstr = <GPIO_8MA>;
+			oe = <GPIO_OE_ENABLE>;
+		};
+	};
+
 };
diff --git a/arch/arm/dts/ipq807x-hk07.dts b/arch/arm/dts/ipq807x-hk07.dts
index e0c40c8..19b999e 100644
--- a/arch/arm/dts/ipq807x-hk07.dts
+++ b/arch/arm/dts/ipq807x-hk07.dts
@@ -23,9 +23,6 @@
 	aliases {
 		console = "/serial@78B3000";
 		uart2 = "/serial@78B0000";
-		i2c0 = "/i2c@78b6000";
-		pci0 = "/pci@20000000";
-		pci1 = "/pci@10000000";
 	};
 	ess-switch {
 		switch_mac_mode = <0x0>;
diff --git a/arch/arm/include/asm/arch-qca-common/iomap.h b/arch/arm/include/asm/arch-qca-common/iomap.h
index bfd35c6..49be52b 100644
--- a/arch/arm/include/asm/arch-qca-common/iomap.h
+++ b/arch/arm/include/asm/arch-qca-common/iomap.h
@@ -26,4 +26,7 @@
 
 #define GCNT_PSHOLD		0x004AB000
 
+#define CPU1_APCS_SAW2_VCTL	0x02099014
+#define CPU1_APCS_CPU_PWR_CTL	0x02098004
+
 #endif /* _PLATFORM_IPQ40XX_IOMAP_H_ */
diff --git a/arch/arm/include/asm/arch-qca-common/scm.h b/arch/arm/include/asm/arch-qca-common/scm.h
index e57cfaa..5cc6705 100644
--- a/arch/arm/include/asm/arch-qca-common/scm.h
+++ b/arch/arm/include/asm/arch-qca-common/scm.h
@@ -28,6 +28,8 @@
 #define SCM_SVC_RD			0x12
 #define QFPROM_IS_AUTHENTICATE_CMD	0x7
 #define TZBSP_BUILD_VER_QUERY_CMD	0x4
+#define SCM_BOOT_ADDR			0x1
+#define SCM_FLAG_COLDBOOT_CPU1		0x1
 
 /* scm_v8 */
 #define SCM_VAL				0x0
diff --git a/arch/arm/include/asm/arch-qca-common/smem.h b/arch/arm/include/asm/arch-qca-common/smem.h
index b4eae39..e980ec7 100644
--- a/arch/arm/include/asm/arch-qca-common/smem.h
+++ b/arch/arm/include/asm/arch-qca-common/smem.h
@@ -116,7 +116,7 @@
 unsigned int get_smem_spi_addr_len(void);
 unsigned int get_rootfs_active_partition(void);
 unsigned int get_mibib_active_partition(void);
-void qca_smem_part_to_mtdparts(char *mtdid);
+void qca_smem_part_to_mtdparts(char *mtdid, int len);
 int ipq_smem_get_socinfo_cpu_type(uint32_t *cpu_type);
 int ipq_smem_get_socinfo_version(uint32_t *version);
 #endif
diff --git a/arch/arm/include/asm/mach-types.h b/arch/arm/include/asm/mach-types.h
index bd0b6ed..524681d 100644
--- a/arch/arm/include/asm/mach-types.h
+++ b/arch/arm/include/asm/mach-types.h
@@ -1132,6 +1132,7 @@
 #define MACH_TYPE_IPQ40XX_AP_DK04_1_C3  0x8010201
 #define MACH_TYPE_IPQ40XX_AP_DK06_1_C1  0x8010005
 #define MACH_TYPE_IPQ40XX_AP_DK07_1_C1  0x8010006
+#define MACH_TYPE_IPQ40XX_AP_DK07_1_C2  0x8010106
 #define MACH_TYPE_IPQ40XX_AP_DK07_1_C3  0x8010206
 #define MACH_TYPE_IPQ40XX_DB_DK01_1_C1  0x1010002
 #define MACH_TYPE_IPQ40XX_DB_DK02_1_C1  0x1010003
diff --git a/board/qca/arm/common/cmd_bootqca.c b/board/qca/arm/common/cmd_bootqca.c
index 252b7fb..15cc691 100644
--- a/board/qca/arm/common/cmd_bootqca.c
+++ b/board/qca/arm/common/cmd_bootqca.c
@@ -28,6 +28,8 @@
 #include <nand.h>
 #include <spi_flash.h>
 #include <spi.h>
+#include <asm/arch-qca-common/iomap.h>
+#include <asm/io.h>
 
 #define DLOAD_MAGIC_COOKIE 0x10
 #define XMK_STR(x)#x
@@ -106,6 +108,40 @@
 
 }
 
+__weak int scm_set_boot_addr(void)
+{
+	return -1;
+}
+
+static int krait_release_secondary(void)
+{
+	writel(0xa4, CPU1_APCS_SAW2_VCTL);
+	barrier();
+	udelay(512);
+
+	writel(0x109, CPU1_APCS_CPU_PWR_CTL);
+	writel(0x101, CPU1_APCS_CPU_PWR_CTL);
+	barrier();
+	udelay(1);
+
+	writel(0x121, CPU1_APCS_CPU_PWR_CTL);
+	barrier();
+	udelay(2);
+
+	writel(0x120, CPU1_APCS_CPU_PWR_CTL);
+	barrier();
+	udelay(2);
+
+	writel(0x100, CPU1_APCS_CPU_PWR_CTL);
+	barrier();
+	udelay(100);
+
+	writel(0x180, CPU1_APCS_CPU_PWR_CTL);
+	barrier();
+
+	return 0;
+}
+
 static int do_dumpqca_data(void)
 {
 	char *serverip = NULL;
@@ -134,6 +170,11 @@
 		dump_entries = dump_entries_s;
 	}
 
+	if (scm_set_boot_addr() == 0) {
+		/* Pull Core-1 out of reset, iff scm call succeeds */
+		krait_release_secondary();
+	}
+
 	for (indx = 0; indx < dump_entries; indx++) {
 		printf("\nProcessing %s:", dumpinfo[indx].name);
 
diff --git a/board/qca/arm/common/ethaddr.c b/board/qca/arm/common/ethaddr.c
index 65d1726..af59522 100644
--- a/board/qca/arm/common/ethaddr.c
+++ b/board/qca/arm/common/ethaddr.c
@@ -128,12 +128,12 @@
 			 * dts entry for the ethernet entries, which in turn
 			 * will be picked up by the HLOS driver
 			 */
-			sprintf(mac, "%x:%x:%x:%x:%x:%x",
+			snprintf(mac, sizeof(mac), "%x:%x:%x:%x:%x:%x",
 					mac_addr[0], mac_addr[1],
 					mac_addr[2], mac_addr[3],
 					mac_addr[4], mac_addr[5]);
 			setenv(ethaddr, mac);
 		}
-		sprintf(ethaddr, "eth%daddr", (i + 1));
+		snprintf(ethaddr, sizeof(ethaddr), "eth%daddr", (i + 1));
 	}
 }
diff --git a/board/qca/arm/common/fdt_fixup.c b/board/qca/arm/common/fdt_fixup.c
index 8574e1e..8c2464c 100644
--- a/board/qca/arm/common/fdt_fixup.c
+++ b/board/qca/arm/common/fdt_fixup.c
@@ -258,6 +258,7 @@
 	u64 memory_size = gd->ram_size;
 	char *mtdparts = NULL;
 	char parts_str[4096];
+	int len = sizeof(parts_str);
 	qca_smem_flash_info_t *sfi = &qca_smem_flash_info;
 	struct flash_node_info nodes[] = {
 		{ "qcom,msm-nand", MTD_DEV_TYPE_NAND, 0 },
@@ -276,20 +277,20 @@
 	ipq_fdt_mem_rsvd_fixup(blob);
 #endif
 	if (sfi->flash_type == SMEM_BOOT_NAND_FLASH) {
-		sprintf(parts_str, "mtdparts=nand0");
+		snprintf(parts_str, sizeof(parts_str), "mtdparts=nand0");
 	} else if (sfi->flash_type == SMEM_BOOT_SPI_FLASH) {
 		/* Patch NOR block size and density for
 		 * generic probe case */
 		ipq_fdt_fixup_spi_nor_params(blob);
-		sprintf(parts_str, "mtdparts=" QCA_SPI_NOR_DEVICE);
+		snprintf(parts_str,sizeof(parts_str), "mtdparts=" QCA_SPI_NOR_DEVICE);
 
 		if (sfi->flash_secondary_type == SMEM_BOOT_NAND_FLASH)
-			sprintf(parts_str,
+			snprintf(parts_str, sizeof(parts_str),
 				"mtdparts=nand0:64M@0(rootfs);nand1");
 	}
 	mtdparts = parts_str;
 	if (mtdparts) {
-		qca_smem_part_to_mtdparts(mtdparts);
+		qca_smem_part_to_mtdparts(mtdparts,len);
 		if (mtdparts[0] != '\0') {
 			debug("mtdparts = %s\n", mtdparts);
 			setenv("mtdparts", mtdparts);
diff --git a/board/qca/arm/ipq40xx/ipq40xx.c b/board/qca/arm/ipq40xx/ipq40xx.c
index 1ae7913..4e23538 100644
--- a/board/qca/arm/ipq40xx/ipq40xx.c
+++ b/board/qca/arm/ipq40xx/ipq40xx.c
@@ -35,6 +35,7 @@
 #include "ipq_phy.h"
 
 #define DLOAD_MAGIC_COOKIE 0x10
+#define TCSR_USB_HSPHY_DEVICE_MODE		0x00C700E70
 DECLARE_GLOBAL_DATA_PTR;
 
 qca_mmc mmc_host;
@@ -174,13 +175,13 @@
 	case MACH_TYPE_IPQ40XX_AP_DK01_1_S1:
 	case MACH_TYPE_IPQ40XX_AP_DK01_1_C2:
 		/* 8075 out of reset */
-		mdelay(100);
+		mdelay(1);
 		gpio_set_value(62, 1);
 		ipq40xx_register_switch(ipq_qca8075_phy_init);
 		break;
 	case MACH_TYPE_IPQ40XX_AP_DK01_1_C1:
 		/* 8075 out of reset */
-		mdelay(100);
+		mdelay(1);
 		gpio_set_value(59, 1);
 		ipq40xx_register_switch(ipq_qca8075_phy_init);
 		break;
@@ -188,26 +189,27 @@
 	case MACH_TYPE_IPQ40XX_AP_DK04_1_C1:
 	case MACH_TYPE_IPQ40XX_AP_DK04_1_C3:
 		/* 8075 out of reset */
-		mdelay(100);
+		mdelay(1);
 		gpio_set_value(47, 1);
 		ipq40xx_register_switch(ipq_qca8075_phy_init);
 		break;
 	case MACH_TYPE_IPQ40XX_AP_DK04_1_C2:
 		/* 8075 out of reset */
-		mdelay(100);
+		mdelay(1);
 		gpio_set_value(67, 1);
 		ipq40xx_register_switch(ipq_qca8075_phy_init);
 		break;
 	case MACH_TYPE_IPQ40XX_AP_DK06_1_C1:
 		/* 8075 out of reset */
-		mdelay(100);
+		mdelay(1);
 		gpio_set_value(19, 1);
 		ipq40xx_register_switch(ipq_qca8075_phy_init);
 		break;
 	case MACH_TYPE_IPQ40XX_AP_DK07_1_C1:
+	case MACH_TYPE_IPQ40XX_AP_DK07_1_C2:
 	case MACH_TYPE_IPQ40XX_AP_DK07_1_C3:
 		/* 8075 out of reset */
-		mdelay(100);
+		mdelay(1);
 		gpio_set_value(41, 1);
 		ipq40xx_register_switch(ipq_qca8075_phy_init);
 		break;
@@ -316,6 +318,58 @@
 
 void ipq_fdt_fixup_usb_device_mode(void *blob)
 {
+	int nodeoff, ret, i;
+	int phy_mode = htonl(TCSR_USB_HSPHY_DEVICE_MODE);
+	const char *mode = "peripheral";
+	const char *node[] = {"/soc/ssphy", "/soc/hsphy", "/soc/usb3"};
+	char *usb_cfg;
+
+	usb_cfg = getenv("usb_mode");
+	if (!usb_cfg)
+		return;
+
+	if (strcmp(usb_cfg, "device"))
+		return;
+
+	nodeoff = fdt_path_offset(blob, "/soc/tcsr");
+	if (nodeoff < 0) {
+		printf("ipq: fdt fixup unable to find node /soc/tcsr\n");
+		return;
+	}
+	ret = fdt_setprop(blob, nodeoff, "ipq,usb-hsphy-mode-select",
+					&phy_mode, sizeof(phy_mode));
+	if (ret != 0) {
+		printf("ipq: unable to set prop: %d\n", ret);
+		return;
+	}
+
+	phy_mode = 0;
+	for (i = 0; i < (sizeof(node) / sizeof(node[0])); i++) {
+		nodeoff = fdt_path_offset(blob, node[i]);
+		if (nodeoff < 0) {
+			printf("ipq: fdt fixup unable to find node %s\n",
+								node[i]);
+			continue;
+		}
+		ret = fdt_setprop(blob, nodeoff, "qca,host",
+					&phy_mode, sizeof(phy_mode));
+		if (ret != 0) {
+			printf("ipq: unable to set prop: %d\n", ret);
+			continue;
+		}
+	}
+
+	nodeoff = fdt_path_offset(blob, "/soc/usb3/dwc3");
+	if (nodeoff < 0) {
+		printf("ipq: fdt fixup unable to find node /soc/usb3/dwc3\n");
+		return;
+	}
+	ret = fdt_setprop(blob, nodeoff, "dr_mode",
+				mode, (strlen(mode) + 1));
+	if (ret != 0) {
+		printf("ipq: unable to set prop: %d\n", ret);
+		return;
+	}
 	return;
 }
 
diff --git a/board/qca/arm/ipq806x/ipq806x.c b/board/qca/arm/ipq806x/ipq806x.c
index c96a755..57fc729 100644
--- a/board/qca/arm/ipq806x/ipq806x.c
+++ b/board/qca/arm/ipq806x/ipq806x.c
@@ -166,6 +166,12 @@
 
 void reset_cpu(unsigned long a)
 {
+	int reset_s17_gpio_node;
+
+	reset_s17_gpio_node = fdt_path_offset(gd->fdt_blob, "/reset_s17_gpio");
+	if (reset_s17_gpio_node)
+		qca_gpio_init(reset_s17_gpio_node);
+
 	reset_crashdump();
 
 	printf("\nResetting with watch dog!\n");
@@ -533,20 +539,16 @@
 void ipq_fdt_fixup_socinfo(void *blob)
 {
 	uint32_t cpu_type;
-	int nodeoff, ret;
+	int ret;
 
 	ret = ipq_smem_get_socinfo_cpu_type(&cpu_type);
 	if (ret) {
 		printf("ipq: fdt fixup cannot get socinfo\n");
 		return;
 	}
-	nodeoff = fdt_node_offset_by_compatible(blob, -1, "qcom,ipq8064");
 
-	if (nodeoff < 0) {
-		printf("ipq: fdt fixup cannot find compatible node\n");
-		return;
-	}
-	ret = fdt_setprop(blob, nodeoff, "cpu_type",
+	/* Add "cpu_type" to root node of the devicetree*/
+	ret = fdt_setprop(blob, 0, "cpu_type",
 			&cpu_type, sizeof(cpu_type));
 	if (ret)
 		printf("%s: cannot set cpu type %d\n", __func__, ret);
@@ -927,6 +929,30 @@
 	return 0;
 }
 
+void forever(void) { while (1); }
+/*
+ * Set the cold/warm boot address for one of the CPU cores.
+ */
+int scm_set_boot_addr(void)
+{
+	int ret;
+	struct {
+		unsigned int flags;
+		unsigned long addr;
+	} cmd;
+
+	cmd.addr = (unsigned long)forever;
+	cmd.flags = SCM_FLAG_COLDBOOT_CPU1;
+
+	ret = scm_call(SCM_SVC_BOOT, SCM_BOOT_ADDR,
+				&cmd, sizeof(cmd), NULL, 0);
+	if (ret) {
+		printf("--- %s: scm_call failed ret = %d\n", __func__, ret);
+	}
+
+	return ret;
+}
+
 void clear_l2cache_err(void)
 {
         unsigned int val;
diff --git a/disk/part_efi.c b/disk/part_efi.c
index b1e0155..37735e9 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -279,9 +279,9 @@
 		     - info->start;
 	info->blksz = dev_desc->blksz;
 
-	sprintf((char *)info->name, "%s",
+	snprintf((char *)info->name, sizeof(info->name), "%s",
 			print_efiname(&gpt_pte[part - 1]));
-	sprintf((char *)info->type, "U-Boot");
+	snprintf((char *)info->type, sizeof(info->type), "U-Boot");
 	info->bootable = is_bootable(&gpt_pte[part - 1]);
 #ifdef CONFIG_PARTITION_UUIDS
 	uuid_bin_to_str(gpt_pte[part - 1].unique_partition_guid.b, info->uuid,
diff --git a/drivers/dma/bam.c b/drivers/dma/bam.c
index 34446b9..4acbe52 100644
--- a/drivers/dma/bam.c
+++ b/drivers/dma/bam.c
@@ -32,6 +32,7 @@
 #include <common.h>
 #include <asm/arch-qca-common/bam.h>
 #define HLOS_EE_INDEX          0
+#define TIMEOUT		2000
 
 /* Resets pipe registers and state machines */
 void bam_pipe_reset(struct bam_instance *bam,
@@ -56,13 +57,17 @@
                            enum p_int_type interrupt)
 {
 	uint32_t val;
+	uint32_t start;
 
 	while (1)
 	{
+		start = get_timer(0);
 		/* Wait for a interrupt on the right pipe */
 		do{
 			/* Determine the pipe causing the interrupt */
 			val = readl(BAM_IRQ_SRCS(bam->base, bam->ee));
+			if(get_timer(start) >= TIMEOUT)
+				return BAM_RESULT_FAILURE;
 			/* Flush out the right most global interrupt bit */
 		} while (!((val & BAM_IRQ_SRCS_PIPE_MASK) &
 				   (1 << bam->pipe[pipe_num].pipe_num)));
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index d8b959d..62765d8 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1485,14 +1485,16 @@
 #if !defined(CONFIG_SPL_BUILD) || \
 		(defined(CONFIG_SPL_LIBCOMMON_SUPPORT) && \
 		!defined(CONFIG_USE_TINY_PRINTF))
-	sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x",
-		mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
+	snprintf(mmc->block_dev.vendor, sizeof(mmc->block_dev.vendor),
+		"Man %06x Snr %04x%04x", mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
 		(mmc->cid[3] >> 16) & 0xffff);
-	sprintf(mmc->block_dev.product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff,
+	snprintf(mmc->block_dev.product, sizeof(mmc->block_dev.product),
+		"%c%c%c%c%c%c", mmc->cid[0] & 0xff,
 		(mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
 		(mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff,
 		(mmc->cid[2] >> 24) & 0xff);
-	sprintf(mmc->block_dev.revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf,
+	snprintf(mmc->block_dev.revision, sizeof(mmc->block_dev.revision),
+		 "%d.%d", (mmc->cid[2] >> 20) & 0xf,
 		(mmc->cid[2] >> 16) & 0xf);
 #else
 	mmc->block_dev.vendor[0] = 0;
diff --git a/drivers/net/ipq40xx/ipq40xx_edma_eth.c b/drivers/net/ipq40xx/ipq40xx_edma_eth.c
index cf13c0d..cce384b 100755
--- a/drivers/net/ipq40xx/ipq40xx_edma_eth.c
+++ b/drivers/net/ipq40xx/ipq40xx_edma_eth.c
@@ -897,7 +897,7 @@
 			dev[i]->enetaddr[4],
 			dev[i]->enetaddr[5]);
 
-		sprintf(dev[i]->name, "eth%d", i);
+		snprintf(dev[i]->name, sizeof(dev[i]->name), "eth%d", i);
 		ipq40xx_edma_dev[i]->dev  = dev[i];
 		ipq40xx_edma_dev[i]->mac_unit = edma_cfg->unit;
 		ipq40xx_edma_dev[i]->c_info = c_info[i];
diff --git a/drivers/net/ipq40xx/ipq40xx_ess_sw.c b/drivers/net/ipq40xx/ipq40xx_ess_sw.c
index ad742fa..6d4d448 100644
--- a/drivers/net/ipq40xx/ipq40xx_ess_sw.c
+++ b/drivers/net/ipq40xx/ipq40xx_ess_sw.c
@@ -76,6 +76,7 @@
 	case MACH_TYPE_IPQ40XX_AP_DK04_1_C3:
 	case MACH_TYPE_IPQ40XX_AP_DK06_1_C1:
 	case MACH_TYPE_IPQ40XX_AP_DK07_1_C1:
+	case MACH_TYPE_IPQ40XX_AP_DK07_1_C2:
 	case MACH_TYPE_IPQ40XX_AP_DK07_1_C3:
 
 		ipq40xx_ess_sw_wr(S17_P0LOOKUP_CTRL_REG, 0x140000);
diff --git a/drivers/net/ipq40xx/ipq40xx_mdio.c b/drivers/net/ipq40xx/ipq40xx_mdio.c
index 702ba63..d4dd918 100644
--- a/drivers/net/ipq40xx/ipq40xx_mdio.c
+++ b/drivers/net/ipq40xx/ipq40xx_mdio.c
@@ -118,7 +118,7 @@
 	bus->read = ipq40xx_phy_read;
 	bus->write = ipq40xx_phy_write;
 	bus->reset = NULL;
-	sprintf(bus->name, name);
+	snprintf(bus->name, MDIO_NAME_LEN, name);
 	return mdio_register(bus);
 }
 
diff --git a/drivers/net/ipq806x/ipq_gmac_eth.c b/drivers/net/ipq806x/ipq_gmac_eth.c
index be297d7..6caa4a2 100644
--- a/drivers/net/ipq806x/ipq_gmac_eth.c
+++ b/drivers/net/ipq806x/ipq_gmac_eth.c
@@ -881,6 +881,24 @@
 		}
 	}
 
+	ar8033_gpio_node = fdt_path_offset(gd->fdt_blob, "/ar8033_gpio");
+
+	if (ar8033_gpio_node != 0) {
+		bb_nodes[i] = malloc(sizeof(struct bitbang_nodes));
+		memset(bb_nodes[i], 0, sizeof(struct bitbang_nodes));
+
+		offset = fdt_first_subnode(gd->fdt_blob, ar8033_gpio_node);
+		bb_nodes[i]->mdio = fdtdec_get_uint(gd->fdt_blob, offset, "gpio", 0);
+
+		offset = fdt_next_subnode(gd->fdt_blob, offset);
+		bb_nodes[i]->mdc = fdtdec_get_uint(gd->fdt_blob, offset, "gpio", 0);
+
+		bb_miiphy_buses[i].priv = bb_nodes[i];
+		strlcpy(bb_miiphy_buses[i].name, "8033",
+				sizeof(bb_miiphy_buses[i].name));
+		miiphy_register(bb_miiphy_buses[i].name, bb_miiphy_read, bb_miiphy_write);
+	}
+
 	/* set the mac address in environment for unconfigured GMAC */
 	if (ret >= 0) {
 		for (; i < CONFIG_IPQ_NO_MACS; i++) {
@@ -901,24 +919,6 @@
 		}
 	}
 
-	ar8033_gpio_node = fdt_path_offset(gd->fdt_blob, "/ar8033_gpio");
-
-	if (ar8033_gpio_node != 0) {
-		bb_nodes[i] = malloc(sizeof(struct bitbang_nodes));
-		memset(bb_nodes[i], 0, sizeof(struct bitbang_nodes));
-
-		offset = fdt_first_subnode(gd->fdt_blob, ar8033_gpio_node);
-		bb_nodes[i]->mdio = fdtdec_get_uint(gd->fdt_blob, offset, "gpio", 0);
-
-		offset = fdt_next_subnode(gd->fdt_blob, offset);
-		bb_nodes[i]->mdc = fdtdec_get_uint(gd->fdt_blob, offset, "gpio", 0);
-
-		bb_miiphy_buses[i].priv = bb_nodes[i];
-		strncpy(bb_miiphy_buses[i].name, "8033",
-				sizeof(bb_miiphy_buses[i].name));
-		miiphy_register(bb_miiphy_buses[i].name, bb_miiphy_read, bb_miiphy_write);
-	}
-
 	return 0;
 
 failed:
diff --git a/drivers/net/ipq_common/ipq_mdio.c b/drivers/net/ipq_common/ipq_mdio.c
index a33f0d3..e63373d 100644
--- a/drivers/net/ipq_common/ipq_mdio.c
+++ b/drivers/net/ipq_common/ipq_mdio.c
@@ -180,7 +180,7 @@
 	bus->read = ipq_phy_read;
 	bus->write = ipq_phy_write;
 	bus->reset = NULL;
-	sprintf(bus->name, name);
+	snprintf(bus->name, MDIO_NAME_LEN, name);
 	return mdio_register(bus);
 }
 
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 5a1391f..318eae8 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -225,7 +225,8 @@
 		puts("WARN waiting for error on ep to be cleared\n");
 		return -EINVAL;
 	case EP_STATE_HALTED:
-		puts("WARN halted endpoint, queueing URB anyway.\n");
+		puts("WARN halted endpoint\n");
+		return -EPIPE;
 	case EP_STATE_STOPPED:
 	case EP_STATE_RUNNING:
 		debug("EP STATE RUNNING.\n");
diff --git a/include/configs/ipq40xx.h b/include/configs/ipq40xx.h
index 7cee93e..7163a29 100644
--- a/include/configs/ipq40xx.h
+++ b/include/configs/ipq40xx.h
@@ -70,6 +70,8 @@
 
 #define CONFIG_IPQ_APPSBL_IMG_TYPE	0x5
 
+#define CONFIG_SYS_DEVICE_NULLDEV
+
 /*
  * IPQ_TFTP_MIN_ADDR: Starting address of Linux HLOS region.
  * CONFIG_TZ_END_ADDR: Ending address of Trust Zone and starting
@@ -127,7 +129,7 @@
 #define CONFIG_ENV_SIZE_MAX		(256 << 10) /* 256 KB */
 #define CONFIG_ENV_RANGE		board_env_range
 #define CONFIG_ENV_SIZE			(256 << 10) /* 256 KB */
-#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE_MAX + (256 << 10))
+#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE_MAX + (2048 << 10))
 
 #define CONFIG_CMD_MEMTEST
 #define CONFIG_SYS_MEMTEST_START	CONFIG_SYS_SDRAM_BASE + 0x1300000
diff --git a/include/configs/ipq806x.h b/include/configs/ipq806x.h
index 61947ee..9a87322 100644
--- a/include/configs/ipq806x.h
+++ b/include/configs/ipq806x.h
@@ -87,6 +87,8 @@
 
 #define CONFIG_HW_WATCHDOG
 
+#define CONFIG_SYS_DEVICE_NULLDEV
+
 /* Environment */
 #define CONFIG_MSM_PCOMM
 #define CONFIG_ARCH_CPU_INIT
diff --git a/tools/fit_image.c b/tools/fit_image.c
index eb2a25e..8780409 100644
--- a/tools/fit_image.c
+++ b/tools/fit_image.c
@@ -100,7 +100,8 @@
 				params->imagefile, params->cmdname);
 		return (EXIT_FAILURE);
 	}
-	sprintf (tmpfile, "%s%s", params->imagefile, MKIMAGE_TMPFILE_SUFFIX);
+	snprintf (tmpfile, MKIMAGE_MAX_TMPFILE_LEN, "%s%s", params->imagefile, 
+					MKIMAGE_TMPFILE_SUFFIX);
 
 	/* We either compile the source file, or use the existing FIT image */
 	if (params->datafile) {
diff --git a/tools/pack.py b/tools/pack.py
index 14b7e92..ba304de 100755
--- a/tools/pack.py
+++ b/tools/pack.py
@@ -328,9 +328,21 @@
         """
 
         if fatal:
+            """Check cmd strings to display reason for failure."""
+
+            if "imxtract" in cmd:
+                self.script.append("failreason='error: failed on image extraction'\n")
+            elif "erase" in cmd:
+                self.script.append("failreason='error: failed on partition erase'\n")
+            elif "write" in cmd:
+                self.script.append("failreason='error: failed on partition write'\n")
+            else:
+                pass
+
             self.script.append(cmd
                                + ' || setenv stdout serial'
                                + ' && echo "$failedmsg"'
+                               + ' && echo "$failreason"'
                                + ' && exit 1\n')
         else:
             self.script.append(cmd + "\n")
diff --git a/tools/pack_legacy.py b/tools/pack_legacy.py
index eb4ae03..f64cf26 100755
--- a/tools/pack_legacy.py
+++ b/tools/pack_legacy.py
@@ -40,7 +40,7 @@
      with address location where the image has been loaded. The script
      expects the variable 'imgaddr' to be set.
 
-     u-boot> imgaddr=0x88000000 source $imgaddr:script
+     u-boot> imgaddr=$fileaddr source $imgaddr:script
 
 Host-side Pre-req
 
@@ -84,6 +84,9 @@
 
 version = "1.1"
 
+TABLE_VERSION_AK = 3
+TABLE_VERSION_DK = 4
+
 #
 # Python 2.6 and earlier did not have OrderedDict use the backport
 # from ordereddict package. If that is not available report error.
@@ -221,7 +224,6 @@
     TABLE_FMT = "<LLLL"
     TABLE_MAGIC1 = 0x55EE73AA
     TABLE_MAGIC2 = 0xE35EBDDB
-    TABLE_VERSION = 4
 
     Entry = namedtuple("Entry", "name offset length"
                         " attr1 attr2 attr3 which_flash")
@@ -235,6 +237,7 @@
         self.nand_blocksize = nand_blocksize
         self.nand_chipsize = nand_chipsize
         self.__partitions = OrderedDict()
+        self.tableversion = TABLE_VERSION_AK
 
     def __validate(self, part_fp):
         """Validate the MIBIB by checking for magic bytes."""
@@ -262,9 +265,11 @@
             or mtable.magic2 != MIBIB.TABLE_MAGIC2):
             error("invalid sys part. table, magic byte not present")
 
-        if mtable.version != MIBIB.TABLE_VERSION:
+        if (mtable.version != TABLE_VERSION_AK
+            and mtable.version != TABLE_VERSION_DK):
             error("unsupported partition table version")
 
+        self.tableversion = mtable.version
         for i in range(mtable.numparts):
             mentry_str = part_fp.read(struct.calcsize(MIBIB.ENTRY_FMT))
             mentry = struct.unpack(MIBIB.ENTRY_FMT, mentry_str)
@@ -933,10 +938,14 @@
 
         self.flinfo = flinfo
         if flinfo.type == "nand":
-            self.ipq_nand = False
+            if mibib.tableversion == TABLE_VERSION_AK:
+                self.ipq_nand = True
+            else:
+                self.ipq_nand = False
             script = NandScript(flinfo, self.ipq_nand, self.spi_nand)
         elif flinfo.type == "nor" or flinfo.type == "norplusnand":
-            self.spi_nand = self.bconf.get(board_section, "spi_nand_available")
+            if mibib.tableversion == TABLE_VERSION_DK:
+                self.spi_nand = self.bconf.get(board_section, "spi_nand_available")
             self.ipq_nand = False
             script = NorScript(flinfo, self.spi_nand)
         elif flinfo.type == "emmc":
@@ -1246,6 +1255,7 @@
         self.bconf_fname = "boardconfig"
         self.part_fname = None
         self.fconf_fname = None
+        self.genitb_fname = None
 
     def __init_pagesize(self, pagesize):
         """Set the pagesize, from the command line argument.
@@ -1393,9 +1403,10 @@
         fconf_fname = None
         bconf = False
         bconf_fname = None
+        genitb_fname = None
 
         try:
-            opts, args = getopt(argv[1:], "Bib:hp:t:o:c:m:f:F:")
+            opts, args = getopt(argv[1:], "Bib:hp:t:o:c:m:f:F:M:")
         except GetoptError, e:
             raise UsageError(e.msg)
 
@@ -1420,6 +1431,8 @@
                 bconf = True
             elif option == "-F":
                 bconf_fname = value
+            elif option == "-M":
+                genitb_fname= value
 
         if len(args) != 1:
             raise UsageError("insufficient arguments")
@@ -1443,6 +1456,8 @@
         if bconf_fname != None:
             self.bconf_fname = bconf_fname
 
+        self.genitb_fname = genitb_fname
+
     def usage(self, msg):
         """Print error message and command usage information.
 
@@ -1472,6 +1487,8 @@
         print "              default is IDIR-TYPE-SIZE-COUNT.img"
         print "              if the filename is relative, it is relative"
         print "              to the parent of IDIR."
+        print "   -M         specifies script name to build single ITB with multiple dtb's,"
+        print "              default disabled."
         print
         print "NOTE: The above invocation method of pack is deprecated."
         print "The new pack invocation uses a board config file to retrieve"
@@ -1508,6 +1525,17 @@
         parser.usage(e.args[0])
         sys.exit(1)
 
+    if parser.genitb_fname:
+       prc = subprocess.Popen(['sh', parser.genitb_fname])
+       prc.wait()
+
+       if prc.returncode != 0:
+          print 'ERROR: unable to create ITB'
+          return prc.returncode
+       else:
+          print '...ITB binary created'
+
+
     pack = Pack()
     if parser.bconf:
         pack.main_bconf(parser.flash_info.type, parser.images_dname,
diff --git a/tools/sysupgrade.c b/tools/sysupgrade.c
index 189ebbf..35b01a9 100644
--- a/tools/sysupgrade.c
+++ b/tools/sysupgrade.c
@@ -34,6 +34,7 @@
 #define CERT_SIZE		2048
 #define PRESENT		1
 #define MBN_HDR_SIZE		40
+#define SBL_HDR_SIZE		80
 #define SIG_SIZE		256
 #define NOT_PRESENT		0
 #define SIG_CERT_2_SIZE	4352
@@ -200,7 +201,7 @@
 
 	while ((file = readdir(dir)) != NULL) {
 		for (i = 0, sec = &sections[0]; i < NO_OF_SECTIONS; i++, sec++) {
-			if (strstr(file->d_name, sec->type)) {
+			if (!strncmp(file->d_name, sec->type, strlen(sec->type))) {
 				if (sec->pre_op) {
 					strlcat(sec->tmp_file, file->d_name,
 							sizeof(sec->tmp_file));
@@ -245,7 +246,7 @@
 
 	while ((file = readdir(dir)) != NULL) {
 		for (i = 0, sec = &sections[0]; i < NO_OF_SECTIONS; i++, sec++) {
-			if (strstr(file->d_name, sec->type)) {
+			if (!strncmp(file->d_name, sec->type, strlen(sec->type))) {
 				if (sec->pre_op) {
 					strlcat(sec->tmp_file, file->d_name,
 							sizeof(sec->tmp_file));
@@ -413,6 +414,18 @@
 }
 
 /**
+ * check_nand_preamble() compares first 12 bytes of section with
+ * pre defined PREAMBLE value and returns 0 if both value matches
+ */
+int check_nand_preamble(uint8_t *mfp)
+{
+	char magic[12] = { 0xd1, 0xdc, 0x4b, 0x84,
+			   0x34, 0x10, 0xd7, 0x73,
+			   0x5a, 0x43, 0x0b, 0x7d };
+	return memcmp(magic, mfp, sizeof(magic));
+}
+
+/**
  * get_sw_id_from_component_bin() parses the MBN header & checks image size v/s
  * code size. If both differ, it means signature & certificates are
  * appended at end.
@@ -451,17 +464,21 @@
 
 	mbn_hdr = (Mbn_Hdr *)fp;
 	if (strstr(section->file, sections[4].type)) {
-		uint32_t preamble = sections[2].is_present ? SBL_NAND_PREAMBLE : 0;
+		uint32_t preamble = !check_nand_preamble(fp) ? SBL_NAND_PREAMBLE : 0;
+		Sbl_Hdr *sbl_hdr = (Sbl_Hdr *)(fp + preamble);
 
-		mbn_hdr = (Mbn_Hdr *)(fp + preamble + SBL_HDR_RESERVED);
+		sig_cert_size = sbl_hdr->image_size - sbl_hdr->code_size;
+		cert_offset = preamble + sbl_hdr->cert_ptr - sbl_hdr->image_dest_ptr +
+				SBL_HDR_SIZE;
+	} else {
+		sig_cert_size = mbn_hdr->image_size - mbn_hdr->code_size;
+		cert_offset = mbn_hdr->cert_ptr - mbn_hdr->image_dest_ptr + 40;
 	}
-	sig_cert_size = mbn_hdr->image_size - mbn_hdr->code_size;
 	if (sig_cert_size != SIG_CERT_2_SIZE && sig_cert_size != SIG_CERT_3_SIZE) {
 		printf("WARNING: signature certificate size is different\n");
 		// ipq807x has certificate size as dynamic, hence ignore this check
 	}
 
-	cert_offset = mbn_hdr->cert_ptr - mbn_hdr->image_dest_ptr + 40;
 	printf("Image with version information\n");
 	sw_version = find_value((char *)(fp + cert_offset), "SW_ID", 17);
 	if (sw_version != NULL) {
@@ -887,9 +904,11 @@
 		char **src, char **sig, char **cert)
 {
 	Mbn_Hdr *mbn_hdr;
+	Sbl_Hdr *sbl_hdr;
 	int fd = open(section->file, O_RDONLY);
 	uint8_t *fp;
 	int sig_offset = 0;
+	int src_offset = 0;
 	int cert_offset = 0;
 	struct stat sb;
 	int sig_cert_size;
@@ -915,26 +934,34 @@
 
 	mbn_hdr = (Mbn_Hdr *)fp;
 	if (strstr(section->file, sections[4].type)) {
-		uint32_t preamble = sections[2].is_present ? SBL_NAND_PREAMBLE : 0;
+		uint32_t preamble = !check_nand_preamble(fp) ? SBL_NAND_PREAMBLE : 0;
 
-		mbn_hdr = (Mbn_Hdr *)(fp + preamble + SBL_HDR_RESERVED);
-		sig_offset = preamble + MBN_HDR_SIZE;
-		cert_offset = preamble + MBN_HDR_SIZE;
+		sbl_hdr = (Sbl_Hdr *)(fp + preamble);
+		src_offset = preamble;
+		sig_offset = preamble + sbl_hdr->sig_ptr - sbl_hdr->image_dest_ptr +
+				SBL_HDR_SIZE;
+		cert_offset = preamble + sbl_hdr->cert_ptr - sbl_hdr->image_dest_ptr +
+				SBL_HDR_SIZE;
+		sig_cert_size = sbl_hdr->image_size - sbl_hdr->code_size;
+		src_size = sbl_hdr->sig_ptr - sbl_hdr->image_dest_ptr + SBL_HDR_SIZE;
+	} else {
+		sig_cert_size = mbn_hdr->image_size - mbn_hdr->code_size;
+		src_size = mbn_hdr->sig_ptr - mbn_hdr->image_dest_ptr + MBN_HDR_SIZE;
+		sig_offset += mbn_hdr->sig_ptr - mbn_hdr->image_dest_ptr + MBN_HDR_SIZE;
+		cert_offset += mbn_hdr->cert_ptr - mbn_hdr->image_dest_ptr + MBN_HDR_SIZE;
 	}
-	sig_cert_size = mbn_hdr->image_size - mbn_hdr->code_size;
+
 	if (sig_cert_size != SIG_CERT_2_SIZE && sig_cert_size != SIG_CERT_3_SIZE) {
 		printf("WARNING: signature certificate size is different\n");
 	}
-	src_size = mbn_hdr->sig_ptr - mbn_hdr->image_dest_ptr + MBN_HDR_SIZE;
         *src = malloc(src_size + 1);
 	if (*src == NULL) {
 		close(fd);
 		return 0;
 	}
-	memcpy(*src, fp, src_size);
+	memcpy(*src, fp + src_offset, src_size);
 	(*src)[src_size] = '\0';
 
-	sig_offset += mbn_hdr->sig_ptr - mbn_hdr->image_dest_ptr + MBN_HDR_SIZE;
 	*sig = malloc((SIG_SIZE + 1) * sizeof(char));
 	if (*sig == NULL) {
 		free(*src);
@@ -943,7 +970,6 @@
 	memcpy(*sig, fp + sig_offset, SIG_SIZE);
 	(*sig)[SIG_SIZE] = '\0';
 
-	cert_offset += mbn_hdr->cert_ptr - mbn_hdr->image_dest_ptr + MBN_HDR_SIZE;
 	*cert = malloc((CERT_SIZE + 1) * sizeof(char));
 	if (*cert == NULL) {
 		free(*src);
diff --git a/tools/sysupgrade.h b/tools/sysupgrade.h
index 1e53ff8..2be2760 100644
--- a/tools/sysupgrade.h
+++ b/tools/sysupgrade.h
@@ -82,6 +82,29 @@
 	__be32  hdr_crc;
 };
 
+typedef struct {
+	uint32_t  codeword;
+	uint32_t  magic;
+	uint32_t  RESERVED_0;
+	uint32_t  RESERVED_1;
+	uint32_t  RESERVED_2;
+	uint32_t  image_src;
+	uint8_t  *image_dest_ptr;
+	uint32_t  image_size;
+	uint32_t  code_size;
+	uint8_t  *sig_ptr;
+	uint32_t  sig_size;
+	uint8_t  *cert_ptr;
+	uint32_t  cert_size;
+	uint32_t  root_cert_sel;
+	uint32_t  num_root_certs;
+	uint32_t  RESERVED_5;
+	uint32_t  RESERVED_6;
+	uint32_t  RESERVED_7;
+	uint32_t  RESERVED_8;
+	uint32_t  RESERVED_9;
+} Sbl_Hdr;
+
 int get_sections(void);
 int is_authentication_check_enabled(void);
 int get_local_image_version(struct image_section *);
@@ -103,3 +126,4 @@
 int is_component_authenticated(char *, char *, char *);
 int is_image_authenticated(void);
 int do_board_upgrade_check(char *);
+int check_nand_preamble(uint8_t *);