Merge "platform: msm_shared: add enum to select pm660."
diff --git a/AndroidBoot.mk b/AndroidBoot.mk
index 104f4de..0156c52 100644
--- a/AndroidBoot.mk
+++ b/AndroidBoot.mk
@@ -1,16 +1,24 @@
 #Android makefile to build lk bootloader as a part of Android Build
 
+ifeq ($(PRODUCT_IOT),true)
+  LK_PATH := hardware/bsp/bootloader/qcom/lk
+  CROOT_DIR := ../../../../..
+else
+  LK_PATH := bootable/bootloader/lk/
+  CROOT_DIR := ../../..
+endif
+
 ifeq ($(BOOTLOADER_GCC_VERSION),)
 ifndef $(2ND_TARGET_GCC_VERSION)
-CROSS_COMPILE := ../../../prebuilts/gcc/linux-x86/arm/arm-eabi-$(TARGET_GCC_VERSION)/bin/arm-eabi-
+CROSS_COMPILE := $(CROOT_DIR)/prebuilts/gcc/linux-x86/arm/arm-eabi-$(TARGET_GCC_VERSION)/bin/arm-eabi-
 else
-CROSS_COMPILE := ../../../prebuilts/gcc/linux-x86/arm/arm-eabi-$(2ND_TARGET_GCC_VERSION)/bin/arm-eabi-
+CROSS_COMPILE := $(CROOT_DIR)/prebuilts/gcc/linux-x86/arm/arm-eabi-$(2ND_TARGET_GCC_VERSION)/bin/arm-eabi-
 endif
 else # BOOTLOADER_GCC_VERSION defined
 ifeq ($(BOOTLOADER_GCC_VERSION),arm-linux-androideabi-4.9)
-CROSS_COMPILE := ../../../prebuilts/gcc/linux-x86/arm/$(BOOTLOADER_GCC_VERSION)/bin/arm-linux-androideabi-
+CROSS_COMPILE := $(CROOT_DIR)/prebuilts/gcc/linux-x86/arm/$(BOOTLOADER_GCC_VERSION)/bin/arm-linux-androideabi-
 else
-CROSS_COMPILE := ../../../prebuilts/gcc/linux-x86/arm/$(BOOTLOADER_GCC_VERSION)/bin/arm-eabi-
+CROSS_COMPILE := $(CROOT_DIR)/prebuilts/gcc/linux-x86/arm/$(BOOTLOADER_GCC_VERSION)/bin/arm-eabi-
 endif
 endif
 
@@ -31,6 +39,16 @@
   VERIFIED_BOOT := VERIFIED_BOOT=0
 endif
 
+ifeq ($(EARLY_MOUNT_SUPPORT),true)
+  ENABLE_BOOTDEVICE_MOUNT := ENABLE_BOOTDEVICE_MOUNT=1
+else
+  ENABLE_BOOTDEVICE_MOUNT := ENABLE_BOOTDEVICE_MOUNT=0
+endif
+
+ifeq ($(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_PM660),true)
+  ENABLE_BG_SUPPORT := ENABLE_BG_SUPPORT=1
+endif
+
 ifeq ($(BOOTLOADER_DISABLE_DISPLAY),true)
   ENABLE_DISPLAY := ENABLE_DISPLAY=0
 else
@@ -53,6 +71,10 @@
   BUILD_VARIANT := USER_BUILD_VARIANT=true
 endif
 
+ifeq ($(TARGET_BOARD_PLATFORM),msm8x09)
+  BOOTLOADER_PLATFORM := msm8909
+endif
+
 ifeq ($(TARGET_BOARD_PLATFORM),msm8660)
   BOOTLOADER_PLATFORM := msm8660_surf
 endif
@@ -73,7 +95,7 @@
 # ELF binary for ABOOT
 TARGET_ABOOT_ELF := $(PRODUCT_OUT)/aboot.elf
 $(TARGET_ABOOT_ELF): ABOOT_CLEAN | $(ABOOT_OUT)
-	$(MAKE) -C bootable/bootloader/lk TOOLCHAIN_PREFIX=$(CROSS_COMPILE) BOOTLOADER_OUT=../../../$(ABOOT_OUT) $(BOOTLOADER_PLATFORM) $(EMMC_BOOT) $(SIGNED_KERNEL) $(VERIFIED_BOOT) $(ENABLE_DISPLAY) $(DEVICE_STATUS) $(BUILD_VARIANT) $(BOARD_NAME) $(ENABLE_VB_ATTEST) $(OSVERSION_IN_BOOTIMAGE)
+	$(MAKE) -C $(LK_PATH) TOOLCHAIN_PREFIX=$(CROSS_COMPILE) BOOTLOADER_OUT=$(CROOT_DIR)/$(ABOOT_OUT) $(BOOTLOADER_PLATFORM) $(EMMC_BOOT) $(SIGNED_KERNEL) $(VERIFIED_BOOT) $(ENABLE_DISPLAY) $(ENABLE_BOOTDEVICE_MOUNT) $(DEVICE_STATUS) $(BUILD_VARIANT) $(BOARD_NAME) $(ENABLE_VB_ATTEST) $(OSVERSION_IN_BOOTIMAGE)
 
 # NAND variant output
 TARGET_NAND_BOOTLOADER := $(PRODUCT_OUT)/appsboot.mbn
@@ -98,11 +120,11 @@
 
 # Top level for NAND variant targets
 $(TARGET_NAND_BOOTLOADER): appsbootldr_clean | $(NAND_BOOTLOADER_OUT)
-	$(MAKE) -C bootable/bootloader/lk TOOLCHAIN_PREFIX=$(CROSS_COMPILE) BOOTLOADER_OUT=../../../$(NAND_BOOTLOADER_OUT) $(BOOTLOADER_PLATFORM) $(SIGNED_KERNEL) $(BOARD_NAME)
+	$(MAKE) -C $(LK_PATH) TOOLCHAIN_PREFIX=$(CROSS_COMPILE) BOOTLOADER_OUT=$(CROOT_DIR)/$(NAND_BOOTLOADER_OUT) $(BOOTLOADER_PLATFORM) $(SIGNED_KERNEL) $(BOARD_NAME)
 
 # Top level for eMMC variant targets
 $(TARGET_EMMC_BOOTLOADER): emmc_appsbootldr_clean | $(EMMC_BOOTLOADER_OUT) $(INSTALLED_KEYSTOREIMAGE_TARGET)
-	$(MAKE) -C bootable/bootloader/lk TOOLCHAIN_PREFIX=$(CROSS_COMPILE) BOOTLOADER_OUT=../../../$(EMMC_BOOTLOADER_OUT) $(BOOTLOADER_PLATFORM) EMMC_BOOT=1 $(SIGNED_KERNEL) $(VERIFIED_BOOT) $(ENABLE_DISPLAY) $(DEVICE_STATUS) $(BUILD_VARIANT) $(BOARD_NAME) $(ENABLE_VB_ATTEST) $(OSVERSION_IN_BOOTIMAGE)
+	$(MAKE) -C $(LK_PATH) TOOLCHAIN_PREFIX=$(CROSS_COMPILE) BOOTLOADER_OUT=$(CROOT_DIR)/$(EMMC_BOOTLOADER_OUT) $(BOOTLOADER_PLATFORM) EMMC_BOOT=1 $(SIGNED_KERNEL) $(VERIFIED_BOOT) $(ENABLE_DISPLAY) $(ENABLE_BOOTDEVICE_MOUNT) $(DEVICE_STATUS) $(BUILD_VARIANT) $(BOARD_NAME) $(ENABLE_VB_ATTEST) $(OSVERSION_IN_BOOTIMAGE)
 
 # Keep build NAND & eMMC as default for targets still using TARGET_BOOTLOADER
 TARGET_BOOTLOADER := $(PRODUCT_OUT)/EMMCBOOT.MBN
@@ -123,4 +145,4 @@
 
 $(TARGET_NANDWRITE): nandwrite_clean | $(NANDWRITE_OUT)
 	@echo $(BOOTLOADER_PLATFORM)_nandwrite
-	$(MAKE) -C bootable/bootloader/lk TOOLCHAIN_PREFIX=$(CROSS_COMPILE) BOOTLOADER_OUT=../../../$(NANDWRITE_OUT) $(BOOTLOADER_PLATFORM)_nandwrite BUILD_NANDWRITE=1
+	$(MAKE) -C $(LK_PATH) TOOLCHAIN_PREFIX=$(CROSS_COMPILE) BOOTLOADER_OUT=$(CROOT_DIR)/$(NANDWRITE_OUT) $(BOOTLOADER_PLATFORM)_nandwrite BUILD_NANDWRITE=1
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index c873882..26c5d1c 100755
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -185,7 +185,8 @@
 static const char *baseband_apq_nowgr   = " androidboot.baseband=baseband_apq_nowgr";
 static const char *androidboot_slot_suffix = " androidboot.slot_suffix=";
 static const char *skip_ramfs = " skip_initramfs";
-static char *sys_path_cmdline = " rootwait ro init=/init root=/dev/mmcblk0p%d"; /*This will be updated*/
+static const char *sys_path_cmdline = " rootwait ro init=/init";
+static const char *sys_path = "  root=/dev/mmcblk0p";
 
 #if VERIFIED_BOOT
 #if !VBOOT_MOTA
@@ -347,6 +348,11 @@
 	char *boot_dev_buf = NULL;
     	bool is_mdtp_activated = 0;
 	int current_active_slot = INVALID;
+	int system_ptn_index = -1;
+	unsigned int lun = 0;
+	char lun_char_base = 'a';
+	int syspath_buflen = strlen(sys_path) + sizeof(int) + 1; /*allocate buflen for largest possible string*/
+	char syspath_buf[syspath_buflen];
 
 #if USE_LE_SYSTEMD
 	is_systemd_present=true;
@@ -495,10 +501,22 @@
 		cmdline_len += (strlen(androidboot_slot_suffix)+
 					strlen(SUFFIX_SLOT(current_active_slot)));
 
-		snprintf(sys_path_cmdline, sizeof(*sys_path_cmdline),
-				sys_path_cmdline, (partition_get_index("system")+1));
-		cmdline_len += strlen(sys_path_cmdline);
+		system_ptn_index = partition_get_index("system");
+		if (platform_boot_dev_isemmc())
+		{
+			snprintf(syspath_buf, syspath_buflen, " root=/dev/mmcblk0p%d",
+				system_ptn_index + 1);
+		}
+		else
+		{
+			lun = partition_get_lun(system_ptn_index);
+			snprintf(syspath_buf, syspath_buflen, " root=/dev/sd%c%d",
+					lun_char_base + lun,
+					partition_get_index_in_lun("system", lun));
+		}
 
+		cmdline_len += strlen(sys_path_cmdline);
+		cmdline_len += strlen(syspath_buf);
 		if (!boot_into_recovery)
 			cmdline_len += strlen(skip_ramfs);
 	}
@@ -722,6 +740,10 @@
 				src = sys_path_cmdline;
 				--dst;
 				while ((*dst++ = *src++));
+
+				src = syspath_buf;
+				--dst;
+				while ((*dst++ = *src++));
 		}
 
 #if TARGET_CMDLINE_SUPPORT
@@ -1242,6 +1264,7 @@
 
 	kernel_actual  = ROUND_TO_PAGE(hdr->kernel_size,  page_mask);
 	ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
+	second_actual  = ROUND_TO_PAGE(hdr->second_size, page_mask);
 
 	image_addr = (unsigned char *)target_get_scratch_address();
 	memcpy(image_addr, (void *)buf, page_size);
@@ -1254,17 +1277,17 @@
 	dt_size = hdr->dt_size;
 #endif
 	dt_actual = ROUND_TO_PAGE(dt_size, page_mask);
-	if (UINT_MAX < ((uint64_t)kernel_actual + (uint64_t)ramdisk_actual+ (uint64_t)dt_actual + page_size)) {
+	if (UINT_MAX < ((uint64_t)kernel_actual + (uint64_t)ramdisk_actual+ (uint64_t)second_actual + (uint64_t)dt_actual + page_size)) {
 		dprintf(CRITICAL, "Integer overflow detected in bootimage header fields at %u in %s\n",__LINE__,__FILE__);
 		return -1;
 	}
-	imagesize_actual = (page_size + kernel_actual + ramdisk_actual + dt_actual);
+	imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual + dt_actual);
 #else
-	if (UINT_MAX < ((uint64_t)kernel_actual + (uint64_t)ramdisk_actual + page_size)) {
+	if (UINT_MAX < ((uint64_t)kernel_actual + (uint64_t)ramdisk_actual + (uint64_t)second_actual + page_size)) {
 		dprintf(CRITICAL, "Integer overflow detected in bootimage header fields at %u in %s\n",__LINE__,__FILE__);
 		return -1;
 	}
-	imagesize_actual = (page_size + kernel_actual + ramdisk_actual);
+	imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual);
 #endif
 
 #if VERIFIED_BOOT
@@ -1395,6 +1418,8 @@
 
 #if VERIFIED_BOOT
 #if !VBOOT_MOTA
+	/* set boot and system versions. */
+	set_os_version((unsigned char *)image_addr);
 	// send root of trust
 	if(!send_rot_command((uint32_t)device.is_unlocked))
 		ASSERT(0);
@@ -1671,6 +1696,7 @@
 
 	kernel_actual  = ROUND_TO_PAGE(hdr->kernel_size,  page_mask);
 	ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
+	second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
 
 	/* ensure commandline is terminated */
 	hdr->cmdline[BOOT_ARGS_SIZE-1] = 0;
@@ -1684,6 +1710,12 @@
 	}
 
 #ifndef DEVICE_TREE
+	if (UINT_MAX < ((uint64_t)kernel_actual + (uint64_t)ramdisk_actual+ (uint64_t)second_actual + page_size)) {
+		dprintf(CRITICAL, "Integer overflow detected in bootimage header fields\n");
+		return -1;
+	}
+	imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual);
+
 	if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE))
 	{
 		dprintf(CRITICAL, "Tags addresses overlap with aboot addresses.\n");
@@ -1694,34 +1726,24 @@
 #ifndef OSVERSION_IN_BOOTIMAGE
 	dt_size = hdr->dt_size;
 #endif
+	dt_actual = ROUND_TO_PAGE(dt_size, page_mask);
+	if (UINT_MAX < ((uint64_t)kernel_actual + (uint64_t)ramdisk_actual+ (uint64_t)second_actual + (uint64_t)dt_actual + page_size)) {
+		dprintf(CRITICAL, "Integer overflow detected in bootimage header fields\n");
+		return -1;
+	}
+
+	imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual + dt_actual);
+
+	if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_size))
+	{
+		dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
+		return -1;
+	}
 #endif
 
 	/* Authenticate Kernel */
 	if(target_use_signed_kernel() && (!device.is_unlocked))
 	{
-
-#if DEVICE_TREE
-		dt_actual = ROUND_TO_PAGE(dt_size, page_mask);
-		if (UINT_MAX < ((uint64_t)kernel_actual + (uint64_t)ramdisk_actual+ (uint64_t)dt_actual + page_size)) {
-			dprintf(CRITICAL, "Integer overflow detected in bootimage header fields\n");
-			return -1;
-		}
-
-		imagesize_actual = (page_size + kernel_actual + ramdisk_actual + dt_actual);
-
-		if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_size))
-		{
-			dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
-			return -1;
-		}
-#else
-		if (UINT_MAX < ((uint64_t)kernel_actual + (uint64_t)ramdisk_actual+ page_size)) {
-			dprintf(CRITICAL, "Integer overflow detected in bootimage header fields\n");
-			return -1;
-		}
-		imagesize_actual = (page_size + kernel_actual + ramdisk_actual);
-#endif
-
 		dprintf(INFO, "Loading (%s) image (%d): start\n",
 			(!boot_into_recovery ? "boot" : "recovery"),imagesize_actual);
 		bs_set_timestamp(BS_KERNEL_LOAD_START);
@@ -1775,6 +1797,13 @@
 				return -1;
 			}
 
+			/* Its Error if, dt_hdr_size (table->num_entries * dt_entry size + Dev_Tree Header)
+			goes beyound hdr->dt_size*/
+			if (dt_hdr_size > ROUND_TO_PAGE(dt_size, hdr->page_size)) {
+				dprintf(CRITICAL, "ERROR: Invalid Device Tree size \n");
+				return -1;
+			}
+
 			/* Find index of device tree within device tree table */
 			if(dev_tree_get_entry_info(table, &dt_entry) != 0){
 				dprintf(CRITICAL, "ERROR: Getting device tree address failed\n");
@@ -1815,17 +1844,12 @@
 	}
 	else
 	{
-		offset = page_size;
-
-		kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
-		ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
-		second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
-
 		dprintf(INFO, "Loading (%s) image (%d): start\n",
 				(!boot_into_recovery ? "boot" : "recovery"), kernel_actual + ramdisk_actual);
 
 		bs_set_timestamp(BS_KERNEL_LOAD_START);
 
+		offset = page_size;
 		if (UINT_MAX - offset < kernel_actual)
 		{
 			dprintf(CRITICAL, "ERROR: Integer overflow in boot image header %s\t%d\n",__func__,__LINE__);
@@ -1887,16 +1911,19 @@
 				return -1;
 			}
 
-			table = (struct dt_table*) memalign(CACHE_LINE, dt_hdr_size);
-			if (!table)
-				return -1;
-
-			/* Read the entire device tree table into buffer */
-			if(flash_read(ptn, offset, (void *)table, dt_hdr_size)) {
-				dprintf(CRITICAL, "ERROR: Cannot read the Device Tree Table\n");
+			table = (void *) target_get_scratch_address();
+			/*Check the availability of RAM before reading boot image + max signature length from flash*/
+			if (target_get_max_flash_size() < dt_actual)
+			{
+				dprintf(CRITICAL, "ERROR: dt_image size is greater than DDR can hold\n");
 				return -1;
 			}
 
+			/* Read the entire device tree table into buffer */
+			if(flash_read(ptn, offset, (void *)table, dt_actual)) {
+				dprintf(CRITICAL, "ERROR: Cannot read the Device Tree Table\n");
+				return -1;
+			}
 
 			/* Find index of device tree within device tree table */
 			if(dev_tree_get_entry_info(table, &dt_entry) != 0){
@@ -1911,12 +1938,20 @@
 				return -1;
 			}
 
-			/* Read device device tree in the "tags_add */
-			if(flash_read(ptn, offset + dt_entry.offset,
-						 (void *)hdr->tags_addr, dt_entry.size)) {
-				dprintf(CRITICAL, "ERROR: Cannot read device tree\n");
+			if(dt_entry.offset > (UINT_MAX - dt_entry.size)) {
+				dprintf(CRITICAL, "ERROR: Device tree contents are Invalid\n");
 				return -1;
 			}
+
+			/* Ensure we are not overshooting dt_size with the dt_entry selected */
+			if ((dt_entry.offset + dt_entry.size) > dt_size) {
+				dprintf(CRITICAL, "ERROR: Device tree contents are Invalid\n");
+				return -1;
+			}
+
+			best_match_dt_addr = (unsigned char *)table + dt_entry.offset;
+			dtb_size = dt_entry.size;
+			memmove((void *)hdr->tags_addr, (char *)best_match_dt_addr, dtb_size);
 		}
 #endif
 
@@ -2446,6 +2481,7 @@
 #endif /* MDTP_SUPPORT */
 	unsigned kernel_actual;
 	unsigned ramdisk_actual;
+	unsigned second_actual;
 	uint32_t image_actual;
 	uint32_t dt_actual = 0;
 	uint32_t sig_actual = 0;
@@ -2493,6 +2529,7 @@
 
 	kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
 	ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
+	second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
 #if DEVICE_TREE
 #ifndef OSVERSION_IN_BOOTIMAGE
 	dt_size = hdr->dt_size;
@@ -2502,6 +2539,7 @@
 
 	image_actual = ADD_OF(page_size, kernel_actual);
 	image_actual = ADD_OF(image_actual, ramdisk_actual);
+	image_actual = ADD_OF(image_actual, second_actual);
 	image_actual = ADD_OF(image_actual, dt_actual);
 
 	/* Checking to prevent oob access in read_der_message_length */
@@ -2571,6 +2609,8 @@
 
 #if VERIFIED_BOOT
 #if !VBOOT_MOTA
+	/* set boot and system versions. */
+	set_os_version((unsigned char *)data);
 	// send root of trust
 	if(!send_rot_command((uint32_t)device.is_unlocked))
 		ASSERT(0);
@@ -3021,6 +3061,7 @@
 	uint64_t chunk_data_sz;
 	uint32_t *fill_buf = NULL;
 	uint32_t fill_val;
+	uint32_t blk_sz_actual = 0;
 	sparse_header_t *sparse_header;
 	chunk_header_t *chunk_header;
 	uint32_t total_blocks = 0;
@@ -3052,6 +3093,11 @@
 	/* Read and skip over sparse image header */
 	sparse_header = (sparse_header_t *) data;
 
+	if (!sparse_header->blk_sz || (sparse_header->blk_sz % 4)){
+		fastboot_fail("Invalid block size\n");
+		return;
+	}
+
 	if (((uint64_t)sparse_header->total_blks * (uint64_t)sparse_header->blk_sz) > size) {
 		fastboot_fail("size too large");
 		return;
@@ -3108,11 +3154,6 @@
 			return;
 		}
 
-		if (!sparse_header->blk_sz ){
-			fastboot_fail("Invalid block size\n");
-			return;
-		}
-
 		chunk_data_sz = (uint64_t)sparse_header->blk_sz * chunk_header->chunk_sz;
 
 		/* Make sure that the chunk size calculated from sparse image does not
@@ -3165,7 +3206,15 @@
 				return;
 			}
 
-			fill_buf = (uint32_t *)memalign(CACHE_LINE, ROUNDUP(sparse_header->blk_sz, CACHE_LINE));
+			blk_sz_actual = ROUNDUP(sparse_header->blk_sz, CACHE_LINE);
+			/* Integer overflow detected */
+			if (blk_sz_actual < sparse_header->blk_sz)
+			{
+				fastboot_fail("Invalid block size");
+				return;
+			}
+
+			fill_buf = (uint32_t *)memalign(CACHE_LINE, blk_sz_actual);
 			if (!fill_buf)
 			{
 				fastboot_fail("Malloc failed for: CHUNK_TYPE_FILL");
@@ -3546,7 +3595,7 @@
 
 void cmd_set_active(const char *arg, void *data, unsigned sz)
 {
-	char *p = NULL;
+	char *p, *sp = NULL;
 	unsigned i,current_active_slot;
 	const char *current_slot_suffix;
 
@@ -3558,14 +3607,18 @@
 
 	if (arg)
 	{
-		p = (char *)arg;
+		p = strtok_r((char *)arg, ":", &sp);
 		if (p)
 		{
 			current_active_slot = partition_find_active_slot();
 
 			/* Check if trying to make curent slot active */
 			current_slot_suffix = SUFFIX_SLOT(current_active_slot);
-			if (!strncmp(p, current_slot_suffix, sizeof(current_slot_suffix)))
+			current_slot_suffix = strtok_r((char *)current_slot_suffix,
+							(char *)suffix_delimiter, &sp);
+
+			if (current_slot_suffix &&
+				!strncmp(p, current_slot_suffix, strlen(current_slot_suffix)))
 			{
 				fastboot_okay("Slot already set active");
 				return;
@@ -3575,7 +3628,10 @@
 				for (i = 0; i < AB_SUPPORTED_SLOTS; i++)
 				{
 					current_slot_suffix = SUFFIX_SLOT(i);
-					if (!strncmp(p, current_slot_suffix, sizeof(current_slot_suffix)))
+					current_slot_suffix = strtok_r((char *)current_slot_suffix,
+									(char *)suffix_delimiter, &sp);
+					if (current_slot_suffix &&
+						!strncmp(p, current_slot_suffix, strlen(current_slot_suffix)))
 					{
 						partition_switch_slots(current_active_slot, i);
 						publish_getvar_multislot_vars();
@@ -4132,7 +4188,7 @@
 						{"oem disable-charger-screen", cmd_oem_disable_charger_screen},
 						{"oem off-mode-charge", cmd_oem_off_mode_charger},
 						{"oem select-display-panel", cmd_oem_select_display_panel},
-						{"oem set_active",cmd_set_active},
+						{"set_active",cmd_set_active},
 #if UNITTEST_FW_SUPPORT
 						{"oem run-tests", cmd_oem_runtests},
 #endif
diff --git a/app/aboot/mdtp_ui.c b/app/aboot/mdtp_ui.c
index 72e4302..1dc2d06 100644
--- a/app/aboot/mdtp_ui.c
+++ b/app/aboot/mdtp_ui.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -132,8 +132,13 @@
 	{
 		uint8_t *base = logo->image;
 		unsigned bytes_per_bpp = ((fb_config->bpp) / BITS_PER_BYTE);
+		unsigned int data_len = ROUNDUP(width*height*bytes_per_bpp, block_size);
+		if (data_len > MDTP_MAX_IMAGE_SIZE) {
+			dprintf(CRITICAL, "ERROR: incorrect mdtp image size\n");
+			return NULL;
+		}
 
-		if (mmc_read(ptn+offset, (void*)base, ROUNDUP(width*height*bytes_per_bpp, block_size))) {
+		if (mmc_read(ptn+offset, (void*)base, data_len)) {
 			fbcon_clear();
 			dprintf(CRITICAL, "ERROR: mdtp image read failed\n");
 			return NULL;
diff --git a/dev/gcdb/display/include/panel_auo_390p_cmd.h b/dev/gcdb/display/include/panel_auo_390p_cmd.h
new file mode 100644
index 0000000..d886cb2
--- /dev/null
+++ b/dev/gcdb/display/include/panel_auo_390p_cmd.h
@@ -0,0 +1,244 @@
+/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name of The Linux Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _PANEL_AUO_390P_CMD_H_
+
+#define _PANEL_AUO_390P_CMD_H_
+/*---------------------------------------------------------------------------*/
+/* HEADER files                                                              */
+/*---------------------------------------------------------------------------*/
+#include "panel.h"
+
+/*---------------------------------------------------------------------------*/
+/* Panel configuration                                                       */
+/*---------------------------------------------------------------------------*/
+
+static struct panel_config auo_390p_cmd_panel_data = {
+	"qcom,mdss_dsi_auo_390p_cmd", "dsi:0:", "qcom,mdss-dsi-panel",
+	11, 1, "DISPLAY_1", 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel resolution                                                          */
+/*---------------------------------------------------------------------------*/
+static struct panel_resolution auo_390p_cmd_panel_res = {
+	390, 390, 4, 4, 4, 0, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel Color Information                                                   */
+/*---------------------------------------------------------------------------*/
+static struct color_info auo_390p_cmd_color = {
+	24, 0, 0xff, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel Command information                                                 */
+/*---------------------------------------------------------------------------*/
+static char auo_390p_cmd_on_cmd0[] = {
+	0xfe, 0x01, 0x015, 0x80,
+};
+
+static char auo_390p_cmd_on_cmd1[] = {
+	0x0a, 0xf0, 0x015, 0x80,
+};
+
+static char auo_390p_cmd_on_cmd2[] = {
+	0xfe, 0x00, 0x15, 0x80,
+};
+
+
+static char auo_390p_cmd_on_cmd3[] = {
+	0x35, 0x00, 0x15, 0x80,
+};
+
+
+static char auo_390p_cmd_on_cmd4[] = {
+	0x05, 0x00, 0x29, 0xC0,
+	0x2a, 0x00, 0x04, 0x01,
+	0x89, 0xFF, 0xFF, 0xFF,
+};
+
+
+static char auo_390p_cmd_on_cmd5[] = {
+	0x05, 0x00, 0x29, 0xC0,
+	0x2b, 0x00, 0x00, 0x01,
+	0x85, 0xFF, 0xFF, 0xFF,
+};
+
+
+static char auo_390p_cmd_on_cmd6[] = {
+	0x05, 0x00, 0x29, 0xC0,
+	0x30, 0x00, 0x00, 0x01,
+	0x85, 0xFF, 0xFF, 0xFF,
+};
+
+
+static char auo_390p_cmd_on_cmd7[] = {
+	0x05, 0x00, 0x29, 0xC0,
+	0x31, 0x00, 0x04, 0x01,
+	0x89, 0xFF, 0xFF, 0xFF,
+};
+
+
+static char auo_390p_cmd_on_cmd8[] = {
+	0x12, 0x00, 0x05, 0x80,
+};
+
+
+static char auo_390p_cmd_on_cmd9[] = {
+	0x53, 0x20, 0x015, 0x80,
+};
+
+
+static char auo_390p_cmd_on_cmd10[] = {
+	0x11, 0x00, 0x05, 0x80,
+};
+
+
+static char auo_390p_cmd_on_cmd11[] = {
+	0x29, 0x00, 0x05, 0x80,
+};
+
+
+static char auo_390p_cmd_on_cmd12[] = {
+	0x06, 0x00, 0x39, 0xC0,
+	0xf0, 0x55, 0xaa, 0x52,
+	0x08, 0x01, 0xff, 0xff,
+};
+
+
+static char auo_390p_cmd_on_cmd13[] = {
+	0x07, 0x00, 0x39, 0xC0,
+	0xff, 0x00, 0x55, 0xaa,
+	0x52, 0x08, 0x01, 0xff,
+};
+
+
+static struct mipi_dsi_cmd auo_390p_cmd_on_command[] = {
+	{ 0x4 , auo_390p_cmd_on_cmd0, 0x00},
+	{ 0x4 , auo_390p_cmd_on_cmd1, 0x00},
+	{ 0x4 , auo_390p_cmd_on_cmd2, 0x00},
+	{ 0x4 , auo_390p_cmd_on_cmd3, 0x00},
+	{ 0xc , auo_390p_cmd_on_cmd4, 0x00},
+	{ 0xc , auo_390p_cmd_on_cmd5, 0x78},
+	{ 0xc , auo_390p_cmd_on_cmd6, 0x00},
+	{ 0xc , auo_390p_cmd_on_cmd7, 0x00},
+	{ 0x4 , auo_390p_cmd_on_cmd8, 0x00},
+	{ 0x4 , auo_390p_cmd_on_cmd9, 0x00},
+	{ 0x4 , auo_390p_cmd_on_cmd10, 0x00},
+	{ 0x4 , auo_390p_cmd_on_cmd11, 0x00},
+	{ 0xc , auo_390p_cmd_on_cmd12, 0x00},
+	{ 0xc , auo_390p_cmd_on_cmd13, 0x00},
+};
+
+#define AUO_390P_CMD_ON_COMMAND 14
+
+
+static char auo_390p_cmd_off_cmd0[] = {
+	0x28, 0x00, 0x05, 0x80
+};
+
+
+static char auo_390p_cmd_off_cmd1[] = {
+	0x10, 0x00, 0x05, 0x80
+};
+
+
+static struct mipi_dsi_cmd auo_390p_cmd_off_command[] = {
+	{ 0x4 , auo_390p_cmd_off_cmd0, 0x0},
+	{ 0x4 , auo_390p_cmd_off_cmd1, 0x0}
+};
+
+#define AUO_390P_CMD_OFF_COMMAND 2
+
+
+static struct command_state auo_390p_cmd_state = {
+	0, 1
+};
+
+/*---------------------------------------------------------------------------*/
+/* Command mode panel information                                            */
+/*---------------------------------------------------------------------------*/
+
+static struct commandpanel_info auo_390p_cmd_command_panel = {
+	0x1, 0x1, 0x1, 0, 0, 0, 0, 0, 0, 0x1, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Video mode panel information                                              */
+/*---------------------------------------------------------------------------*/
+
+static struct videopanel_info auo_390p_cmd_video_panel = {
+	0, 0, 0, 0, 1, 1, 1, 0, 0x9
+};
+
+/*---------------------------------------------------------------------------*/
+/* Lane Configuration                                                        */
+/*---------------------------------------------------------------------------*/
+
+static struct lane_configuration auo_390p_cmd_lane_config = {
+	1, 0, 1, 0, 0, 0, 0
+};
+
+
+/*---------------------------------------------------------------------------*/
+/* Panel Timing                                                              */
+/*---------------------------------------------------------------------------*/
+const uint32_t auo_390p_cmd_timings[] = {
+	0x5F, 0x12, 0x0A, 0x00, 0x32, 0x34, 0x10, 0x16, 0x0F, 0x03, 0x04, 0x00
+};
+
+static struct panel_timing auo_390p_cmd_timing_info = {
+	0, 4, 0x05, 0x11
+};
+
+static const uint32_t auo_390p_14nm_cmd_timings[] = {
+	0x23, 0x1e, 0x7, 0x8, 0x5, 0x3, 0x4, 0xa0,
+	0x23, 0x1e, 0x7, 0x8, 0x5, 0x3, 0x4, 0xa0,
+	0x23, 0x1e, 0x7, 0x8, 0x5, 0x3, 0x4, 0xa0,
+	0x23, 0x1e, 0x7, 0x8, 0x5, 0x3, 0x4, 0xa0,
+	0x23, 0x18, 0x7, 0x8, 0x5, 0x3, 0x4, 0xa0,
+};
+
+static struct panel_reset_sequence auo_390p_cmd_panel_reset_seq = {
+	{ 1, 0, 1, }, { 200, 200, 200, }, 2
+};
+
+/*---------------------------------------------------------------------------*/
+/* Backlight Settings                                                        */
+/*---------------------------------------------------------------------------*/
+
+static struct backlight auo_390p_cmd_backlight = {
+	1, 1, 4095, 100, 1, "PMIC_8941"
+};
+
+#define AUO_390P_CMD_SIGNATURE 0xFFFF
+
+#endif /*_AUO_390P_CMD_H_*/
diff --git a/dev/pmic/pm8x41/include/pm8x41.h b/dev/pmic/pm8x41/include/pm8x41.h
index 2c79ee4..2e0a270 100644
--- a/dev/pmic/pm8x41/include/pm8x41.h
+++ b/dev/pmic/pm8x41/include/pm8x41.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2015, 2017, The Linux Foundation. All rights reserved.
 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -64,6 +64,9 @@
 #define PON_PSHOLD_SHUTDOWN     0x4
 #define PON_PSHOLD_HARD_RESET   0x7
 
+#define PM_GPIO_NO_INVERT       0x00
+#define PM_GPIO_INVERT          0x01
+
 enum PM8X41_VERSIONS
 {
 	PM8X41_VERSION_V1 = 0,
diff --git a/dev/pmic/pm8x41/include/pm8x41_hw.h b/dev/pmic/pm8x41/include/pm8x41_hw.h
index 26fbd5e..6484a10 100644
--- a/dev/pmic/pm8x41/include/pm8x41_hw.h
+++ b/dev/pmic/pm8x41/include/pm8x41_hw.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2015, 2017, The Linux Foundation. All rights reserved.
 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -58,6 +58,7 @@
 #define GPIO_MODE_CTL                         0x40
 #define GPIO_DIG_VIN_CTL                      0x41
 #define GPIO_DIG_PULL_CTL                     0x42
+#define GPIO_DIG_OUT_SRC_CTL                  0x44
 #define GPIO_DIG_OUT_CTL                      0x45
 #define GPIO_EN_CTL                           0x46
 
diff --git a/dev/pmic/pm8x41/pm8x41.c b/dev/pmic/pm8x41/pm8x41.c
index 4a4da3a..51a0f96 100644
--- a/dev/pmic/pm8x41/pm8x41.c
+++ b/dev/pmic/pm8x41/pm8x41.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2015, 2017, The Linux Foundation. All rights reserved.
 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -186,6 +186,10 @@
 		REG_WRITE(gpio_base + GPIO_DIG_OUT_CTL, val);
 	}
 
+	/* Output source sel and output invert */
+	val = config->inv_int_pol << 7;
+	REG_WRITE(gpio_base + GPIO_DIG_OUT_SRC_CTL, val);
+
 	/* Enable the GPIO */
 	val  = REG_READ(gpio_base + GPIO_EN_CTL);
 	val |= BIT(PERPH_EN_BIT);
diff --git a/include/platform.h b/include/platform.h
index 292cd1a..6965c5a 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -90,4 +90,5 @@
 uint64_t platform_get_ddr_start();
 bool platform_is_glink_enabled();
 bool platform_is_mdm9206();
+int is_vb_le_enabled();
 #endif
diff --git a/lib/libfdt/fdt.c b/lib/libfdt/fdt.c
index 15e66e4..8d99980 100644
--- a/lib/libfdt/fdt.c
+++ b/lib/libfdt/fdt.c
@@ -219,3 +219,31 @@
 	memmove(buf, fdt, fdt_totalsize(fdt));
 	return 0;
 }
+
+int fdt_first_subnode(const void *fdt, int offset)
+{
+        int depth = 0;
+
+        offset = fdt_next_node(fdt, offset, &depth);
+        if (offset < 0 || depth != 1)
+                return -FDT_ERR_NOTFOUND;
+
+        return offset;
+}
+
+int fdt_next_subnode(const void *fdt, int offset)
+{
+        int depth = 1;
+
+        /*
+         * With respect to the parent, the depth of the next subnode will be
+         * the same as the last.
+         */
+        do {
+                offset = fdt_next_node(fdt, offset, &depth);
+                if (offset < 0 || depth < 1)
+                        return -FDT_ERR_NOTFOUND;
+        } while (depth > 1);
+
+        return offset;
+}
diff --git a/lib/libfdt/libfdt.h b/lib/libfdt/libfdt.h
index 667964c..88ea3e3 100644
--- a/lib/libfdt/libfdt.h
+++ b/lib/libfdt/libfdt.h
@@ -136,6 +136,28 @@
 
 int fdt_next_node(const void *fdt, int offset, int *depth);
 
+/**
+ * fdt_first_subnode() - get offset of first direct subnode
+ *
+ * @fdt:        FDT blob
+ * @offset:     Offset of node to check
+ * @return offset of first subnode, or -FDT_ERR_NOTFOUND if there is none
+ */
+int fdt_first_subnode(const void *fdt, int offset);
+
+/**
+ * fdt_next_subnode() - get offset of next direct subnode
+ *
+ * After first calling fdt_first_subnode(), call this function repeatedly to
+ * get direct subnodes of a parent node.
+ *
+ * @fdt:        FDT blob
+ * @offset:     Offset of previous subnode
+ * @return offset of next subnode, or -FDT_ERR_NOTFOUND if there are no more
+ * subnodes
+ */
+int fdt_next_subnode(const void *fdt, int offset);
+
 /**********************************************************************/
 /* General functions                                                  */
 /**********************************************************************/
diff --git a/lib/zlib_inflate/inflate.c b/lib/zlib_inflate/inflate.c
index e341300..95690e0 100644
--- a/lib/zlib_inflate/inflate.c
+++ b/lib/zlib_inflate/inflate.c
@@ -1506,7 +1506,7 @@
 {
     struct inflate_state FAR *state;
 
-    if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16;
+    if (strm == Z_NULL || strm->state == Z_NULL) return -(1L<<16);
     state = (struct inflate_state FAR *)strm->state;
     return ((long)(state->back) << 16) +
         (state->mode == COPY ? state->length :
diff --git a/makefile b/makefile
index cc0f10f..f4e7c19 100644
--- a/makefile
+++ b/makefile
@@ -70,6 +70,11 @@
 ifeq ($(ENABLE_HARD_FPU),1)
   CFLAGS += -mfloat-abi=hard -mfpu=neon
 endif
+
+ifeq ($(ENABLE_EARLY_ETHERNET),1)
+  CFLAGS += -DENABLE_EARLY_ETHERNET=1
+endif
+
 # setup toolchain prefix
 TOOLCHAIN_PREFIX ?= arm-eabi-
 CFLAGS += -fstack-protector-all
@@ -111,6 +116,13 @@
   endif
 endif
 
+ifeq ($(VERIFIED_BOOT_LE),1)
+  DEFINES += VERIFIED_BOOT_LE=1
+  ifeq ($(DEFAULT_UNLOCK),true)
+    DEFINES += DEFAULT_UNLOCK=1
+  endif
+endif
+
 ifeq ($(OSVERSION_IN_BOOTIMAGE),1)
  DEFINES += OSVERSION_IN_BOOTIMAGE=1
 endif
diff --git a/platform/msm8909/include/platform/iomap.h b/platform/msm8909/include/platform/iomap.h
index f0a7db9..9b59657 100644
--- a/platform/msm8909/include/platform/iomap.h
+++ b/platform/msm8909/include/platform/iomap.h
@@ -79,6 +79,9 @@
 
 #define CLK_CTL_BASE                0x1800000
 
+#define PMI_SECOND_SLAVE_OFFSET 0x1
+#define PMI_SECOND_SLAVE_ADDR_BASE (PMI_SECOND_SLAVE_OFFSET << 16)
+
 #define SPMI_BASE                   0x02000000
 #define SPMI_GENI_BASE              (SPMI_BASE + 0xA000)
 #define SPMI_PIC_BASE               (SPMI_BASE +  0x01800000)
diff --git a/platform/msm_shared/LEOEMCertificate.h b/platform/msm_shared/LEOEMCertificate.h
new file mode 100644
index 0000000..af72a51
--- /dev/null
+++ b/platform/msm_shared/LEOEMCertificate.h
@@ -0,0 +1,110 @@
+/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ *  with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __LE_OEM_CERTIFICATE_H
+#define __LE_OEM_CERTIFICATE_H
+
+/*
+	Instructions to generate private.key and X509 certificate
+
+A) Generate a sha256 self-signed X509 certificate and a 2048 bits RSA private key
+$ openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout qtipri.key -out qti.crt.pem
+
+B) convert private key from PKCS#8 to PKCS#1 format, save it as qti.key.
+$ openssl rsa -in qtipri.key -out qti.key
+
+C) This private key "qti.key" need to be saved under folder "poky/recipes-kernel/linux-quic/kernel/" and
+"poky/recipes-kernel/linux-msm-4.4/kernel/", used to generate bootimage signature.
+
+D) convert certificate from PEM to DER format
+$ openssl x509 -outform der -in qti.crt.pem -out qti.crt.der
+
+E) open qti.crt.der file in a HEX editor, and then put HEX numbers into array
+    LE_OEM_CERTIFICATE[] in LEOEMCertificate.h
+
+*/
+
+const char LE_OEM_CERTIFICATE[] = {
+	0x30, 0x82, 0x03, 0x5D, 0x30, 0x82, 0x02, 0x45, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00,
+	0xFA, 0xCD, 0x18, 0x11, 0xED, 0xD3, 0x4D, 0xC8, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86,
+	0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55,
+	0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C,
+	0x0A, 0x53, 0x6F, 0x6D, 0x65, 0x2D, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1F, 0x06,
+	0x03, 0x55, 0x04, 0x0A, 0x0C, 0x18, 0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65, 0x74, 0x20, 0x57,
+	0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4C, 0x74, 0x64, 0x30, 0x1E,
+	0x17, 0x0D, 0x31, 0x37, 0x30, 0x38, 0x30, 0x35, 0x30, 0x36, 0x33, 0x39, 0x32, 0x32, 0x5A, 0x17,
+	0x0D, 0x31, 0x38, 0x30, 0x38, 0x30, 0x35, 0x30, 0x36, 0x33, 0x39, 0x32, 0x32, 0x5A, 0x30, 0x45,
+	0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30,
+	0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, 0x0A, 0x53, 0x6F, 0x6D, 0x65, 0x2D, 0x53, 0x74, 0x61,
+	0x74, 0x65, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x18, 0x49, 0x6E, 0x74,
+	0x65, 0x72, 0x6E, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74,
+	0x79, 0x20, 0x4C, 0x74, 0x64, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48,
+	0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0F, 0x00, 0x30, 0x82, 0x01,
+	0x0A, 0x02, 0x82, 0x01, 0x01, 0x00, 0xA6, 0xC6, 0x48, 0xE4, 0xF6, 0x8B, 0x42, 0x2A, 0xFC, 0xB0,
+	0x4A, 0x7A, 0x0F, 0x1A, 0x5E, 0x40, 0x78, 0x8B, 0xBD, 0x30, 0xBD, 0xA1, 0xBF, 0xDC, 0xB4, 0x53,
+	0x48, 0x31, 0x42, 0x11, 0xCD, 0x83, 0x70, 0x48, 0x75, 0x58, 0x00, 0x82, 0x50, 0x43, 0x4B, 0xA9,
+	0xCF, 0xEE, 0x81, 0x8C, 0xA4, 0x57, 0xA2, 0x55, 0xB2, 0x84, 0x5C, 0xAA, 0xC9, 0x3F, 0xBA, 0xDE,
+	0x4C, 0x1B, 0x54, 0xDE, 0xF0, 0x06, 0x3E, 0x3F, 0x3B, 0x5F, 0x6D, 0x78, 0xA3, 0xEB, 0x8F, 0x6F,
+	0xAC, 0xFC, 0x2F, 0x1F, 0xFC, 0x20, 0x58, 0xDB, 0x5D, 0x86, 0x04, 0xE1, 0x45, 0xF2, 0x98, 0x9A,
+	0x41, 0x00, 0x46, 0x45, 0x6C, 0x05, 0x5C, 0xE7, 0x7C, 0xC0, 0x25, 0x6F, 0x22, 0xE2, 0xDE, 0x76,
+	0xA1, 0xAC, 0xC8, 0x82, 0xF7, 0x15, 0x5B, 0x0C, 0xFF, 0xC1, 0xB1, 0xA8, 0x17, 0xB4, 0xFC, 0x0B,
+	0x98, 0x89, 0xBA, 0x2C, 0xFC, 0xAD, 0xDB, 0x03, 0xD8, 0x48, 0xDD, 0x38, 0x1B, 0xC6, 0x6E, 0x1A,
+	0x6D, 0xD9, 0x8B, 0x19, 0x73, 0x79, 0x33, 0xFC, 0x7C, 0x5F, 0x9B, 0x9C, 0x91, 0x4F, 0xDC, 0x65,
+	0x1B, 0x1C, 0xBF, 0x66, 0xF3, 0xDA, 0x79, 0x7C, 0x7F, 0x19, 0xE9, 0xAF, 0x75, 0x34, 0xB2, 0xA0,
+	0x2F, 0xA7, 0xF4, 0x2B, 0x9C, 0x4D, 0xF5, 0xC8, 0x68, 0xC5, 0xCB, 0x89, 0x6E, 0xA0, 0x72, 0x8E,
+	0x14, 0x22, 0x4F, 0x1A, 0xD8, 0x32, 0x04, 0x93, 0x91, 0x54, 0xD2, 0x54, 0xDA, 0x5E, 0x62, 0xAB,
+	0xB6, 0x53, 0x56, 0xAA, 0x8E, 0x17, 0x6D, 0xE7, 0x20, 0x28, 0xBE, 0x50, 0x68, 0x04, 0x8D, 0x38,
+	0xF6, 0x6F, 0x3E, 0x32, 0x6F, 0x61, 0x47, 0xBA, 0xE7, 0x5E, 0xDD, 0x33, 0x5A, 0xD9, 0x97, 0x8E,
+	0xD3, 0x9D, 0x0A, 0x78, 0x4B, 0x31, 0xFE, 0x74, 0x41, 0xC8, 0x7D, 0x77, 0x1D, 0x8B, 0x63, 0x67,
+	0x7C, 0x2D, 0xE1, 0xD3, 0xF1, 0x21, 0x02, 0x03, 0x01, 0x00, 0x01, 0xA3, 0x50, 0x30, 0x4E, 0x30,
+	0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0x8E, 0x52, 0xC7, 0xA0, 0x78, 0xAD,
+	0xCF, 0xE3, 0x9D, 0xF9, 0xD5, 0x26, 0xE0, 0xDB, 0x80, 0x1A, 0xB8, 0xE2, 0x2D, 0xD1, 0x30, 0x1F,
+	0x06, 0x03, 0x55, 0x1D, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x8E, 0x52, 0xC7, 0xA0, 0x78,
+	0xAD, 0xCF, 0xE3, 0x9D, 0xF9, 0xD5, 0x26, 0xE0, 0xDB, 0x80, 0x1A, 0xB8, 0xE2, 0x2D, 0xD1, 0x30,
+	0x0C, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x0D, 0x06,
+	0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01,
+	0x00, 0x65, 0x5A, 0x8E, 0x9F, 0xC3, 0x52, 0xC9, 0x52, 0xCE, 0x6B, 0xF0, 0xAA, 0x8D, 0x78, 0xA0,
+	0x85, 0xB3, 0x0E, 0xEB, 0x8B, 0x17, 0xC2, 0xB4, 0xFA, 0xF4, 0x20, 0x52, 0x98, 0xCC, 0x1D, 0x45,
+	0x6F, 0x83, 0x9F, 0xCF, 0xA1, 0x4D, 0x91, 0xBA, 0xE2, 0x29, 0xC2, 0xAA, 0x9A, 0x07, 0xE0, 0xC3,
+	0xCE, 0x39, 0xDB, 0x5F, 0x5F, 0x96, 0xF1, 0x77, 0x8F, 0x73, 0x6D, 0xDD, 0x83, 0x0C, 0x1D, 0x8C,
+	0xCC, 0xC0, 0xC9, 0x65, 0x64, 0x67, 0x8F, 0x90, 0x3D, 0x53, 0x24, 0xED, 0x49, 0x18, 0x8A, 0x06,
+	0xDC, 0x96, 0xC1, 0x40, 0x9C, 0x11, 0x41, 0x70, 0x91, 0x7D, 0x7C, 0xFD, 0x63, 0x81, 0x73, 0x9F,
+	0xD9, 0x50, 0xF2, 0xA5, 0x86, 0x6A, 0x31, 0xA5, 0x43, 0x66, 0x7D, 0xB2, 0x88, 0x4C, 0x96, 0x08,
+	0x8B, 0x36, 0xA8, 0x21, 0x47, 0x17, 0xD4, 0x1D, 0xDE, 0xD9, 0x58, 0x45, 0x36, 0x1B, 0x2A, 0x82,
+	0x46, 0x40, 0x6F, 0x16, 0x41, 0xFB, 0xF2, 0x17, 0x49, 0x2A, 0x13, 0x8E, 0xCC, 0xB8, 0x5B, 0xD3,
+	0xDA, 0xCA, 0xB3, 0x48, 0xFC, 0xC7, 0x5C, 0x3B, 0x2B, 0xAC, 0x56, 0x41, 0x5F, 0x2B, 0x61, 0x15,
+	0x08, 0x9D, 0xDA, 0x72, 0x13, 0x43, 0x51, 0x00, 0xCE, 0xA1, 0x4C, 0x98, 0xC6, 0xC3, 0xD4, 0xEE,
+	0xEF, 0x51, 0xAF, 0xFC, 0x03, 0x86, 0x77, 0xB7, 0xB9, 0x14, 0x8A, 0x79, 0xCB, 0xC8, 0xA9, 0x0D,
+	0x82, 0xE3, 0xED, 0x05, 0x99, 0x10, 0xFD, 0x80, 0x0D, 0x24, 0x72, 0x1F, 0x1C, 0xB0, 0xCA, 0x64,
+	0x1D, 0x10, 0x5D, 0x3E, 0x48, 0x5B, 0x54, 0x56, 0x4E, 0xEE, 0x5D, 0x02, 0xEC, 0xEE, 0x0B, 0x2E,
+	0x77, 0x74, 0xB2, 0x8C, 0xD5, 0x7C, 0xF3, 0xA4, 0x0E, 0x1A, 0x48, 0x04, 0x81, 0x32, 0xF1, 0x39,
+	0x9B, 0x57, 0xC9, 0xBB, 0xFF, 0x15, 0xB6, 0xE5, 0x20, 0x0D, 0x03, 0x60, 0xBD, 0x3F, 0x29, 0x03,
+	0xEF
+};
+
+#endif
diff --git a/platform/msm_shared/ab_partition_parser.c b/platform/msm_shared/ab_partition_parser.c
index bd900d9..c224e0f 100644
--- a/platform/msm_shared/ab_partition_parser.c
+++ b/platform/msm_shared/ab_partition_parser.c
@@ -31,12 +31,18 @@
 #include <crc32.h>
 #include <ab_partition_parser.h>
 #include <partition_parser.h>
+#include <boot_device.h>
+#if defined(MMC_SDHCI_SUPPORT) || defined(UFS_SUPPORT)
+#include <mmc_wrapper.h>
+#include <ufs.h>
+#endif
 
 //#define AB_DEBUG
 
 /* Slot suffix */
 const char *suffix_slot[] = {"_a",
 		"_b"};
+const char *suffix_delimiter = "_";
 
 /* local global variables */
 static signed active_slot = INVALID;		/* to store current active slot */
@@ -580,6 +586,11 @@
 	int ret = 0;
 	uint64_t max_gpt_size_bytes =
 		(PARTITION_ENTRY_SIZE*NUM_PARTITIONS + GPT_HEADER_BLOCKS*block_size);
+	int lun = -1;
+
+	/* Get Current LUN for UFS target */
+	if (!platform_boot_dev_isemmc())
+		lun = mmc_get_lun();
 
 	buffer = memalign(CACHE_LINE, ROUNDUP(max_gpt_size_bytes, CACHE_LINE));
 	if (!buffer)
@@ -604,6 +615,18 @@
 	tmp = gpt_entries_ptr;
 	for (i=0;i<partition_count;i++)
 	{
+		if (lun != -1)
+		{
+			/* Partition table is populated with entries from lun 0 to max lun.
+			* break out of the loop once we see the partition lun is > current lun */
+			if (partition_entries[i].lun > lun)
+				break;
+			/* Find the entry where the partition table for 'lun' starts
+			and then update the attributes */
+			if (partition_entries[i].lun != lun)
+				continue;
+		}
+
 		/* Update the partition attributes */
 		PUT_LONG_LONG(&tmp[ATTRIBUTE_FLAG_OFFSET],
 			partition_entries[i].attribute_flag);
@@ -657,32 +680,47 @@
 	unsigned max_entries_size_bytes = PARTITION_ENTRY_SIZE*NUM_PARTITIONS;
 	unsigned max_entries_blocks = max_entries_size_bytes/block_size;
 	unsigned max_gpt_blocks = GPT_HEADER_BLOCKS + max_entries_blocks;
+	int max_luns = 0, lun;
+	int cur_lun = mmc_get_lun();
 
-	/* Update Primary GPT */
-	offset = 0x01;	/*  offset is 0x1 for primary GPT */
-	gpt_start_addr = offset*block_size;
-	/* Take gpt_start_addr as start and calculate offset from that in block sz*/
-	gpt_hdr_offset = 0; /* For primary partition offset is zero */
-	gpt_entries_offset = GPT_HEADER_BLOCKS;
-
-	ret = update_gpt(gpt_start_addr, gpt_hdr_offset, gpt_entries_offset);
-	if (ret)
+#if defined(MMC_SDHCI_SUPPORT) || defined(UFS_SUPPORT)
+	if (platform_boot_dev_isemmc())
+		max_luns = 1;
+	else
+		max_luns = ufs_get_num_of_luns((struct ufs_dev*)target_mmc_device());
+#endif
+	for (lun = 0; lun < max_luns; lun++)
 	{
-		dprintf(CRITICAL, "Failed to update Primary GPT\n");
-		return;
-	}
+		/* Set current LUN */
+		mmc_set_lun(lun);
 
-	/* Update Secondary GPT */
-	offset = ((mmc_get_device_capacity()/block_size) - max_gpt_blocks);
-	gpt_start_addr = offset*block_size;
-	gpt_hdr_offset = max_entries_blocks;
-	gpt_entries_offset = 0; /* For secondary GPT entries offset is zero */
+		/* Update Primary GPT */
+		offset = 0x01;	/*  offset is 0x1 for primary GPT */
+		gpt_start_addr = offset*block_size;
+		/* Take gpt_start_addr as start and calculate offset from that in block sz*/
+		gpt_hdr_offset = 0; /* For primary partition offset is zero */
+		gpt_entries_offset = GPT_HEADER_BLOCKS;
 
-	ret = update_gpt(gpt_start_addr, gpt_hdr_offset, gpt_entries_offset);
-	if (ret)
-	{
-		dprintf(CRITICAL, "Failed to update Secondary GPT\n");
-		return;
+		ret = update_gpt(gpt_start_addr, gpt_hdr_offset, gpt_entries_offset);
+		if (ret)
+		{
+			dprintf(CRITICAL, "Failed to update Primary GPT\n");
+			return;
+		}
+
+		/* Update Secondary GPT */
+		offset = ((mmc_get_device_capacity()/block_size) - max_gpt_blocks);
+		gpt_start_addr = offset*block_size;
+		gpt_hdr_offset = max_entries_blocks;
+		gpt_entries_offset = 0; /* For secondary GPT entries offset is zero */
+
+		ret = update_gpt(gpt_start_addr, gpt_hdr_offset, gpt_entries_offset);
+		if (ret)
+		{
+			dprintf(CRITICAL, "Failed to update Secondary GPT\n");
+			return;
+		}
 	}
+	mmc_set_lun(cur_lun);
 	return;
 }
diff --git a/platform/msm_shared/boot_verifier.c b/platform/msm_shared/boot_verifier.c
index 90cbfeb..c2312fc 100644
--- a/platform/msm_shared/boot_verifier.c
+++ b/platform/msm_shared/boot_verifier.c
@@ -421,7 +421,7 @@
 		ASSERT(0);
 	}
 
-	if (version_rsp.major_version >= 0x2)
+	if (version_rsp.major_version > 0x2)
 	{
 		bs_req = malloc(sizeof(km_set_boot_state_req_t) + sizeof(km_boot_state_t));
 		ASSERT(bs_req);
@@ -596,9 +596,6 @@
 	unsigned char* sig_addr = (unsigned char*)(img_addr + img_size);
 	uint32_t sig_len = 0;
 	unsigned char *signature = NULL;
-#if OSVERSION_IN_BOOTIMAGE
-	struct boot_img_hdr *img_hdr = NULL;
-#endif
 
 	if(dev_boot_state == ORANGE)
 	{
@@ -647,13 +644,6 @@
 
 	ret = verify_image_with_sig(img_addr, img_size, pname, sig, user_keystore);
 
-#if OSVERSION_IN_BOOTIMAGE
-	/* Extract the os version and patch level */
-	img_hdr = (struct boot_img_hdr *)img_addr;
-	boot_state_info.system_version = (img_hdr->os_version & 0xFFFFF8) >> 11;
-	boot_state_info.system_security_level = (img_hdr->os_version & 0x7FF);
-#endif
-
 	if(sig != NULL)
 		VERIFIED_BOOT_SIG_free(sig);
 verify_image_error:
@@ -756,3 +746,24 @@
 	read_oem_keystore();
 	return oem_keystore;
 }
+
+#if OSVERSION_IN_BOOTIMAGE
+void set_os_version(unsigned char* img_addr)
+{
+	struct boot_img_hdr *img_hdr = NULL;
+
+	/* Extract the os version and patch level */
+	if (img_addr) {
+		img_hdr = (struct boot_img_hdr *)img_addr;
+		boot_state_info.system_version = (img_hdr->os_version & 0xFFFFF800) >> 11;
+		boot_state_info.system_security_level = (img_hdr->os_version & 0x7FF);
+	} else {
+		dprintf(CRITICAL, "Image address should not be NULL\n");
+	}
+}
+#else
+void set_os_version(unsigned char* img_addr)
+{
+	return;
+}
+#endif
diff --git a/platform/msm_shared/dev_tree.c b/platform/msm_shared/dev_tree.c
index 6a73826..11f9616 100755
--- a/platform/msm_shared/dev_tree.c
+++ b/platform/msm_shared/dev_tree.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2015,2017 The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -39,6 +39,11 @@
 #include <kernel/thread.h>
 #include <target.h>
 #include <partial_goods.h>
+#include <boot_device.h>
+#include <platform.h>
+
+#define BOOT_DEV_MAX_LEN        64
+#define NODE_PROPERTY_MAX_LEN   64
 
 struct dt_entry_v1
 {
@@ -49,12 +54,29 @@
 	uint32_t size;
 };
 
+#if ENABLE_BOOTDEVICE_MOUNT
+/* Look up table for fstab node */
+struct fstab_node
+{
+        const char *parent_node;
+        const char *node_prop;
+        const char *device_path_id;
+};
+
+static struct fstab_node fstab_table =
+{
+	"/firmware/android/fstab", "dev", "/soc/"
+};
+#endif
+
 static struct dt_mem_node_info mem_node;
 static int platform_dt_absolute_match(struct dt_entry *cur_dt_entry, struct dt_entry_node *dt_list);
 static struct dt_entry *platform_dt_match_best(struct dt_entry_node *dt_list);
 static int update_dtb_entry_node(struct dt_entry_node *dt_list, uint32_t dtb_info);
 extern int target_is_emmc_boot(void);
 extern uint32_t target_dev_tree_mem(void *fdt, uint32_t memory_node_offset);
+static int update_fstab_node(void *fdt);
+
 /* TODO: This function needs to be moved to target layer to check violations
  * against all the other regions as well.
  */
@@ -1366,6 +1388,15 @@
 		}
 	}
 
+#if ENABLE_BOOTDEVICE_MOUNT
+	/* Update fstab node */
+	dprintf(SPEW, "Start of fstab node update:%zu ms\n", platform_get_sclk_count());
+	if (update_fstab_node(fdt) != 0) {
+		dprintf(CRITICAL, "ERROR: Cannot update fstab node\n");
+		return ret;
+	}
+	dprintf(SPEW, "End of fstab node update:%zu ms\n", platform_get_sclk_count());
+#endif
 	fdt_pack(fdt);
 
 #if ENABLE_PARTIAL_GOODS_SUPPORT
@@ -1374,3 +1405,101 @@
 
 	return ret;
 }
+
+#if ENABLE_BOOTDEVICE_MOUNT
+/*Update device tree for fstab node */
+static int update_fstab_node(void *fdt)
+{
+	int ret = 0;
+	int str_len = 0;
+	int parent_offset = 0;
+	int subnode_offset = 0;
+	int prop_length = 0;
+	int prefix_string_len = 0;
+	char *node_name = NULL;
+	char *boot_dev_buf = NULL;
+	char *new_str = NULL;
+	char *prefix_str = NULL;
+	char *suffix_str = NULL;
+	const struct fdt_property *prop = NULL;
+
+	/* Find the parent node */
+	parent_offset = fdt_path_offset(fdt, fstab_table.parent_node);
+	if (parent_offset < 0) {
+		dprintf(CRITICAL, "Failed to get parent node: fstab error: %d\n", parent_offset);
+		return -1;
+	}
+	dprintf(SPEW, "Node: %s found.\n", fdt_get_name(fdt, parent_offset, NULL));
+
+	/* Get boot device type */
+	boot_dev_buf = (char *) malloc(sizeof(char) * BOOT_DEV_MAX_LEN);
+	if (!boot_dev_buf) {
+		dprintf(CRITICAL, "Failed to allocate memory for boot device\n");
+		return -1;
+	}
+
+	new_str = (char *) malloc(sizeof(char) * NODE_PROPERTY_MAX_LEN);
+	if (!new_str) {
+		dprintf(CRITICAL, "Failed to allocate memory for node property string\n");
+		return -1;
+	}
+
+
+	platform_boot_dev_cmdline(boot_dev_buf);
+
+	/* Get properties of all sub nodes */
+	for (subnode_offset = fdt_first_subnode(fdt, parent_offset); subnode_offset >= 0; subnode_offset = fdt_next_subnode(fdt, subnode_offset)) {
+		prop = fdt_get_property(fdt, subnode_offset, fstab_table.node_prop, &prop_length);
+		node_name = (char *)(uintptr_t)fdt_get_name(fdt, subnode_offset, NULL);
+		if (!prop) {
+			dprintf(CRITICAL, "Property:%s is not found for sub node:%s\n", fstab_table.node_prop, node_name);
+		} else {
+			dprintf(CRITICAL, "Property:%s found for sub node:%s\tproperty:%s\n", fstab_table.node_prop, node_name, prop->data);
+			/* Pointer to fdt 'dev' property string that needs to update based on the 'androidboot.bootdevice' */
+			memset(new_str, 0, NODE_PROPERTY_MAX_LEN);
+			prefix_str = (char *)prop->data;
+			if (strlen(prefix_str) > NODE_PROPERTY_MAX_LEN) {
+				dprintf(CRITICAL, "Property string length is greater than node property max length\n");
+				continue;
+			}
+			suffix_str = strstr(prefix_str, fstab_table.device_path_id);
+			if (!suffix_str) {
+				dprintf(CRITICAL, "Property is not proper to update\n");
+				continue;
+			}
+			suffix_str += strlen(fstab_table.device_path_id);
+			prefix_string_len = strlen(prefix_str) - (strlen(suffix_str) - 1);
+			suffix_str = strstr((suffix_str + 1), "/");
+			str_len = strlcpy(new_str, prefix_str, prefix_string_len);
+			if (!str_len) {
+				dprintf(CRITICAL, "Property length is not proper to update\n");
+				continue;
+			}
+			str_len = strlcat(new_str, boot_dev_buf, strlen(prefix_str));
+			if (!str_len) {
+				dprintf(CRITICAL, "Property length is not proper to update\n");
+				continue;
+			}
+			str_len = strlcat(new_str, suffix_str, strlen(prefix_str));
+			if (!str_len) {
+				dprintf(CRITICAL, "Property length  is not proper to update\n");
+				continue;
+			}
+			/* Update the new property in the memory */
+			memscpy(prefix_str, strlen(prefix_str), new_str, strlen(new_str) + 1);
+			/* Update the property with new value */
+			ret = fdt_setprop(fdt, subnode_offset, fstab_table.node_prop, (const void *)prefix_str, strlen(prefix_str) + 1);
+			if(ret) {
+				dprintf(CRITICAL, "Failed to update the node with new property\n");
+				continue;
+			}
+			dprintf(CRITICAL, "Updated %s with new property %s\n", node_name, prop->data);
+		}
+	}
+	if (boot_dev_buf)
+	        free(boot_dev_buf);
+	if (new_str)
+		free(new_str);
+        return ret;
+}
+#endif
diff --git a/platform/msm_shared/flash-ubi.c b/platform/msm_shared/flash-ubi.c
index ca46876..e0836c6 100644
--- a/platform/msm_shared/flash-ubi.c
+++ b/platform/msm_shared/flash-ubi.c
@@ -855,6 +855,12 @@
 		/* Total size of valid data in peb */
 		peb_valid_sz = num_pages * page_size;
 
+		if (size < UBI_MAGIC_SIZE)
+		{
+			dprintf(CRITICAL, "flash_ubi_img: invalid size provided.\n");
+			return -1;
+		}
+
 		/*
 		* Check for oob access if any in img_peb.
 		*/
diff --git a/platform/msm_shared/image_verify.c b/platform/msm_shared/image_verify.c
index 6fff3d2..6fedfd8 100644
--- a/platform/msm_shared/image_verify.c
+++ b/platform/msm_shared/image_verify.c
@@ -29,10 +29,17 @@
 #include <certificate.h>
 #include <crypto_hash.h>
 #include <string.h>
+#include <platform.h>
 #include <openssl/err.h>
 #include "image_verify.h"
 #include "scm.h"
 
+#include <LEOEMCertificate.h>
+
+const char hash_identifier[] = {
+	0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
+	0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
+};
 
 /*
  * Returns -1 if decryption failed otherwise size of plain_text in bytes
@@ -66,8 +73,17 @@
 	 */
 	int ret = -1;
 	X509 *x509_certificate = NULL;
-	const unsigned char *cert_ptr = (const unsigned char *)certBuffer;
-	unsigned int cert_size = sizeof(certBuffer);
+	const unsigned char *cert_ptr = NULL;
+	unsigned int cert_size = 0;
+
+	if (is_vb_le_enabled()) {
+		cert_ptr = (const unsigned char *)LE_OEM_CERTIFICATE;
+		cert_size = sizeof(LE_OEM_CERTIFICATE);
+	} else {
+		cert_ptr = (const unsigned char *)certBuffer;
+		cert_size = sizeof(certBuffer);
+	}
+
 	EVP_PKEY *pub_key = NULL;
 	RSA *rsa_key = NULL;
 
@@ -166,23 +182,43 @@
 	 * we avoid a potential vulnerability due to trailing data placed at the end of digest.
 	 */
 	ret = image_decrypt_signature(signature_ptr, plain_text);
-	if (ret != hash_size) {
-		dprintf(CRITICAL, "ERROR: Image Invalid! signature check failed! ret %d\n", ret);
-		goto cleanup;
+	if (is_vb_le_enabled()) {
+		int sha256_pkcs1_hash_identifier_len = sizeof(hash_identifier);
+		if (ret != (hash_size + sha256_pkcs1_hash_identifier_len)) {
+			dprintf(CRITICAL, "ERROR: VB: Image Invalid! signature check failed! ret %d\n", ret);
+			goto cleanup;
+		}
+		/*
+		 * Compare the expected hash with the calculated hash.
+		 */
+		if (memcmp(plain_text, hash_identifier, sha256_pkcs1_hash_identifier_len) != 0) {
+			dprintf(CRITICAL,
+				"ERROR: VB: Hash identifier is wrong!\n");
+			goto cleanup;
+		}
+		if (memcmp(plain_text + sha256_pkcs1_hash_identifier_len, digest, hash_size) != 0) {
+			dprintf(CRITICAL,
+				"ERROR: VB: Image Invalid! Please use another image!\n");
+			goto cleanup;
+		}
+	} else {
+		if (ret != hash_size) {
+			dprintf(CRITICAL, "ERROR: Image Invalid! signature check failed! ret %d\n", ret);
+			goto cleanup;
+		}
+		/*
+		 * Compare the expected hash with the calculated hash.
+		 */
+		if (memcmp(plain_text, digest, hash_size) != 0) {
+			dprintf(CRITICAL,
+				"ERROR: Image Invalid! Please use another image!\n");
+			ret = -1;
+			goto cleanup;
+		}
 	}
 
-	/*
-	 * Compare the expected hash with the calculated hash.
-	 */
-	if (memcmp(plain_text, digest, hash_size) != 0) {
-		dprintf(CRITICAL,
-			"ERROR: Image Invalid! Please use another image!\n");
-		ret = -1;
-		goto cleanup;
-	} else {
-		/* Authorized image */
-		auth = 1;
-	}
+	/* Authorized image */
+	auth = 1;
 
 	/* Cleanup after complete usage of openssl - cached data and objects */
  cleanup:
diff --git a/platform/msm_shared/include/ab_partition_parser.h b/platform/msm_shared/include/ab_partition_parser.h
index 2bbddb8..0d49441 100644
--- a/platform/msm_shared/include/ab_partition_parser.h
+++ b/platform/msm_shared/include/ab_partition_parser.h
@@ -29,6 +29,7 @@
 #include <fastboot.h>
 
 extern const char *suffix_slot[];
+extern const char *suffix_delimiter;
 
 #define SUFFIX_SLOT(part_slot) suffix_slot[(part_slot)]
 
diff --git a/platform/msm_shared/include/boot_verifier.h b/platform/msm_shared/include/boot_verifier.h
index 38bcf17..1f74d0b 100644
--- a/platform/msm_shared/include/boot_verifier.h
+++ b/platform/msm_shared/include/boot_verifier.h
@@ -175,6 +175,8 @@
 bool boot_verify_validate_keystore(unsigned char * user_addr, unsigned sz);
 /* Function to send root of trust to trust zone */
 bool send_rot_command(uint32_t is_unlocked);
+/* function to set the os version and patch level. */
+void set_os_version(unsigned char* img_addr);
 unsigned char* get_boot_fingerprint(unsigned int* buf_size);
 bool boot_verify_compare_sha256(unsigned char *image_ptr,
 		unsigned int image_size, unsigned char *signature_ptr, RSA *rsa);
diff --git a/platform/msm_shared/include/regulator.h b/platform/msm_shared/include/regulator.h
index 03fb10a..9759354 100644
--- a/platform/msm_shared/include/regulator.h
+++ b/platform/msm_shared/include/regulator.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -67,10 +67,13 @@
 
 #define REG_LDO1	BIT(0)
 #define REG_LDO2	BIT(1)
+#define REG_LDO5	BIT(4)
 #define REG_LDO6	BIT(5)
+#define REG_LDO11	BIT(10)
 #define REG_LDO12	BIT(11)
 #define REG_LDO14	BIT(13)
 #define REG_LDO17	BIT(16)
+#define REG_LDO18	BIT(17)
 #define REG_LDO28	BIT(27)
 #define REG_SMPS3	BIT(7)
 #define REG_LDO3	BIT(2)
diff --git a/platform/msm_shared/qseecom_lk.c b/platform/msm_shared/qseecom_lk.c
index 445904a..563d1e5 100644
--- a/platform/msm_shared/qseecom_lk.c
+++ b/platform/msm_shared/qseecom_lk.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2015,2017 The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -555,6 +555,7 @@
 	int index = INVALID_PTN;
 	unsigned long long ptn = 0;
 	unsigned long long size = 0;
+	unsigned long long rounded_size = 0;
 	void *buf = NULL;
 	void *req = NULL;
 	struct qseecom_load_app_ireq load_req = {0};
@@ -572,8 +573,13 @@
 	mmc_set_lun(lun);
 
 	size = partition_get_size(index);
-
-	buf = memalign(PAGE_SIZE, ROUNDUP(size, PAGE_SIZE));
+	if ((ULLONG_MAX - PAGE_SIZE + 1) < size) {
+		dprintf(CRITICAL, "Integer overflow detected in rounding up the partition size!");
+		ret = GENERIC_ERROR;
+		goto err;
+	}
+	rounded_size = ROUNDUP(size, PAGE_SIZE);
+	buf = memalign(PAGE_SIZE, rounded_size);
 	if (!buf) {
 		dprintf(CRITICAL, "%s: Aloc failed for %s image\n",
 				__func__, app_name);
@@ -624,6 +630,7 @@
 	int index = INVALID_PTN;
 	unsigned long long ptn = 0;
 	unsigned long long size = 0;
+	unsigned long long rounded_size = 0;
 	void *buf = NULL;
 	void *req = NULL;
 	struct qseecom_load_app_ireq load_req = {0};
@@ -637,8 +644,13 @@
 	mmc_set_lun(lun);
 
 	size = partition_get_size(index);
-
-	buf = memalign(PAGE_SIZE, ROUNDUP(size, PAGE_SIZE));
+	if ((ULLONG_MAX - PAGE_SIZE + 1) < size) {
+		dprintf(CRITICAL, "Integer overflow detected in rounding up the partition size!");
+		ret = GENERIC_ERROR;
+		goto err;
+	}
+	rounded_size = ROUNDUP(size, PAGE_SIZE);
+	buf = memalign(PAGE_SIZE, rounded_size);
 	if (!buf) {
 		dprintf(CRITICAL, "%s: Aloc failed for %s image\n",
 				__func__, app_name);
diff --git a/project/msm8909.mk b/project/msm8909.mk
index bdf593e..0d820e6 100644
--- a/project/msm8909.mk
+++ b/project/msm8909.mk
@@ -63,7 +63,11 @@
 endif
 
 #enable power on vibrator feature
+ifeq ($(ENABLE_BG_SUPPORT),1)
+ENABLE_HAP_VIB_SUPPORT := true
+else
 ENABLE_PON_VIB_SUPPORT := true
+endif
 
 ifeq ($(EMMC_BOOT),1)
 DEFINES += _EMMC_BOOT=1
@@ -73,6 +77,10 @@
 DEFINES += PON_VIB_SUPPORT=1
 endif
 
+ifeq ($(ENABLE_HAP_VIB_SUPPORT),true)
+DEFINES += PON_VIB_SUPPORT=1
+endif
+
 ifeq ($(ENABLE_SMD_SUPPORT),1)
 DEFINES += SMD_SUPPORT=1
 endif
diff --git a/project/msm8996.mk b/project/msm8996.mk
index 2147ba6..aa9fb8e 100644
--- a/project/msm8996.mk
+++ b/project/msm8996.mk
@@ -142,3 +142,8 @@
 endif
 # Target specific command line
 DEFINES += TARGET_CMDLINE_SUPPORT=1
+
+#Enable early mount support for mmc/ufs
+ifeq ($(ENABLE_BOOTDEVICE_MOUNT),1)
+DEFINES += ENABLE_BOOTDEVICE_MOUNT=1
+endif
diff --git a/target/init.c b/target/init.c
index b4696f1..06be1f0 100644
--- a/target/init.c
+++ b/target/init.c
@@ -281,6 +281,26 @@
 	return ret;
 }
 
+#if VERIFIED_BOOT_LE
+int verified_boot_le = 1;
+#else
+int verified_boot_le = 0;
+#endif
+
+int is_vb_le_enabled(void)
+{
+	uint32_t platform = board_platform_id();
+
+	switch(platform)
+	{
+		case APQ8053:
+			return verified_boot_le;
+		default:
+			break;
+	}
+	return 0;
+}
+
 #if PON_VIB_SUPPORT
 void get_vibration_type(struct qpnp_hap *config)
 {
diff --git a/target/mdm9640/init.c b/target/mdm9640/init.c
index 21e43c9..97e55ec 100644
--- a/target/mdm9640/init.c
+++ b/target/mdm9640/init.c
@@ -143,6 +143,24 @@
 	return platform_boot_dev_isemmc();
 }
 
+#if ENABLE_EARLY_ETHERNET
+void toggle_neutrino(void)
+{
+	struct pm8x41_gpio gpio = {
+	.direction = PM_GPIO_DIR_OUT,
+	.function = PM_GPIO_FUNC_HIGH,
+	.vin_sel = 1,   /* VIN_1 */
+	.output_buffer = PM_GPIO_OUT_CMOS,
+	.out_strength = PM_GPIO_OUT_DRIVE_LOW,
+	};
+
+	pm8x41_gpio_config(4, &gpio);
+	pm8x41_gpio_set(4, 1);
+	mdelay(10);
+	pm8x41_gpio_set(4, 0);
+}
+#endif
+
 /* init */
 void target_init(void)
 {
@@ -161,6 +179,10 @@
 		rpm_glink_init();
 	}
 
+#if ENABLE_EARLY_ETHERNET
+	/*enable pmic gpio 4*/
+	toggle_neutrino();
+#endif
 	if (platform_boot_dev_isemmc()) {
 		target_sdc_init();
 		if (partition_read_table()) {
diff --git a/target/mdm9640/rules.mk b/target/mdm9640/rules.mk
index 84d1417..12b4c94 100644
--- a/target/mdm9640/rules.mk
+++ b/target/mdm9640/rules.mk
@@ -9,7 +9,7 @@
 BASE_ADDR                           := 0x80000000
 SCRATCH_ADDR                        := 0x80000000
 SCRATCH_REGION1                     := 0x81300000
-SCRATCH_REGION1_SIZE                := 0x06900000 # 105MB
+SCRATCH_REGION1_SIZE                := 0x06400000 # 100MB
 SCRATCH_REGION2                     := 0x88000000
 SCRATCH_REGION2_SIZE                := 0x08000000 # 128MB
 KERNEL_REGION                       := 0x80000000
diff --git a/target/msm8909/oem_panel.c b/target/msm8909/oem_panel.c
index 4909008..e4da42e 100644
--- a/target/msm8909/oem_panel.c
+++ b/target/msm8909/oem_panel.c
@@ -48,6 +48,7 @@
 #include "include/panel_auo_qvga_cmd.h"
 #include "include/panel_auo_cx_qvga_cmd.h"
 #include "include/panel_auo_400p_cmd.h"
+#include "include/panel_auo_390p_cmd.h"
 
 #define DISPLAY_MAX_PANEL_DETECTION 0
 #define ILI9806E_FWVGA_VIDEO_PANEL_POST_INIT_DELAY 68
@@ -79,6 +80,7 @@
 	AUO_QVGA_CMD_PANEL,
 	AUO_CX_QVGA_CMD_PANEL,
 	AUO_400P_CMD_PANEL,
+	AUO_390P_CMD_PANEL,
 	UNKNOWN_PANEL
 };
 
@@ -98,6 +100,7 @@
 	{"auo_qvga_cmd", AUO_QVGA_CMD_PANEL},
 	{"auo_cx_qvga_cmd", AUO_CX_QVGA_CMD_PANEL},
 	{"auo_400p_cmd", AUO_400P_CMD_PANEL},
+	{"auo_390p_cmd", AUO_390P_CMD_PANEL},
 };
 
 static uint32_t panel_id;
@@ -405,6 +408,30 @@
 					= auo_400P_CMD_OFF_COMMAND;
 		memcpy(phy_db->timing, auo_400p_cmd_timings, TIMING_SIZE);
 		break;
+	case AUO_390P_CMD_PANEL:
+		panelstruct->paneldata    = &auo_390p_cmd_panel_data;
+		panelstruct->panelres     = &auo_390p_cmd_panel_res;
+		panelstruct->color        = &auo_390p_cmd_color;
+		panelstruct->videopanel   = &auo_390p_cmd_video_panel;
+		panelstruct->commandpanel = &auo_390p_cmd_command_panel;
+		panelstruct->state        = &auo_390p_cmd_state;
+		panelstruct->laneconfig   = &auo_390p_cmd_lane_config;
+		panelstruct->paneltiminginfo
+					= &auo_390p_cmd_timing_info;
+		panelstruct->panelresetseq
+					= &auo_390p_cmd_panel_reset_seq;
+		panelstruct->backlightinfo
+					= &auo_390p_cmd_backlight;
+		pinfo->mipi.panel_on_cmds
+					= auo_390p_cmd_on_command;
+		pinfo->mipi.num_of_panel_on_cmds
+					= AUO_390P_CMD_ON_COMMAND;
+		pinfo->mipi.panel_off_cmds
+					= auo_390p_cmd_off_command;
+		pinfo->mipi.num_of_panel_off_cmds
+					= AUO_390P_CMD_OFF_COMMAND;
+		memcpy(phy_db->timing, auo_390p_cmd_timings, TIMING_SIZE);
+		break;
 	case UNKNOWN_PANEL:
 	default:
 		memset(panelstruct, 0, sizeof(struct panel_struct));
@@ -457,7 +484,7 @@
 	case HW_PLATFORM_RCM:
 		switch (platform_subtype) {
 		case BG_WTP:
-			panel_id = AUO_CX_QVGA_CMD_PANEL;
+			panel_id = AUO_390P_CMD_PANEL;
 			break;
 		default:
 			panel_id = HX8394D_720P_VIDEO_PANEL;
diff --git a/target/msm8909/regulator.c b/target/msm8909/regulator.c
index bbe83b4..be9b532 100644
--- a/target/msm8909/regulator.c
+++ b/target/msm8909/regulator.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, 2017, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -49,6 +49,24 @@
 	},
 };
 
+static uint32_t ldo5[][11]=
+{
+	{
+		LDOA_RES_TYPE, 5,
+		KEY_SOFTWARE_ENABLE, 4, GENERIC_DISABLE,
+		KEY_MICRO_VOLT, 4, 0,
+		KEY_CURRENT, 4, 0,
+	},
+
+	{
+		LDOA_RES_TYPE, 5,
+		KEY_SOFTWARE_ENABLE, 4, GENERIC_ENABLE,
+		KEY_MICRO_VOLT, 4, 1200000,
+		KEY_CURRENT, 4, 86,
+	},
+};
+
+
 static uint32_t ldo6[][11]=
 {
 	{
@@ -67,6 +85,42 @@
 };
 
 
+static uint32_t ldo11[][11]=
+{
+	{
+		LDOA_RES_TYPE, 11,
+		KEY_SOFTWARE_ENABLE, 4, GENERIC_DISABLE,
+		KEY_MICRO_VOLT, 4, 0,
+		KEY_CURRENT, 4, 0,
+	},
+
+	{
+		LDOA_RES_TYPE, 11,
+		KEY_SOFTWARE_ENABLE, 4, GENERIC_ENABLE,
+		KEY_MICRO_VOLT, 4, 1800000,
+		KEY_CURRENT, 4, 150,
+	},
+};
+
+
+static uint32_t ldo12[][11]=
+{
+	{
+		LDOA_RES_TYPE, 12,
+		KEY_SOFTWARE_ENABLE, 4, GENERIC_DISABLE,
+		KEY_MICRO_VOLT, 4, 0,
+		KEY_CURRENT, 4, 0,
+	},
+
+	{
+		LDOA_RES_TYPE, 12,
+		KEY_SOFTWARE_ENABLE, 4, GENERIC_ENABLE,
+		KEY_MICRO_VOLT, 4, 1800000,
+		KEY_CURRENT, 4, 150,
+	},
+};
+
+
 static uint32_t ldo17[][11]=
 {
 	{
@@ -84,6 +138,24 @@
 	},
 };
 
+static uint32_t ldo18[][11]=
+{
+	{
+		LDOA_RES_TYPE, 18,
+		KEY_SOFTWARE_ENABLE, 4, GENERIC_DISABLE,
+		KEY_MICRO_VOLT, 4, 0,
+		KEY_CURRENT, 4, 0,
+	},
+
+	{
+		LDOA_RES_TYPE, 18,
+		KEY_SOFTWARE_ENABLE, 4, GENERIC_ENABLE,
+		KEY_MICRO_VOLT, 4, 3000000,
+		KEY_CURRENT, 4, 5,
+	},
+};
+
+
 void regulator_enable(uint32_t enable)
 {
 	if (enable & REG_LDO2)
@@ -95,6 +167,17 @@
 	if (enable & REG_LDO6)
 		rpm_send_data(&ldo6[GENERIC_ENABLE][0], 36, RPM_REQUEST_TYPE);
 
+	if (enable & REG_LDO5)
+		rpm_send_data(&ldo5[GENERIC_ENABLE][0], 36, RPM_REQUEST_TYPE);
+
+	if (enable & REG_LDO11)
+		rpm_send_data(&ldo11[GENERIC_ENABLE][0], 36, RPM_REQUEST_TYPE);
+
+	if (enable & REG_LDO12)
+		rpm_send_data(&ldo12[GENERIC_ENABLE][0], 36, RPM_REQUEST_TYPE);
+
+	if (enable & REG_LDO18)
+		rpm_send_data(&ldo18[GENERIC_ENABLE][0], 36, RPM_REQUEST_TYPE);
 
 
 }
diff --git a/target/msm8909/rules.mk b/target/msm8909/rules.mk
index f2ae532..55aa9d0 100644
--- a/target/msm8909/rules.mk
+++ b/target/msm8909/rules.mk
@@ -11,7 +11,10 @@
 BASE_ADDR        := 0x80000000
 SCRATCH_ADDR     := 0x90100000
 
+ifeq ($(ENABLE_DISPLAY),1)
+DEFINES += ENABLE_DISPLAY=1
 DEFINES += DISPLAY_SPLASH_SCREEN=1
+endif
 DEFINES += DISPLAY_TYPE_MIPI=1
 DEFINES += DISPLAY_TYPE_DSI6G=1
 DEFINES += NO_ALARM_DISPLAY=0
@@ -22,6 +25,7 @@
 	lib/ptable \
 	dev/gcdb/display \
 	dev/pmic/pm8x41 \
+	dev/qpnp_haptic \
 	dev/pmic/pmi8994 \
 	lib/libfdt
 
diff --git a/target/msm8909/target_display.c b/target/msm8909/target_display.c
index 63f546f..9c4cd48 100755
--- a/target/msm8909/target_display.c
+++ b/target/msm8909/target_display.c
@@ -54,6 +54,13 @@
 #define PWM_PERIOD_US 27
 #define PM8916_VER 0x20000
 
+/*---------------------------------------------------------------------------*/
+/* GPIO configuration                                                        */
+/*---------------------------------------------------------------------------*/
+static struct gpio_pin bob_gpio = {
+  "pm8941_gpios", 12, 2, 1, 0, 1
+};
+
 static void mdss_dsi_uniphy_pll_sw_reset_8909(uint32_t pll_base)
 {
 	writel(0x01, pll_base + 0x0068); /* PLL TEST CFG */
@@ -187,38 +194,44 @@
 
 int target_backlight_ctrl(struct backlight *bl, uint8_t enable)
 {
-	struct pm8x41_mpp mpp;
 	uint32_t hw_id = board_hardware_id();
-	struct board_pmic_data pmic_info;
-	int rc;
+	uint32_t platform = board_platform_id();
+	uint32_t platform_subtype = board_hardware_subtype();
 
 	if (bl->bl_interface_type == BL_DCS)
 		return 0;
 
-	board_pmic_info(&pmic_info, 1);
-	if (pmic_info.pmic_version == PM8916_VER)
-		mpp.base = PM8x41_MMP4_BASE;
-	else
-		mpp.base = PM8x41_MMP2_BASE;
+	if (!((HW_PLATFORM_SUBTYPE_8909_PM660 == platform_subtype) &&
+		(MSM8909W == platform) &&
+		(HW_PLATFORM_MTP == hw_id))) {
+		struct pm8x41_mpp mpp;
+		struct board_pmic_data pmic_info;
+		int rc;
 
-	mpp.vin = MPP_VIN0;
-	if (enable) {
-		pm_pwm_enable(false);
-		rc = pm_pwm_config(PWM_DUTY_US, PWM_PERIOD_US);
-		if (rc < 0)
-			mpp.mode = MPP_HIGH;
-		else {
-			mpp.mode = MPP_DTEST1;
-			pm_pwm_enable(true);
+		board_pmic_info(&pmic_info, 1);
+		if (pmic_info.pmic_version == PM8916_VER)
+			mpp.base = PM8x41_MMP4_BASE;
+		else
+			mpp.base = PM8x41_MMP2_BASE;
+
+		mpp.vin = MPP_VIN0;
+		if (enable) {
+			pm_pwm_enable(false);
+			rc = pm_pwm_config(PWM_DUTY_US, PWM_PERIOD_US);
+			if (rc < 0)
+				mpp.mode = MPP_HIGH;
+			else {
+				mpp.mode = MPP_DTEST1;
+				pm_pwm_enable(true);
+			}
+			pm8x41_config_output_mpp(&mpp);
+			pm8x41_enable_mpp(&mpp, MPP_ENABLE);
+		} else {
+			pm_pwm_enable(false);
+			pm8x41_enable_mpp(&mpp, MPP_DISABLE);
 		}
-		pm8x41_config_output_mpp(&mpp);
-		pm8x41_enable_mpp(&mpp, MPP_ENABLE);
-	} else {
-		pm_pwm_enable(false);
-		pm8x41_enable_mpp(&mpp, MPP_DISABLE);
+		mdelay(20);
 	}
-	mdelay(20);
-
 	if (enable) {
 		gpio_tlmm_config(bkl_gpio.pin_id, 0,
 			bkl_gpio.pin_direction, bkl_gpio.pin_pull,
@@ -280,8 +293,25 @@
 						struct msm_panel_info *pinfo)
 {
 	int ret = NO_ERROR;
+	uint32_t bob_pmic_gpio = bob_gpio.pin_id;
 	uint32_t hw_id = board_hardware_id();
 	uint32_t hw_subtype = board_hardware_subtype();
+	uint32_t platform = board_platform_id();
+
+	if ((HW_PLATFORM_SUBTYPE_8909_PM660 == hw_subtype) &&
+		(MSM8909W == platform) &&
+		(HW_PLATFORM_MTP == hw_id)) {
+		struct pm8x41_gpio bobgpio_param = {
+			.direction = PM_GPIO_DIR_OUT,
+			.vin_sel = 0,
+			.out_strength = PM_GPIO_OUT_DRIVE_MED,
+			.function = PM_GPIO_FUNC_HIGH,
+			.pull = PM_GPIO_PULLDOWN_10,
+			.inv_int_pol = PM_GPIO_INVERT,
+		};
+
+		pm8x41_gpio_config(bob_pmic_gpio, &bobgpio_param);
+	}
 
 	if (enable) {
 		if (pinfo->mipi.use_enable_gpio) {
@@ -318,8 +348,18 @@
 
 int target_ldo_ctrl(uint8_t enable, struct msm_panel_info *pinfo)
 {
-	if (enable)
-		regulator_enable(REG_LDO2 | REG_LDO6 | REG_LDO17);
+	uint32_t hw_id = board_hardware_id();
+	uint32_t hw_subtype = board_hardware_subtype();
+	uint32_t platform = board_platform_id();
+
+	if (enable) {
+		if ((HW_PLATFORM_SUBTYPE_8909_PM660 == hw_subtype) &&
+			(MSM8909W == platform) &&
+			(HW_PLATFORM_MTP == hw_id))
+			regulator_enable(REG_LDO12 | REG_LDO5 | REG_LDO11 | REG_LDO18);
+		else
+			regulator_enable(REG_LDO2 | REG_LDO6 | REG_LDO17);
+	}
 
 	return NO_ERROR;
 }
diff --git a/target/msm8952/rules.mk b/target/msm8952/rules.mk
index d50f8d9..d86ea01 100644
--- a/target/msm8952/rules.mk
+++ b/target/msm8952/rules.mk
@@ -18,7 +18,10 @@
 SCRATCH_SIZE     := 511
 SCRATCH_SIZE_512 := 234
 
+ifeq ($(ENABLE_DISPLAY),1)
+DEFINES += ENABLE_DISPLAY=1
 DEFINES += DISPLAY_SPLASH_SCREEN=1
+endif
 DEFINES += DISPLAY_TYPE_MIPI=1
 DEFINES += DISPLAY_TYPE_DSI6G=1
 
diff --git a/target/msm8953/meminfo.c b/target/msm8953/meminfo.c
index 23e82fd..3968185 100644
--- a/target/msm8953/meminfo.c
+++ b/target/msm8953/meminfo.c
@@ -81,5 +81,5 @@
 
 unsigned target_get_max_flash_size(void)
 {
-	return (512 * 1024 * 1024);
+	return (510 * 1024 * 1024);
 }
diff --git a/target/msm8996/rules.mk b/target/msm8996/rules.mk
index a9d5093..ed6bae0 100644
--- a/target/msm8996/rules.mk
+++ b/target/msm8996/rules.mk
@@ -27,8 +27,11 @@
 ifeq ($(DISPLAY_SCREEN),0)
  DEFINES += DISPLAY_SPLASH_SCREEN=0
 else
+ifeq ($(ENABLE_DISPLAY),1)
+ DEFINES += ENABLE_DISPLAY=1
  DEFINES += DISPLAY_SPLASH_SCREEN=1
 endif
+endif
 
 DEFINES += DISPLAY_TYPE_MIPI=1
 DEFINES += DISPLAY_TYPE_DSI6G=1