Merge "target: msm8994: read mdtp eFuse in runtime"
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 7ff5fae..07f87e5 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -76,6 +76,7 @@
 #include <wdog.h>
 #endif
 
+#include <reboot.h>
 #include "image_verify.h"
 #include "recovery.h"
 #include "bootimg.h"
@@ -92,12 +93,13 @@
 extern void platform_uninit(void);
 extern void target_uninit(void);
 extern int get_target_boot_params(const char *cmdline, const char *part,
-				  char *buf, int buflen);
+				  char **buf);
 
 void *info_buf;
 void write_device_info_mmc(device_info *dev);
 void write_device_info_flash(device_info *dev);
 static int aboot_save_boot_hash_mmc(uint32_t image_addr, uint32_t image_size);
+static int aboot_frp_unlock(char *pname, void *data, unsigned sz);
 
 /* fastboot command function pointer */
 typedef void (*fastboot_cmd_fn) (const char *, void *, unsigned);
@@ -122,14 +124,6 @@
 
 #define MAX_TAGS_SIZE   1024
 
-#define RECOVERY_HARD_RESET_MODE   0x01
-#define FASTBOOT_HARD_RESET_MODE   0x02
-#define RTC_HARD_RESET_MODE        0x03
-
-#define RECOVERY_MODE   0x77665502
-#define FASTBOOT_MODE   0x77665500
-#define ALARM_BOOT      0x77665503
-
 /* make 4096 as default size to ensure EFS,EXT4's erasing */
 #define DEFAULT_ERASE_SIZE  4096
 #define MAX_PANEL_BUF_SIZE 128
@@ -171,7 +165,7 @@
 static unsigned page_mask = 0;
 static char ffbm_mode_string[FFBM_MODE_BUF_SIZE];
 static bool boot_into_ffbm;
-static char target_boot_params[64];
+static char *target_boot_params = NULL;
 static bool boot_reason_alarm;
 static bool devinfo_present = true;
 
@@ -309,8 +303,7 @@
 
 	if (get_target_boot_params(cmdline, boot_into_recovery ? "recoveryfs" :
 								 "system",
-				   target_boot_params,
-				   sizeof(target_boot_params)) == 0) {
+						&target_boot_params) == 0) {
 		have_target_boot_params = 1;
 		cmdline_len += strlen(target_boot_params);
 	}
@@ -523,6 +516,7 @@
 			if (have_cmdline) --dst;
 			src = target_boot_params;
 			while ((*dst++ = *src++));
+			free(target_boot_params);
 		}
 	}
 
@@ -2183,6 +2177,14 @@
 		cmd_erase_nand(arg, data, sz);
 }
 
+static uint32_t aboot_get_secret_key()
+{
+	/* 0 is invalid secret key, update this implementation to return
+	 * device specific unique secret key
+	 */
+	return 0;
+}
+
 void cmd_flash_mmc_img(const char *arg, void *data, unsigned sz)
 {
 	unsigned long long ptn = 0;
@@ -2206,6 +2208,19 @@
 
 	if (pname)
 	{
+		if (!strncmp(pname, "frp-unlock", strlen("frp-unlock")))
+		{
+			if (!aboot_frp_unlock(pname, data, sz))
+			{
+				fastboot_info("FRP unlock successful");
+				fastboot_okay("");
+			}
+			else
+				fastboot_fail("Secret key is invalid, please update the bootloader with secret key");
+
+			return;
+		}
+
 		if (!strcmp(pname, "partition"))
 		{
 			dprintf(INFO, "Attempt to write partition image.\n");
@@ -2825,6 +2840,26 @@
 	fastboot_okay("");
 }
 
+static int aboot_frp_unlock(char *pname, void *data, unsigned sz)
+{
+	int ret = 1;
+	uint32_t secret_key;
+	char seckey_buffer[MAX_RSP_SIZE];
+
+	secret_key = aboot_get_secret_key();
+	if (secret_key)
+	{
+		snprintf((char *) seckey_buffer, MAX_RSP_SIZE, "%x", secret_key);
+		if (!memcmp((void *)data, (void *)seckey_buffer, sz))
+		{
+			is_allow_unlock = true;
+			write_allow_oem_unlock(is_allow_unlock);
+			ret = 0;
+		}
+	}
+	return ret;
+}
+
 void cmd_oem_lock(const char *arg, void *data, unsigned sz)
 {
 	/* TODO: Wipe user data */
@@ -3180,7 +3215,6 @@
 void aboot_init(const struct app_descriptor *app)
 {
 	unsigned reboot_mode = 0;
-	unsigned hard_reboot_mode = 0;
 	bool boot_into_fastboot = false;
 
 	/* Setup page size information for nv storage */
@@ -3207,6 +3241,8 @@
 #endif
 		dprintf(SPEW, "Display Init: Start\n");
 #if ENABLE_WBC
+		/* Wait if the display shutdown is in progress */
+		while(pm_app_display_shutdown_in_prgs());
 		if (!pm_appsbl_display_init_done())
 			target_display_init(device.display_panel);
 		else
@@ -3260,16 +3296,21 @@
 		boot_into_fastboot = true;
 	#endif
 
+#if USE_PON_REBOOT_REG
+	reboot_mode = check_hard_reboot_mode();
+#else
 	reboot_mode = check_reboot_mode();
-	hard_reboot_mode = check_hard_reboot_mode();
-	if (reboot_mode == RECOVERY_MODE ||
-		hard_reboot_mode == RECOVERY_HARD_RESET_MODE) {
+#endif
+	if (reboot_mode == RECOVERY_MODE)
+	{
 		boot_into_recovery = 1;
-	} else if(reboot_mode == FASTBOOT_MODE ||
-		hard_reboot_mode == FASTBOOT_HARD_RESET_MODE) {
+	}
+	else if(reboot_mode == FASTBOOT_MODE)
+	{
 		boot_into_fastboot = true;
-	} else if(reboot_mode == ALARM_BOOT ||
-		hard_reboot_mode == RTC_HARD_RESET_MODE) {
+	}
+	else if(reboot_mode == ALARM_BOOT)
+	{
 		boot_reason_alarm = true;
 	}
 
diff --git a/app/aboot/recovery.c b/app/aboot/recovery.c
index 15797a1..96441e2 100644
--- a/app/aboot/recovery.c
+++ b/app/aboot/recovery.c
@@ -592,6 +592,10 @@
 
 		if (scratch_addr != buf)
 			memcpy(scratch_addr, buf, size);
+
+		/* Set Lun for misc partition */
+		mmc_set_lun(partition_get_lun(index));
+
 		if (mmc_write(ptn + offset, aligned_size, (unsigned int *)scratch_addr))
 		{
 			dprintf(CRITICAL, "Writing MMC failed\n");
diff --git a/app/tests/include/app/kauth_test.h b/app/tests/include/app/kauth_test.h
index f38be0c..7f8e9c9 100644
--- a/app/tests/include/app/kauth_test.h
+++ b/app/tests/include/app/kauth_test.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2015, 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
@@ -37,4 +37,338 @@
 
 void kauth_test(const char *arg, void *data, unsigned sz);
 
+#if VERIFIED_BOOT
+unsigned char correct_signature_signature[] = {
+  0xdb, 0x81, 0x5e, 0x7b, 0x78, 0x66, 0xe5, 0x5b, 0x18, 0x5d, 0x97, 0x4b,
+  0x95, 0xfc, 0xf2, 0xe0, 0x0f, 0xa5, 0x13, 0x1b, 0x4d, 0xa9, 0x14, 0x87,
+  0x15, 0xa4, 0xfc, 0xf8, 0x53, 0xf5, 0xeb, 0xd9, 0x50, 0x60, 0xa0, 0xc2,
+  0x31, 0x09, 0xd3, 0x9a, 0xb5, 0x98, 0x5c, 0x08, 0x1d, 0xce, 0x48, 0x9e,
+  0x78, 0xde, 0xff, 0x8f, 0x8d, 0x20, 0x26, 0x58, 0xd9, 0x0f, 0xd2, 0x00,
+  0x91, 0x3c, 0x4e, 0xc6, 0x5e, 0x40, 0xeb, 0x09, 0x3f, 0xef, 0xbf, 0xaf,
+  0x9d, 0xea, 0xd7, 0x35, 0x59, 0x36, 0x1f, 0xa8, 0xf9, 0x01, 0x1e, 0xdf,
+  0x7c, 0xf1, 0xb6, 0xaa, 0x85, 0x37, 0xc3, 0x29, 0x35, 0x31, 0xb2, 0xd3,
+  0xba, 0xaf, 0xfe, 0xd8, 0x2d, 0xca, 0xab, 0x62, 0x4c, 0x5c, 0x66, 0x87,
+  0x76, 0xc5, 0xaf, 0x79, 0x69, 0xf8, 0xd8, 0xbe, 0x47, 0x38, 0x8b, 0x6a,
+  0x44, 0xe1, 0x48, 0x87, 0x5a, 0xc6, 0x0d, 0x47, 0xec, 0x8c, 0x3a, 0x23,
+  0x38, 0x77, 0xee, 0x13, 0x80, 0x09, 0xd8, 0xe9, 0xc8, 0xf0, 0xc5, 0x39,
+  0xcb, 0xc5, 0xc2, 0x47, 0x43, 0x58, 0xd7, 0x47, 0xf6, 0x9f, 0xb6, 0xae,
+  0x25, 0x98, 0x27, 0xa8, 0x4f, 0xf2, 0x75, 0x08, 0xa1, 0xf4, 0xf5, 0xf7,
+  0xc0, 0x52, 0xe7, 0xab, 0xba, 0x14, 0x1b, 0x64, 0x2d, 0x00, 0x35, 0x1d,
+  0x6d, 0xe3, 0x04, 0x57, 0xec, 0x18, 0x3c, 0xce, 0x1e, 0xeb, 0x6a, 0x16,
+  0x08, 0x2a, 0xf0, 0x4a, 0xf6, 0x1c, 0xe7, 0x7f, 0xc6, 0x3f, 0x2d, 0x96,
+  0x09, 0x1a, 0x69, 0x3d, 0xd4, 0x7d, 0x3d, 0x77, 0xa5, 0xa0, 0x59, 0x91,
+  0x14, 0x98, 0x8f, 0x79, 0x51, 0x32, 0x66, 0x0a, 0x31, 0x23, 0xe4, 0xe6,
+  0x41, 0x6e, 0xfd, 0x11, 0xc5, 0x91, 0x1d, 0x18, 0x87, 0x14, 0xf8, 0xf5,
+  0x53, 0x8e, 0x62, 0x8f, 0x7a, 0xc7, 0x7c, 0x19, 0xe5, 0x65, 0xef, 0xa0,
+  0xbc, 0xa5, 0x28, 0x7c
+};
+
+unsigned char missing_first_byte_signature[] = {
+  0x5e, 0x7f, 0x55, 0x65, 0x67, 0xce, 0xae, 0xce, 0x9a, 0xf6, 0x5d, 0x87,
+  0x4c, 0x46, 0xc0, 0x26, 0xc5, 0x57, 0xa7, 0xeb, 0xe8, 0x5d, 0xc4, 0x5b,
+  0xc9, 0xed, 0x94, 0xb7, 0x81, 0xc1, 0xdb, 0xed, 0x5f, 0x12, 0x21, 0x8e,
+  0x0a, 0x76, 0x00, 0x2a, 0x11, 0xed, 0x20, 0x64, 0xcb, 0xf3, 0x4e, 0x9a,
+  0x5f, 0xf2, 0xde, 0xf9, 0xd9, 0xe5, 0x91, 0x10, 0x33, 0x07, 0x2b, 0x92,
+  0xd7, 0x53, 0x75, 0x5c, 0xc6, 0x00, 0x13, 0x07, 0x7c, 0x39, 0x6f, 0xf2,
+  0xe3, 0xd8, 0x33, 0x82, 0x97, 0xb5, 0xff, 0x79, 0x4e, 0x92, 0x5d, 0xe7,
+  0x18, 0x6c, 0x4c, 0xa0, 0x43, 0x64, 0x80, 0xa1, 0xe5, 0xf2, 0x53, 0x8e,
+  0x04, 0xa1, 0x16, 0x68, 0x88, 0xca, 0x00, 0x76, 0x8f, 0xff, 0xc8, 0xc8,
+  0xf9, 0x1e, 0x1c, 0x43, 0x52, 0x40, 0xa0, 0x5b, 0x8e, 0x4d, 0x5b, 0xa0,
+  0x42, 0xf4, 0x28, 0xbe, 0x07, 0x70, 0x3c, 0xcc, 0x2e, 0x61, 0x77, 0xb6,
+  0x65, 0x58, 0xca, 0x2d, 0x5e, 0xcb, 0xbd, 0xfa, 0xdc, 0xbb, 0x38, 0xee,
+  0x78, 0x01, 0x6d, 0xcd, 0x88, 0x73, 0xa2, 0x0b, 0x18, 0x0d, 0x6f, 0x9a,
+  0xdb, 0xcf, 0x15, 0x02, 0xc0, 0xe7, 0xa3, 0xc8, 0x78, 0x62, 0xf5, 0x70,
+  0x92, 0x80, 0x68, 0x88, 0x00, 0x9f, 0xcf, 0xdc, 0x52, 0xfc, 0xc4, 0xa3,
+  0xd9, 0xae, 0xbe, 0xbd, 0xcd, 0xf4, 0xa4, 0x04, 0x62, 0x42, 0x6c, 0x14,
+  0x83, 0x2b, 0x6a, 0x2a, 0x55, 0x3b, 0xb3, 0xe3, 0x1d, 0xdc, 0x5e, 0x18,
+  0xa8, 0x76, 0x98, 0x52, 0x92, 0x64, 0xae, 0xb7, 0x65, 0x2d, 0xc4, 0xd8,
+  0x14, 0x01, 0xb2, 0x15, 0xfc, 0xcf, 0x2f, 0xf6, 0xb5, 0xe9, 0xb5, 0x07,
+  0x43, 0xca, 0x05, 0x90, 0x9c, 0x84, 0x49, 0x8a, 0xd5, 0x5b, 0xb5, 0xe5,
+  0x23, 0x9a, 0x62, 0x33, 0xdf, 0x3f, 0xd5, 0xc0, 0xcb, 0x3f, 0x55, 0x0c,
+  0xd2, 0xea, 0xf1, 0x1a
+};
+
+unsigned char incorrect_first_byte_signature[] = {
+  0x24, 0x72, 0x99, 0x43, 0x76, 0x36, 0xb4, 0x00, 0xfa, 0x08, 0x95, 0xf9,
+  0xea, 0x12, 0x17, 0x0e, 0x5a, 0x12, 0x05, 0xd7, 0x5e, 0x53, 0x99, 0xbf,
+  0x51, 0xec, 0xaa, 0x21, 0x22, 0xd9, 0x6b, 0x2a, 0xb6, 0x2a, 0x8a, 0xd8,
+  0xdf, 0x3c, 0xe9, 0xa2, 0x28, 0xdf, 0xbf, 0x41, 0x53, 0x7e, 0x2a, 0x9b,
+  0xff, 0xca, 0x63, 0x0e, 0x43, 0xee, 0xae, 0x18, 0x8b, 0x45, 0xa0, 0x8b,
+  0xdb, 0x9a, 0x1c, 0xa9, 0xed, 0xf5, 0x25, 0x15, 0x48, 0xb1, 0xac, 0xe6,
+  0x09, 0xe5, 0x19, 0xbd, 0xa6, 0xef, 0x07, 0xc4, 0x87, 0x42, 0x79, 0x9c,
+  0x69, 0x51, 0xcd, 0x57, 0x99, 0x7c, 0x2d, 0x3c, 0xe2, 0x84, 0x81, 0xbb,
+  0xb1, 0xb9, 0xa5, 0xcc, 0x1f, 0xd3, 0xec, 0x34, 0xd1, 0xc8, 0xda, 0x07,
+  0x86, 0x7d, 0x52, 0xdc, 0x76, 0x02, 0xfe, 0x3d, 0xb8, 0x8c, 0x79, 0xe4,
+  0x43, 0x0b, 0xd3, 0x93, 0xb4, 0x05, 0xbb, 0xf4, 0x00, 0x54, 0x5a, 0x7d,
+  0xef, 0x50, 0xdb, 0x88, 0xc1, 0xf4, 0xb5, 0xa4, 0x5a, 0x3d, 0xe3, 0x37,
+  0x37, 0x1c, 0xf1, 0x22, 0x81, 0x5a, 0x08, 0xf5, 0xe9, 0x3c, 0xc5, 0xdd,
+  0xef, 0x50, 0x65, 0x47, 0xad, 0xb4, 0xfe, 0xaa, 0x51, 0xd5, 0xdc, 0x6e,
+  0x0f, 0x35, 0x57, 0x01, 0x52, 0x41, 0x47, 0x07, 0x20, 0xba, 0x6d, 0x1d,
+  0x2d, 0x44, 0xd7, 0xb9, 0xff, 0x4a, 0x62, 0xac, 0x38, 0xaa, 0x2e, 0x00,
+  0x86, 0x86, 0x5f, 0x59, 0x47, 0x6c, 0xdd, 0x64, 0x10, 0x47, 0x53, 0x6d,
+  0x65, 0x43, 0xde, 0x22, 0x3c, 0xa8, 0x4e, 0x4c, 0xa5, 0xad, 0xc8, 0xc7,
+  0x69, 0x34, 0xbf, 0x22, 0x52, 0x86, 0x73, 0x8f, 0xe8, 0x21, 0x4e, 0xb9,
+  0x74, 0x53, 0xbc, 0x0c, 0x80, 0xcb, 0xe3, 0x04, 0x3f, 0xe7, 0x09, 0x4e,
+  0x10, 0x9f, 0x71, 0x15, 0x98, 0x91, 0xf3, 0x01, 0xfe, 0x55, 0xa3, 0x81,
+  0x19, 0xb9, 0x9c, 0x34
+};
+
+unsigned char missing_second_byte_signature[] = {
+  0xbc, 0x1d, 0xa8, 0x10, 0x50, 0x9f, 0x37, 0x1d, 0x5a, 0xb5, 0x9f, 0x79,
+  0x13, 0x85, 0x86, 0x7d, 0x09, 0xdf, 0x6c, 0x12, 0xc4, 0x54, 0xe6, 0x63,
+  0x71, 0x0d, 0x8b, 0x6d, 0x6a, 0xa0, 0x94, 0xac, 0x3b, 0xb9, 0xcd, 0xa7,
+  0x05, 0x78, 0xff, 0x80, 0x71, 0x11, 0x85, 0xd9, 0x59, 0x79, 0xa3, 0x74,
+  0xbe, 0xb7, 0x9e, 0xd1, 0x6c, 0x49, 0x7c, 0xf1, 0x70, 0x8b, 0x27, 0x68,
+  0xa4, 0x06, 0xda, 0x4f, 0x3b, 0x63, 0x37, 0xcc, 0xdf, 0xe4, 0xe8, 0xc4,
+  0x78, 0x19, 0x1d, 0x6d, 0x92, 0xe7, 0x74, 0x9c, 0x0e, 0x54, 0x29, 0x94,
+  0x6c, 0x5e, 0x67, 0xbb, 0xf1, 0x6d, 0x1b, 0xc5, 0xa6, 0x8d, 0x43, 0x6b,
+  0xd9, 0x46, 0x97, 0xfb, 0xe0, 0xbd, 0x98, 0xa7, 0x83, 0x50, 0x21, 0x4c,
+  0xb0, 0xa3, 0x37, 0x9e, 0x4f, 0x56, 0x12, 0x78, 0x4c, 0x6a, 0x91, 0x7b,
+  0x9e, 0x54, 0x0d, 0x48, 0x65, 0x17, 0x62, 0xa3, 0xb4, 0xff, 0x5d, 0xc0,
+  0xd5, 0xc9, 0x8e, 0x96, 0x58, 0x05, 0x3b, 0x80, 0x94, 0xe9, 0x42, 0xe1,
+  0x28, 0x87, 0xf4, 0x87, 0xbe, 0x39, 0x4e, 0x24, 0xe5, 0x6f, 0x3c, 0x4d,
+  0x4c, 0x88, 0x3c, 0x64, 0x8f, 0x8e, 0xc7, 0xe8, 0x63, 0x8a, 0x82, 0x9f,
+  0xfe, 0xfd, 0x8f, 0x31, 0x84, 0xcb, 0x9a, 0x22, 0x63, 0xe5, 0x91, 0x7f,
+  0xb3, 0x68, 0xed, 0x60, 0x7d, 0x14, 0xf7, 0x64, 0x99, 0x29, 0xdd, 0x9d,
+  0x49, 0x5f, 0xa5, 0x4a, 0x7f, 0x8f, 0x5c, 0x3a, 0xba, 0x15, 0xc4, 0x13,
+  0x07, 0x90, 0xcc, 0x8b, 0x7f, 0x36, 0x47, 0xa2, 0xcb, 0x15, 0x40, 0x26,
+  0xf7, 0x34, 0x26, 0xe2, 0x01, 0x0d, 0x9c, 0x02, 0x48, 0x96, 0xb7, 0xe7,
+  0x30, 0x04, 0xfe, 0x83, 0x19, 0xc1, 0xac, 0x19, 0x6a, 0x15, 0xdc, 0xab,
+  0x0f, 0x67, 0x1d, 0x77, 0xc2, 0xf0, 0xd8, 0x1b, 0x7e, 0x13, 0x88, 0x92,
+  0x1a, 0x6d, 0x13, 0x2a
+};
+
+unsigned char incorrect_second_byte_signature[] = {
+  0xe6, 0x8a, 0xa2, 0xb4, 0xa5, 0xbb, 0x95, 0xb8, 0x74, 0xb1, 0xa6, 0x65,
+  0x50, 0xa2, 0xf9, 0x86, 0x47, 0x12, 0x20, 0xbc, 0x7d, 0xe1, 0x68, 0x87,
+  0x47, 0xb8, 0xf9, 0x77, 0x14, 0xb5, 0x5e, 0xe8, 0x40, 0x05, 0xe1, 0xb4,
+  0x0f, 0xc4, 0xec, 0x0c, 0xcc, 0xe3, 0xfd, 0x60, 0xcc, 0x8b, 0x87, 0x1f,
+  0xcb, 0xd3, 0xdb, 0x49, 0xf0, 0x43, 0x5c, 0x14, 0xed, 0x76, 0xc1, 0x5a,
+  0x42, 0x2b, 0x17, 0x30, 0xe4, 0x78, 0xc9, 0xc8, 0x77, 0xb4, 0x9e, 0xee,
+  0xa2, 0xd3, 0x49, 0x68, 0xff, 0xe2, 0xa7, 0xeb, 0xef, 0x78, 0x1c, 0x63,
+  0x88, 0x38, 0xd6, 0x78, 0x17, 0xb8, 0x97, 0x17, 0x99, 0x9d, 0x59, 0xfd,
+  0xfd, 0x4f, 0xff, 0xe9, 0xb8, 0x97, 0xc9, 0xa7, 0xa5, 0x03, 0x32, 0x8d,
+  0x8f, 0xdd, 0x2d, 0xf4, 0xcf, 0x0d, 0xd1, 0x17, 0xa3, 0xa6, 0x13, 0x85,
+  0x67, 0xd1, 0x9d, 0x84, 0xd5, 0xf2, 0x3d, 0x1b, 0xc3, 0x7c, 0xf2, 0xa7,
+  0x55, 0x9c, 0x75, 0xbf, 0xc4, 0x2a, 0x87, 0xa4, 0xf4, 0xf8, 0xfc, 0xba,
+  0x9f, 0x6b, 0x6d, 0xc9, 0xc4, 0x50, 0x39, 0x7d, 0x72, 0xb2, 0x35, 0xbf,
+  0xee, 0x6e, 0xe8, 0xf8, 0x8b, 0xd8, 0xdf, 0x06, 0x4c, 0xe5, 0xb3, 0x3f,
+  0x8e, 0x0b, 0x0b, 0xdb, 0x99, 0x4a, 0x30, 0xfc, 0x63, 0x03, 0xd6, 0xa6,
+  0x1d, 0x3e, 0x96, 0x71, 0x90, 0xa1, 0x49, 0xaf, 0x50, 0xf3, 0x95, 0xd7,
+  0x37, 0x01, 0xf9, 0xfb, 0xad, 0x21, 0x13, 0xdb, 0xdc, 0x28, 0x73, 0xdc,
+  0x1e, 0x0f, 0x81, 0xc7, 0xda, 0xf0, 0x4b, 0x59, 0x4c, 0x5d, 0x04, 0x1b,
+  0x79, 0x03, 0x20, 0x91, 0x43, 0x3f, 0xc7, 0x3c, 0xe1, 0xa2, 0xa9, 0x39,
+  0x15, 0xc1, 0xbe, 0x82, 0x40, 0xb4, 0xf1, 0x3b, 0x5b, 0x02, 0xae, 0x87,
+  0x82, 0x60, 0xf6, 0x8f, 0x16, 0x21, 0x29, 0xac, 0xe2, 0x87, 0x06, 0xf0,
+  0xd2, 0x74, 0xbd, 0x5f
+};
+
+unsigned char incorrect_ff_padding_signature[] = {
+  0x91, 0x78, 0xcc, 0x63, 0xc7, 0x03, 0x63, 0xe7, 0xe9, 0x7e, 0x0f, 0xe5,
+  0xe1, 0x75, 0x15, 0x9f, 0x17, 0xff, 0x5f, 0x2b, 0x91, 0xe9, 0x0d, 0x94,
+  0x02, 0xe4, 0x57, 0x41, 0x5e, 0x98, 0x81, 0xb5, 0x01, 0x43, 0x40, 0x02,
+  0x45, 0xbe, 0xc8, 0x67, 0x51, 0xfd, 0xd8, 0x49, 0xa8, 0xaf, 0x20, 0x93,
+  0xc2, 0xae, 0xf6, 0x06, 0xef, 0xb0, 0x8d, 0xc1, 0xca, 0xf2, 0x6f, 0x93,
+  0x09, 0xa1, 0xae, 0xf4, 0xeb, 0xc6, 0xa8, 0xc7, 0x37, 0xee, 0xeb, 0xd1,
+  0xe8, 0xf9, 0xcf, 0xf1, 0x34, 0x26, 0xf9, 0xc8, 0x50, 0x98, 0x65, 0x97,
+  0x75, 0x06, 0xcd, 0xf6, 0x91, 0x18, 0xbd, 0x5d, 0xc9, 0x35, 0xc6, 0xa4,
+  0x07, 0xc2, 0x88, 0x03, 0x7a, 0xf9, 0x81, 0x2c, 0x5d, 0xd3, 0x86, 0xb4,
+  0xd1, 0x63, 0x78, 0x38, 0x18, 0xdd, 0xb4, 0x93, 0xcd, 0xe6, 0x65, 0x22,
+  0x61, 0xd3, 0xdd, 0xf1, 0x74, 0x3c, 0xd6, 0x4f, 0x5e, 0xd9, 0xfc, 0x16,
+  0x98, 0xbf, 0x67, 0xbb, 0x77, 0xcb, 0x56, 0xdc, 0x34, 0x31, 0xf9, 0x34,
+  0x12, 0xde, 0x69, 0x40, 0x0d, 0x57, 0x10, 0xec, 0x81, 0x91, 0x07, 0xda,
+  0x88, 0x9c, 0xb9, 0x32, 0x05, 0x73, 0x9a, 0x4b, 0xa8, 0xaf, 0x61, 0x75,
+  0x56, 0x43, 0xfc, 0x17, 0x3a, 0x0e, 0xf3, 0x0f, 0x87, 0x69, 0x0f, 0x86,
+  0x40, 0x2c, 0x15, 0x17, 0x0a, 0x21, 0xbc, 0x1d, 0x15, 0x96, 0xe9, 0x35,
+  0x3c, 0x9d, 0x0d, 0x27, 0x1a, 0xb0, 0x54, 0x41, 0x2c, 0x79, 0xd6, 0xd8,
+  0xc9, 0x55, 0x94, 0x4b, 0xc9, 0x2e, 0x03, 0xca, 0x68, 0x37, 0xb8, 0xcc,
+  0x69, 0x33, 0xec, 0x43, 0xfb, 0x3e, 0xbb, 0x7c, 0x00, 0xc2, 0xc1, 0xb3,
+  0xd6, 0x6c, 0x09, 0x11, 0xcc, 0xd7, 0x76, 0x90, 0xcd, 0xdc, 0x5a, 0x9e,
+  0xed, 0x49, 0xa6, 0xff, 0x98, 0x82, 0xdf, 0xce, 0x91, 0xf1, 0xc5, 0xfd,
+  0xae, 0x44, 0xb0, 0x6e
+};
+
+unsigned char missing_delimiter_signature[] = {
+  0x6b, 0xbe, 0x2d, 0xda, 0xfe, 0xae, 0x7d, 0xa4, 0x98, 0xb8, 0x8a, 0xcc,
+  0x5c, 0x6b, 0xc4, 0xa6, 0x43, 0x33, 0x46, 0xfe, 0x84, 0x68, 0xde, 0xa8,
+  0x1f, 0x63, 0x7d, 0x98, 0x7e, 0x36, 0x75, 0x33, 0xba, 0x70, 0x26, 0x1b,
+  0x7c, 0xbd, 0x12, 0xfa, 0x4d, 0x3c, 0x1b, 0x9c, 0xfc, 0x1b, 0x75, 0xf2,
+  0xc5, 0xbf, 0xea, 0xc2, 0xf6, 0x92, 0xe5, 0xd9, 0x8e, 0xec, 0x81, 0x9d,
+  0x6b, 0x43, 0x9a, 0x2e, 0x9a, 0x7a, 0xfb, 0x9a, 0x76, 0xd4, 0xcc, 0x94,
+  0xd0, 0xf5, 0x14, 0x0e, 0xab, 0xc9, 0xab, 0x5a, 0xf0, 0x49, 0x4d, 0xdb,
+  0x82, 0xc1, 0xca, 0x2a, 0xe6, 0x36, 0xa8, 0x4e, 0x34, 0x6d, 0xa9, 0x81,
+  0xf9, 0xad, 0x65, 0xbe, 0xd0, 0xad, 0x9a, 0xac, 0x76, 0x25, 0xfc, 0x93,
+  0x8c, 0x26, 0x90, 0x23, 0x2b, 0x06, 0xee, 0xde, 0x52, 0x85, 0x63, 0xf2,
+  0xee, 0xd0, 0x12, 0x29, 0x6e, 0xce, 0xfb, 0x49, 0x5f, 0x68, 0xd9, 0xa0,
+  0xfd, 0x5c, 0x8c, 0x95, 0x6b, 0x06, 0x6c, 0x41, 0x8b, 0xb5, 0x93, 0xca,
+  0xbe, 0x1c, 0xc3, 0x42, 0x57, 0xed, 0x11, 0xf9, 0x6c, 0x3e, 0x0f, 0xff,
+  0xf2, 0xf7, 0x3c, 0x91, 0x5a, 0x64, 0xcc, 0x48, 0x4a, 0x03, 0x46, 0xb1,
+  0x31, 0xe8, 0xdd, 0xcb, 0x84, 0xdb, 0x35, 0x7d, 0xbf, 0x59, 0x53, 0xeb,
+  0x58, 0xa7, 0xa0, 0x39, 0x5c, 0xc9, 0x0a, 0x84, 0x42, 0x2b, 0xdd, 0xfc,
+  0xcb, 0x39, 0x19, 0xfa, 0xa0, 0x43, 0x8a, 0x85, 0xa4, 0x9f, 0x5d, 0x73,
+  0x88, 0xc5, 0xb3, 0xab, 0x03, 0x3e, 0x8b, 0xdb, 0x71, 0x4c, 0x7d, 0xd5,
+  0xf4, 0xe5, 0xd7, 0xa4, 0xff, 0x43, 0xb4, 0x88, 0xd2, 0xb7, 0x97, 0xe0,
+  0x1f, 0xb5, 0x2a, 0x51, 0x62, 0x4d, 0x70, 0xe1, 0x5e, 0x54, 0x53, 0x38,
+  0x48, 0xde, 0xc7, 0xb2, 0x4a, 0x1b, 0xaa, 0x86, 0x9c, 0x48, 0x1a, 0xfa,
+  0x41, 0x33, 0x39, 0x5c
+};
+
+unsigned char incorrect_delimiter_signature[] = {
+  0xd7, 0xe1, 0x8e, 0x27, 0xf9, 0xae, 0xfd, 0xbf, 0xf4, 0x0e, 0x2f, 0xa5,
+  0x8e, 0xc8, 0x5d, 0x45, 0x5f, 0xfa, 0x49, 0x7e, 0xab, 0xe8, 0x00, 0xe2,
+  0x8a, 0x71, 0xcc, 0xb3, 0x88, 0x20, 0xaa, 0x32, 0x68, 0x5e, 0x70, 0x9f,
+  0x78, 0xb4, 0xcc, 0x13, 0x83, 0x11, 0xc6, 0x7f, 0xf1, 0xde, 0x83, 0xb2,
+  0x06, 0x3b, 0xe1, 0xfe, 0xa7, 0xde, 0xb1, 0xcd, 0xce, 0x9e, 0xd6, 0x25,
+  0xcf, 0x56, 0x26, 0xe7, 0x52, 0xf2, 0x8e, 0x11, 0xe9, 0xec, 0xdd, 0x80,
+  0xa7, 0xc2, 0x8d, 0x57, 0x43, 0x26, 0x56, 0xa2, 0x2c, 0x82, 0x12, 0xf7,
+  0x4c, 0xb1, 0x30, 0x16, 0x8c, 0xaf, 0x39, 0xfd, 0x98, 0xe6, 0xca, 0x07,
+  0x4d, 0xe0, 0x08, 0xe0, 0x67, 0x9b, 0x3b, 0x20, 0x8f, 0x0b, 0x44, 0xd4,
+  0x28, 0x1e, 0xb4, 0x08, 0x4f, 0x1c, 0x8e, 0x72, 0x1c, 0x5f, 0x2d, 0xea,
+  0x6e, 0xdf, 0x7a, 0x04, 0x68, 0x79, 0x54, 0x60, 0x68, 0xb5, 0x4e, 0xb4,
+  0x07, 0x63, 0xa5, 0x5d, 0x57, 0xcc, 0x6b, 0x1d, 0xcd, 0x9c, 0xa6, 0xf0,
+  0xc1, 0x09, 0xc7, 0xdf, 0x89, 0xef, 0x47, 0x48, 0x8b, 0x03, 0xc7, 0x34,
+  0x79, 0xa7, 0x37, 0x73, 0x35, 0xee, 0x70, 0x9c, 0x53, 0x96, 0xab, 0xb3,
+  0x4f, 0xb4, 0x85, 0x50, 0xda, 0x30, 0x97, 0x8d, 0xf6, 0xe0, 0x6c, 0x10,
+  0xba, 0x51, 0xa3, 0x62, 0xbf, 0xeb, 0x64, 0x6c, 0x44, 0x6f, 0x98, 0x0a,
+  0xf4, 0x6a, 0x07, 0xdc, 0xc5, 0xde, 0x72, 0xe5, 0xb7, 0xb5, 0xbd, 0x53,
+  0x80, 0x72, 0xd0, 0x91, 0x22, 0x96, 0x40, 0xc9, 0xc9, 0x62, 0x9a, 0xc3,
+  0x2c, 0x81, 0x9c, 0xcc, 0xf6, 0x9b, 0x68, 0xcc, 0x71, 0x28, 0x56, 0xee,
+  0xd0, 0x80, 0xa8, 0xbe, 0xdf, 0x5a, 0x31, 0x56, 0x69, 0x73, 0x2f, 0xfc,
+  0xe9, 0xeb, 0xa8, 0x48, 0xa0, 0x72, 0x87, 0xbc, 0x74, 0x0c, 0x1e, 0x13,
+  0x45, 0x48, 0x7b, 0x24
+};
+
+unsigned char bad_oid_signature[] = {
+  0xe3, 0x63, 0x2c, 0x68, 0x6b, 0x44, 0x2b, 0x07, 0x07, 0xe2, 0x69, 0x24,
+  0x95, 0x7e, 0xb4, 0x86, 0x11, 0x03, 0xd3, 0x2b, 0xec, 0x70, 0xf4, 0xa6,
+  0xdc, 0xcf, 0xb6, 0xa1, 0x27, 0xcf, 0x10, 0xd0, 0xa5, 0xae, 0x50, 0xf2,
+  0x14, 0x93, 0xba, 0x66, 0x39, 0x81, 0xfd, 0x05, 0xb6, 0xff, 0xd5, 0xcb,
+  0x46, 0x15, 0xca, 0x9d, 0x9f, 0x74, 0xeb, 0x0d, 0xe9, 0x63, 0xd1, 0x0a,
+  0x6c, 0x71, 0xbd, 0x34, 0x29, 0xea, 0xbb, 0x45, 0x97, 0xe5, 0x53, 0x62,
+  0x3a, 0xb6, 0xa5, 0xf2, 0x7f, 0x66, 0xa5, 0x9c, 0x15, 0x18, 0xd1, 0x41,
+  0x73, 0xf8, 0xda, 0x13, 0x13, 0xff, 0xf6, 0x72, 0x37, 0x97, 0x32, 0x19,
+  0xd6, 0x08, 0xac, 0xf2, 0x4a, 0x79, 0xf3, 0x97, 0x70, 0x6b, 0x05, 0xbb,
+  0x6a, 0x7c, 0xc9, 0xf4, 0xd7, 0x03, 0xbb, 0x93, 0x8e, 0xcc, 0xca, 0xda,
+  0x38, 0x49, 0x52, 0xb7, 0x11, 0xe9, 0x60, 0xda, 0xf5, 0x25, 0xd1, 0x62,
+  0x2a, 0x5e, 0x69, 0xcd, 0x32, 0x41, 0x4f, 0x5b, 0x7e, 0x0b, 0x2e, 0xd0,
+  0xd8, 0xf0, 0xd1, 0xd7, 0xf6, 0x3a, 0xee, 0x18, 0x39, 0xb8, 0x97, 0xe6,
+  0x5e, 0x07, 0x7f, 0xa8, 0xcb, 0xa0, 0x15, 0xa2, 0xce, 0xce, 0x48, 0xae,
+  0x42, 0xdc, 0xb5, 0xf6, 0x43, 0x8c, 0xc7, 0xb6, 0x66, 0xee, 0x45, 0x44,
+  0x18, 0xbd, 0x1a, 0x1a, 0x4a, 0x41, 0xfe, 0xff, 0xc5, 0x3f, 0x94, 0x2e,
+  0xf3, 0xf7, 0x98, 0xd7, 0x1a, 0x1d, 0xd7, 0xc1, 0xe3, 0xd8, 0xec, 0x64,
+  0x57, 0x3b, 0x05, 0x16, 0x99, 0x8c, 0x36, 0x7a, 0x0f, 0xc9, 0x0b, 0x10,
+  0xae, 0x89, 0xb7, 0x37, 0xca, 0xf3, 0x3a, 0x54, 0x03, 0xc1, 0x7a, 0x92,
+  0x68, 0x1f, 0xe1, 0xf5, 0xcf, 0xc5, 0x7f, 0x44, 0x83, 0xa4, 0xbd, 0x62,
+  0x00, 0x67, 0x73, 0x8e, 0xfd, 0xbf, 0xe5, 0xc3, 0xb4, 0x0e, 0xcc, 0xcb,
+  0x1b, 0xb4, 0xa2, 0x39
+};
+
+unsigned char bad_hash_value_signature[] = {
+  0x3e, 0x78, 0x12, 0xac, 0x4b, 0x07, 0xfd, 0xcc, 0x1b, 0x1f, 0x82, 0x76,
+  0x49, 0x52, 0xae, 0x5f, 0x48, 0x74, 0xe8, 0x1b, 0xbc, 0xa2, 0x94, 0x87,
+  0x9c, 0x06, 0xbb, 0x48, 0x78, 0x63, 0x69, 0x80, 0x7a, 0x48, 0xa0, 0x34,
+  0xab, 0x5f, 0x44, 0x2b, 0xd2, 0x3a, 0x55, 0x58, 0x0f, 0x97, 0xbc, 0x18,
+  0x74, 0x38, 0x78, 0x51, 0x47, 0x12, 0x45, 0xbe, 0xe0, 0x06, 0xb5, 0xc3,
+  0x46, 0xfd, 0xae, 0xbd, 0x66, 0x25, 0xd7, 0x36, 0x94, 0x3f, 0xda, 0x69,
+  0x21, 0xd0, 0x94, 0x81, 0x54, 0xb4, 0xf3, 0x45, 0x31, 0x93, 0x3c, 0x69,
+  0x02, 0xc0, 0xb4, 0x38, 0xf5, 0xff, 0xa0, 0x63, 0x87, 0xee, 0x32, 0x10,
+  0x57, 0xfa, 0xe6, 0x12, 0xad, 0xb8, 0xaa, 0x37, 0xec, 0x88, 0x4a, 0xb3,
+  0xfd, 0x52, 0x4d, 0x91, 0xe8, 0x17, 0x19, 0x39, 0xc7, 0xdf, 0x43, 0x81,
+  0x62, 0x08, 0x12, 0xaa, 0xa1, 0x08, 0xd9, 0xc4, 0xdf, 0x5b, 0x8d, 0xcb,
+  0x60, 0x0d, 0x34, 0x7d, 0x4e, 0xd7, 0xda, 0xc9, 0x84, 0xe8, 0x36, 0xbf,
+  0x2f, 0x7a, 0xa6, 0x98, 0xd4, 0x9c, 0x8d, 0x65, 0x34, 0x66, 0xcf, 0x7e,
+  0x57, 0x7e, 0x32, 0xb8, 0x70, 0xca, 0x1d, 0xf6, 0x69, 0x0c, 0xb9, 0x49,
+  0x33, 0x68, 0xba, 0x29, 0x50, 0x48, 0xc0, 0xe1, 0xf9, 0x6f, 0x1d, 0x48,
+  0x48, 0x5c, 0x99, 0xf2, 0xbb, 0xd1, 0x2c, 0x95, 0xcd, 0xf2, 0xe9, 0x0c,
+  0x2a, 0x2e, 0x60, 0x01, 0xbb, 0x2e, 0xf2, 0x6d, 0x4e, 0xd6, 0x03, 0x7b,
+  0xf5, 0xb1, 0x65, 0x34, 0xb8, 0xdd, 0x60, 0x10, 0xa6, 0x32, 0xe1, 0x50,
+  0x5c, 0x27, 0x72, 0x03, 0x74, 0x7b, 0x98, 0x13, 0x86, 0xbc, 0xdc, 0x21,
+  0xd1, 0x9d, 0xb1, 0x4f, 0xaf, 0x51, 0xaf, 0xda, 0xc6, 0xfc, 0x24, 0x92,
+  0x4e, 0x96, 0xa7, 0xc3, 0x72, 0x77, 0x66, 0x62, 0xd4, 0xf7, 0x3e, 0x9b,
+  0x36, 0x5f, 0xcf, 0x32
+};
+
+unsigned char Bleichenbacher_at_start_signature[] = {
+  0x80, 0xfb, 0xe0, 0xd9, 0xcf, 0x90, 0x9f, 0xd1, 0xc9, 0x3c, 0xd5, 0xad,
+  0x7e, 0x79, 0xaa, 0xab, 0x47, 0x35, 0x9c, 0xce, 0x52, 0xac, 0xc1, 0x8f,
+  0xfc, 0x0a, 0xd6, 0x61, 0xee, 0x92, 0xf7, 0xcc, 0x25, 0xdc, 0x64, 0x65,
+  0x21, 0xab, 0xab, 0x6c, 0x64, 0x18, 0x78, 0x6e, 0xdf, 0xef, 0x5e, 0xf3,
+  0xe0, 0xb9, 0x2e, 0xf9, 0x07, 0xb3, 0x68, 0x65, 0x67, 0x1c, 0xca, 0xfd,
+  0xb0, 0x71, 0xee, 0x6c, 0xbc, 0xb3, 0x12, 0xa6, 0x32, 0x48, 0x29, 0xb8,
+  0xd0, 0xc4, 0x53, 0xf4, 0xc6, 0x5e, 0x4c, 0xa8, 0x66, 0x87, 0x69, 0xce,
+  0xcd, 0x7d, 0x21, 0x8b, 0x50, 0x21, 0x22, 0xec, 0x06, 0xfc, 0xe9, 0x78,
+  0x6f, 0x7b, 0xc5, 0xbb, 0xd7, 0x7b, 0xe4, 0xf3, 0x3a, 0xd3, 0xd4, 0x68,
+  0xa8, 0xb3, 0x5f, 0xea, 0xdb, 0xa9, 0xa2, 0x9b, 0x5c, 0x87, 0xce, 0x4f,
+  0x0b, 0x33, 0x16, 0x5a, 0xe3, 0x0e, 0x02, 0xe1, 0xff, 0x79, 0x11, 0xd4,
+  0x5c, 0xa0, 0x4c, 0x6b, 0xf6, 0xcf, 0x81, 0x2c, 0x0a, 0xef, 0x80, 0x2f,
+  0x96, 0xeb, 0xe2, 0x93, 0xdb, 0x4c, 0x97, 0x55, 0x0f, 0xf9, 0x90, 0x02,
+  0x61, 0x60, 0xdb, 0xf9, 0xd4, 0x5a, 0x8c, 0xbb, 0x3f, 0x28, 0x97, 0xda,
+  0x29, 0x69, 0xfb, 0xfc, 0x7f, 0xb5, 0x1d, 0xcd, 0xbc, 0x1a, 0xad, 0xbb,
+  0xce, 0x7f, 0xcb, 0xd5, 0x4d, 0x2a, 0xd6, 0xb3, 0x2b, 0xbf, 0x1d, 0x0c,
+  0x5d, 0xfd, 0x83, 0x07, 0xfe, 0x08, 0x52, 0x13, 0xc1, 0x51, 0xfe, 0xec,
+  0x9f, 0x02, 0x4f, 0x96, 0x79, 0xe7, 0x22, 0x9a, 0xef, 0x64, 0x2a, 0x3c,
+  0xef, 0xe9, 0xd7, 0x39, 0xad, 0x38, 0xec, 0x0d, 0x82, 0xd7, 0x34, 0xcc,
+  0x32, 0x94, 0x8a, 0xf9, 0xfa, 0xc9, 0xb4, 0x05, 0x35, 0xf5, 0xe7, 0x4c,
+  0x7f, 0x9c, 0xe3, 0x1c, 0x46, 0x54, 0x91, 0xd0, 0x52, 0xf8, 0xb1, 0x54,
+  0xfe, 0xd1, 0xb5, 0xec
+};
+
+unsigned char Bleichenbacher_at_end_signature[] = {
+  0xe5, 0xbe, 0x82, 0xbd, 0x24, 0x6c, 0xd9, 0x6b, 0xd5, 0xb5, 0xaa, 0x41,
+  0x24, 0x70, 0x89, 0xe0, 0x6e, 0xd7, 0x3c, 0xb1, 0x38, 0x98, 0x51, 0x5c,
+  0xed, 0xa4, 0x27, 0xd8, 0xe4, 0x2f, 0xd4, 0x0a, 0x3d, 0x14, 0x30, 0x61,
+  0x99, 0x6c, 0xc4, 0xf3, 0x6f, 0x94, 0x4c, 0x66, 0xee, 0x60, 0x99, 0x9d,
+  0xfa, 0xea, 0xaf, 0x1d, 0xd9, 0xe3, 0xa1, 0xaa, 0x51, 0xfa, 0xde, 0xbc,
+  0x35, 0xd1, 0xd3, 0xd2, 0xfc, 0x37, 0x8a, 0xd1, 0x79, 0x80, 0x8d, 0x91,
+  0x69, 0xca, 0xc5, 0xf7, 0x85, 0xe3, 0x19, 0xf0, 0x8b, 0xb5, 0xcb, 0x9f,
+  0x61, 0xba, 0xee, 0xb7, 0xba, 0x5a, 0xfd, 0xc5, 0x78, 0x7b, 0x47, 0x6a,
+  0xe5, 0x8c, 0x8c, 0xa5, 0x1f, 0x8c, 0x5c, 0x63, 0x9a, 0x38, 0x17, 0xfc,
+  0x09, 0x0d, 0x87, 0x94, 0x7a, 0xe1, 0xfd, 0x26, 0xd0, 0xee, 0xa5, 0xe2,
+  0x34, 0x83, 0xc8, 0xe9, 0xa2, 0x83, 0x98, 0x18, 0x83, 0xab, 0xe7, 0xbf,
+  0x52, 0x8d, 0xa9, 0xf7, 0x0d, 0x9a, 0x3a, 0x0f, 0x63, 0x83, 0x29, 0x9c,
+  0xa9, 0xfb, 0x52, 0x38, 0x96, 0xa4, 0x1a, 0x50, 0x07, 0x16, 0x68, 0x6a,
+  0x84, 0x5b, 0x90, 0x31, 0x65, 0xea, 0xee, 0xc0, 0x9c, 0x57, 0xc3, 0x48,
+  0x3a, 0xcd, 0x1d, 0xa9, 0x1f, 0x59, 0x54, 0x4f, 0x85, 0x92, 0x78, 0x44,
+  0xb6, 0x93, 0x0a, 0xd0, 0xe2, 0x78, 0xd9, 0x92, 0xe6, 0x3b, 0x69, 0x32,
+  0x52, 0x59, 0x8e, 0x1d, 0x6e, 0xd9, 0x0f, 0xa9, 0x81, 0x70, 0x21, 0x29,
+  0xce, 0x2e, 0xce, 0xb3, 0xef, 0xe1, 0x12, 0x81, 0xa1, 0x7c, 0x1d, 0x4c,
+  0xad, 0x5e, 0x14, 0x20, 0x2c, 0x4b, 0x7f, 0x37, 0xea, 0xff, 0x84, 0x84,
+  0xf5, 0x97, 0x16, 0xc1, 0x96, 0xeb, 0xba, 0x84, 0x36, 0x7e, 0xc0, 0xa5,
+  0x11, 0x13, 0xa9, 0x88, 0x88, 0xe5, 0xf8, 0x56, 0x88, 0xaa, 0x47, 0x83,
+  0xbb, 0x36, 0x5b, 0x62
+};
+
+unsigned char *vboot_signatures[] =
+{
+	correct_signature_signature,
+	missing_first_byte_signature,
+	incorrect_first_byte_signature,
+	missing_second_byte_signature,
+	incorrect_second_byte_signature,
+	incorrect_ff_padding_signature,
+	missing_delimiter_signature,
+	incorrect_delimiter_signature,
+	bad_oid_signature,
+	bad_hash_value_signature,
+	Bleichenbacher_at_start_signature,
+	Bleichenbacher_at_end_signature,
+};
+
+const char *vboot_signatures_str[] =
+{
+	"correct_signature_signature",
+	"missing_first_byte_signature",
+	"incorrect_first_byte_signature",
+	"missing_second_byte_signature",
+	"incorrect_second_byte_signature",
+	"incorrect_ff_padding_signature",
+	"missing_delimiter_signature",
+	"incorrect_delimiter_signature",
+	"bad_oid_signature",
+	"bad_hash_value_signature",
+	"Bleichenbacher_at_start_signature",
+	"Bleichenbacher_at_end_signature",
+};
+#endif
+
 #endif
diff --git a/app/tests/kauth_test.c b/app/tests/kauth_test.c
index 0904601..e92922e 100644
--- a/app/tests/kauth_test.c
+++ b/app/tests/kauth_test.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2015, 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
@@ -33,7 +33,10 @@
 #include <arch/defines.h>
 #include <debug.h>
 #include <stdlib.h>
-
+#include <string.h>
+#if VERIFIED_BOOT
+#include <boot_verifier.h>
+#endif
 /* The test assumes the image and its signature to be verified
  * are flashed in the system and userdata partitions respectively.
  * The test reads the images and validates the decrypted signature
@@ -43,20 +46,31 @@
 
 void kauth_test(const char *arg, void *data, unsigned sz)
 {
+	int ret = 0;
+#if VERIFIED_BOOT
+	int i;
+	int vboot_ret[12];
+	int vboot_expected[12] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+	const char *image = "Test Input File";
+	unsigned int image_len = strlen(image);
+	KEYSTORE *ks = boot_gerity_get_oem_keystore();
+	bool test_pass = true;
+#else
 	unsigned long long ptn = 0;
 	int index = INVALID_PTN;
-	unsigned char *signature = NULL;
 	unsigned char *image = NULL;
-	int ret = 0;
-	uint32_t page_size = 0;
+	unsigned char *signature = NULL;
+	uint32_t page_size = mmc_page_size();
+#endif
+#if !VERIFIED_BOOT
 #if IMAGE_VERIF_ALGO_SHA1
 	uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA1;
 #else
 	uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA256;
 #endif
+#endif
 
-	page_size = mmc_page_size();
-
+#if !VERIFIED_BOOT
 	index = partition_get_index("system");
 	ptn = partition_get_offset(index);
 
@@ -75,7 +89,6 @@
 		dprintf(CRITICAL,"mmc_read system failed\n");
 		goto err;
 	}
-
 	signature = (unsigned char*) memalign(CACHE_LINE, ROUNDUP(page_size, CACHE_LINE));
 
 	ASSERT(signature);
@@ -94,16 +107,37 @@
 		dprintf(CRITICAL,"mmc_read signature failed\n");
 		goto err;
 	}
+#endif
 
 	dprintf(INFO, "kauth_test: Authenticating boot image (%d): start\n", IMAGE_SIZE);
 
+#if VERIFIED_BOOT
+	for (i = 0; i < 12; i++)
+	{
+		ret = boot_verify_compare_sha256((unsigned char *)image, image_len, vboot_signatures[i], ks->mykeybag->mykey->key_material);
+		vboot_ret[i] = ret;
+	}
+	for (i = 0; i < 12; i++)
+	{
+		if (vboot_ret[i] != vboot_expected[i])
+			test_pass = false;
+			ret = i;
+	}
+
+	if (test_pass)
+		dprintf(INFO, "Kauth_test: PASS for all usecases\n");
+	else
+		dprintf(INFO, "Kauth_test failed for : %s\n", vboot_signatures_str[ret]);
+#else
 	ret = image_verify(image, signature, IMAGE_SIZE, auth_algo);
+	dprintf(INFO, "kauth_test: Authenticating boot image: done return value = %d\n", ret);
+#endif
 
-        dprintf(INFO, "kauth_test: Authenticating boot image: done return value = %d\n", ret);
-
+#if !VERIFIED_BOOT
 err:
 	if(image)
 		free(image);
 	if(signature)
 		free(signature);
+#endif
 }
diff --git a/arch/arm/mmu_lpae.c b/arch/arm/mmu_lpae.c
index ddf66fd..e4f9c27 100644
--- a/arch/arm/mmu_lpae.c
+++ b/arch/arm/mmu_lpae.c
@@ -31,10 +31,12 @@
 #include <compiler.h>
 #include <arch.h>
 #include <arch/arm.h>
+#include <arch/ops.h>
 #include <arch/defines.h>
 #include <arch/arm/mmu.h>
 #include <mmu.h>
 #include <platform.h>
+#include <stdlib.h>
 
 #if ARM_WITH_MMU
 
@@ -51,8 +53,8 @@
 #define L2_PT_MASK              0xFFFFE00000
 #define L2_INDEX_MASK           0x3FE00000
 
-uint64_t mmu_l1_pagetable[L1_PT_SZ] __attribute__ ((aligned(4096))); /* Max is 8 */
-uint64_t mmu_l2_pagetable[L2_PT_SZ*MMU_L2_PT_SIZE] __attribute__ ((aligned(4096))); /* Macro from target code * 512 */
+uint64_t mmu_l1_pagetable[ROUNDUP(L1_PT_SZ, CACHE_LINE)] __attribute__ ((aligned(4096))); /* Max is 8 */
+uint64_t mmu_l2_pagetable[ROUNDUP(L2_PT_SZ*MMU_L2_PT_SIZE, CACHE_LINE)] __attribute__ ((aligned(4096))); /* Macro from target code * 512 */
 uint64_t avail_l2_pt = L2_PT_SZ;
 uint64_t *empty_l2_pt = mmu_l2_pagetable;
 
@@ -101,6 +103,7 @@
 		/* Advance pointer to next empty l2 page table */
 		empty_l2_pt += MMU_L2_PT_SIZE;
 		avail_l2_pt--;
+		arch_clean_invalidate_cache_range((addr_t) mmu_l1_pagetable, L1_PT_SZ);
 	}
 	else
 	{
@@ -134,6 +137,7 @@
 		p_addr += SIZE_2MB;
 		arm_invalidate_tlb();
 	}
+	arch_clean_invalidate_cache_range((addr_t) mmu_l2_pagetable, (L2_PT_SZ*MMU_L2_PT_SIZE));
 }
 
 /************************************************************/
@@ -171,6 +175,7 @@
 		address_start++;
 		arm_invalidate_tlb();
 	}
+	arch_clean_invalidate_cache_range((addr_t) mmu_l1_pagetable, L1_PT_SZ);
 }
 
 void arm_mmu_map_entry(mmu_section_t *entry)
@@ -201,8 +206,8 @@
 	arm_write_mair0(MAIR0);
 	arm_write_mair1(MAIR1);
 
-	/* TTBCR.EAE = 1 */
-	arm_write_ttbcr(0x80000000);
+	/* TTBCR.EAE = 1 & IRGN0 [9:8], ORNG0 bits [11:10]: 01 */
+	arm_write_ttbcr(0x80000500);
 
 	/* Enable TRE */
 	arm_write_cr1(arm_read_cr1() | (1<<28));
diff --git a/dev/gcdb/display/fastboot_oem_display.h b/dev/gcdb/display/fastboot_oem_display.h
index 9dd8b5c..b0a1371 100644
--- a/dev/gcdb/display/fastboot_oem_display.h
+++ b/dev/gcdb/display/fastboot_oem_display.h
@@ -76,6 +76,7 @@
 	{"jdi_fhd_video", "qcom,mdss_dsi_jdi_fhd_video", false},
 	{"jdi_qhd_dualdsi_cmd", "qcom,mdss_dsi_jdi_qhd_dualmipi_cmd", true},
 	{"jdi_qhd_dualdsi_video", "qcom,dsi_jdi_qhd_video", true},
+	{"jdi_4k_dualdsi_video_nofbc", "qcom,dsi_jdi_4k_nofbc_video", true},
 	{"nt35521_720p_video", "qcom,mdss_dsi_nt35521_720p_video", false},
 	{"nt35521_wxga_video", "qcom,mdss_dsi_nt35521_wxga_video", false},
 	{"nt35590_720p_cmd", "qcom,mdss_dsi_nt35590_720p_cmd", false},
@@ -101,6 +102,8 @@
 	{"truly_1080p_video", "qcom,mdss_dsi_truly_1080p_video", false},
 	{"truly_wvga_cmd", "qcom,mdss_dsi_truly_wvga_cmd", false},
 	{"truly_wvga_video", "qcom,mdss_dsi_truly_wvga_video", false},
+	{"adv16", "qcom,mdss_dsi_adv7533_1080p", false},
+	{"adv4", "qcom,mdss_dsi_adv7533_720p", false},
 };
 
 struct sim_lookup_list lookup_sim[] = {
diff --git a/dev/gcdb/display/gcdb_autopll.c b/dev/gcdb/display/gcdb_autopll.c
index 1d2db47..b78cecc 100755
--- a/dev/gcdb/display/gcdb_autopll.c
+++ b/dev/gcdb/display/gcdb_autopll.c
@@ -42,6 +42,7 @@
 	uint32_t h_period = 0, v_period = 0;
 	uint32_t width = pinfo->xres;
 	struct dsc_desc *dsc = NULL;
+	int bpp_lane;
 
 	if (pinfo->mipi.dual_dsi)
 		width /= 2;
@@ -62,19 +63,22 @@
 		pinfo->lcdc.v_front_porch + pinfo->lcdc.v_pulse_width +
 		pinfo->lcdc.yres_pad;
 
+	bpp_lane = pinfo->bpp / pinfo->mipi.num_of_lanes;
+
 	/*
 	 * If a bit clock rate is not specified, calculate it based
 	 * on panel parameters
 	 */
 	if (pinfo->mipi.bitclock == 0)
 		pll_data.bit_clock = (h_period * v_period *
-				pinfo->mipi.frame_rate * pinfo->bpp) /
-				pinfo->mipi.num_of_lanes;
+				pinfo->mipi.frame_rate * bpp_lane);
 	else
 		pll_data.bit_clock = pinfo->mipi.bitclock;
 
-	pll_data.pixel_clock = (pll_data.bit_clock * pinfo->mipi.num_of_lanes) /
-				pinfo->bpp;
+	pll_data.pixel_clock = (pll_data.bit_clock / bpp_lane);
+
+	dprintf(SPEW, "%s: bit_clk=%d pix_clk=%d\n", __func__,
+			pll_data.bit_clock, pll_data.pixel_clock);
 
 	pll_data.byte_clock = pll_data.bit_clock >> 3;
 
@@ -273,6 +277,11 @@
 		return ERROR;
 	}
 
+	pll_data.vco_clock = pll_data.bit_clock * pll_data.ndiv *
+						pll_data.n1div;
+
+	rate = pll_data.vco_clock;
+
 	rate /= pll_data.n1div;
 	rate /= FIX_PIXEL_CLOCK_DIV;
 
@@ -287,7 +296,6 @@
 			__func__, pll_data.n2div);
 		return ERROR;
 	}
-	pll_data.vco_clock = pll_data.bit_clock * pll_data.ndiv * pll_data.n1div;
 
 	dprintf(SPEW, "%s: vco:%u n1div:%d n2div:%d bit_clk:%u pixel_clk:%u\n",
 		__func__, pll_data.vco_clock, pll_data.n1div, pll_data.n2div,
diff --git a/dev/gcdb/display/gcdb_display.c b/dev/gcdb/display/gcdb_display.c
index d4fe865..6035ec3 100644
--- a/dev/gcdb/display/gcdb_display.c
+++ b/dev/gcdb/display/gcdb_display.c
@@ -408,20 +408,51 @@
 	return panelstruct;
 }
 
+static void mdss_dsi_check_swap_status(void)
+{
+	char *panel_dest, *dsi_controller;
+	struct oem_panel_data *oem_data = mdss_dsi_get_oem_data_ptr();
+
+	if (!oem_data->swap_dsi_ctrl)
+		return;
+
+	if (panelstruct.paneldata->panel_operating_mode &
+		(SPLIT_DISPLAY_FLAG | DUAL_DSI_FLAG)) {
+		dprintf(CRITICAL, "DSI swap invalid for split DSI panel!\n");
+		return;
+	}
+
+	/* Swap the panel destination and use appropriate PLL */
+	if (!strcmp(panelstruct.paneldata->panel_destination, "DISPLAY_1")) {
+		panel_dest = "DISPLAY_2";
+		dsi_controller = "dsi:1:";
+		panelstruct.paneldata->panel_operating_mode |= USE_DSI1_PLL_FLAG;
+	} else {
+		panel_dest = "DISPLAY_1";
+		dsi_controller = "dsi:0:";
+		panelstruct.paneldata->panel_operating_mode &= ~USE_DSI1_PLL_FLAG;
+	}
+	panelstruct.paneldata->panel_destination = panel_dest;
+	panelstruct.paneldata->panel_controller = dsi_controller;
+}
+
 static void mdss_dsi_set_pll_src(void)
 {
 	struct oem_panel_data *oem_data = mdss_dsi_get_oem_data_ptr();
 
-	if (panelstruct.paneldata->panel_operating_mode & USE_DSI1_PLL_FLAG)
+	/* Set PLL_SRC to PLL1 for non dual-DSI cases only */
+	if (!is_dsi_config_dual() &&
+		(panelstruct.paneldata->panel_operating_mode &
+		USE_DSI1_PLL_FLAG))
 		oem_data->dsi_pll_src = DSI_PLL1;
 
-	if (strcmp(oem_data->sec_panel, "")) {
+	if (is_dsi_config_dual()) {
 		if (oem_data->dsi_pll_src != DSI_PLL_DEFAULT) {
 			dprintf(CRITICAL, "Dual DSI config detected!"
 				"Use default PLL\n");
 			oem_data->dsi_pll_src = DSI_PLL_DEFAULT;
 		}
-	} else if (panelstruct.paneldata->slave_panel_node_id) {
+	} else if (is_dsi_config_split()) {
 		if((dsi_video_mode_phy_db.pll_type != DSI_PLL_TYPE_THULIUM)
 			&& (oem_data->dsi_pll_src == DSI_PLL1)) {
 			dprintf(CRITICAL, "Split DSI on 28nm/20nm!"
@@ -441,10 +472,9 @@
 	if (oem_data->dsi_pll_src == DSI_PLL1)
 		panelstruct.paneldata->panel_operating_mode |=
 			USE_DSI1_PLL_FLAG;
-	else
+	else if (oem_data->dsi_pll_src == DSI_PLL0)
 		panelstruct.paneldata->panel_operating_mode &=
 			~USE_DSI1_PLL_FLAG;
-
 }
 
 int gcdb_display_init(const char *panel_name, uint32_t rev, void *base)
@@ -458,6 +488,7 @@
 
 	if (pan_type == PANEL_TYPE_DSI) {
 		target_dsi_phy_config(&dsi_video_mode_phy_db);
+		mdss_dsi_check_swap_status();
 		mdss_dsi_set_pll_src();
 		if (dsi_panel_init(&(panel.panel_info), &panelstruct)) {
 			dprintf(CRITICAL, "DSI panel init failed!\n");
diff --git a/dev/gcdb/display/gcdb_display.h b/dev/gcdb/display/gcdb_display.h
index 088aa05..aaed691 100755
--- a/dev/gcdb/display/gcdb_display.h
+++ b/dev/gcdb/display/gcdb_display.h
@@ -72,6 +72,7 @@
 	char sec_panel[MAX_PANEL_ID_LEN];
 	bool cont_splash;
 	bool skip;
+	bool swap_dsi_ctrl;
 	uint32_t sim_mode;
 	char dsi_config[DSI_CFG_SIZE];
 	uint32_t dsi_pll_src;
@@ -83,4 +84,30 @@
     DSI_PLL1,
 };
 
+static inline bool is_dsi_config_split(void)
+{
+	struct panel_struct panelstruct = mdss_dsi_get_panel_data();
+
+	return panelstruct.paneldata->panel_node_id &&
+		panelstruct.paneldata->slave_panel_node_id &&
+		(panelstruct.paneldata->panel_operating_mode & (DUAL_DSI_FLAG |
+		SPLIT_DISPLAY_FLAG | DST_SPLIT_FLAG));
+}
+
+static inline bool is_dsi_config_dual(void)
+{
+	struct oem_panel_data *oem_data = mdss_dsi_get_oem_data_ptr();
+
+	return !is_dsi_config_split() && oem_data->sec_panel &&
+		strcmp(oem_data->sec_panel, "");
+}
+
+static inline bool is_dsi_config_single()
+{
+	struct panel_struct panelstruct = mdss_dsi_get_panel_data();
+
+	return panelstruct.paneldata->panel_node_id && !is_dsi_config_split()
+		&& !is_dsi_config_dual();
+}
+
 #endif /*_GCDB_DISPLAY_H_ */
diff --git a/dev/gcdb/display/gcdb_display_param.c b/dev/gcdb/display/gcdb_display_param.c
index 91ce12b..e236fa1 100644
--- a/dev/gcdb/display/gcdb_display_param.c
+++ b/dev/gcdb/display/gcdb_display_param.c
@@ -37,7 +37,8 @@
 #include "target/display.h"
 #include "fastboot_oem_display.h"
 
-struct oem_panel_data oem_data = {{'\0'}, {'\0'}, false, false, SIM_NONE, "single_dsi", DSI_PLL_DEFAULT};
+struct oem_panel_data oem_data = {{'\0'}, {'\0'}, false, false, false, SIM_NONE,
+	"single_dsi", DSI_PLL_DEFAULT};
 
 static int panel_name_to_dt_string(struct panel_lookup_list supp_panels[],
 			  uint32_t supp_panels_size,
@@ -195,6 +196,10 @@
 	ch = strstr((char *) panel_name, ":disable");
 	oem_data.cont_splash = ch ? false : true;
 
+	/* Interposer card to swap DSI0 and DSI1 lanes */
+	ch = strstr((char *) panel_name, ":swap");
+	oem_data.swap_dsi_ctrl = ch ? true : false;
+
 	/* DSI PLL source */
 	ch = strstr((char *) panel_name, ":pll0");
 	if (ch) {
diff --git a/dev/gcdb/display/include/panel_fl10802_fwvga_video.h b/dev/gcdb/display/include/panel_fl10802_fwvga_video.h
index 80c64bd..4a511df 100644
--- a/dev/gcdb/display/include/panel_fl10802_fwvga_video.h
+++ b/dev/gcdb/display/include/panel_fl10802_fwvga_video.h
@@ -328,7 +328,7 @@
 /* Backlight setting                                                         */
 /*---------------------------------------------------------------------------*/
 static struct backlight fl10802_fwvga_video_backlight = {
-  1, 1, 255, 100, 2, "PMIC_8941"
+  BL_DCS, 1, 255, 100, 2, "PMIC_8941"
 };
 
 #define FL10802_FWVGA_VIDEO_SIGNATURE 0xFFFF
diff --git a/dev/gcdb/display/include/panel_hx8394d_720p_video.h b/dev/gcdb/display/include/panel_hx8394d_720p_video.h
index ac4806f..1c05b35 100644
--- a/dev/gcdb/display/include/panel_hx8394d_720p_video.h
+++ b/dev/gcdb/display/include/panel_hx8394d_720p_video.h
@@ -47,7 +47,7 @@
 
 static struct panel_config hx8394d_720p_video_panel_data = {
   "qcom,mdss_dsi_hx8394d_720p_video", "dsi:0:", "qcom,mdss-dsi-panel",
-  10, 0, "DISPLAY_1", 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  10, 0, "DISPLAY_1", 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL
 };
 
 /*---------------------------------------------------------------------------*/
@@ -259,14 +259,6 @@
   0x79, 0x1a, 0x12, 0x00, 0x3e, 0x42, 0x16, 0x1e, 0x15, 0x03, 0x04, 0x00
 };
 
-
-
-static struct mipi_dsi_cmd hx8394d_720p_video_rotation[] = {
-
-};
-#define HX8394D_720P_VIDEO_ROTATION 0
-
-
 static struct panel_timing hx8394d_720p_video_timing_info = {
   0, 4, 0x04, 0x1b
 };
diff --git a/dev/gcdb/display/include/panel_hx8399a_1080p_video.h b/dev/gcdb/display/include/panel_hx8399a_1080p_video.h
index 0ac37ac..f2d828e 100644
--- a/dev/gcdb/display/include/panel_hx8399a_1080p_video.h
+++ b/dev/gcdb/display/include/panel_hx8399a_1080p_video.h
@@ -40,7 +40,7 @@
 /*---------------------------------------------------------------------------*/
 static struct panel_config hx8399a_1080p_video_panel_data = {
 	"qcom,mdss_dsi_hx8399a_1080p_video", "dsi:0:", "qcom,mdss-dsi-panel",
-	10, 0, "DISPLAY_1", 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL
+	10, 0, "DISPLAY_1", 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 866400000, 0, 0, 0, NULL
 };
 
 /*---------------------------------------------------------------------------*/
diff --git a/dev/gcdb/display/include/panel_jdi_4k_dualdsi_video_nofbc.h b/dev/gcdb/display/include/panel_jdi_4k_dualdsi_video_nofbc.h
new file mode 100644
index 0000000..ae73869
--- /dev/null
+++ b/dev/gcdb/display/include/panel_jdi_4k_dualdsi_video_nofbc.h
@@ -0,0 +1,184 @@
+/* Copyright (c) 2015, 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_JDI_4K_DUALDSI_VIDEO_NOFBC__H_
+#define _PANEL_JDI_4K_DUALDSI_VIDEO_NOFBC__H_
+/*---------------------------------------------------------------------------*/
+/* HEADER files                                                              */
+/*---------------------------------------------------------------------------*/
+#include "panel.h"
+
+/*---------------------------------------------------------------------------*/
+/* Panel configuration                                                       */
+/*---------------------------------------------------------------------------*/
+static struct panel_config jdi_4k_dualdsi_video_nofbc_panel_data = {
+	"qcom,dsi_jdi_4k_nofbc_video", "dsi:0:", "qcom,mdss-dsi-panel",
+	10, 0, "DISPLAY_1", 0, 0, 40, 0, 0, 1, 0, 0, 0, 0, 0, 11, 0, 0,
+	"qcom,dsi_jdi_4k_nofbc_video",
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel resolution                                                          */
+/*---------------------------------------------------------------------------*/
+static struct panel_resolution jdi_4k_dualdsi_video_nofbc_panel_res = {
+	3840, 2160, 100, 80, 12, 0, 16, 16, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel color information                                                   */
+/*---------------------------------------------------------------------------*/
+static struct color_info jdi_4k_dualdsi_video_nofbc_color = {
+	24, 0, 0xff, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel on/off command information                                          */
+/*---------------------------------------------------------------------------*/
+static char jdi_4k_dualdsi_video_on_cmd0[] = {
+	0x51, 0xff, 0x15, 0x80,
+};
+
+static char jdi_4k_dualdsi_video_on_cmd1[] = {
+	0x53, 0x24, 0x15, 0x80,
+};
+
+static char jdi_4k_dualdsi_video_on_cmd2[] = {
+	0x11, 0x00, 0x05, 0x80
+};
+
+static char jdi_4k_dualdsi_video_on_cmd3[] = {
+	0x29, 0x00, 0x05, 0x80
+};
+
+static char jdi_4k_dualdsi_video_on_cmd_ip_0[] = {
+	0xb0, 0x04, 0x23, 0x80
+};
+
+static char jdi_4k_dualdsi_video_on_cmd_ip_1[] = {
+	0x08, 0x00, 0x29, 0xC0,
+	0xb3, 0x14, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00
+};
+
+static char jdi_4k_dualdsi_video_on_cmd_ip_2[] = {
+	0xd6, 0x01, 0x23, 0x80
+};
+
+static struct mipi_dsi_cmd jdi_4k_dualdsi_video_nofbc_on_command[] = {
+	{0x4, jdi_4k_dualdsi_video_on_cmd0, 0x0a},
+	{0x4, jdi_4k_dualdsi_video_on_cmd1, 0x0a},
+	{0x4, jdi_4k_dualdsi_video_on_cmd2, 0xc9},
+	{0x4, jdi_4k_dualdsi_video_on_cmd_ip_0, 0x0a},
+	{0xc, jdi_4k_dualdsi_video_on_cmd_ip_1, 0x0a},
+	{0x4, jdi_4k_dualdsi_video_on_cmd_ip_2, 0x0a},
+	{0x4, jdi_4k_dualdsi_video_on_cmd3, 0x78}
+};
+
+#define JDI_4K_DUALDSI_VIDEO_NOFBC_ON_COMMAND 7
+
+static char jdi_4k_dualdsi_videooff_cmd0[] = {
+	0x28, 0x00, 0x05, 0x80
+};
+
+static char jdi_4k_dualdsi_videooff_cmd1[] = {
+	0x10, 0x00, 0x05, 0x80
+};
+
+static struct mipi_dsi_cmd jdi_4k_dualdsi_video_nofbc_off_command[] = {
+	{0x4, jdi_4k_dualdsi_videooff_cmd0, 0x32},
+	{0x4, jdi_4k_dualdsi_videooff_cmd1, 0x78}
+};
+
+#define JDI_4K_DUALDSI_VIDEO_NOFBC_OFF_COMMAND 2
+
+
+static struct command_state jdi_4k_dualdsi_video_nofbc_state = {
+	0, 1
+};
+
+/*---------------------------------------------------------------------------*/
+/* Command mode panel information                                            */
+/*---------------------------------------------------------------------------*/
+static struct commandpanel_info jdi_4k_dualdsi_video_nofbc_command_panel = {
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Video mode panel information                                              */
+/*---------------------------------------------------------------------------*/
+static struct videopanel_info jdi_4k_dualdsi_video_nofbc_video_panel = {
+	0, 0, 0, 0, 1, 1, 1, 0, 0x9
+};
+
+/*---------------------------------------------------------------------------*/
+/* Lane configuration                                                        */
+/*---------------------------------------------------------------------------*/
+static struct lane_configuration jdi_4k_dualdsi_video_nofbc_lane_config = {
+	4, 0, 1, 1, 1, 1, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel timing                                                              */
+/*---------------------------------------------------------------------------*/
+static const uint32_t jdi_4k_dualdsi_video_nofbc_timings[] = {
+	0x3e, 0x38, 0x26, 0x00, 0x68, 0x6e, 0x2a, 0x3c, 0x2c, 0x03, 0x04, 0x00
+};
+
+
+static const uint32_t jdi_4k_dualdsi_thulium_video_nofbc_timings[] = {
+		0x2c, 0x27, 0x0e, 0x10, 0x0a, 0x03, 0x04, 0xa0,
+		0x2c, 0x27, 0x0e, 0x10, 0x0a, 0x03, 0x04, 0xa0,
+		0x2c, 0x27, 0x0e, 0x10, 0x0a, 0x03, 0x04, 0xa0,
+		0x2c, 0x27, 0x0e, 0x10, 0x0a, 0x03, 0x04, 0xa0,
+		0x2c, 0x32, 0x0e, 0x0f, 0x0a, 0x03, 0x04, 0xa0,
+};
+
+static struct panel_timing jdi_4k_dualdsi_video_nofbc_timing_info = {
+	0x0, 0x04, 0x0d, 0x3e
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel reset sequence                                                      */
+/*---------------------------------------------------------------------------*/
+static struct panel_reset_sequence jdi_4k_dualdsi_video_nofbc_reset_seq = {
+	{0, 0, 1, }, {200, 200, 200, }, 2
+};
+
+/*---------------------------------------------------------------------------*/
+/* Backlight setting                                                         */
+/*---------------------------------------------------------------------------*/
+static struct backlight jdi_4k_dualdsi_video_nofbc_backlight = {
+	0, 1, 4095, 100, 1, "PMIC_8941"
+};
+
+static struct labibb_desc jdi_4k_dualdsi_video_nofbc_labibb = {
+	0, 1, 5500000, 5500000, 5500000, 5500000, 3, 3, 1
+};
+
+#endif /*_PANEL_JDI_4K_DUALDSI_VIDEO_NOFBC__H_*/
diff --git a/dev/gcdb/display/include/panel_r69007_wqxga_cmd.h b/dev/gcdb/display/include/panel_r69007_wqxga_cmd.h
new file mode 100644
index 0000000..ab68848
--- /dev/null
+++ b/dev/gcdb/display/include/panel_r69007_wqxga_cmd.h
@@ -0,0 +1,381 @@
+/* Copyright (c) 2015, 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 _PANEL_R69007_WQXGA_CMD_H_
+#define _PANEL_R69007_WQXGA_CMD_H_
+/*---------------------------------------------------------------------------*/
+/* HEADER files                                                              */
+/*---------------------------------------------------------------------------*/
+#include "panel.h"
+
+/*---------------------------------------------------------------------------*/
+/* Panel configuration                                                       */
+/*---------------------------------------------------------------------------*/
+static struct panel_config r69007_wqxga_cmd_panel_data = {
+	"qcom,mdss_dsi_r69007_wqxga_cmd", "dsi:0:", "qcom,mdss-dsi-panel",
+	10, 1, "DISPLAY_1", 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0,
+	"qcom,mdss_dsi_r69007_wqxga_cmd"
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel resolution                                                          */
+/*---------------------------------------------------------------------------*/
+static struct panel_resolution r69007_wqxga_cmd_panel_res = {
+	1440, 2560, 112, 70, 10, 0, 9, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel color information                                                   */
+/*---------------------------------------------------------------------------*/
+static struct color_info r69007_wqxga_cmd_color = {
+	24, 0, 0xff, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel on/off command information                                          */
+/*---------------------------------------------------------------------------*/
+static char r69007_wqxga_cmd_on_cmd0[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xB0, 0x00, 0xFF, 0xFF,
+};
+
+static char r69007_wqxga_cmd_on_cmd1[] = {
+	0x04, 0x00, 0x29, 0xC0,
+	0xB3, 0x00, 0x00, 0x00,
+};
+
+static char r69007_wqxga_cmd_on_cmd2[] = {
+	0x04, 0x00, 0x29, 0xC0,
+	0xB6, 0x3b, 0xd3, 0x00,
+};
+
+static char r69007_wqxga_cmd_on_cmd3[] = {
+	0x28, 0x00, 0x29, 0xC0,
+	0xC1, 0x80, 0x08, 0x11,
+	0x1F, 0xFC, 0xF2, 0xC9,
+	0x1F, 0x5F, 0x98, 0xB3,
+	0xFE, 0xFF, 0xF7, 0xFE,
+	0xFF, 0xD7, 0x31, 0xF1,
+	0xCB, 0x3F, 0x3F, 0xFD,
+	0xEF, 0x03, 0x24, 0x69,
+	0x18, 0xAA, 0x40, 0x01,
+	0x42, 0x02, 0x08, 0x00,
+	0x01, 0x00, 0x01, 0x00,
+};
+
+static char r69007_wqxga_cmd_on_cmd4[] = {
+	0x0F, 0x00, 0x29, 0xC0,
+	0xC2, 0x01, 0xFA, 0x00,
+	0x04, 0x64, 0x08, 0x00,
+	0x60, 0x00, 0x38, 0x70,
+	0x00, 0x00, 0x00, 0xFF,
+};
+
+static char r69007_wqxga_cmd_on_cmd5[] = {
+	0x09, 0x00, 0x29, 0xC0,
+	0xC3, 0x07, 0x01, 0x08,
+	0x01, 0x00, 0x00, 0x00,
+	0x00, 0xFF, 0xFF, 0xFF,
+};
+
+static char r69007_wqxga_cmd_on_cmd6[] = {
+	0x12, 0x00, 0x29, 0xC0,
+	0xC4, 0x70, 0x00, 0x00,
+	0x00, 0x02, 0x00, 0x00,
+	0x00, 0x00, 0x02, 0x01,
+	0x00, 0x01, 0x01, 0x00,
+	0x00, 0x00, 0xFF, 0xFF,
+};
+
+static char r69007_wqxga_cmd_on_cmd7[] = {
+	0x11, 0x00, 0x29, 0xC0,
+	0xC6, 0x3C, 0x00, 0x3C,
+	0x02, 0x37, 0x01, 0x0E,
+	0x01, 0x02, 0x01, 0x02,
+	0x03, 0x0F, 0x04, 0x3C,
+	0x46, 0xFF, 0xFF, 0xFF,
+};
+
+static char r69007_wqxga_cmd_on_cmd8[] = {
+	0x1F, 0x00, 0x29, 0xC0,
+	0xC7, 0x00, 0x16, 0x22,
+	0x2C, 0x3B, 0x48, 0x51,
+	0x5D, 0x40, 0x47, 0x53,
+	0x61, 0x6A, 0x71, 0x78,
+	0x00, 0x16, 0x22, 0x2C,
+	0x3B, 0x48, 0x51, 0x5D,
+	0x40, 0x47, 0x53, 0x61,
+	0x6A, 0x71, 0x78, 0xFF,
+};
+
+static char r69007_wqxga_cmd_on_cmd9[] = {
+	0x14, 0x00, 0x29, 0xC0,
+	0xC8, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0xFC, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0xFC, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0xFC, 0x00,
+};
+
+static char r69007_wqxga_cmd_on_cmd10[] = {
+	0x14, 0x00, 0x29, 0xC0,
+	0xC9, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0xFC, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0xFC, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0xFC, 0x00,
+};
+
+static char r69007_wqxga_cmd_on_cmd11[] = {
+	0x14, 0x00, 0x29, 0xC0,
+	0xCB, 0xAA, 0x1E, 0xE3,
+	0x55, 0xF1, 0xFF, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+};
+
+static char r69007_wqxga_cmd_on_cmd12[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xCC, 0x07, 0xFF, 0xFF,
+};
+
+static char r69007_wqxga_cmd_on_cmd13[] = {
+	0x0B, 0x00, 0x29, 0xC0,
+	0xCD, 0x3A, 0x86, 0x3A,
+	0x86, 0x8D, 0x8D, 0x04,
+	0x04, 0x00, 0x00, 0xFF,
+};
+
+static char r69007_wqxga_cmd_on_cmd14[] = {
+	0x11, 0x00, 0x29, 0xC0,
+	0xD0, 0x2A, 0x01, 0x91,
+	0x6A, 0xDC, 0x59, 0x19,
+	0x00, 0x00, 0x00, 0x19,
+	0x99, 0x04, 0x00, 0x00,
+	0x00, 0xFF, 0xFF, 0xFF,
+};
+
+static char r69007_wqxga_cmd_on_cmd15[] = {
+	0x21, 0x00, 0x29, 0xC0,
+	0xD3, 0x1B, 0x3B, 0xBB,
+	0x77, 0x77, 0x77, 0xBB,
+	0xB3, 0x33, 0x00, 0x80,
+	0xA7, 0xAF, 0x5B, 0x5B,
+	0x33, 0x33, 0x33, 0xC0,
+	0x00, 0xF2, 0x0F, 0x7D,
+	0x7C, 0xFF, 0x0F, 0x99,
+	0x00, 0x33, 0x00, 0xFF,
+	0xFF, 0xFF, 0xFF, 0xFF,
+};
+
+static char r69007_wqxga_cmd_on_cmd16[] = {
+	0x06, 0x00, 0x29, 0xC0,
+	0xD4, 0x57, 0x33, 0x05,
+	0x00, 0xF4, 0xFF, 0xFF,
+};
+
+static char r69007_wqxga_cmd_on_cmd17[] = {
+	0x0C, 0x00, 0x29, 0xC0,
+	0xD5, 0x66, 0x00, 0x00,
+	0x01, 0x3D, 0x01, 0x3D,
+	0x00, 0x38, 0x00, 0x38,
+};
+
+static char r69007_wqxga_cmd_on_cmd18[] = {
+	0x22, 0x00, 0x29, 0xC0,
+	0xD7, 0x04, 0xff, 0x23,
+	0x15, 0x75, 0xa4, 0xc3,
+	0x1f, 0xc3, 0x1f, 0xd9,
+	0x07, 0x1c, 0x1f, 0x30,
+	0x8e, 0x87, 0xc7, 0xe3,
+	0xf1, 0xcc, 0xf0, 0x1f,
+	0xf0, 0x0d, 0x70, 0x00,
+	0x2A, 0x00, 0x7e, 0x1d,
+	0x07, 0x00, 0xFF, 0xFF,
+};
+
+static char r69007_wqxga_cmd_on_cmd19[] = {
+	0x05, 0x00, 0x29, 0xC0,
+	0xDE, 0x00, 0x3f, 0xff,
+	0x10, 0xFF, 0xFF, 0xFF,
+};
+
+static char r69007_wqxga_cmd_on_cmd20[] = {
+	0x02, 0x00, 0x29, 0xC0,
+	0xD6, 0x01, 0xFF, 0xFF,
+};
+
+static char r69007_wqxga_cmd_on_cmd21[] = {
+	0x02, 0x00, 0x39, 0xC0,
+	0x35, 0x00, 0xFF, 0xFF,
+};
+
+static char r69007_wqxga_cmd_on_cmd22[] = {
+	0x05, 0x00, 0x39, 0xC0,
+	0x2A, 0x00, 0x00, 0x05,
+	0x9F, 0xFF, 0xFF, 0xFF,
+};
+
+static char r69007_wqxga_cmd_on_cmd23[] = {
+	0x05, 0x00, 0x39, 0xC0,
+	0x2B, 0x00, 0x00, 0x09,
+	0xFF, 0xFF, 0xFF, 0xFF,
+};
+
+static char r69007_wqxga_cmd_on_cmd24[] = {
+	0x02, 0x00, 0x39, 0xC0,
+	0x2C, 0x00, 0xFF, 0xFF,
+};
+
+static char r69007_wqxga_cmd_on_cmd25[] = {
+	0x02, 0x00, 0x39, 0xC0,
+	0x36, 0x40, 0xFF, 0xFF,
+};
+
+static char r69007_wqxga_cmd_on_cmd26[] = {
+	0x29, 0x00, 0x05, 0x80
+};
+
+static char r69007_wqxga_cmd_on_cmd27[] = {
+	0x11, 0x00, 0x05, 0x80
+};
+
+static struct mipi_dsi_cmd r69007_wqxga_cmd_on_command[] = {
+	{0x8, r69007_wqxga_cmd_on_cmd0, 0x00},
+	{0x8, r69007_wqxga_cmd_on_cmd1, 0x00},
+	{0x8, r69007_wqxga_cmd_on_cmd2, 0x00},
+	{0x2c, r69007_wqxga_cmd_on_cmd3, 0x00},
+	{0x14, r69007_wqxga_cmd_on_cmd4, 0x00},
+	{0x10, r69007_wqxga_cmd_on_cmd5, 0x00},
+	{0x18, r69007_wqxga_cmd_on_cmd6, 0x00},
+	{0x18, r69007_wqxga_cmd_on_cmd7, 0x00},
+	{0x24, r69007_wqxga_cmd_on_cmd8, 0x00},
+	{0x18, r69007_wqxga_cmd_on_cmd9, 0x00},
+	{0x18, r69007_wqxga_cmd_on_cmd10, 0x00},
+	{0x18, r69007_wqxga_cmd_on_cmd11, 0x00},
+	{0x8, r69007_wqxga_cmd_on_cmd12, 0x00},
+	{0x10, r69007_wqxga_cmd_on_cmd13, 0x00},
+	{0x18, r69007_wqxga_cmd_on_cmd14, 0x00},
+	{0x28, r69007_wqxga_cmd_on_cmd15, 0x00},
+	{0xc, r69007_wqxga_cmd_on_cmd16, 0x00},
+	{0x10, r69007_wqxga_cmd_on_cmd17, 0x00},
+	{0x28, r69007_wqxga_cmd_on_cmd18, 0x00},
+	{0xc, r69007_wqxga_cmd_on_cmd19, 0x00},
+	{0x8, r69007_wqxga_cmd_on_cmd20, 0x00},
+	{0x8, r69007_wqxga_cmd_on_cmd21, 0x00},
+	{0xc, r69007_wqxga_cmd_on_cmd22, 0x00},
+	{0xc, r69007_wqxga_cmd_on_cmd23, 0x00},
+	{0x8, r69007_wqxga_cmd_on_cmd24, 0x00},
+	{0x8, r69007_wqxga_cmd_on_cmd25, 0x00},
+	{0x4, r69007_wqxga_cmd_on_cmd26, 0x78},
+	{0x4, r69007_wqxga_cmd_on_cmd27, 0x14}
+};
+
+#define R69007_WQXGA_CMD_ON_COMMAND 28
+
+
+static char r69007_wqxga_cmdoff_cmd0[] = {
+	0x28, 0x00, 0x05, 0x80
+};
+
+static char r69007_wqxga_cmdoff_cmd1[] = {
+	0x10, 0x00, 0x05, 0x80
+};
+
+static struct mipi_dsi_cmd r69007_wqxga_cmd_off_command[] = {
+	{0x4, r69007_wqxga_cmdoff_cmd0, 0x32},
+	{0x4, r69007_wqxga_cmdoff_cmd1, 0x78}
+};
+
+#define R69007_WQXGA_CMD_OFF_COMMAND 2
+
+
+static struct command_state r69007_wqxga_cmd_state = {
+	0, 1
+};
+
+/*---------------------------------------------------------------------------*/
+/* Command mode panel information                                            */
+/*---------------------------------------------------------------------------*/
+static struct commandpanel_info r69007_wqxga_cmd_command_panel = {
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Video mode panel information                                              */
+/*---------------------------------------------------------------------------*/
+static struct videopanel_info r69007_wqxga_cmd_video_panel = {
+	1, 0, 0, 0, 1, 1, 2, 0, 0x9
+};
+
+/*---------------------------------------------------------------------------*/
+/* Lane configuration                                                        */
+/*---------------------------------------------------------------------------*/
+static struct lane_configuration r69007_wqxga_cmd_lane_config = {
+	4, 0, 1, 1, 1, 1, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel timing                                                              */
+/*---------------------------------------------------------------------------*/
+static const uint32_t r69007_wqxga_cmd_timings[] = {
+	0xDA, 0x34, 0x24, 0x00, 0x64, 0x68, 0x28, 0x38, 0x2A, 0x03, 0x04, 0x00
+};
+
+static const uint32_t r69007_wqxga_thulium_cmd_timings[] = {
+	0x23, 0x1F, 0x07, 0x09, 0x05, 0x03, 0x04, 0xa0,
+	0x23, 0x1F, 0x07, 0x09, 0x05, 0x03, 0x04, 0xa0,
+	0x23, 0x1F, 0x07, 0x09, 0x05, 0x03, 0x04, 0xa0,
+	0x23, 0x1F, 0x07, 0x09, 0x05, 0x03, 0x04, 0xa0,
+	0x23, 0x19, 0x08, 0x08, 0x05, 0x03, 0x04, 0xa0
+};
+
+static struct panel_timing r69007_wqxga_cmd_timing_info = {
+	0x0, 0x04, 0x03, 0x29
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel reset sequence                                                      */
+/*---------------------------------------------------------------------------*/
+static struct panel_reset_sequence r69007_wqxga_cmd_reset_seq = {
+	{1, 0, 1, }, {2, 5, 120, }, 2
+};
+
+static struct labibb_desc r69007_wqxga_cmd_labibb = {
+	0, 1, 5500000, 5500000, 5500000, 5500000, 3, 3, 1
+};
+
+/*---------------------------------------------------------------------------*/
+/* Backlight setting                                                         */
+/*---------------------------------------------------------------------------*/
+static struct backlight r69007_wqxga_cmd_backlight = {
+	1, 1, 4095, 100, 1, "PMIC_8941"
+};
+
+#endif /*_PANEL_R69007_WQXGA_CMD_H_*/
diff --git a/dev/pmic/pmi8994/include/pm_app_smbchg.h b/dev/pmic/pmi8994/include/pm_app_smbchg.h
index bfc12ca..81a7b39 100644
--- a/dev/pmic/pmi8994/include/pm_app_smbchg.h
+++ b/dev/pmic/pmi8994/include/pm_app_smbchg.h
@@ -201,5 +201,6 @@
 bool pm_appsbl_display_init_done();
 bool pm_appsbl_charging_in_progress();
 pm_err_flag_type pm_appsbl_set_dcin_suspend();
+bool pm_app_display_shutdown_in_prgs();
 #endif  //PM_APP_SMBCHG__H
 
diff --git a/dev/pmic/pmi8994/pm_app_smbchg.c b/dev/pmic/pmi8994/pm_app_smbchg.c
index d3d1d6b..4b9693b 100644
--- a/dev/pmic/pmi8994/pm_app_smbchg.c
+++ b/dev/pmic/pmi8994/pm_app_smbchg.c
@@ -40,11 +40,12 @@
 #include "pm_smbchg_driver.h"
 #include "pm_comm.h"
 #include "pm_smbchg_dc_chgpth.h"
+#include <kernel/thread.h>
 #include <debug.h>
 #include <platform/timer.h>
 #include <sys/types.h>
 #include <target.h>
-
+#include <pm8x41.h>
 
 /*===========================================================================
 
@@ -64,16 +65,27 @@
 #define  PM_MIN_ADC_READY_DELAY             1 * 1000  //1ms
 #define  PM_MAX_ADC_READY_DELAY     2000              //2s
 #define SBL_PACKED_SRAM_CONFIG_SIZE 3
-
+#define  PM_CHARGE_DISPLAY_TIMEOUT       5 * 1000 //5 secs
 #define boot_log_message(...) dprintf(CRITICAL, __VA_ARGS__)
 
 static pm_smbchg_bat_if_low_bat_thresh_type pm_dbc_bootup_volt_threshold;
+/* Need to maintain flags to track
+ * 1. charge_in_progress: Charging progress and exit the loop once charging is completed.
+ * 2. display_initialized: Track if the display is already initialized to make sure display
+ *    thread does not reinitialize the display again.
+ * 3. display_shutdown_in_prgs: To avoid race condition between regualr display initialization and
+ *    display shutdown in display thread.
+ */
+
 static bool display_initialized;
 static bool charge_in_progress;
+static bool display_shutdown_in_prgs;
+
 char panel_name[256];
 
 pm_err_flag_type pm_smbchg_get_charger_path(uint32 device_index, pm_smbchg_usb_chgpth_pwr_pth_type* charger_path);
 pm_err_flag_type pm_appsbl_chg_config_vbat_low_threshold(uint32 device_index, pm_smbchg_specific_data_type *chg_param_ptr);
+static void display_thread_initialize();
 
 /*===========================================================================
 
@@ -173,6 +185,7 @@
             vbatt_weak_status = FALSE;
             break; //bootup
          }
+		dprintf(INFO, "Vbatt Level: %u\n", vbat_adc);
    }
    else
    {
@@ -227,14 +240,11 @@
 
       charge_in_progress = true;
 #if DISPLAY_SPLASH_SCREEN
-      if (!display_initialized)
-         target_display_init(panel_name);
-      display_initialized = true;
+	display_thread_initialize();
 #endif
       /* Wait for 500 msecs before looking for vbat */
       udelay(PM_WEAK_BATTERY_CHARGING_DELAY); //500ms
 
-
       //Check if Charging in progress
       err_flag |= pm_smbchg_chgr_get_chgr_sts(device_index, &vbatt_chging_status);
       if ( err_flag != PM_ERR_FLAG__SUCCESS )  { break;}
@@ -584,3 +594,83 @@
 
 	return err_flag;
 }
+
+static bool is_power_key_pressed()
+{
+	int count = 0;
+
+	if (pm8x41_get_pwrkey_is_pressed())
+	{
+		while(count++ < 10 && pm8x41_get_pwrkey_is_pressed())
+			thread_sleep(100);
+
+		dprintf(INFO, "Power Key Pressed\n");
+		return true;
+	}
+
+	return false;
+}
+
+bool pm_app_display_shutdown_in_prgs()
+{
+	return display_shutdown_in_prgs;
+}
+
+static int display_charger_screen()
+{
+	static bool display_init_first_time;
+
+	/* By default first time display the charger screen
+	 * Wait for 5 seconds and turn off the display
+	 * If user presses power key & charging is in progress display the charger screen
+	 */
+	do {
+		if (!display_init_first_time || (is_power_key_pressed() && charge_in_progress))
+		{
+			/* Display charger screen */
+			target_display_init(panel_name);
+			/* wait for 5 seconds to show the charger screen */
+			display_initialized = true;
+			thread_sleep(PM_CHARGE_DISPLAY_TIMEOUT);
+			/* Shutdown the display: If the charging is complete
+			 * continue boot up with display on
+			 */
+			if (charge_in_progress)
+			{
+				display_shutdown_in_prgs = true;
+				target_display_shutdown();
+				display_shutdown_in_prgs = false;
+				display_initialized = false;
+			}
+			display_init_first_time = true;
+		}
+		/* Wait for 100ms before reading the pmic interrupt status
+		 * again, reading the pmic interrupt status in a loop without delays
+		 * reports false key presses */
+		thread_sleep(100);
+	} while (charge_in_progress);
+
+	return 0;
+}
+
+/* Create a thread to monitor power key press events
+ * and turn on/off the display for battery
+ */
+static void display_thread_initialize()
+{
+	thread_t *thr = NULL;
+	static bool is_thread_start;
+
+	if (!is_thread_start)
+	{
+		thr = thread_create("display_charger_screen", &display_charger_screen, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);
+		if (!thr)
+		{
+			dprintf(CRITICAL, "Error: Could not create display charger screen thread\n");
+			return;
+		}
+		thread_resume(thr);
+
+		is_thread_start = true;
+	}
+}
diff --git a/dev/qpnp_haptic/qpnp_haptic.c b/dev/qpnp_haptic/qpnp_haptic.c
index 1bdadee..e1200a1 100644
--- a/dev/qpnp_haptic/qpnp_haptic.c
+++ b/dev/qpnp_haptic/qpnp_haptic.c
@@ -29,6 +29,8 @@
 #include <spmi.h>
 #include <platform/iomap.h>
 #include <pm_vib.h>
+#include <target.h>
+#include <vibrator.h>
 
 #define HAPTIC_BASE (PMI_ADDR_BASE+ 0xC000)
 #define QPNP_HAP_EN_CTL_REG (HAPTIC_BASE + 0x46)
@@ -71,6 +73,7 @@
 #define QPNP_HAP_BRAKE_VMAX_MASK 0xFF
 #define QPNP_HAP_BRAKE_VMAX 0xF
 #define QPNP_HAP_ERM 0x1
+#define QPNP_HAP_LRA 0x0
 #define QPNP_HAP_PLAY_MASK 0x80
 #define QPNP_HAP_PLAY_EN 0x80
 #define QPNP_HAP_MASK 0x80
@@ -84,17 +87,23 @@
 /* Turn on vibrator */
 void pm_vib_turn_on(void)
 {
+	uint32_t vib_type = VIB_ERM_TYPE;
+	vib_type = get_vibration_type();
 	/* Configure the ACTUATOR TYPE register as ERM*/
 	pmic_spmi_reg_mask_write(QPNP_HAP_ACT_TYPE_REG,
-					QPNP_HAP_ACT_TYPE_MASK, QPNP_HAP_ERM);
+					QPNP_HAP_ACT_TYPE_MASK,
+					VIB_ERM_TYPE == vib_type ? QPNP_HAP_ERM
+					: QPNP_HAP_LRA);
 
 	/* Disable auto resonance for ERM */
 	pmic_spmi_reg_mask_write(QPNP_HAP_LRA_AUTO_RES_REG,
-					QPNP_HAP_LRA_AUTO_MASK, QPNP_HAP_LRA_AUTO_DISABLE);
+					QPNP_HAP_LRA_AUTO_MASK,
+					QPNP_HAP_LRA_AUTO_DISABLE);
 
 	/* Configure the PLAY MODE register as direct*/
 	pmic_spmi_reg_mask_write(QPNP_HAP_PLAY_MODE_REG,
-					QPNP_HAP_PLAY_MODE_MASK, QPNP_HAP_DIRECT);
+					QPNP_HAP_PLAY_MODE_MASK,
+					QPNP_HAP_DIRECT);
 
 	/* Configure the VMAX register */
 	pmic_spmi_reg_mask_write(QPNP_HAP_VMAX_REG,
diff --git a/dev/vib/include/vibrator.h b/dev/vib/include/vibrator.h
index d6fb8bf..2ec1346 100644
--- a/dev/vib/include/vibrator.h
+++ b/dev/vib/include/vibrator.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, 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
@@ -29,6 +29,8 @@
 #define __DEV_VIB_VIBRATOR_H
 
 #define VIB_TIMER_DEFAULT_TIMEOUT   250
+#define VIB_LRA_TYPE 0x00
+#define VIB_ERM_TYPE 0x01
 
 void vib_turn_on(void);
 void vib_turn_off(void);
diff --git a/include/platform.h b/include/platform.h
index 50ef337..9c8e698 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -71,4 +71,5 @@
 uint32_t platform_get_max_periph();
 int platform_is_msm8996();
 uint64_t platform_get_ddr_start();
+bool platform_use_qmp_misc_settings();
 #endif
diff --git a/include/target.h b/include/target.h
index b7f92a2..f2e2acd 100644
--- a/include/target.h
+++ b/include/target.h
@@ -87,4 +87,9 @@
 int target_cont_splash_screen(void);
 bool target_build_variant_user();
 void pmic_reset_configure(uint8_t reset_type);
+
+#if PON_VIB_SUPPORT
+uint32_t get_vibration_type();
+#endif
+
 #endif
diff --git a/platform/init.c b/platform/init.c
index 9919b22..e6f0f66 100644
--- a/platform/init.c
+++ b/platform/init.c
@@ -111,7 +111,7 @@
 }
 
 __WEAK int get_target_boot_params(const char *cmdline, const char *part,
-				  char *buf, int buflen)
+				  char **buf)
 {
 	return -1;
 }
diff --git a/platform/mdm9640/include/platform/iomap.h b/platform/mdm9640/include/platform/iomap.h
index 5803acd..f92f556 100644
--- a/platform/mdm9640/include/platform/iomap.h
+++ b/platform/mdm9640/include/platform/iomap.h
@@ -180,6 +180,8 @@
 /* SS QMP (Qulacomm Multi Protocol) */
 #define QMP_PHY_BASE                0x78000
 
+#define AHB2_PHY_BASE               0x0007e000
+#define PERIPH_SS_AHB2PHY_TOP_CFG   (AHB2_PHY_BASE + 0x10)
 /* QMP register offset */
 #define PLATFORM_QMP_OFFSET         0x8
 
diff --git a/platform/mdmfermium/platform.c b/platform/mdmfermium/platform.c
index 3ca23a0..2c38ec7 100644
--- a/platform/mdmfermium/platform.c
+++ b/platform/mdmfermium/platform.c
@@ -35,6 +35,42 @@
 #include <arch/arm/mmu.h>
 #include <smem.h>
 
+#define MB (1024 *1024)
+
+#define MSM_IOMAP_SIZE                      ((MSM_IOMAP_END - MSM_IOMAP_BASE)/MB)
+
+#define A7_SS_SIZE                          ((A7_SS_END - A7_SS_BASE)/MB)
+
+/* LK memory */
+#define LK_MEMORY                             (MMU_MEMORY_TYPE_NORMAL_WRITE_THROUGH | \
+                                                                 MMU_MEMORY_AP_READ_WRITE)
+/* Scratch memory - Strongly ordered, non-executable */
+#define SCRATCH_MEMORY                        (MMU_MEMORY_TYPE_NORMAL_WRITE_THROUGH | \
+                                                                 MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN)
+/* Peripherals - shared device */
+#define IOMAP_MEMORY                          (MMU_MEMORY_TYPE_DEVICE_SHARED | \
+                                                                 MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN)
+
+
+/* Map all the accesssible memory according to the following rules:
+ * 1. Map 1MB from MSM_SHARED_BASE with 1 -1 mapping.
+ * 2. Map MEMBASE - MEMSIZE with 1 -1 mapping.
+ * 3. Map all the scratch regions immediately after Appsbl memory.
+ *     Virtual addresses start right after Appsbl Virtual address.
+ * 4. Map all the IOMAP space with 1 - 1 mapping.
+ * 5. Map all the rest of the SDRAM/ IMEM regions as 1 -1.
+ */
+mmu_section_t mmu_section_table[] = {
+/*   Physical addr,               Virtual addr,                   Size (in MB),                   Flags   */
+	{MSM_SHARED_BASE,         MSM_SHARED_BASE,                1,                              SCRATCH_MEMORY},
+	{MEMBASE,                 MEMBASE,                        MEMSIZE / MB,                   LK_MEMORY},
+	{MSM_IOMAP_BASE,          MSM_IOMAP_BASE,                 MSM_IOMAP_SIZE,                 IOMAP_MEMORY},
+	{A7_SS_BASE,              A7_SS_BASE,                     A7_SS_SIZE,                     IOMAP_MEMORY},
+	{MSM_SHARED_IMEM_BASE,    MSM_SHARED_IMEM_BASE,           1,                              IOMAP_MEMORY},
+	{SCRATCH_REGION1,         SCRATCH_REGION1,                SCRATCH_REGION1_SIZE / MB,      SCRATCH_MEMORY},
+	{KERNEL_REGION,           KERNEL_REGION,                  KERNEL_REGION_SIZE / MB,        SCRATCH_MEMORY},
+};
+
 void platform_early_init(void)
 {
 	board_init();
@@ -65,8 +101,43 @@
 	return ((addr_t)BS_INFO_ADDR);
 }
 
+addr_t platform_get_virt_to_phys_mapping(addr_t virt_addr)
+{
+	/* Fixed 1-1 mapping */
+	return virt_addr;
+}
+
+addr_t platform_get_phys_to_virt_mapping(addr_t phys_addr)
+{
+        /* Fixed 1-1 mapping */
+	return phys_addr;
+}
+
+/* Setup memory for this platform */
+void platform_init_mmu_mappings(void)
+{
+	uint32_t i;
+	uint32_t sections;
+	uint32_t table_size = ARRAY_SIZE(mmu_section_table);
+
+	/* Configure the MMU page entries for memory read from the
+           mmu_section_table */
+	for (i = 0; i < table_size; i++)
+	{
+		sections = mmu_section_table[i].num_of_sections;
+
+		while (sections--)
+		{
+			arm_mmu_map_section(mmu_section_table[i].paddress +
+								sections * MB,
+								mmu_section_table[i].vaddress +
+								sections * MB,
+								mmu_section_table[i].flags);
+		}
+	}
+}
 int platform_use_identity_mmu_mappings(void)
 {
 	/* Use only the mappings specified in this file. */
-	return 1;
+	return 0;
 }
diff --git a/platform/msm8994/include/platform/iomap.h b/platform/msm8994/include/platform/iomap.h
index e645ca6..345ce1d 100644
--- a/platform/msm8994/include/platform/iomap.h
+++ b/platform/msm8994/include/platform/iomap.h
@@ -94,6 +94,7 @@
 
 /* SS QMP (Qulacomm Multi Protocol) */
 #define QMP_PHY_BASE                0xF9B38000
+#define PERIPH_SS_AHB2PHY_TOP_CFG   0xF9B3E010
 
 /* Clocks */
 #define CLK_CTL_BASE                0xFC400000
diff --git a/platform/msm8996/include/platform/iomap.h b/platform/msm8996/include/platform/iomap.h
index 2ae1d17..d3ba81a 100644
--- a/platform/msm8996/include/platform/iomap.h
+++ b/platform/msm8996/include/platform/iomap.h
@@ -78,6 +78,9 @@
 #define QUSB2_PHY_BASE              0x7411000
 #define GCC_QUSB2_PHY_BCR           (CLK_CTL_BASE + 0x00012038)
 
+#define AHB2_PHY_BASE               0x7416000
+#define PERIPH_SS_AHB2PHY_TOP_CFG   (AHB2_PHY_BASE + 0x10)
+
 /* Clocks */
 #define CLK_CTL_BASE                0x300000
 
diff --git a/platform/msm8996/platform.c b/platform/msm8996/platform.c
index 090e81c..08c0025 100644
--- a/platform/msm8996/platform.c
+++ b/platform/msm8996/platform.c
@@ -222,3 +222,11 @@
 {
 	return ddr_start;
 }
+
+bool platform_use_qmp_misc_settings()
+{
+	if (board_soc_version() < 0x30000)
+		return true;
+
+	return false;
+}
diff --git a/platform/msm_shared/bam.c b/platform/msm_shared/bam.c
index 723ce00..ef39321 100644
--- a/platform/msm_shared/bam.c
+++ b/platform/msm_shared/bam.c
@@ -139,16 +139,7 @@
 /* Reset and initialize the bam module */
 void bam_init(struct bam_instance *bam)
 {
-	/* Check for only one pipe's direction.
-	 * The other is assumed to be the opposite system
-	 * transaction.
-	 */
-	if (bam->pipe[0].trans_type == SYS2BAM ||
-		bam->pipe[0].trans_type == BAM2SYS)
-	{
-		/* Program the threshold count */
-		writel(bam->threshold, BAM_DESC_CNT_TRSHLD_REG(bam->base));
-	}
+	/* bam is initialized by TZ, so nothing needs to be done here */
 }
 
 /* Funtion to setup a simple fifo structure.
diff --git a/platform/msm_shared/boot_verifier.c b/platform/msm_shared/boot_verifier.c
index 36c72c9..67f28c3 100644
--- a/platform/msm_shared/boot_verifier.c
+++ b/platform/msm_shared/boot_verifier.c
@@ -40,6 +40,9 @@
 #include <openssl/err.h>
 #include <platform.h>
 
+#define ASN1_ENCODED_SHA256_SIZE 0x33
+#define ASN1_ENCODED_SHA256_OFFSET 0x13
+
 static KEYSTORE *oem_keystore;
 static KEYSTORE *user_keystore;
 static uint32_t dev_boot_state = RED;
@@ -131,52 +134,25 @@
 	return len;
 }
 
-static int verify_digest(unsigned char* input, unsigned char *digest, int hash_size)
-{
-	int ret = -1;
-	X509_SIG *sig = NULL;
-	uint32_t len = read_der_message_length(input);
-	if(!len)
-	{
-		dprintf(CRITICAL, "boot_verifier: Signature length is invalid.\n");
-		return ret;
-	}
-
-	sig = d2i_X509_SIG(NULL, (const unsigned char **) &input, len);
-	if(sig == NULL)
-	{
-		dprintf(CRITICAL, "boot_verifier: Reading digest failed\n");
-		return ret;
-	}
-
-	if(sig->digest->length != SHA256_SIZE)
-	{
-		dprintf(CRITICAL, "boot_verifier: Digest length error.\n");
-		goto verify_digest_error;
-	}
-
-	if(memcmp(sig->digest->data, digest, hash_size) == 0)
-		ret = 0;
-
-verify_digest_error:
-	if(sig != NULL)
-		X509_SIG_free(sig);
-
-	return ret;
-}
-
 static int add_attribute_to_img(unsigned char *ptr, AUTH_ATTR *input)
 {
 	return i2d_AUTH_ATTR(input, &ptr);
 }
 
-static bool boot_verify_compare_sha256(unsigned char *image_ptr,
+bool boot_verify_compare_sha256(unsigned char *image_ptr,
 		unsigned int image_size, unsigned char *signature_ptr, RSA *rsa)
 {
 	int ret = -1;
 	bool auth = false;
 	unsigned char *plain_text = NULL;
-	unsigned int digest[8];
+
+	/* The magic numbers here are drawn from the PKCS#1 standard and are the ASN.1
+	 *encoding of the SHA256 object identifier that is required for a PKCS#1
+	* signature.*/
+	uint8_t digest[ASN1_ENCODED_SHA256_SIZE] = {0x30, 0x31, 0x30, 0x0d, 0x06,
+												0x09, 0x60, 0x86, 0x48, 0x01,
+												0x65, 0x03, 0x04, 0x02, 0x01,
+												0x05, 0x00, 0x04, 0x20};
 
 	plain_text = (unsigned char *)calloc(sizeof(char), SIGNATURE_SIZE);
 	if (plain_text == NULL) {
@@ -184,22 +160,34 @@
 		goto cleanup;
 	}
 
-	/* Calculate SHA256sum */
+	/* Calculate SHA256 of image and place it into the ASN.1 structure*/
 	image_find_digest(image_ptr, image_size, CRYPTO_AUTH_ALG_SHA256,
-			(unsigned char *)&digest);
+			digest + ASN1_ENCODED_SHA256_OFFSET);
 
-	/* Find digest from the image */
+	/* Find digest from the image. This performs the PKCS#1 padding checks up to
+	 * but not including the ASN.1 OID and hash function check. The return value
+	 * is not positive for a failure or the length of the part after the padding */
 	ret = image_decrypt_signature_rsa(signature_ptr, plain_text, rsa);
 
-	dprintf(SPEW, "boot_verifier: Return of RSA_public_decrypt = %d\n",
+	/* Make sure the length returned from rsa decrypt is same as x509 signature format
+	 * otherwise the signature is invalid and we fail
+	 */
+	if (ret != ASN1_ENCODED_SHA256_SIZE)
+	{
+		dprintf(CRITICAL, "boot_verifier: Signature decrypt failed! Signature invalid = %d\n",
 			ret);
+		goto cleanup;
+	}
+	/* So plain_text contains the ASN.1 encoded hash from the signature and
+	* digest contains the value that this should be for the image that we're
+	* verifying, so compare them.*/
 
-	ret = verify_digest(plain_text, (unsigned char*)digest, SHA256_SIZE);
+	ret = memcmp(plain_text, digest, ASN1_ENCODED_SHA256_SIZE);
 	if(ret == 0)
 	{
 		auth = true;
 #ifdef TZ_SAVE_KERNEL_HASH
-		save_kernel_hash((unsigned char *) &digest, CRYPTO_AUTH_ALG_SHA256);
+		save_kernel_hash((unsigned char *) digest + ASN1_ENCODED_SHA256_OFFSET, CRYPTO_AUTH_ALG_SHA256);
 #endif
 	}
 
@@ -521,3 +509,9 @@
 {
 	return check_list(VERIFIED_FLASH_ALLOWED_PTN, entry);
 }
+
+KEYSTORE *boot_gerity_get_oem_keystore()
+{
+	read_oem_keystore();
+	return oem_keystore;
+}
diff --git a/platform/msm_shared/crypto5_eng.c b/platform/msm_shared/crypto5_eng.c
index 6f0cc8f..0861cc8 100644
--- a/platform/msm_shared/crypto5_eng.c
+++ b/platform/msm_shared/crypto5_eng.c
@@ -286,9 +286,6 @@
 	uint32_t config = CRYPTO_RESET_CONFIG
 			| (dev->bam.pipe[CRYPTO_READ_PIPE_INDEX].pipe_num >> 1) << PIPE_SET_SELECT_SHIFT;
 
-	/* Configure CE clocks. */
-	clock_config_ce(dev->instance);
-
 	/* Setup BAM */
 	if (crypto_bam_init(dev) != CRYPTO_ERR_NONE)
 	{
diff --git a/platform/msm_shared/crypto5_wrapper.c b/platform/msm_shared/crypto5_wrapper.c
index 0be227a..868eca0 100644
--- a/platform/msm_shared/crypto5_wrapper.c
+++ b/platform/msm_shared/crypto5_wrapper.c
@@ -28,6 +28,7 @@
 
 #include <debug.h>
 #include <crypto5_wrapper.h>
+#include <platform/clock.h>
 
 /* This file is a wrapper to the crypto5_eng.c.
  * This is required so that we maintian the backward compatibility
@@ -52,7 +53,8 @@
 
 void ce_clock_init(void)
 {
-	/* Clock init is done during crypto_init. */
+	/* Configure CE clocks. */
+	clock_config_ce(dev.instance);
 }
 
 void crypto_eng_reset(void)
diff --git a/platform/msm_shared/glink/glink_api.c b/platform/msm_shared/glink/glink_api.c
index fe5fd92..f2bdae6 100644
--- a/platform/msm_shared/glink/glink_api.c
+++ b/platform/msm_shared/glink/glink_api.c
@@ -35,9 +35,10 @@
 #include <glink_os_utils.h>
 #include <glink_internal.h>
 #include <glink_vector.h>
-#include <glink_channel_migration.h>
-#include <smem_list.h>
-#include <smem_type.h>
+
+#ifdef FEATURE_TRACER_PACKET
+#include "glink_tracer.h"
+#endif
 
 #define GLINK_NOT_INITIALIZED 0
 #define GLINK_INITIALIZED     1
@@ -45,276 +46,9 @@
 /*===========================================================================
                         GLOBAL DATA DECLARATIONS
 ===========================================================================*/
-int glink_core_status = GLINK_NOT_INITIALIZED;
-
-os_cs_type *glink_transport_q_cs;
-os_cs_type *glink_mem_log_cs;
-
-glink_mem_log_entry_type glink_mem_log_arr[GLINK_MEM_LOG_SIZE];
-uint32 glink_mem_log_idx = 0;
-
-/* Keep a list of registered transport for each edge allowed for this host */
-smem_list_type glink_registered_transports[GLINK_NUM_HOSTS];
-
-smem_list_type glink_link_notif_list;
-
-/* List of supported hosts */
-const char* glink_hosts_supported[]   = { "apss",
-                                          "mpss",
-                                          "lpass",
-                                          "dsps",
-                                          "wcnss",
-                                          "tz",
-                                          "rpm",
-                                        };
-
-/* Forward function declarations */
-void glinki_free_intents(glink_channel_ctx_type *open_ch_ctx);
-
 /*===========================================================================
                     LOCAL FUNCTION DEFINITIONS
 ===========================================================================*/
-/*===========================================================================
-  FUNCTION      glinki_add_ch_to_xport
-===========================================================================*/
-/**
- * Add remote/local channel context to xport open channel queue
- *
- * @param[in]    if_ptr            Pointer to xport if on which channel is to
- *                                 be opened
- * @param[in]    req_if_ptr        Pointer to xport if on which channel
- *                                 actually wants to open
- * @param[in]    ch_ctx            channel context
- * @param[out]   allocated_ch_ctx  Pointer to channel context pointer
- * @param[in]    local_open        flag to determine if channel is opened
- *                                 locally or remotely
- * @param[in]    prio              negotiated xport priority
- *                                 (used to send priority via remote_open_ack to
- *                                  remote side)
- *
- * @return       pointer to glink_transport_if_type struct
- *
- * @sideeffects  NONE
- */
-/*=========================================================================*/
-glink_err_type glinki_add_ch_to_xport
-(
-  glink_transport_if_type  *if_ptr,
-  glink_transport_if_type  *req_if_ptr,
-  glink_channel_ctx_type   *ch_ctx,
-  glink_channel_ctx_type  **allocated_ch_ctx,
-  unsigned int              local_open,
-  glink_xport_priority      migrated_ch_prio
-)
-{
-  glink_err_type             status;
-  glink_channel_ctx_type     *open_ch_ctx;
-  glink_core_xport_ctx_type  *xport_ctx = if_ptr->glink_core_priv;
-
-  /* See if channel already exists in open_list */
-  glink_os_cs_acquire(&xport_ctx->channel_q_cs);
-
-  for( open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
-       open_ch_ctx;
-       open_ch_ctx = smem_list_next(open_ch_ctx) )
-  {
-    if( 0 != glink_os_string_compare( open_ch_ctx->name, ch_ctx->name ) )
-    {
-      continue;
-    }
-    /* grab lock to avoid race condition for channel state change */
-    glink_os_cs_acquire(&open_ch_ctx->ch_state_cs);
-
-    if( local_open )
-    {
-      /* LOCAL OPEN REQUEST */
-      ASSERT( open_ch_ctx->local_state == GLINK_LOCAL_CH_CLOSED );
-
-      glink_os_cs_init( &ch_ctx->tx_cs );
-      glink_os_cs_init( &ch_ctx->ch_state_cs );
-
-      ch_ctx->rcid        = open_ch_ctx->rcid;
-      ch_ctx->lcid        = open_ch_ctx->lcid;
-      ch_ctx->pintents    = open_ch_ctx->pintents;
-      ch_ctx->if_ptr      = open_ch_ctx->if_ptr;
-      ch_ctx->req_if_ptr  = req_if_ptr;
-
-      ch_ctx->remote_state = open_ch_ctx->remote_state;
-      ch_ctx->local_state  = GLINK_LOCAL_CH_OPENING;
-
-      /* release lock before context switch otherwise it is causing
-       * deadlock */
-      smem_list_delete( &xport_ctx->open_list, open_ch_ctx );
-      smem_list_append( &xport_ctx->open_list, ch_ctx );
-
-      glink_os_cs_release(&open_ch_ctx->ch_state_cs);
-      glink_os_cs_release(&xport_ctx->channel_q_cs);
-
-      glink_os_free( open_ch_ctx );
-      *allocated_ch_ctx = ch_ctx;
-      /* Send open cmd to transport */
-      status = if_ptr->tx_cmd_ch_open( if_ptr,
-                                       ch_ctx->lcid,
-                                       ch_ctx->name,
-                                       ch_ctx->req_if_ptr->glink_priority );
-    }
-    else
-    {
-      /* REMOTE OPEN REQUEST */
-
-      if( open_ch_ctx->remote_state == GLINK_REMOTE_CH_SSR_RESET )
-      {/* During SSR previous channel ctx needs to be destroyed
-        * new remote/local open request will create new context */
-        glink_os_cs_release( &open_ch_ctx->ch_state_cs );
-        continue;
-      }
-
-      ASSERT( open_ch_ctx->remote_state == GLINK_REMOTE_CH_CLOSED );
-
-      open_ch_ctx->rcid = ch_ctx->rcid;
-      *allocated_ch_ctx = open_ch_ctx;
-      status = xport_ctx->channel_init(open_ch_ctx);
-
-      if( status == GLINK_STATUS_SUCCESS )
-      {
-        open_ch_ctx->remote_state = GLINK_REMOTE_CH_OPENED;
-      }
-
-      /* release lock before context switch otherwise it is causing deadlock */
-      glink_os_cs_release(&open_ch_ctx->ch_state_cs);
-      glink_os_cs_release(&xport_ctx->channel_q_cs);
-
-
-      if ( status == GLINK_STATUS_SUCCESS )
-      {
-        /* Send ACK to transport */
-        if_ptr->tx_cmd_ch_remote_open_ack( if_ptr,
-                                           open_ch_ctx->rcid,
-                                           migrated_ch_prio );
-
-        /* Inform the client */
-        if( open_ch_ctx->local_state == GLINK_LOCAL_CH_OPENED )
-        {
-          open_ch_ctx->notify_state( open_ch_ctx,
-                                     open_ch_ctx->priv,
-                                     GLINK_CONNECTED );
-        }
-      }
-
-      glink_os_free(ch_ctx);
-    } /* end If - else (local_open) */
-
-    return status;
-  } /* end for */
-
-  ASSERT( open_ch_ctx == NULL );
-
-  /* Channel not in the list - it was not previously opened */
-  ch_ctx->if_ptr = if_ptr;
-  *allocated_ch_ctx = ch_ctx;
-
-  /* Set channel state */
-  if (local_open)
-  {
-    /* This is a local open */
-    ch_ctx->local_state = GLINK_LOCAL_CH_OPENING;
-    ch_ctx->req_if_ptr  = req_if_ptr;
-  }
-  else
-  {
-    ch_ctx->remote_state = GLINK_REMOTE_CH_OPENED;
-  }
-
-  glink_os_cs_init(&ch_ctx->tx_cs);
-  glink_os_cs_init(&ch_ctx->ch_state_cs);
-
-  /* Append the channel to the transport interface's open_list */
-  ch_ctx->lcid = xport_ctx->free_lcid;
-  xport_ctx->free_lcid++;
-  smem_list_append(&if_ptr->glink_core_priv->open_list, ch_ctx);
-
-  /* release lock before context switch otherwise it is causing deadlock */
-  glink_os_cs_release(&xport_ctx->channel_q_cs);
-
-  /* Send the OPEN command to transport */
-  if ( local_open )
-  {
-    status = if_ptr->tx_cmd_ch_open( if_ptr, ch_ctx->lcid,
-                                     ch_ctx->name,
-                                     ch_ctx->req_if_ptr->glink_priority );
-  }
-  else
-  {
-    /* initialize channel resources */
-    status = xport_ctx->channel_init(ch_ctx);
-
-    /* ACK the transport for remote open */
-    if (status == GLINK_STATUS_SUCCESS)
-    {
-      if_ptr->tx_cmd_ch_remote_open_ack( if_ptr, ch_ctx->rcid,
-                                         migrated_ch_prio );
-    }
-  }
-
-  if (status != GLINK_STATUS_SUCCESS)
-  {
-    /* Remove the channel from the transport interface's open_list */
-    xport_ctx->free_lcid--;
-    glink_os_cs_acquire(&xport_ctx->channel_q_cs);
-    smem_list_delete(&if_ptr->glink_core_priv->open_list, ch_ctx);
-    glink_os_cs_release(&xport_ctx->channel_q_cs);
-
-    /* free the ch_ctx structure and return */
-    xport_ctx->channel_cleanup(ch_ctx);
-    glink_os_free(ch_ctx);
-  }
-
-  return status;
-}
-
-/*===========================================================================
-  FUNCTION      glink_is_channel_fully_opened
-===========================================================================*/
-/**
- * Check whether this channel is fully opened or not (local & remote)
- * This also checks transport status
- *
- * @param[in]  handle        glink channel handle
- * @param[in]  xport_ctx     glink transport core private
- *
- * @return     TRUE,  if channel is fully opened
- *             FASLE, otherwise
- *
- * @sideeffects  NONE
- */
-/*=========================================================================*/
-static boolean glink_is_channel_fully_opened
-(
-  glink_handle_type          handle,
-  glink_core_xport_ctx_type *xport_ctx
-)
-{
-  boolean ch_fully_opened = TRUE;
-
-  glink_os_cs_acquire( &handle->ch_state_cs );
-
-  if( handle->local_state != GLINK_LOCAL_CH_OPENED ||
-      handle->remote_state != GLINK_REMOTE_CH_OPENED )
-  {
-    ch_fully_opened = FALSE;
-  }
-
-  glink_os_cs_acquire( &xport_ctx->status_cs );
-  if( xport_ctx->status != GLINK_XPORT_LINK_UP )
-  {
-    ch_fully_opened = FALSE;
-  }
-
-  glink_os_cs_release( &xport_ctx->status_cs );
-  glink_os_cs_release( &handle->ch_state_cs );
-
-  return ch_fully_opened;
-}
 
 /** Default implementation of optional callbacks */
 static void glink_default_notify_rx_sigs
@@ -325,507 +59,16 @@
   uint32             curr
 )
 {
+  GLINK_OS_UNREFERENCED_PARAM( handle );
+  GLINK_OS_UNREFERENCED_PARAM( priv );
+  GLINK_OS_UNREFERENCED_PARAM( prev );
+  GLINK_OS_UNREFERENCED_PARAM( curr );
   return;
 }
 
-static void glinki_call_link_notifier
-(
-  glink_link_notif_data_type *link_notif_data,
-  glink_core_xport_ctx_type  *xport_ctx,
-  glink_link_state_type      state
-)
-{
-  glink_link_info_type link_info;
-
-  ASSERT(xport_ctx);
-  ASSERT(link_notif_data);
-
-  link_info.xport = xport_ctx->xport;
-  link_info.remote_ss = xport_ctx->remote_ss;
-  link_info.link_state = state;
-  link_notif_data->link_notifier(&link_info, link_notif_data->priv);
-}
-
-uint32 glinki_find_remote_host
-(
-  const char *remote_ss
-)
-{
-  uint32 remote_host;
-  ASSERT(remote_ss);
-
-  for(remote_host = 0; remote_host < GLINK_NUM_HOSTS; remote_host++)
-  {
-    if( 0 == glink_os_string_compare( glink_hosts_supported[remote_host],
-                                      remote_ss ) )
-    {
-      /* Match found, break out of loop */
-      break;
-    }
-  }
-  return remote_host;
-}
-
-static void glinki_check_xport_and_notify
-(
-  glink_link_notif_data_type *link_notif_data,
-  glink_core_xport_ctx_type  *xport_ctx,
-  glink_link_state_type      state
-)
-{
-  ASSERT(xport_ctx);
-  ASSERT(link_notif_data);
-
-  if( link_notif_data->xport == NULL ||
-      0 == glink_os_string_compare( xport_ctx->xport, link_notif_data->xport ) )
-  {
-    /* xport not specified, or it is specified and matches the current xport */
-    /* Invoke registered callback */
-    glinki_call_link_notifier(link_notif_data, xport_ctx, state);
-  }
-}
-
-static void glinki_scan_xports_and_notify
-(
-  glink_link_notif_data_type *link_notif_data
-)
-{
-  unsigned int remote_host;
-  glink_transport_if_type *if_ptr;
-  glink_core_xport_ctx_type  *xport_ctx;
-
-  ASSERT(link_notif_data);
-
-  /* Find matching subsystem */
-  for(remote_host = 0;
-      remote_host < sizeof(glink_hosts_supported)/sizeof(char *);
-      remote_host++)
-  {
-    if ( link_notif_data->remote_ss != NULL &&
-         0 != glink_os_string_compare( glink_hosts_supported[remote_host],
-                                       link_notif_data->remote_ss ) )
-    {
-      /* client is not interested in this remote SS */
-      continue;
-    }
-
-    /* Find the xport and give link UP notification */
-    for (if_ptr = smem_list_first(&glink_registered_transports[remote_host]);
-         if_ptr != NULL;
-         if_ptr = smem_list_next(if_ptr))
-    {
-      xport_ctx = if_ptr->glink_core_priv;
-
-      if (xport_ctx->status == GLINK_XPORT_LINK_UP)
-      {
-        /* Invoke registered callback */
-        glinki_check_xport_and_notify( link_notif_data, xport_ctx,
-                                       GLINK_LINK_STATE_UP );
-      }
-    }
-  } /* end for remote_host */
-} /* glinki_scan_xports_and_notify */
-
-void glinki_scan_notif_list_and_notify
-(
-  glink_transport_if_type *if_ptr,
-  glink_link_state_type state
-)
-{
-  glink_link_notif_data_type *link_notif_data;
-  glink_core_xport_ctx_type  *xport_ctx = if_ptr->glink_core_priv;
-
-  for (link_notif_data = smem_list_first(&glink_link_notif_list);
-       link_notif_data != NULL;
-       link_notif_data = smem_list_next(link_notif_data))
-  {
-    if( link_notif_data->remote_ss == NULL ||
-        0 == glink_os_string_compare( xport_ctx->remote_ss,
-                                      link_notif_data->remote_ss ) )
-    {
-      glinki_check_xport_and_notify(link_notif_data, xport_ctx, state);
-    }
-  }
-} /* glinki_scan_notif_list_and_notify */
-
-void glinki_scan_channels_and_notify_discon
-(
-  glink_transport_if_type *if_ptr
-)
-{
-  glink_channel_ctx_type     *open_ch_ctx, *dummy_open_ch_ctx;
-  glink_core_xport_ctx_type  *xport_ctx;
-
-  ASSERT(if_ptr != NULL);
-
-  xport_ctx = if_ptr->glink_core_priv;
-
-  /* Find channel in the open_list */
-  glink_os_cs_acquire(&xport_ctx->channel_q_cs);
-  open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
-  while( open_ch_ctx )
-  {
-    glink_os_cs_acquire( &open_ch_ctx->ch_state_cs );
-    open_ch_ctx->remote_state = GLINK_REMOTE_CH_SSR_RESET;
-    glink_os_cs_release( &open_ch_ctx->ch_state_cs );
-
-    dummy_open_ch_ctx = smem_list_next( open_ch_ctx );
-
-    switch( open_ch_ctx->local_state )
-    {
-      case GLINK_LOCAL_CH_OPENED:
-      case GLINK_LOCAL_CH_OPENING:
-        /* local channel has called open at the moment. */
-        open_ch_ctx->notify_state( open_ch_ctx,
-                                   open_ch_ctx->priv,
-                                   GLINK_REMOTE_DISCONNECTED );
-        break;
-
-      case GLINK_LOCAL_CH_CLOSING:
-        /* Case when local client already closed channel
-         * but has not received ack yet */
-        if_ptr->glink_core_if_ptr->rx_cmd_ch_close_ack( if_ptr,
-                                                        open_ch_ctx->lcid );
-        break;
-
-      case GLINK_LOCAL_CH_CLOSED:
-        /* Channel fully closed - local, remote */
-        xport_ctx->channel_cleanup(open_ch_ctx);
-        smem_list_delete(&if_ptr->glink_core_priv->open_list, open_ch_ctx);
-        glink_os_free(open_ch_ctx);
-        break;
-
-      default:
-        /* invalid local channel state */
-        ASSERT(0);
-    }
-
-    open_ch_ctx = dummy_open_ch_ctx;
-
-  } /* end while */
-  glink_os_cs_release(&xport_ctx->channel_q_cs);
-}
-
-void glink_ssr(const char* remote_ss)
-{
-  unsigned int remote_host;
-  glink_transport_if_type *if_ptr;
-
-  remote_host = glinki_find_remote_host(remote_ss);
-
-  /* Scan through the registered interfaces with the crashing ss
-     and let the clients know about the crash via LINK_DOWN
-     notification followed by REMOTE_DISCONNECT */
-  if_ptr = smem_list_first(&glink_registered_transports[remote_host]);
-
-  while(if_ptr != NULL)
-  {
-    /* xport is down. change the xport state */
-    glink_os_cs_acquire(&if_ptr->glink_core_priv->status_cs);
-    if_ptr->glink_core_priv->status = GLINK_XPORT_REGISTERED;
-
-    /* Let the xport know about ssr */
-    if_ptr->ssr( if_ptr );
-
-    /* Invoke LINK_DOWN notification for any registered notifiers */
-    glinki_scan_notif_list_and_notify(if_ptr, GLINK_LINK_STATE_DOWN);
-
-    /* Invoke REMOTE_DISCONNECT for all channels associated with if_ptr */
-    glinki_scan_channels_and_notify_discon(if_ptr);
-
-    glink_os_cs_release(&if_ptr->glink_core_priv->status_cs);
-
-    if_ptr = smem_list_next(if_ptr);
-  }
-}
-
-
 /*===========================================================================
                     EXTERNAL FUNCTION DEFINITIONS
 ===========================================================================*/
-/*===========================================================================
-FUNCTION      glink_init
-
-DESCRIPTION   Initializes the GLink core library.
-
-ARGUMENTS     None
-
-RETURN VALUE  None
-
-SIDE EFFECTS  None
-===========================================================================*/
-void glink_init(void)
-{
-  uint32 i;
-
-  glink_mem_log_cs = glink_os_cs_create();
-
-  glink_core_status = GLINK_INITIALIZED;
-
-  /* Create/Initalize crtitical sections */
-  glink_transport_q_cs = glink_os_cs_create();
-  if(glink_transport_q_cs == NULL) {
-    return;
-  }
-
-  glink_os_cs_acquire(glink_transport_q_cs);
-  for(i= 0; i < sizeof(glink_registered_transports)/sizeof(smem_list_type);
-      i++)
-  {
-    smem_list_init(&glink_registered_transports[i]);
-  }
-  glink_os_cs_release(glink_transport_q_cs);
-}
-
-/*===========================================================================
-FUNCTION      glink_core_register_transport
-
-DESCRIPTION   Transport calls this API to register its interface with GLINK
-              Core
-
-ARGUMENTS   *if_ptr   Pointer to interface instance; must be unique
-                      for each edge
-
-            *cfg      Pointer to transport configuration structure.
-
-RETURN VALUE  Standard GLINK error codes.
-
-SIDE EFFECTS  None
-===========================================================================*/
-glink_err_type glink_core_register_transport
-(
-  glink_transport_if_type       *if_ptr,
-  glink_core_transport_cfg_type *cfg
-)
-{
-  unsigned int remote_host = 0;
-  glink_core_xport_ctx_type *xport_ctx;
-  /* Param validation */
-  if(if_ptr == NULL || cfg == NULL)
-  {
-    GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, NULL, "", "",
-        GLINK_STATUS_INVALID_PARAM);
-    return GLINK_STATUS_INVALID_PARAM;
-  }
-
-  if(cfg->name == NULL       ||
-     cfg->remote_ss == NULL  ||
-     cfg->version == NULL    ||
-     cfg->version_count == 0 ||
-     cfg->max_cid == 0)
-  {
-    GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, NULL, "", "",
-        GLINK_STATUS_INVALID_PARAM);
-    return GLINK_STATUS_INVALID_PARAM;
-  }
-
-
-  if(if_ptr->tx_cmd_version == NULL             ||
-     if_ptr->tx_cmd_version_ack == NULL         ||
-     if_ptr->set_version == NULL                ||
-     if_ptr->tx_cmd_ch_open == NULL             ||
-     if_ptr->tx_cmd_ch_close == NULL            ||
-     if_ptr->tx_cmd_ch_remote_open_ack == NULL  ||
-     if_ptr->tx_cmd_ch_remote_close_ack == NULL ||
-     if_ptr->tx_cmd_set_sigs  == NULL           ||
-     if_ptr->ssr  == NULL)
-  {
-    GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, NULL, cfg->name,
-        cfg->remote_ss, GLINK_STATUS_INVALID_PARAM);
-    return GLINK_STATUS_INVALID_PARAM;;
-  }
-
-  remote_host = glinki_find_remote_host(cfg->remote_ss);
-
-  if(remote_host == GLINK_NUM_HOSTS ) {
-    /* Unknown transport name trying to register with GLink */
-    GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, NULL, cfg->name,
-           cfg->remote_ss, GLINK_STATUS_INVALID_PARAM);
-
-    return GLINK_STATUS_INVALID_PARAM;
-  }
-
-  /* Set the glink_core_if_ptr to point to the default interface */
-  if_ptr->glink_core_if_ptr = glink_core_get_default_interface();
-
-  /* Allocate/fill out the GLink private context data */
-  {
-     xport_ctx = glink_os_calloc(sizeof(glink_core_xport_ctx_type));
-    if(xport_ctx == NULL) {
-      /* Free previously allocated memory */
-      glink_os_free(if_ptr->glink_core_if_ptr);
-
-      GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, NULL, cfg->name,
-          cfg->remote_ss, GLINK_STATUS_OUT_OF_RESOURCES);
-
-      return GLINK_STATUS_OUT_OF_RESOURCES;
-    }
-
-    xport_ctx->xport = cfg->name;
-    xport_ctx->remote_ss = cfg->remote_ss;
-    xport_ctx->free_lcid = 1; /* lcid 0 is reserved for invalid channel */
-    xport_ctx->version_array = cfg->version;
-    xport_ctx->version_indx = cfg->version_count - 1;
-
-    glink_os_cs_init(&xport_ctx->channel_q_cs);
-    glink_os_cs_init(&xport_ctx->liid_cs);
-    glink_os_cs_init(&xport_ctx->status_cs);
-
-    glink_os_cs_acquire(&xport_ctx->channel_q_cs);
-    smem_list_init(&xport_ctx->open_list);
-    glink_os_cs_release(&xport_ctx->channel_q_cs);
-
-    /* Set the glink_core_if_ptr to point to the allocated structure */
-    if_ptr->glink_core_priv = xport_ctx;
-    xport_ctx->status = GLINK_XPORT_REGISTERED;
-  }
-
-  /* Push the transport interface into appropriate queue */
-  glink_os_cs_acquire(glink_transport_q_cs);
-  smem_list_append(&glink_registered_transports[remote_host], if_ptr);
-  glink_os_cs_release(glink_transport_q_cs);
-
-  GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, NULL, xport_ctx->xport,
-      xport_ctx->remote_ss, GLINK_STATUS_SUCCESS);
-
-  return GLINK_STATUS_SUCCESS;
-}
-
-/**
- * Regsiters a client specified callback to be invoked when the specified
- * transport (link) is up/down.
- *
- * @param[in]    link_id  Pointer to the configuration structure for the
- *                        xport(link) to be monitored. See glink.h
- * @param[in]    priv     Callback data returned to client when callback
- *                        is invoked.
- *
- * @return       Standard GLink error codes
- *
- * @sideeffects  Puts the callback in a queue which gets scanned when a
- *               transport(link) comes up OR an SSR happnes.
- */
-glink_err_type glink_register_link_state_cb
-(
-  glink_link_id_type *link_id,
-  void*              priv
-)
-{
-  glink_link_notif_data_type* link_notif_data;
-  unsigned int remote_host;
-
-  /* Input validation */
-  ASSERT(link_id != NULL);
-
-  /* Make sure client provided us with the correct version of the input
-   * structure */
-  if(link_id->version != GLINK_LINK_ID_VER || link_id->link_notifier == NULL) {
-    return GLINK_STATUS_INVALID_PARAM;
-  }
-
-  /* Save the callback on the notification list */
-  if((link_notif_data = glink_os_malloc(sizeof(glink_link_notif_data_type)))
-       == NULL) {
-    return GLINK_STATUS_OUT_OF_RESOURCES;
-  }
-
-  /* Check for remote_ss validity */
-  if(link_id->remote_ss != NULL) {
-    remote_host = glinki_find_remote_host(link_id->remote_ss);
-
-    if(remote_host == sizeof(glink_hosts_supported)/sizeof(char *)) {
-      glink_os_free(link_notif_data);
-      return GLINK_STATUS_INVALID_PARAM;
-    }
-  }
-
-  link_notif_data->xport = link_id->xport;
-  link_notif_data->remote_ss = link_id->remote_ss;
-  link_notif_data->link_notifier = link_id->link_notifier;
-  link_notif_data->priv = priv; /* private client data */
-
-  /* Append the request to the list for link UP/DOWN notifications */
-  smem_list_append(&glink_link_notif_list, link_notif_data);
-
-  link_id->handle = (glink_link_handle_type)link_notif_data;
-
-  /* Scan the list of available transport to see if this link is already up */
-  glinki_scan_xports_and_notify(link_notif_data);
-
-  return GLINK_STATUS_SUCCESS;
-}
-
-/**
- * Degsiter the link UP/DOWN notification callback associated with the
- * provided handle.
- *
- * @param[in]    handle  Callback handler returned by
- *                       glink_register_link_state_cb
- *
- * @return       Standard GLink error codes
- *
- * @sideeffects  Removes the callback in a queue which gets scanned when a
- *               transport(link) comes up OR an SSR happnes.
- */
-glink_err_type glink_deregister_link_state_cb
-(
-  glink_link_handle_type handle
-)
-{
-  /* check if glink handle is NULL and return appropriate
-     return code  */
-  if(handle == NULL)
-  {
-    return GLINK_STATUS_INVALID_PARAM;
-  }
-
-  smem_list_delete(&glink_link_notif_list,
-                   (glink_link_notif_data_type*)handle);
-
-  glink_os_free(handle);
-
-  return GLINK_STATUS_SUCCESS;
-}
-
-/**
- * This function gives best available transport for give edge
- *
- * @param[in]    remote_host  Index into glink_registered_transports array of
- *                            registered transports list per edge
- *
- * @return       pointer to glink_transport_if_type
- *
- * @sideeffects  NONE
- */
-glink_transport_if_type* glink_get_best_xport
-(
-  unsigned int remote_host
-)
-{
-  glink_transport_if_type   *if_ptr    = NULL, *best_if_ptr = NULL;
-  glink_xport_priority       priority  = GLINK_MIN_PRIORITY;
-  glink_core_xport_ctx_type *xport_ctx = NULL;
-
-  best_if_ptr = if_ptr = smem_list_first(
-                          &glink_registered_transports[remote_host]);
-
-  while(if_ptr != NULL)
-  {
-    xport_ctx = if_ptr->glink_core_priv;
-    /* check if priority of current transport is higher than
-     * current highest priority (0 = highest priority)
-     */
-    if( xport_ctx->status == GLINK_XPORT_LINK_UP &&
-        if_ptr->glink_priority < priority )
-    {
-      best_if_ptr = if_ptr;
-      priority    = if_ptr->glink_priority;
-    }
-    if_ptr = smem_list_next(if_ptr);
-  } /* end while() */
-
-  return best_if_ptr;
-}
 
 /**
  * Opens a logical GLink based on the specified config params
@@ -845,23 +88,20 @@
   glink_handle_type      *handle
 )
 {
-  glink_transport_if_type *if_ptr, *req_if_ptr;
+  glink_transport_if_type *if_ptr;
   glink_channel_ctx_type  *ch_ctx;
   unsigned int            remote_host;
+  glink_xport_priority     suggested_priority;
+  glink_channel_ctx_type  *allocated_ch_ctx;
+  glink_err_type           status;
 
   /* Param validation */
-  if(cfg_ptr == NULL)
-  {
-    GLINK_LOG_EVENT(GLINK_EVENT_CH_OPEN, NULL, "", "",
-        GLINK_STATUS_INVALID_PARAM);
-    return GLINK_STATUS_INVALID_PARAM;
-  }
-
-  if(cfg_ptr->remote_ss == NULL             ||
+  if(cfg_ptr == NULL            ||
+     cfg_ptr->remote_ss == NULL ||
      cfg_ptr->name == NULL                  ||
      cfg_ptr->notify_state == NULL)
   {
-    GLINK_LOG_EVENT(GLINK_EVENT_CH_OPEN, NULL, "", "",
+    GLINK_LOG_ERROR_EVENT( GLINK_EVENT_CH_OPEN, "", "", "", 
         GLINK_STATUS_INVALID_PARAM);
     return GLINK_STATUS_INVALID_PARAM;
   }
@@ -869,19 +109,24 @@
   /* Evaluate the equivalent edge name->enum for future use */
   remote_host = glinki_find_remote_host(cfg_ptr->remote_ss);
 
-  if(remote_host == GLINK_NUM_HOSTS ) {
+  if (remote_host == GLINK_NUM_HOSTS)
+  {
     /* Unknown transport name trying to register with GLink */
-    GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, cfg_ptr->name, "",
-        cfg_ptr->remote_ss, GLINK_STATUS_INVALID_PARAM);
+    GLINK_LOG_ERROR_EVENT( GLINK_EVENT_REGISTER_XPORT, 
+                           cfg_ptr->name, "", 
+                           cfg_ptr->remote_ss, 
+                           GLINK_STATUS_INVALID_PARAM );    
 
     return GLINK_STATUS_INVALID_PARAM;
   }
 
   /* Allocate and initialize channel info structure */
   ch_ctx = glink_os_calloc(sizeof(glink_channel_ctx_type));
-  if(ch_ctx == NULL) {
-    GLINK_LOG_EVENT(GLINK_EVENT_CH_OPEN, cfg_ptr->name, "",
-        "", GLINK_STATUS_OUT_OF_RESOURCES);
+  if(ch_ctx == NULL) 
+  {
+    GLINK_LOG_ERROR_EVENT( GLINK_EVENT_CH_OPEN, 
+                           cfg_ptr->name, "", "",
+                           GLINK_STATUS_OUT_OF_RESOURCES );
     return GLINK_STATUS_OUT_OF_RESOURCES;
   }
 
@@ -899,80 +144,60 @@
   ch_ctx->notify_rx_abort = cfg_ptr->notify_rx_abort;
   ch_ctx->notify_tx_abort = cfg_ptr->notify_tx_abort;
 
-  if (ch_ctx->notify_rx_sigs == NULL) {
+  if (ch_ctx->notify_rx_sigs == NULL)
+  {
     /* set default callback */
     ch_ctx->notify_rx_sigs = glink_default_notify_rx_sigs;
   }
 
-  glink_os_cs_acquire(glink_transport_q_cs);
+  if_ptr = glinki_find_requested_xport( cfg_ptr->transport, 
+                                       cfg_ptr->remote_ss,
+                                        cfg_ptr->options,
+                                        &suggested_priority );
 
-  /* Check to see if requested transport is available */
-  for (if_ptr = smem_list_first(&glink_registered_transports[remote_host]);
-       if_ptr != NULL;
-       if_ptr = smem_list_next(if_ptr))
-  {
-    glink_core_xport_ctx_type *xport_ctx = if_ptr->glink_core_priv;
-    glink_channel_ctx_type    *allocated_ch_ctx;
-
-    if (xport_ctx->status == GLINK_XPORT_LINK_UP &&
-        (cfg_ptr->transport == NULL ||
-         0 == strcmp(cfg_ptr->transport, xport_ctx->xport)) &&
-        xport_ctx->verify_open_cfg(ch_ctx))
+  if( !if_ptr )
     {
-      glink_err_type status;
-
-      if(cfg_ptr->transport == NULL)
-      {
-        /* get best available transport */
-        if_ptr = req_if_ptr = glink_get_best_xport(remote_host);
+    /* Code gets here if we are not able to find reqeusted transport */
+    GLINK_LOG_ERROR_EVENT( GLINK_EVENT_CH_OPEN,
+                     cfg_ptr->name,
+                     cfg_ptr->transport,
+                     cfg_ptr->remote_ss,
+                     GLINK_STATUS_NO_TRANSPORT );
+    glink_os_free(ch_ctx);
+    return GLINK_STATUS_NO_TRANSPORT;
       }
-      else
-      {
-        if(cfg_ptr->options & GLINK_OPT_INITIAL_XPORT)
-        {
-          /* xport suggested by client is optional.
-           * get best available xport */
-          req_if_ptr = glink_get_best_xport(remote_host);
-        }
-        else
-        {
-          req_if_ptr = if_ptr;
-        }
-      }
-      /* Xport match found */
+  
       status = glinki_add_ch_to_xport( if_ptr,
-                                       req_if_ptr,
                                        ch_ctx,
                                        &allocated_ch_ctx,
                                        TRUE,
-                                       if_ptr->glink_priority );
+                                   suggested_priority );
 
       if( status == GLINK_STATUS_SUCCESS )
       {
         /* Set the handle and return */
         *handle = allocated_ch_ctx;
+    GLINK_LOG_EVENT( *handle,
+                     GLINK_EVENT_CH_OPEN,
+                     cfg_ptr->name,
+                     cfg_ptr->transport,
+                     cfg_ptr->remote_ss,
+                     status );
       }
       else
       {
         *handle = NULL;
-      }
+    GLINK_LOG_ERROR_EVENT( GLINK_EVENT_CH_OPEN,
+                   cfg_ptr->name,
+                   cfg_ptr->transport,
+                   cfg_ptr->remote_ss,
+                   status );
+  }
 
-      glink_os_cs_release(glink_transport_q_cs);
+  
 
-      GLINK_LOG_EVENT(GLINK_EVENT_CH_OPEN, ch_ctx->name, xport_ctx->xport,
-        xport_ctx->remote_ss, status);
       return status;
     }
-  } /* end for() */
-
-  glink_os_cs_release(glink_transport_q_cs);
-
-  /* Code gets here if we are not able to find reqeusted transport */
-  GLINK_LOG_EVENT(GLINK_EVENT_CH_OPEN, cfg_ptr->name, cfg_ptr->transport,
-      cfg_ptr->remote_ss, GLINK_STATUS_NO_TRANSPORT);
-  glink_os_free(ch_ctx);
-  return GLINK_STATUS_NO_TRANSPORT;
-}
 
 /**
  * Closes the GLink logical channel specified by the handle.
@@ -989,43 +214,45 @@
 )
 {
   glink_err_type status;
-  glink_core_xport_ctx_type *xport_ctx = NULL;
+  glink_core_xport_ctx_type *xport_ctx; 
 
   if(handle == NULL)
   {
-    GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE, NULL, "",
-        "", GLINK_STATUS_INVALID_PARAM);
+    GLINK_LOG_ERROR_EVENT( GLINK_EVENT_CH_CLOSE, "", "", "",
+                           GLINK_STATUS_INVALID_PARAM );
     return GLINK_STATUS_INVALID_PARAM;
   }
 
   /* get xport context after NULL check */
-  xport_ctx = handle->if_ptr->glink_core_priv;
-
+  xport_ctx = handle->if_ptr->glink_core_priv;  
+  
+  ASSERT( xport_ctx != NULL );
+  
   /* grab lock to change/check channel state atomically */
-  glink_os_cs_acquire( &handle->ch_state_cs );
+  glink_os_cs_acquire( &xport_ctx->channel_q_cs );
 
   /* Check to see if closed called again for same channel */
-  if ( handle->local_state == GLINK_LOCAL_CH_CLOSING ||
-       handle->local_state == GLINK_LOCAL_CH_CLOSED )
+  if (handle->local_state != GLINK_LOCAL_CH_OPENED &&
+      handle->local_state != GLINK_LOCAL_CH_OPENING)
   {
-    GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE, handle->name, xport_ctx->xport,
-      xport_ctx->remote_ss, handle->local_state);
+    GLINK_LOG_ERROR_EVENT( GLINK_EVENT_CH_CLOSE, 
+                           handle->name, 
+                           xport_ctx->xport,
+                           xport_ctx->remote_ss, 
+                           handle->local_state );
 
-    glink_os_cs_release(&handle->ch_state_cs);
+    glink_os_cs_release(&xport_ctx->channel_q_cs);
 
-    return GLINK_STATUS_FAILURE;
+    return GLINK_STATUS_CH_ALREADY_CLOSED;
   }
 
   handle->local_state = GLINK_LOCAL_CH_CLOSING;
 
-  glink_os_cs_acquire( &xport_ctx->status_cs );
-
-  if( GLINK_XPORT_LINK_UP != xport_ctx->status ||
-      handle->remote_state == GLINK_REMOTE_CH_SSR_RESET )
+  if (handle->remote_state == GLINK_REMOTE_CH_SSR_RESET ||
+      glinki_xport_linkup(handle->if_ptr) == FALSE)
   {
-    /* SSR happened on remote-SS. Fake close_ack from here */
-    glink_os_cs_release( &xport_ctx->status_cs );
-    glink_os_cs_release( &handle->ch_state_cs );
+    /* SSR happened on remote-SS OR XPORT link is down. Fake close_ack from here */
+    glink_os_cs_release( &xport_ctx->channel_q_cs);
 
     handle->if_ptr->glink_core_if_ptr->rx_cmd_ch_close_ack( handle->if_ptr,
                                                             handle->lcid );
@@ -1034,13 +261,16 @@
   }
   else
   {
-    glink_os_cs_release( &xport_ctx->status_cs );
-    glink_os_cs_release( &handle->ch_state_cs );
+    glink_os_cs_release(&xport_ctx->channel_q_cs);
 
     status = handle->if_ptr->tx_cmd_ch_close(handle->if_ptr, handle->lcid);
 
-    GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE, handle->name, xport_ctx->xport,
-        xport_ctx->remote_ss, status);
+    GLINK_LOG_EVENT( handle,
+                     GLINK_EVENT_CH_CLOSE, 
+                     handle->name, 
+                     xport_ctx->xport,
+                     xport_ctx->remote_ss, 
+                     status );
   }
 
   return status;
@@ -1119,31 +349,34 @@
 
   /* Input validation */
   if(handle == NULL || iovec == NULL || size == 0 ||
-     (vprovider == NULL && pprovider == NULL)) {
-    GLINK_LOG_EVENT(GLINK_EVENT_CH_TX, NULL, "",
-        "", GLINK_STATUS_INVALID_PARAM);
+     (vprovider == NULL && pprovider == NULL))
+  {
+    GLINK_LOG_ERROR_EVENT( GLINK_EVENT_CH_TX, "", "", "",
+                           GLINK_STATUS_INVALID_PARAM );
     return GLINK_STATUS_INVALID_PARAM;
   }
 
   xport_ctx = handle->if_ptr->glink_core_priv;
 
-  if( !glink_is_channel_fully_opened( handle, xport_ctx ) )
+  if (!glinki_channel_fully_opened(handle))
   {
-    GLINK_LOG_EVENT( GLINK_EVENT_CH_TX,
+    GLINK_LOG_ERROR_EVENT( GLINK_EVENT_CH_TX, 
                      handle->name,
                      xport_ctx->xport,
                      xport_ctx->remote_ss,
-                     GLINK_STATUS_FAILURE );
-
-    return GLINK_STATUS_FAILURE;
+                           GLINK_STATUS_CH_NOT_FULLY_OPENED );
+    return GLINK_STATUS_CH_NOT_FULLY_OPENED;
   }
 
   pctx = glink_os_calloc( sizeof( glink_core_tx_pkt_type ) );
 
   if (pctx == NULL)
   {
-    GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE, handle->name, xport_ctx->xport,
-      xport_ctx->remote_ss, GLINK_STATUS_OUT_OF_RESOURCES);
+    GLINK_LOG_ERROR_EVENT( GLINK_EVENT_CH_TX, 
+                           handle->name, 
+                           xport_ctx->xport,
+                           xport_ctx->remote_ss, 
+                           GLINK_STATUS_OUT_OF_RESOURCES );
     return GLINK_STATUS_OUT_OF_RESOURCES;
   }
 
@@ -1168,11 +401,25 @@
     pctx->iovec = iovec;
   }
 
+#ifdef FEATURE_TRACER_PACKET
+  pctx->tracer_pkt = options & GLINK_TX_TRACER_PKT ? TRUE : FALSE;
+  if( pctx->tracer_pkt )
+  {
+    glink_tracer_packet_log_pctx_pkt( pctx, GLINK_CORE_TX );
+  }
+#endif
 
   status = xport_ctx->channel_submit_pkt(handle, pctx, req_intent);
 
-  GLINK_LOG_EVENT(GLINK_EVENT_CH_TX, handle->name, xport_ctx->xport,
-      xport_ctx->remote_ss, status);
+  /*Update the channel stats*/
+  GLINK_UPDATE_CHANNEL_STATS( handle->ch_stats, tx_request, size);
+  
+  GLINK_LOG_EVENT( handle,
+                   GLINK_EVENT_CH_TX, 
+                   handle->name, 
+                   xport_ctx->xport,
+                   xport_ctx->remote_ss, 
+                   status);
 
   glink_os_cs_release(&handle->tx_cs);
   return status;
@@ -1200,75 +447,89 @@
 {
   glink_err_type         status;
   glink_rx_intent_type   *lc_intent;
-  glink_core_xport_ctx_type *xport_ctx = handle->if_ptr->glink_core_priv;
+  glink_core_xport_ctx_type *xport_ctx; 
   size_t tmp;
 
   /* Input validation */
-  if(handle == NULL || size == 0) {
-    GLINK_LOG_EVENT(GLINK_EVENT_CH_Q_RX_INTENT, NULL, "",
-        "", GLINK_STATUS_INVALID_PARAM);
+  if(handle == NULL || size == 0)
+  {
+    GLINK_LOG_ERROR_EVENT( GLINK_EVENT_CH_Q_RX_INTENT, "", "", "", 
+                           GLINK_STATUS_INVALID_PARAM);
     return GLINK_STATUS_INVALID_PARAM;
   }
 
+  xport_ctx = handle->if_ptr->glink_core_priv;
+  
   /* short circuit for intentless mode */
-  if(xport_ctx->xport_capabilities & GLINK_CAPABILITY_INTENTLESS) {
-    return GLINK_STATUS_FAILURE;
+  if(xport_ctx->xport_capabilities & GLINK_CAPABILITY_INTENTLESS)
+  {
+    return GLINK_STATUS_API_NOT_SUPPORTED;
   }
 
-  if( !glink_is_channel_fully_opened( handle, xport_ctx ) )
+  if (!glinki_channel_fully_opened(handle))
   {
-    GLINK_LOG_EVENT( GLINK_EVENT_CH_Q_RX_INTENT,
+    GLINK_LOG_ERROR_EVENT( GLINK_EVENT_CH_Q_RX_INTENT, 
                      handle->name,
                      xport_ctx->xport,
                      xport_ctx->remote_ss,
-                     GLINK_STATUS_FAILURE );
-
-    return GLINK_STATUS_FAILURE;
+                           GLINK_STATUS_CH_NOT_FULLY_OPENED );
+    return GLINK_STATUS_CH_NOT_FULLY_OPENED;
   }
 
   /* Allocate an intent structure */
   lc_intent = glink_os_calloc(sizeof(glink_rx_intent_type));
-  if(lc_intent == NULL) {
-    GLINK_LOG_EVENT(GLINK_EVENT_CH_Q_RX_INTENT, handle->name, xport_ctx->xport,
-        xport_ctx->remote_ss, GLINK_STATUS_OUT_OF_RESOURCES);
+  if(lc_intent == NULL)
+  {
+    GLINK_LOG_ERROR_EVENT( GLINK_EVENT_CH_Q_RX_INTENT, 
+                           handle->name, 
+                           xport_ctx->xport,
+                           xport_ctx->remote_ss, 
+                           GLINK_STATUS_OUT_OF_RESOURCES );
     return GLINK_STATUS_OUT_OF_RESOURCES;
   }
 
-  glink_os_cs_acquire(&handle->if_ptr->glink_core_priv->liid_cs);
-
   /* Call transport API to allocate rx intent buffer */
   status = handle->if_ptr->allocate_rx_intent(handle->if_ptr, size, lc_intent);
-  if(status != GLINK_STATUS_SUCCESS) {
+  if(status != GLINK_STATUS_SUCCESS)
+  {
     glink_os_free(lc_intent);
-    glink_os_cs_release(&handle->if_ptr->glink_core_priv->liid_cs);
-    GLINK_LOG_EVENT(GLINK_EVENT_CH_Q_RX_INTENT, handle->name, xport_ctx->xport,
-        xport_ctx->remote_ss, status);
+    GLINK_LOG_ERROR_EVENT( GLINK_EVENT_CH_Q_RX_INTENT, 
+                           handle->name, 
+                           xport_ctx->xport,
+                           xport_ctx->remote_ss, 
+                           status );
     return status;
   }
 
   if (handle->notify_rxv == NULL &&
-     (lc_intent->vprovider(lc_intent->iovec, 0, &tmp) == NULL || tmp < size)) {
+     (lc_intent->vprovider(lc_intent->iovec, 0, &tmp) == NULL || tmp < size))
+  {
     /* Allocate bounce buffer for non-vectored Rx */
     lc_intent->data = glink_os_malloc(size);
 
-    if(lc_intent->data == NULL) {
+    if(lc_intent->data == NULL)
+    {
       handle->if_ptr->deallocate_rx_intent(handle->if_ptr, lc_intent);
       glink_os_free(lc_intent);
-      glink_os_cs_release(&handle->if_ptr->glink_core_priv->liid_cs);
-      GLINK_LOG_EVENT(GLINK_EVENT_CH_Q_RX_INTENT, handle->name,
-        xport_ctx->xport, xport_ctx->remote_ss, GLINK_STATUS_OUT_OF_RESOURCES);
+      GLINK_LOG_ERROR_EVENT( GLINK_EVENT_CH_Q_RX_INTENT, 
+                             handle->name, 
+                             xport_ctx->xport, 
+                             xport_ctx->remote_ss, 
+                             GLINK_STATUS_OUT_OF_RESOURCES );
       return GLINK_STATUS_OUT_OF_RESOURCES;
     }
   }
 
+  glink_os_cs_acquire(&handle->if_ptr->glink_core_priv->liid_cs);
+  
   /* push the intent on local queue. Do this before calling tx cmd
      as transport may try to read data into the newly queued rx_buffer */
   lc_intent->iid = handle->if_ptr->glink_core_priv->liid;
   lc_intent->size = size;
   lc_intent->pkt_priv = pkt_priv;
-  glink_os_cs_acquire(&handle->pintents->intent_q_cs);
-  smem_list_append(&handle->pintents->local_intent_q, lc_intent);
-  glink_os_cs_release(&handle->pintents->intent_q_cs);
+  glinki_enqueue_item(&handle->pintents->local_intent_q,
+                      lc_intent,
+                      &handle->pintents->intent_q_cs);
 
   /* Call transport API to queue rx intent */
   /* Increment the local intent ID counter associated with this channel */
@@ -1276,11 +537,12 @@
 
   status = handle->if_ptr->tx_cmd_local_rx_intent(handle->if_ptr,
               handle->lcid, size, lc_intent->iid);
-  if(status != GLINK_STATUS_SUCCESS) {
+  if(status != GLINK_STATUS_SUCCESS)
+  {
     /* Failure */
-    glink_os_cs_acquire(&handle->pintents->intent_q_cs);
-    smem_list_delete(&handle->pintents->local_intent_q, lc_intent);
-    glink_os_cs_release(&handle->pintents->intent_q_cs);
+    glinki_dequeue_item(&handle->pintents->local_intent_q,
+                        lc_intent,
+                        &handle->pintents->intent_q_cs);
 
     handle->if_ptr->deallocate_rx_intent(handle->if_ptr, lc_intent);
     glink_os_free(lc_intent->data);
@@ -1288,8 +550,12 @@
   }
   glink_os_cs_release(&handle->if_ptr->glink_core_priv->liid_cs);
 
-  GLINK_LOG_EVENT(GLINK_EVENT_CH_Q_RX_INTENT, handle->name, xport_ctx->xport,
-      xport_ctx->remote_ss, status);
+  GLINK_LOG_EVENT( handle,
+                   GLINK_EVENT_CH_Q_RX_INTENT, 
+                   handle->name, 
+                   xport_ctx->xport,
+                   xport_ctx->remote_ss, 
+                   status );
   return status;
 }
 
@@ -1319,59 +585,66 @@
   glink_core_xport_ctx_type *xport_ctx = handle->if_ptr->glink_core_priv;
 
   /* Input validation */
-  if(handle == NULL || ptr == NULL) {
-    GLINK_LOG_EVENT(GLINK_EVENT_CH_RX_DONE, NULL, "",
-        "", GLINK_STATUS_INVALID_PARAM);
+  if(handle == NULL || ptr == NULL)
+  {
+    GLINK_LOG_ERROR_EVENT( GLINK_EVENT_CH_RX_DONE, "", "", "", 
+                           GLINK_STATUS_INVALID_PARAM );
     return GLINK_STATUS_INVALID_PARAM;
   }
 
   /* short circuit for intentless mode */
-  if(xport_ctx->xport_capabilities & GLINK_CAPABILITY_INTENTLESS) {
-    return GLINK_STATUS_SUCCESS;
+  if (xport_ctx->xport_capabilities & GLINK_CAPABILITY_INTENTLESS)
+  {
+    return GLINK_STATUS_API_NOT_SUPPORTED;
   }
 
-  if( !glink_is_channel_fully_opened( handle, xport_ctx ) )
+  if (!glinki_channel_fully_opened(handle))
   {
-    GLINK_LOG_EVENT( GLINK_EVENT_CH_RX_DONE,
+    GLINK_LOG_ERROR_EVENT( GLINK_EVENT_CH_RX_DONE, 
                      handle->name,
                      xport_ctx->xport,
                      xport_ctx->remote_ss,
-                     GLINK_STATUS_FAILURE );
-
-    return GLINK_STATUS_FAILURE;
+			   GLINK_STATUS_CH_NOT_FULLY_OPENED );
+    return GLINK_STATUS_CH_NOT_FULLY_OPENED;
   }
 
   /* Free the intent */
   lc_intent = smem_list_first(&handle->pintents->local_intent_client_q);
-  while(lc_intent != NULL) {
+  while(lc_intent != NULL)
+  {
     size_t tmp;
 
     if(lc_intent->iovec == ptr || (handle->notify_rxv == NULL &&
        (lc_intent->data == ptr ||
-       ptr == lc_intent->vprovider(lc_intent->iovec, 0, &tmp)))) {
+       ptr == lc_intent->vprovider(lc_intent->iovec, 0, &tmp))))
+    {
 
       uint32 iid;
 
       /* Found intent, delete it */
-      glink_os_cs_acquire(&handle->pintents->intent_q_cs);
-      smem_list_delete(&handle->pintents->local_intent_client_q, lc_intent);
-      glink_os_cs_release(&handle->pintents->intent_q_cs);
+      glinki_dequeue_item(&handle->pintents->local_intent_client_q,
+                          lc_intent,
+                          &handle->pintents->intent_q_cs);
 
       iid = lc_intent->iid;
 
+      GLINK_UPDATE_CHANNEL_STATS( handle->ch_stats, rx_done, lc_intent->pkt_sz);
+
       if (reuse)
       {
         lc_intent->used = 0;
 
-        glink_os_cs_acquire(&handle->pintents->intent_q_cs);
-        smem_list_append(&handle->pintents->local_intent_q, lc_intent);
-        glink_os_cs_release(&handle->pintents->intent_q_cs);
+        glinki_enqueue_item(&handle->pintents->local_intent_q,
+                            lc_intent,
+                            &handle->pintents->intent_q_cs);
+        
       }
       else
       {
         /* Free the intent */
         handle->if_ptr->deallocate_rx_intent(handle->if_ptr, lc_intent);
-        if(lc_intent->data) {
+        if(lc_intent->data)
+        {
           /* Free the bounce buffer if we had allocated one */
           glink_os_free(lc_intent->data);
         }
@@ -1381,18 +654,28 @@
       /* Note that the actual buffer, lc_intent->data, was allocated by the
       * transport and should be freed by the xport. We should not touch it */
       /* Let the xport know we are done with the buffer */
-      handle->if_ptr->tx_cmd_local_rx_done(handle->if_ptr, handle->lcid,
-                                           iid, reuse);
+      handle->if_ptr->tx_cmd_local_rx_done(handle->if_ptr,
+                                           handle->lcid,
+                                           iid,
+                                           reuse);
 
-      GLINK_LOG_EVENT(GLINK_EVENT_CH_RX_DONE, handle->name, xport_ctx->xport,
-          xport_ctx->remote_ss, GLINK_STATUS_SUCCESS);
+      GLINK_LOG_EVENT( handle,
+                       GLINK_EVENT_CH_RX_DONE, 
+                       handle->name, 
+                       xport_ctx->xport,
+                       xport_ctx->remote_ss, 
+                       GLINK_STATUS_SUCCESS );
+
       return GLINK_STATUS_SUCCESS;
     }
     lc_intent = smem_list_next(lc_intent);
   }
 
-  GLINK_LOG_EVENT(GLINK_EVENT_CH_RX_DONE, handle->name, xport_ctx->xport,
-      xport_ctx->remote_ss, GLINK_STATUS_INVALID_PARAM);
+  GLINK_LOG_ERROR_EVENT( GLINK_EVENT_CH_RX_DONE, 
+                         handle->name, 
+                         xport_ctx->xport,
+                         xport_ctx->remote_ss, 
+                         GLINK_STATUS_INVALID_PARAM );
   return GLINK_STATUS_INVALID_PARAM;
 }
 
@@ -1415,32 +698,37 @@
   uint32            sig_value
 )
 {
-  glink_core_xport_ctx_type *xport_ctx;
+  glink_core_xport_ctx_type *xport_ctx; 
   glink_err_type status;
 
   /* Input validation */
-  if(handle == NULL) {
-    GLINK_LOG_EVENT(GLINK_EVENT_CH_SIG_SET, NULL, "",
-        "", GLINK_STATUS_INVALID_PARAM);
+  if(handle == NULL)
+  {
+    GLINK_LOG_ERROR_EVENT( GLINK_EVENT_CH_SIG_SET, "", "", "", 
+                           GLINK_STATUS_INVALID_PARAM );
     return GLINK_STATUS_INVALID_PARAM;
   }
 
-  xport_ctx = handle->if_ptr->glink_core_priv;
+	xport_ctx = handle->if_ptr->glink_core_priv;
 
-  if( !glink_is_channel_fully_opened( handle, xport_ctx ) )
+	ASSERT( xport_ctx != NULL );
+
+  if (!glinki_channel_fully_opened(handle))
   {
-    GLINK_LOG_EVENT( GLINK_EVENT_CH_SIG_SET,
+    GLINK_LOG_ERROR_EVENT( GLINK_EVENT_CH_SIG_SET, 
                      handle->name,
                      xport_ctx->xport,
                      xport_ctx->remote_ss,
-                     GLINK_STATUS_FAILURE );
+                           GLINK_STATUS_CH_NOT_FULLY_OPENED );
 
-    return GLINK_STATUS_FAILURE;
+    return GLINK_STATUS_CH_NOT_FULLY_OPENED;
   }
 
-  status = handle->if_ptr->tx_cmd_set_sigs(handle->if_ptr, handle->lcid,
+  status = handle->if_ptr->tx_cmd_set_sigs(handle->if_ptr,
+                                           handle->lcid,
                                            sig_value);
-  if(GLINK_STATUS_SUCCESS == status) {
+  if(GLINK_STATUS_SUCCESS == status)
+  {
     /* Update local copy of local control signal state */
     handle->local_sigs = sig_value;
   }
@@ -1466,9 +754,10 @@
 )
 {
   /* Input validation */
-  if(handle == NULL || sig_value == NULL) {
-    GLINK_LOG_EVENT(GLINK_EVENT_CH_SIG_L_GET, NULL, "",
-        "", GLINK_STATUS_INVALID_PARAM);
+  if(handle == NULL || sig_value == NULL)
+  {
+    GLINK_LOG_ERROR_EVENT( GLINK_EVENT_CH_SIG_L_GET, "", "", "", 
+                           GLINK_STATUS_INVALID_PARAM );
     return GLINK_STATUS_INVALID_PARAM;
   }
 
@@ -1495,9 +784,10 @@
 )
 {
   /* Input validation */
-  if(handle == NULL || sig_value == NULL) {
-    GLINK_LOG_EVENT(GLINK_EVENT_CH_SIG_R_GET, NULL, "",
-        "", GLINK_STATUS_INVALID_PARAM);
+  if(handle == NULL || sig_value == NULL)
+  {
+    GLINK_LOG_ERROR_EVENT( GLINK_EVENT_CH_SIG_R_GET, "", "", "", 
+                           GLINK_STATUS_INVALID_PARAM );
     return GLINK_STATUS_INVALID_PARAM;
   }
 
@@ -1506,6 +796,100 @@
   return GLINK_STATUS_SUCCESS;
 }
 
+/** 
+ * Regsiters a client specified callback to be invoked when the specified
+ * transport (link) is up/down.
+ *
+ * @param[in]    link_id  Pointer to the configuration structure for the
+ *                        xport(link) to be monitored. See glink.h
+ * @param[in]    priv     Callback data returned to client when callback
+ *                        is invoked.
+ *
+ * @return       Standard GLink error codes
+ *
+ * @sideeffects  Puts the callback in a queue which gets scanned when a 
+ *               transport(link) comes up OR an SSR happnes.
+ */
+glink_err_type glink_register_link_state_cb
+(
+  glink_link_id_type *link_id,
+  void*              priv
+)
+{
+  glink_link_notif_data_type* link_notif_data;
+  unsigned int remote_host;
+
+  /* Input validation */
+  if (link_id == NULL ||
+      link_id->version != GLINK_LINK_ID_VER ||
+      link_id->link_notifier == NULL)
+  {
+    return GLINK_STATUS_INVALID_PARAM;
+  }
+
+  /* Check for remote_ss validity */
+  if (link_id->remote_ss != NULL)
+  {
+    remote_host = glinki_find_remote_host(link_id->remote_ss);
+    if (remote_host == GLINK_NUM_HOSTS)
+    {
+      return GLINK_STATUS_INVALID_PARAM;
+    }
+  }
+  
+  /* Save the callback on the notification list */
+  if((link_notif_data = glink_os_calloc(sizeof(glink_link_notif_data_type)))
+       == NULL)
+  {
+    return GLINK_STATUS_OUT_OF_RESOURCES;
+  }
+
+  link_notif_data->xport = link_id->xport;
+  link_notif_data->remote_ss = link_id->remote_ss;
+  link_notif_data->link_notifier = link_id->link_notifier;
+  link_notif_data->priv = priv; /* private client data */
+
+  /* Append the request to the list for link UP/DOWN notifications */
+  glinki_register_link_notif_data(link_notif_data);
+  link_id->handle = (glink_link_handle_type)link_notif_data;
+  
+  /* Scan the list of available transport to see if this link is already up */
+  glinki_scan_xports_and_notify(link_notif_data);
+
+  return GLINK_STATUS_SUCCESS;
+}
+
+/** 
+ * Degsiter the link UP/DOWN notification callback associated with the
+ * provided handle.
+ *
+ * @param[in]    handle  Callback handler returned by 
+ *                       glink_register_link_state_cb
+ *
+ * @return       Standard GLink error codes
+ *
+ * @sideeffects  Removes the callback in a queue which gets scanned when a 
+ *               transport(link) comes up OR an SSR happnes.
+ */
+glink_err_type glink_deregister_link_state_cb
+(
+  glink_link_handle_type handle
+)
+{
+  /* check if glink handle is NULL and return appropriate
+     return code  */
+  if(handle == NULL) 
+  {
+    return GLINK_STATUS_INVALID_PARAM;
+  }
+
+  glinki_deregister_link_notif_data((glink_link_notif_data_type *)handle);
+  
+  glink_os_free(handle);
+
+  return GLINK_STATUS_SUCCESS;
+}
+
 /*================= RESTRICTED API ==========================*/
 
 /**
@@ -1524,12 +908,15 @@
   glink_handle_type handle
 )
 {
-  ASSERT(handle);
+  if (!handle)
+  {
+    return GLINK_STATUS_INVALID_PARAM;
+  }
 
   if(handle->if_ptr->poll) {
     return handle->if_ptr->poll(handle->if_ptr);
   }
-  return GLINK_STATUS_FAILURE;
+  return GLINK_STATUS_API_NOT_SUPPORTED;
 }
 
 /**
@@ -1553,12 +940,15 @@
   void              *platform_struct
 )
 {
-  ASSERT(handle);
+  if (!handle)
+  {
+    return GLINK_STATUS_INVALID_PARAM;
+  }
 
   if(handle->if_ptr->mask_rx_irq) {
     return handle->if_ptr->mask_rx_irq(handle->if_ptr, mask);
   }
-  return GLINK_STATUS_FAILURE;
+  return GLINK_STATUS_API_NOT_SUPPORTED;
 }
 
 /**
@@ -1580,20 +970,3 @@
   return handle->if_ptr->wait_link_down(handle->if_ptr) ?
          GLINK_STATUS_SUCCESS : GLINK_STATUS_FAILURE;
 }
-
-/* ============ Internal Logging API ================ */
-void glink_mem_log
-(
-  const char *func,
-  uint32 line,
-  glink_log_event_type type,
-  const char *msg,
-  const char *xport,
-  const char *remote_ss,
-  uint32 param
-)
-{
-#ifdef DEBUG_GLINK
-  dprintf(INFO, "%s:%u, event:%d, msg:%s, xport:%s, remote_ss:%s, param:%u\n", func, line, type, msg, xport, remote_ss, param);
-#endif
-}
diff --git a/platform/msm_shared/glink/glink_core_if.c b/platform/msm_shared/glink/glink_core_if.c
index 5e3abd5..5b56c65 100644
--- a/platform/msm_shared/glink/glink_core_if.c
+++ b/platform/msm_shared/glink/glink_core_if.c
@@ -34,21 +34,12 @@
 #include "glink_os_utils.h"
 #include "glink.h"
 #include "glink_internal.h"
-#include "smem_list.h"
-#include "glink_channel_migration.h"
 
 #define FEATURE_CH_MIGRATION_FREE
 
 /*===========================================================================
                         GLOBAL FUNCTION DECLARATIONS
-==========================================================================*/
-extern void glinki_scan_notif_list_and_notify
-(
-  glink_transport_if_type *if_ptr,
-  glink_link_state_type state
-);
-
-
+===========================================================================*/
 /*===========================================================================
                      LOCAL FUNCTION DEFINITIONS
 ===========================================================================*/
@@ -87,16 +78,11 @@
    * Only go through process once in case they are negotiated
    * in ver_req before receiving ver_ack */
 
-  glink_os_cs_acquire( &xport_ctx->status_cs );
-
-  if( xport_ctx->status == GLINK_XPORT_LINK_UP )
+  if (glinki_xport_linkup(if_ptr))
   {
-    glink_os_cs_release( &xport_ctx->status_cs );
     return;
   }
 
-  glink_os_cs_release(&if_ptr->glink_core_priv->status_cs);
-
   /* setup core based on transport capabilities*/
   xport_ctx->xport_capabilities = if_ptr->set_version( if_ptr,
                                                        version,
@@ -106,27 +92,26 @@
   /* transport is ready to open channels */
   glink_os_cs_acquire( &xport_ctx->status_cs );
   if_ptr->glink_core_priv->status = GLINK_XPORT_LINK_UP;
-  glink_os_cs_release(&if_ptr->glink_core_priv->status_cs);
+  glink_os_cs_release(&xport_ctx->status_cs);
 
   /* Scan the notification list to check is we have to let any registered
    * clients know that link came online */
   glinki_scan_notif_list_and_notify(if_ptr, GLINK_LINK_STATE_UP);
 }
 
-
 /*===========================================================================
   FUNCTION      glink_clean_channel_ctx
 ===========================================================================*/
 /**
 
-  This is called when channel is fully closed
-  Clean up the context and redeem channel id if possible
+  This is called when channel is fully closed.
+  Clean up the context and redeem channel id if possible.
 
   @param[in]    xport_ctx    transport context
   @param[in]    channel_ctx  channel context
 
 
-  @return        None
+  @return        None.
   @sideeffects   None.
   @dependencies  This function needs to be called in safe context
                  which is critical sections locked - channel_q_cs
@@ -138,7 +123,10 @@
   glink_channel_ctx_type    *channel_ctx
 )
 {
-  xport_ctx->channel_cleanup( channel_ctx );
+  /* If logging was enabled for this channel reset the logging filter */
+  glinki_update_logging_filter(channel_ctx, TRUE);
+  
+  smem_list_delete(&xport_ctx->open_list, channel_ctx);
 
   if( channel_ctx->lcid == ( xport_ctx->free_lcid - 1 ) )
   {
@@ -147,7 +135,87 @@
     xport_ctx->free_lcid--;
   }
 
-  smem_list_delete(&xport_ctx->open_list, channel_ctx);
+  xport_ctx->channel_cleanup(channel_ctx);
+}
+
+/*===========================================================================
+  FUNCTION      glink_get_current_version
+===========================================================================*/
+/**
+
+  Get current version/feature. This is necessarily highest version.
+
+  @param[in]     xport_ctx    transport context
+  
+  @return        pointer to version/feature if available.
+                 NULL otherwise.
+  
+  @sideeffects   None.
+  @dependencies  None.
+*/
+/*=========================================================================*/
+static const glink_core_version_type *glink_get_current_version
+(
+  glink_core_xport_ctx_type *xport_ctx
+)
+{
+  const glink_core_version_type *ver;
+  
+  ver = &xport_ctx->version_array[xport_ctx->version_indx];
+  ASSERT(ver);
+  
+  return ver;
+}
+
+/*===========================================================================
+  FUNCTION      glink_is_local_ch_closed
+===========================================================================*/
+/**
+
+  Check if local channel is fully closed
+  
+  @param[in]     local_state local channel state
+  
+  @return        TRUE, if local channel is closed
+  
+  @sideeffects   None.
+  @dependencies  None.
+*/
+/*=========================================================================*/
+static boolean glink_is_local_ch_closed
+(
+  glink_local_state_type local_state
+)
+{
+  return local_state == GLINK_LOCAL_CH_INIT ||
+         local_state == GLINK_LOCAL_CH_CLOSED;
+}
+
+/*===========================================================================
+  FUNCTION      glink_is_remote_ch_closed
+===========================================================================*/
+/**
+
+  Check if remote channel is fully closed.
+  This doesn't chek GLINK_REMOTE_CH_CLEANUP state as channel ctx shouldn't be
+  destroyed yet
+  
+  @param[in]     ch_ctx  channel ctx
+  
+  @return        TRUE, if remote channel is closed
+  
+  @sideeffects   None.
+  @dependencies  None.
+*/
+/*=========================================================================*/
+static boolean glink_is_remote_ch_closed
+(
+    glink_remote_state_type remote_state
+)
+{
+  return remote_state == GLINK_REMOTE_CH_INIT ||
+         remote_state == GLINK_REMOTE_CH_CLOSED ||
+         remote_state == GLINK_REMOTE_CH_SSR_RESET;
 }
 
 /*===========================================================================
@@ -173,14 +241,12 @@
   glink_transport_if_type *if_ptr
 )
 {
-  const glink_core_version_type *version_array;
   glink_core_xport_ctx_type *xport_ctx;
-
-  ASSERT(if_ptr != NULL);
+  const glink_core_version_type *version_array;
 
   xport_ctx = if_ptr->glink_core_priv;
 
-  version_array = xport_ctx->version_array;
+  version_array = glink_get_current_version(xport_ctx);
 
   /* Update the transport state */
   glink_os_cs_acquire(&if_ptr->glink_core_priv->status_cs);
@@ -188,12 +254,14 @@
   glink_os_cs_release(&if_ptr->glink_core_priv->status_cs);
 
   /* Start the negtiation */
-  if_ptr->tx_cmd_version(if_ptr, version_array->version,
+  if_ptr->tx_cmd_version(if_ptr,
+                         version_array->version,
       version_array->features);
 
-  GLINK_LOG_EVENT(GLINK_EVENT_LINK_UP, NULL, xport_ctx->xport,
-      xport_ctx->remote_ss, GLINK_STATUS_SUCCESS);
-
+  GLINK_LOG_EVENT_NO_FILTER( GLINK_EVENT_LINK_UP, "", 
+                             xport_ctx->xport, 
+                             xport_ctx->remote_ss, 
+                             GLINK_STATUS_SUCCESS);
 }
 
 /*===========================================================================
@@ -224,40 +292,28 @@
   uint32 negotiated_features;
   glink_core_xport_ctx_type *xport_ctx;
 
-  ASSERT(if_ptr != NULL);
-
   xport_ctx = if_ptr->glink_core_priv;
 
+  ver = glink_get_current_version(xport_ctx);
+  
   /* The version to use must be a subset of supported version and features
    * on this host and remote host */
-  ver = &xport_ctx->version_array[xport_ctx->version_indx];
-  ASSERT(ver);
-
   if (version == ver->version)
   {
     /* Call the transport's negotiation function */
     negotiated_features = ver->negotiate_features(if_ptr, ver, features);
 
+    if_ptr->tx_cmd_version_ack(if_ptr, version, negotiated_features);
+    
     /* If negotiated features match the provided features, version nogetiation
      * is complete */
     if(negotiated_features == features)
     {
-      /* send version ack before allowing to open channels */
-      if_ptr->tx_cmd_version_ack(if_ptr, version, features);
-
       glink_process_negotiation_complete( if_ptr, version, features );
-      return;
-    }
-    else
-    {
-      if_ptr->tx_cmd_version_ack(if_ptr, version, negotiated_features);
     }
   }
   else
   {
-    /* Next time use older version */
-    ver = &xport_ctx->version_array[xport_ctx->version_indx];
-
     /* Versions don't match, return ACK with the feature set that we support */
     if_ptr->tx_cmd_version_ack(if_ptr, ver->version, ver->features);
   }
@@ -291,38 +347,33 @@
   uint32 negotiated_features;
   glink_core_xport_ctx_type *xport_ctx;
 
-  ASSERT(if_ptr != NULL);
-
   xport_ctx = if_ptr->glink_core_priv;
 
   /* Check to see if version returned by remote end is supported by
    * this host. Remote side would have acked only when the version/features
    * sent by this host did not match the remote */
-
-  ver = &xport_ctx->version_array[xport_ctx->version_indx];
-  ASSERT(ver);
+  ver = glink_get_current_version(xport_ctx);
 
   if (ver->version == version)
   {
     /* Call the transport's negotiation function */
     negotiated_features = ver->negotiate_features(if_ptr, ver, features);
 
-    if(negotiated_features != features)
+    if(negotiated_features == features)
+    {
+      glink_process_negotiation_complete( if_ptr, version, features );
+    }
+    else
     {
       /* Continue negotiating */
       if_ptr->tx_cmd_version(if_ptr, version, negotiated_features);
     }
-    else
-    {
-      glink_process_negotiation_complete( if_ptr, version, features );
-    }
   }
   else
   {
-    while (ver->version > version)
+    while (ver->version > version && xport_ctx->version_indx > 0)
     {
       /* Next time use older version */
-      ASSERT(xport_ctx->version_indx > 0);
       xport_ctx->version_indx--;
       ver = &xport_ctx->version_array[xport_ctx->version_indx];
     }
@@ -334,23 +385,22 @@
 
 /*===========================================================================
 FUNCTION      glink_rx_cmd_ch_remote_open
-
-DESCRIPTION   Receive remote channel open request; Calls
-              glink_transport_if:: tx_cmd_ch_remote_open_ack as a result
-
-ARGUMENTS   *if_ptr   Pointer to interface instance; must be unique
-                      for each edge
-
-            rcid     Remote Channel ID
-
-            *name    String name for logical channel
-
-            prio     xport priority requested by remote side
-
-RETURN VALUE  None.
-
-SIDE EFFECTS  None
 ===========================================================================*/
+/** 
+ * Receive remote channel open request; 
+ * Calls glink_transport_if:: tx_cmd_ch_remote_open_ack as a result
+ *
+ * @param[in]    if_ptr    Pointer to interface instance; must be unique
+                           for each edge
+ * @param[in]    rcid      Remote Channel ID
+ * @param[in]    name      String name for logical channel
+ * @param[in]    priority  xport priority requested by remote side
+ *
+ * @return       None
+ *
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
 void glink_rx_cmd_ch_remote_open
 (
   glink_transport_if_type *if_ptr,
@@ -361,22 +411,19 @@
 {
   glink_channel_ctx_type     *remote_ch_ctx  = NULL;
   glink_channel_ctx_type     *allocated_ch_ctx;
-
-  glink_xport_priority        negotiated_xport_priority;
-  glink_core_xport_ctx_type  *xport_ctx;
   glink_err_type              status;
 
-  ASSERT( if_ptr != NULL );
-  ASSERT( name != NULL );
-
-  xport_ctx = if_ptr->glink_core_priv;
-
+  GLINK_OS_UNREFERENCED_PARAM( priority );
+  
   /* Allocate and initialize channel info structure */
   remote_ch_ctx = glink_os_calloc( sizeof( glink_channel_ctx_type ) );
   if(remote_ch_ctx == NULL)
   {
-    GLINK_LOG_EVENT(GLINK_EVENT_RM_CH_OPEN, name, xport_ctx->xport,
-        xport_ctx->remote_ss, GLINK_STATUS_OUT_OF_RESOURCES);
+    GLINK_LOG_ERROR_EVENT( GLINK_EVENT_RM_CH_OPEN,
+                     name,
+                     if_ptr->glink_core_priv->xport,
+                     if_ptr->glink_core_priv->remote_ss,
+                     GLINK_STATUS_OUT_OF_RESOURCES );
     ASSERT(0);
   }
 
@@ -384,132 +431,39 @@
   glink_os_string_copy(remote_ch_ctx->name, name, sizeof(remote_ch_ctx->name));
   remote_ch_ctx->rcid = rcid;
 
-#ifndef FEATURE_CH_MIGRATION_FREE
-  glink_channel_ctx_type     *present_ch_ctx = NULL;
-  glink_transport_if_type    *negotiated_xport;
-  glink_channel_ctx_type     *dummy_ch_ctx;
+	status = glinki_add_ch_to_xport( if_ptr,
+																	 remote_ch_ctx,
+																	 &allocated_ch_ctx,
+																	 FALSE,
+																	 if_ptr->glink_priority );
 
-  /* search if channel with given name exists locally */
+  GLINK_LOG_EVENT( allocated_ch_ctx,
+                   GLINK_EVENT_RM_CH_OPEN,
+                     name,
+                   if_ptr->glink_core_priv->xport,
+                   if_ptr->glink_core_priv->remote_ss,
+                   status );
 
-  glink_os_cs_acquire( &xport_ctx->channel_q_cs );
-  present_ch_ctx = glinki_local_channel_exists( if_ptr, name );
-
-  if( !present_ch_ctx )
-  {
-    // channel doesn't exists yet and migration will not happen here
-    status = glinki_add_ch_to_xport( if_ptr,
-                                     if_ptr,
-                                     remote_ch_ctx,
-                                     &allocated_ch_ctx,
-                                     FALSE,
-                                     if_ptr->glink_priority );
-    ASSERT(status == GLINK_STATUS_SUCCESS);
-
-    GLINK_LOG_EVENT(GLINK_EVENT_RM_CH_OPEN, name, xport_ctx->xport,
-      xport_ctx->remote_ss, GLINK_STATUS_SUCCESS);
-
-    glink_os_cs_release( &xport_ctx->channel_q_cs );
-    return;
-  }
-
-  glink_os_cs_release( &xport_ctx->channel_q_cs );
-
-  present_ch_ctx->rcid = rcid;
-
-  if( present_ch_ctx->tag_ch_for_close )
-  {
-    // Migration already started.
-    GLINK_LOG_EVENT(GLINK_EVENT_CH_MIGRATION_IN_PROGRESS, name, xport_ctx->xport,
-      xport_ctx->remote_ss, GLINK_STATUS_SUCCESS);
-
-    return;
-  }
-
-  /* Negotiate the priority for migration if needed */
-  if( priority < present_ch_ctx->req_if_ptr->glink_priority )
-  {
-    negotiated_xport_priority = present_ch_ctx->req_if_ptr->glink_priority;
-  }
-  else
-  {
-    negotiated_xport_priority = priority;
-  }
-
-  negotiated_xport =  glinki_get_xport_from_prio( negotiated_xport_priority,
-                                                  xport_ctx->remote_ss );
-
-  if( if_ptr == negotiated_xport )
-  {
-    /* Current transport is best one. No need to migrate */
-
-    status = glinki_add_ch_to_xport( if_ptr,
-                                     if_ptr,
-                                     remote_ch_ctx,
-                                     &allocated_ch_ctx,
-                                     FALSE,
-                                     negotiated_xport_priority );
-
-    ASSERT(status == GLINK_STATUS_SUCCESS);
-    GLINK_LOG_EVENT( GLINK_EVENT_CH_NO_MIGRATION, name, xport_ctx->xport,
-      xport_ctx->remote_ss, GLINK_STATUS_SUCCESS);
-
-    return;
-  }
-
-  /* Need to migrate to new transport */
-  if_ptr->tx_cmd_ch_remote_open_ack( if_ptr,
-                                     rcid,
-                                     negotiated_xport_priority );
-
-  glink_create_dummy_ch_ctx( &dummy_ch_ctx, present_ch_ctx );
-  glink_close_dummy_ch_for_migration( if_ptr, dummy_ch_ctx );
-  glink_init_ch_migrate_candidate( present_ch_ctx );
-
-  status = glinki_add_ch_to_xport( negotiated_xport,
-                                   negotiated_xport,
-                                   present_ch_ctx,
-                                   &allocated_ch_ctx,
-                                   TRUE,
-                                   negotiated_xport_priority );
-
-  ASSERT( status == GLINK_STATUS_SUCCESS );
-
-  glink_os_free( remote_ch_ctx );
-
-#else
-  negotiated_xport_priority = if_ptr->glink_priority;
-
-  status = glinki_add_ch_to_xport( if_ptr,
-                                   NULL,
-                                   remote_ch_ctx,
-                                   &allocated_ch_ctx,
-                                   FALSE,
-                                   negotiated_xport_priority );
-
-  ASSERT(status == GLINK_STATUS_SUCCESS);
-#endif
-
-  GLINK_LOG_EVENT(GLINK_EVENT_RM_CH_OPEN, name, xport_ctx->xport,
-    xport_ctx->remote_ss, GLINK_STATUS_SUCCESS);
+  ASSERT(GLINK_STATUS_SUCCESS == status);
 }
 
 /*===========================================================================
 FUNCTION      glink_rx_cmd_ch_open_ack
-
-DESCRIPTION   This function is invoked by the transport in response to
-              glink_transport_if:: tx_cmd_ch_open
-
-ARGUMENTS   *if_ptr   Pointer to interface instance; must be unique
-                      for each edge
-
-            lcid     Local Channel ID
-
-            prio     Negotiated xport priority from remote side
-
-RETURN VALUE  None.
-
-SIDE EFFECTS  None
 ===========================================================================*/
+/** 
+ * This function is invoked by the transport
+ * in response to glink_transport_if:: tx_cmd_ch_open
+ *
+ * @param[in]    if_ptr            Pointer to interface instance; must be unique
+ *                                 for each edge
+ * @param[in]    lcid              Local Channel ID
+ * @param[in]    migrated_ch_prio  Negotiated xport priority from remote side
+ *
+ * @return       None
+ *
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
 void glink_rx_cmd_ch_open_ack
 (
   glink_transport_if_type *if_ptr,
@@ -519,312 +473,241 @@
 {
   glink_channel_ctx_type     *open_ch_ctx;
   glink_core_xport_ctx_type  *xport_ctx;
+  glink_remote_state_type    remote_state;
 
-  ASSERT(if_ptr != NULL);
-
+  GLINK_OS_UNREFERENCED_PARAM( migrated_ch_prio );
+  
   xport_ctx = if_ptr->glink_core_priv;
 
   /* Move to closed state. Implies we clean up the channel from the
    * open list */
   glink_os_cs_acquire(&xport_ctx->channel_q_cs);
-  /* Find channel in the open_list */
-  open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
-  while(open_ch_ctx != NULL)
-  {
-    if(open_ch_ctx->lcid == lcid)
-    {
-#ifndef FEATURE_CH_MIGRATION_FREE
-      glink_transport_if_type    *negotiated_xport = NULL;
-      negotiated_xport = glinki_get_xport_from_prio( migrated_ch_prio,
-                                                     xport_ctx->remote_ss );
+  
+  open_ch_ctx = glinki_find_ch_ctx_by_lcid(xport_ctx, lcid);
+  
+			if( open_ch_ctx->local_state == GLINK_LOCAL_CH_CLOSING )
+			{
+			/* Client called glink_close before gettng open ack. 
+			 * Ignore open ack and go for closing sequence */
+				glink_os_cs_release( &xport_ctx->channel_q_cs );
+				return;
+			}
 
-      if( negotiated_xport != if_ptr &&
-          !open_ch_ctx->tag_ch_for_close &&
-          ( open_ch_ctx->ch_open_options & GLINK_OPT_INITIAL_XPORT ) )
-      {
-        glink_channel_ctx_type *dummy_ch_ctx;
-        glink_err_type          status;
+  ASSERT(open_ch_ctx->local_state == GLINK_LOCAL_CH_OPENING);
+  
+			open_ch_ctx->local_state = GLINK_LOCAL_CH_OPENED;
 
-        glink_create_dummy_ch_ctx( &dummy_ch_ctx, open_ch_ctx );
-        glink_close_dummy_ch_for_migration( if_ptr, dummy_ch_ctx );
-
-        glink_init_ch_migrate_candidate( open_ch_ctx );
-        dummy_ch_ctx = NULL;
-
-        status = glinki_add_ch_to_xport( negotiated_xport,
-                                         negotiated_xport,
-                                         open_ch_ctx,
-                                         &dummy_ch_ctx,
-                                         TRUE,
-                                         negotiated_xport->glink_priority );
-
-        ASSERT( status == GLINK_STATUS_SUCCESS );
-      }
-      else
-      {
-        glink_os_cs_acquire( &open_ch_ctx->ch_state_cs );
-
-        if( open_ch_ctx->local_state == GLINK_LOCAL_CH_CLOSING )
-        {
-          /* Local client called glink_close
-           * before local channel is fully opened */
-          glink_os_cs_release( &open_ch_ctx->ch_state_cs );
-          glink_os_cs_release( &xport_ctx->channel_q_cs );
-          return;
-        }
-
-        open_ch_ctx->local_state = GLINK_LOCAL_CH_OPENED;
-
-        if( open_ch_ctx->remote_state == GLINK_REMOTE_CH_OPENED )
-        {
-          glink_os_cs_release( &open_ch_ctx->ch_state_cs );
-          open_ch_ctx->notify_state( open_ch_ctx,
-                                     open_ch_ctx->priv,
-                                     GLINK_CONNECTED );
-        }
-        else
-        {
-          glink_os_cs_release( &open_ch_ctx->ch_state_cs );
-        }
-      }
-
-#else
-      /* This is same code as above. once core capability code is done copy
-       * issue should be resolved */
-      glink_os_cs_acquire( &open_ch_ctx->ch_state_cs );
-      open_ch_ctx->local_state = GLINK_LOCAL_CH_OPENED;
-      if( open_ch_ctx->remote_state == GLINK_REMOTE_CH_OPENED )
-      {
-        /* remote channel is open on same xport as current xport.
-         * change channel state to GLINK_CH_STATE_OPEN and notify client */
-        glink_os_cs_release( &open_ch_ctx->ch_state_cs );
-        open_ch_ctx->notify_state( open_ch_ctx,
-                                   open_ch_ctx->priv,
-                                   GLINK_CONNECTED);
-      }
-#endif
-
-      GLINK_LOG_EVENT(GLINK_EVENT_CH_OPEN_ACK, open_ch_ctx->name,
-          xport_ctx->xport, xport_ctx->remote_ss, lcid);
-      glink_os_cs_release(&xport_ctx->channel_q_cs);
-      return;
-    }
-    open_ch_ctx = smem_list_next(open_ch_ctx);
-  }
+  remote_state = open_ch_ctx->remote_state;
   glink_os_cs_release(&xport_ctx->channel_q_cs);
-  /* We are here in case we could not find the channel in the open list. */
-  ASSERT(0);
+  
+  if (remote_state == GLINK_REMOTE_CH_OPENED)
+			{
+			/* remote channel is open on same xport as current xport.
+			 * change channel state to GLINK_CH_STATE_OPEN and notify client */
+				open_ch_ctx->notify_state( open_ch_ctx,
+																	 open_ch_ctx->priv,
+																	 GLINK_CONNECTED );
+			}
+
+  GLINK_LOG_EVENT( open_ch_ctx, 
+                   GLINK_EVENT_CH_OPEN_ACK, 
+                   open_ch_ctx->name, 
+                   xport_ctx->xport, 
+                   xport_ctx->remote_ss, 
+                   lcid );
 }
 
 /*===========================================================================
 FUNCTION      glink_rx_cmd_ch_close_ack
-
-DESCRIPTION   This function is invoked by the transport in response to
-              glink_transport_if_type:: tx_cmd_ch_close
-
-ARGUMENTS   *if_ptr   Pointer to interface instance; must be unique
-                      for each edge
-
-            lcid      Local Channel ID
-
-RETURN VALUE  None.
-
-SIDE EFFECTS  None
 ===========================================================================*/
+/** 
+ * This function is invoked by the transport in response to 
+ * glink_transport_if_type:: tx_cmd_ch_close
+ *
+ * @param[in]    if_ptr            Pointer to interface instance; must be unique
+ *                                 for each edge
+ * @param[in]    lcid              Local Channel ID
+ *
+ * @return       None
+ *
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
 void glink_rx_cmd_ch_close_ack
 (
-  glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
-  uint32                  lcid     /* Local channel ID */
+  glink_transport_if_type *if_ptr,
+  uint32                   lcid
 )
 {
   glink_channel_ctx_type *open_ch_ctx;
   glink_core_xport_ctx_type  *xport_ctx;
 
-  ASSERT(if_ptr != NULL);
-
   xport_ctx = if_ptr->glink_core_priv;
 
-  /* Move to closed state. Implies we clean up the channel from the
-   * open list */
-
-  /* Find channel in the open_list */
   glink_os_cs_acquire(&xport_ctx->channel_q_cs);
-  open_ch_ctx = smem_list_first(&xport_ctx->open_list);
-  while( open_ch_ctx )
-  {
-    if( open_ch_ctx->lcid == lcid )
-    {
-      /* Found channel */
-      glink_os_cs_acquire( &open_ch_ctx->ch_state_cs );
-
-
-      GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE_ACK, open_ch_ctx->name,
-          xport_ctx->xport, xport_ctx->remote_ss, lcid);
+  
+  open_ch_ctx = glinki_find_ch_ctx_by_lcid(xport_ctx, lcid);
+  
+  GLINK_LOG_EVENT( open_ch_ctx, 
+                   GLINK_EVENT_CH_CLOSE_ACK, 
+                   open_ch_ctx->name,
+                   xport_ctx->xport, 
+                   xport_ctx->remote_ss, 
+                   lcid);
 
       ASSERT( open_ch_ctx->local_state == GLINK_LOCAL_CH_CLOSING );
 
       open_ch_ctx->local_state = GLINK_LOCAL_CH_CLOSED;
+  open_ch_ctx->lcid        = GLINK_INVALID_CID;
 
-      if( open_ch_ctx->remote_state == GLINK_REMOTE_CH_CLOSED ||
-          open_ch_ctx->remote_state == GLINK_REMOTE_CH_SSR_RESET )
+  if ( glink_is_remote_ch_closed( open_ch_ctx->remote_state ) )
       {
         glink_clean_channel_ctx( xport_ctx, open_ch_ctx );
       }
 
-      glink_os_cs_release(&open_ch_ctx->ch_state_cs);
       glink_os_cs_release(&xport_ctx->channel_q_cs);
 
       open_ch_ctx->notify_state( open_ch_ctx,
                                  open_ch_ctx->priv,
                                  GLINK_LOCAL_DISCONNECTED );
 
-      if( open_ch_ctx->remote_state == GLINK_REMOTE_CH_CLOSED ||
-          open_ch_ctx->remote_state == GLINK_REMOTE_CH_SSR_RESET )
+  if ( glink_is_remote_ch_closed( open_ch_ctx->remote_state ) )
       {
         glink_os_free( open_ch_ctx );
       }
-
-      return;
-    }
-    open_ch_ctx = smem_list_next(open_ch_ctx);
-  }/* end while */
-
-  glink_os_cs_release(&xport_ctx->channel_q_cs);
-  /* We are here in case we could not find the channel in the open list. */
-  ASSERT(0);
 }
 
 /*===========================================================================
 FUNCTION      glink_rx_cmd_ch_remote_close
-
-DESCRIPTION   Remote channel close request; will result in sending
-              glink_transport_if_type:: tx_cmd_ch_remote_close_ack
-
-ARGUMENTS   *if_ptr   Pointer to interface instance; must be unique
-                      for each edge
-
-            rcid      Remote Channel ID
-
-RETURN VALUE  None.
-
-SIDE EFFECTS  None
 ===========================================================================*/
+/** 
+ * Remote channel close request; will result in sending 
+ * glink_transport_if_type:: tx_cmd_ch_remote_close_ack
+ *
+ * @param[in]    if_ptr            Pointer to interface instance; must be unique
+ *                                 for each edge
+ * @param[in]    rcid              Remote Channel ID
+ *
+ * @return       None.
+ *
+ * @sideeffects  None.
+ */
+/*=========================================================================*/
 void glink_rx_cmd_ch_remote_close
 (
-  glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
-  uint32                  rcid     /* Remote channel ID */
+  glink_transport_if_type *if_ptr,
+  uint32                   rcid
 )
 {
   glink_channel_ctx_type *open_ch_ctx;
   glink_core_xport_ctx_type  *xport_ctx;
-
-  ASSERT(if_ptr != NULL);
+  glink_remote_state_type    remote_state;
 
   xport_ctx = if_ptr->glink_core_priv;
 
-  /* Find channel in the open_list */
   glink_os_cs_acquire( &xport_ctx->channel_q_cs );
 
-  open_ch_ctx = smem_list_first( &if_ptr->glink_core_priv->open_list );
-  while(open_ch_ctx != NULL)
-  {
-    if( open_ch_ctx->rcid == rcid )
-    {
-      GLINK_LOG_EVENT( GLINK_EVENT_CH_REMOTE_CLOSE, open_ch_ctx->name,
-                       xport_ctx->xport, xport_ctx->remote_ss, rcid);
-      /* Found channel, transition to appropriate state based on current state
-       * grab lock to perform channel state related operations */
-      glink_os_cs_acquire(&open_ch_ctx->ch_state_cs);
+  open_ch_ctx = glinki_find_ch_ctx_by_rcid(xport_ctx, rcid);
 
+  GLINK_LOG_EVENT( open_ch_ctx, 
+                   GLINK_EVENT_CH_REMOTE_CLOSE, 
+                   open_ch_ctx->name, 
+                   xport_ctx->xport, 
+                   xport_ctx->remote_ss, 
+                   rcid );
+
+  /* It is possible that the remote subsystem sending close might crash 
+     before we handle the close request from it */
+  if (open_ch_ctx->remote_state == GLINK_REMOTE_CH_SSR_RESET)
+  {
+    glink_os_cs_release(&xport_ctx->channel_q_cs);
+    return;
+  }
+                   
       ASSERT( open_ch_ctx->remote_state == GLINK_REMOTE_CH_OPENED );
 
       open_ch_ctx->remote_state = GLINK_REMOTE_CH_CLOSED;
+  open_ch_ctx->rcid         = GLINK_INVALID_CID;
 
-      if( open_ch_ctx->local_state == GLINK_LOCAL_CH_CLOSED )
+  if ( glink_is_local_ch_closed( open_ch_ctx->local_state ) )
       {
         /* Local side never opened the channel OR it opened it but closed it */
         /* Free channel resources */
         glink_clean_channel_ctx( xport_ctx, open_ch_ctx );
       }
 
-      glink_os_cs_release(&open_ch_ctx->ch_state_cs);
+      remote_state = open_ch_ctx->remote_state;
+
       glink_os_cs_release(&xport_ctx->channel_q_cs);
 
       /* Send the remote close ACK back to the other side */
-      if_ptr->tx_cmd_ch_remote_close_ack(if_ptr, open_ch_ctx->rcid);
+  if_ptr->tx_cmd_ch_remote_close_ack(if_ptr, rcid);
 
-      if( open_ch_ctx->local_state == GLINK_LOCAL_CH_CLOSED )
+  if ( glink_is_local_ch_closed( open_ch_ctx->local_state ) )
       {
+    /* Destroy channel context only if there isn't any pending intents */
+        if (remote_state != GLINK_REMOTE_CH_CLEANUP)
+        {
         glink_os_free(open_ch_ctx);
       }
+      }
       else
       {
         /* Inform the client */
-        open_ch_ctx->notify_state( open_ch_ctx, open_ch_ctx->priv,
+    open_ch_ctx->notify_state(open_ch_ctx,
+                              open_ch_ctx->priv,
                                    GLINK_REMOTE_DISCONNECTED);
       }
-
-      return;
-    }
-    open_ch_ctx = smem_list_next(open_ch_ctx);
-  }/* end while */
-
-  glink_os_cs_release( &xport_ctx->channel_q_cs );
-  ASSERT(0);
 }
 
 /*===========================================================================
 FUNCTION      glink_rx_put_pkt_ctx
-
-DESCRIPTION   Transport invokes this call to receive a packet fragment (must
-              have previously received an rx_cmd_rx_data packet)
-
-ARGUMENTS   *if_ptr      Pointer to interface instance; must be unique
-                         for each edge
-
-            rcid         Remote Channel ID
-
-            *intent_ptr  Pointer to the intent fragment
-
-            complete     True if pkt is complete
-
-RETURN VALUE  None
-
-SIDE EFFECTS  None
 ===========================================================================*/
+/** 
+ * Transport invokes this call to receive a packet fragment (must 
+ * have previously received an rx_cmd_rx_data packet)
+ *
+ * @param[in]    if_ptr       Pointer to interface instance; must be unique
+ *                            for each edge
+ * @param[in]    rcid         Remote Channel ID
+ * @param[in]    intent_ptr   Pointer to the intent fragment
+ * @param[in]    complete     True if pkt is complete
+ *
+ * @return       None.
+ *
+ * @sideeffects  None.
+ */
+/*=========================================================================*/
 void glink_rx_put_pkt_ctx
 (
-  glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
-  uint32                  rcid,    /* Remote channel ID */
-  glink_rx_intent_type    *intent_ptr, /* Fragment ptr */
-  boolean                 complete     /* True if pkt is complete */
+  glink_transport_if_type *if_ptr,
+  uint32                   rcid,
+  glink_rx_intent_type    *intent_ptr,
+  boolean                  complete
 )
 {
   glink_channel_ctx_type *open_ch_ctx;
   glink_core_xport_ctx_type  *xport_ctx;
 
-  ASSERT(if_ptr != NULL && intent_ptr != NULL);
+  GLINK_OS_UNREFERENCED_PARAM( complete );
+  
+  ASSERT(intent_ptr);
 
   xport_ctx = if_ptr->glink_core_priv;
 
   /* Find channel in the open_list */
-  open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
-  while(open_ch_ctx != NULL)
-  {
-    if(open_ch_ctx->rcid == rcid) {
-      /* Found channel */
-      GLINK_LOG_EVENT(GLINK_EVENT_CH_PUT_PKT_CTX, open_ch_ctx->name,
-          xport_ctx->xport, xport_ctx->remote_ss, intent_ptr->iid);
+  glink_os_cs_acquire(&xport_ctx->channel_q_cs);
+  open_ch_ctx = glinki_find_ch_ctx_by_rcid(xport_ctx, rcid);
+  glink_os_cs_release(&xport_ctx->channel_q_cs);
+  
+  GLINK_LOG_EVENT( open_ch_ctx,
+                   GLINK_EVENT_CH_PUT_PKT_CTX, 
+                   open_ch_ctx->name,
+                   xport_ctx->xport, 
+                   xport_ctx->remote_ss, 
+                   intent_ptr->iid);
 
       xport_ctx->channel_receive_pkt(open_ch_ctx, intent_ptr);
-
-      return;
-    }
-    open_ch_ctx = smem_list_next(open_ch_ctx);
-  }/* end while */
-
-  /* We end up here if we don't find the channel */
-  ASSERT(0);
 }
 
 /*===========================================================================
@@ -851,59 +734,27 @@
   uint32                  remote_sigs /* Remote control signals */
 )
 {
+  glink_core_xport_ctx_type *xport_ctx;
   glink_channel_ctx_type *open_ch_ctx;
   uint32 prev_sigs;
 
-  ASSERT(if_ptr != NULL);
-
-  /* Find channel in the open_list */
-  open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
-  while(open_ch_ctx != NULL)
-  {
-    if(open_ch_ctx->rcid == rcid ) {
-      glink_os_cs_acquire( &open_ch_ctx->ch_state_cs );
-      if( open_ch_ctx->local_state != GLINK_LOCAL_CH_OPENED &&
-          open_ch_ctx->remote_state != GLINK_REMOTE_CH_OPENED )
+  xport_ctx = if_ptr->glink_core_priv;
+      
+  glink_os_cs_acquire(&xport_ctx->channel_q_cs);
+  open_ch_ctx = glinki_find_ch_ctx_by_rcid(xport_ctx, rcid);
+  glink_os_cs_release( &xport_ctx->channel_q_cs );
+      
+  if (!glinki_channel_fully_opened(open_ch_ctx))
       {
-        glink_os_cs_release( &open_ch_ctx->ch_state_cs );
         ASSERT(0);
-        return;
       }
-      glink_os_cs_release( &open_ch_ctx->ch_state_cs );
+  
       /* Found channel, let client know of new remote signal state */
       prev_sigs = open_ch_ctx->remote_sigs;
       open_ch_ctx->remote_sigs = remote_sigs;
-      open_ch_ctx->notify_rx_sigs(open_ch_ctx, open_ch_ctx->priv,
-                                  prev_sigs, remote_sigs);
-      return;
-    }
-    open_ch_ctx = smem_list_next(open_ch_ctx);
+  open_ch_ctx->notify_rx_sigs(open_ch_ctx,
+                              open_ch_ctx->priv,
+                              prev_sigs,
+                              remote_sigs);
   }
 
-  /* We end up here if we don't find the channel */
-  ASSERT(0);
-}
-
-
-/*===========================================================================
-FUNCTION      glink_set_core_version
-
-DESCRIPTION   Sets the core version used by the transport; called after
-              completing negotiation.
-
-ARGUMENTS   *if_ptr    Pointer to interface instance; must be unique
-                       for each edge
-
-             version   Negotiated transport version
-
-RETURN VALUE  None.
-
-SIDE EFFECTS  None
-===========================================================================*/
-void glink_set_core_version
-(
-  glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
-  uint32                  version  /* Version */
-)
-{
-}
diff --git a/platform/msm_shared/glink/glink_core_intentless_xport.c b/platform/msm_shared/glink/glink_core_intentless_xport.c
index 98ced24..2feba42 100644
--- a/platform/msm_shared/glink/glink_core_intentless_xport.c
+++ b/platform/msm_shared/glink/glink_core_intentless_xport.c
@@ -42,9 +42,6 @@
   glink_rx_cmd_version,
   /** Receive ACK to previous glink_transport_if_type::tx_cmd_version command */
   glink_rx_cmd_version_ack,
-  /** Sets the core version used by the transport; called after completing
-   *  negotiation.*/
-  glink_set_core_version,
   /** Receive remote channel open request; expected response is
    *  glink_transport_if_type:: tx_cmd_ch_remote_open_ack */
   glink_rx_cmd_ch_remote_open,
@@ -178,6 +175,7 @@
   glink_transport_if_type *if_ptr = open_ch_ctx->if_ptr;
   glink_err_type status = if_ptr->tx(if_ptr, open_ch_ctx->lcid, pctx);
 
+  GLINK_OS_UNREFERENCED_PARAM( req_intent );
   glink_os_free(pctx);
 
   return status;
diff --git a/platform/msm_shared/glink/glink_core_internal.c b/platform/msm_shared/glink/glink_core_internal.c
new file mode 100644
index 0000000..ddc69c2
--- /dev/null
+++ b/platform/msm_shared/glink/glink_core_internal.c
@@ -0,0 +1,1616 @@
+/* Copyright (c) 2015, 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.
+*/
+
+
+/*===========================================================================
+                        INCLUDE FILES
+===========================================================================*/
+#include <glink_internal.h>
+
+#ifdef FEATURE_TRACER_PACKET
+#include "glink_tracer.h"
+#endif
+/*===========================================================================
+  MACRO DEFINITION
+===========================================================================*/
+/*===========================================================================
+  GLOBAL DATA DECLARATIONS
+===========================================================================*/
+static os_cs_type glink_transport_q_cs[GLINK_NUM_HOSTS];
+
+#if defined(GLINK_OS_DEFINED_LOGGING) || defined(GLINK_MEMORY_LOGGING)
+/* glink_log_filter_status indicates if channel filtering is enabled or not */
+glink_logging_filter_cfg_type log_filter_cfg = { 
+    FALSE,      /* Filter Disabled */
+    "",         /* Filter channel name */
+    0x0,        /* Filter lcid - will be updated dynamically */
+    0x0,        /* Filter rcid - will be updated dynamically */
+    0xFFFFFFFF, /* remote host ID */
+    0x0,        /* Channel Context */
+    0xFFFFFFFF, /* All xports are enabled */
+   };
+#endif
+
+/* Keep a list of registered transport for each edge allowed for this host 
+ * ***IMPORTANT*** 
+ * it should be safe to traverse this list without taking locks */
+static smem_list_type glink_registered_transports[GLINK_NUM_HOSTS];
+
+/* List of supported hosts */
+const char* glink_hosts_supported[] = { "apss",
+                                        "mpss",
+                                        "lpass",
+                                        "dsps",
+                                        "wcnss",
+                                        "tz",
+                                        "rpm",
+                                      };
+
+#if defined(GLINK_MEMORY_LOGGING)
+static glink_mem_log_entry_type glink_mem_log_arr[GLINK_MEM_LOG_SIZE];
+static uint32 glink_mem_log_idx = 0;
+static os_cs_type glink_mem_log_cs;
+#endif
+
+static smem_list_type  glink_link_notif_list;
+static os_cs_type      glink_link_notif_list_cs;
+
+/*===========================================================================
+  GLOBAL FUNCTION DECLARATION
+===========================================================================*/
+/*===========================================================================
+  LOCAL FUNCTION DEFINITIONS
+===========================================================================*/
+/*===========================================================================
+  FUNCTION      glinki_scan_channels_and_notify_discon
+===========================================================================*/
+/** 
+ * Close all the channels belong to this transport
+ * This is helper function for glink_ssr
+ *
+ * @param[in]    if_ptr  pointer to transport interface
+ *
+ * @return       None.
+ *
+ * @sideeffects  None.
+ */
+/*=========================================================================*/
+static void glinki_scan_channels_and_notify_discon
+(
+  glink_transport_if_type *if_ptr
+)
+{
+  glink_channel_ctx_type     *open_ch_ctx, *dummy_open_ch_ctx;
+  glink_core_xport_ctx_type  *xport_ctx;
+  glink_remote_state_type     remote_state;
+  
+  xport_ctx = if_ptr->glink_core_priv;
+
+  /* Find channel in the open_list */
+  glink_os_cs_acquire(&xport_ctx->channel_q_cs);
+  open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
+  glink_os_cs_release(&xport_ctx->channel_q_cs);
+  
+  while(open_ch_ctx)
+  {
+    glink_os_cs_acquire(&xport_ctx->channel_q_cs);
+    open_ch_ctx->remote_state = GLINK_REMOTE_CH_SSR_RESET;
+    
+    dummy_open_ch_ctx = smem_list_next(open_ch_ctx);
+    
+    switch (open_ch_ctx->local_state)
+    {
+      case GLINK_LOCAL_CH_OPENED:
+      case GLINK_LOCAL_CH_OPENING:
+        glink_os_cs_release(&xport_ctx->channel_q_cs);
+        /* local channel has called open at the moment. */
+        open_ch_ctx->notify_state(open_ch_ctx, 
+                                  open_ch_ctx->priv, 
+                                  GLINK_REMOTE_DISCONNECTED);
+        break;
+        
+      case GLINK_LOCAL_CH_CLOSING:
+        /* Case when local client already closed channel 
+         * but has not received ack yet */
+        if_ptr->glink_core_if_ptr->rx_cmd_ch_close_ack(if_ptr, 
+                                                       open_ch_ctx->lcid);
+       glink_os_cs_release(&xport_ctx->channel_q_cs);
+        break;
+        
+      case GLINK_LOCAL_CH_CLOSED:  /* Channel fully closed - local, remote */
+      case GLINK_LOCAL_CH_INIT:    /* We had only remote open and waiting for local open */
+        xport_ctx->channel_cleanup(open_ch_ctx);
+        smem_list_delete(&if_ptr->glink_core_priv->open_list, open_ch_ctx);
+        remote_state = open_ch_ctx->remote_state;
+
+        if (remote_state != GLINK_REMOTE_CH_CLEANUP)
+        {
+          glink_os_free(open_ch_ctx);
+        }
+        glink_os_cs_release(&xport_ctx->channel_q_cs);
+        break;
+        
+      default:
+        glink_os_cs_release(&xport_ctx->channel_q_cs);
+        /* invalid local channel state */
+        ASSERT(0);
+    }
+    
+    open_ch_ctx = dummy_open_ch_ctx;
+  } /* end while */
+}
+
+/*===========================================================================
+  FUNCTION      glinki_xport_priority_comp
+===========================================================================*/
+/** 
+ * Helper function for glinki_get_xport_from_prio. This will be provided to
+ * glinki_xports_find function.
+ * Return true if given transport has same priority
+ *
+ * @param[in]    if_ptr     transport interface pointer
+ * @param[in]    cond1      unused
+ * @param[in]    priority   glink transport priority to find
+ *
+ * @return       TRUE   if if_ptr priority matches
+ *               FALSE  otherwise
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+static boolean glinki_xport_priority_comp
+(
+  glink_transport_if_type *if_ptr,
+  void                    *cond1,
+  uint32                   priority,
+  void                   **out
+)
+{
+  GLINK_OS_UNREFERENCED_PARAM( cond1 );
+  GLINK_OS_UNREFERENCED_PARAM( out );
+
+  return if_ptr->glink_priority == (glink_xport_priority)priority;
+}
+
+/*===========================================================================
+  FUNCTION      glinki_client_requested_xport_check
+===========================================================================*/
+/**
+ * check whether this is client requested xport or not
+ *
+ * @param[in]    if_ptr     transport interface pointer
+ * @param[in]    xport_name transport name to find
+ * @param[in]    cond2      unused
+ * @param[in]    out        unused
+ * 
+ * @return       TRUE   if transport name
+ *               FALSE  otherwise
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+static boolean glinki_client_requested_xport_check
+(
+  glink_transport_if_type *if_ptr,
+  void                    *xport_name,
+  uint32                   cond2,
+  void                   **out
+)
+{
+  GLINK_OS_UNREFERENCED_PARAM( cond2 );
+  GLINK_OS_UNREFERENCED_PARAM( out );
+  
+  if (!glinki_xport_linkup(if_ptr))
+  {
+    return FALSE;
+  }
+  
+  return 0 == glink_os_string_compare(if_ptr->glink_core_priv->xport,
+                                      (const char *)xport_name);
+}
+
+/*===========================================================================
+  FUNCTION      glinki_update_best_xport
+===========================================================================*/
+/** 
+ * Check whether given transport (if_ptr) has higher priority than
+ * priority user wants to check and update if it is true.
+ *
+ * @param[in]    if_ptr          transport interface pointer
+ * @param[in]    priority_param  xport priority to compare
+ * @param[in]    param2          unused
+ * @param[out]   best_xport      pointer to result xport
+ * 
+ * @return       FALSE  all the time since this needs to iterate all transports
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+static void glinki_update_best_xport
+(
+  glink_transport_if_type  *if_ptr,
+  void                     *priority_param,
+  uint32                    param2,
+  void                    **best_xport
+)
+{
+  glink_xport_priority *priority;
+  
+  GLINK_OS_UNREFERENCED_PARAM( param2 );
+
+  ASSERT(best_xport && priority_param);
+  
+  priority = (glink_xport_priority*)priority_param;
+  
+  if (!glinki_xport_linkup(if_ptr))
+  {
+    return;
+  }
+  
+  /* Given xport is best one if comparing xport doesn't exist */ 
+  if (if_ptr->glink_priority < *priority)
+  {
+    *best_xport = (void*)if_ptr;
+    *priority = if_ptr->glink_priority;
+  }
+}
+
+/*===========================================================================
+  FUNCTION      glinki_notify_xport_ssr
+===========================================================================*/
+/** 
+ * Notify this xport of ssr event and do ssr clean up
+ *
+ * @param[in]    if_ptr         transport interface pointer
+ * @param[in]    priority       priority to check
+ * @param[in]    cond2          unused
+ * @param[out]   updated_xport  pointer to result xport
+ * 
+ * @return       FALSE  all the time since this needs to iterate all transports
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+static void glinki_notify_xport_ssr
+(
+  glink_transport_if_type  *if_ptr,
+  void                     *param1,
+  uint32                    param2,
+  void                    **out
+)
+{
+  GLINK_OS_UNREFERENCED_PARAM( param1 );
+  GLINK_OS_UNREFERENCED_PARAM( param2 );
+  GLINK_OS_UNREFERENCED_PARAM( out );
+  /* xport is down. change the xport state */
+  glink_os_cs_acquire(&if_ptr->glink_core_priv->status_cs);
+  if_ptr->glink_core_priv->status = GLINK_XPORT_REGISTERED;
+  
+  /* Let the xport know about ssr */
+  if_ptr->ssr( if_ptr );
+  
+  /* Invoke LINK_DOWN notification for any registered notifiers */
+  glinki_scan_notif_list_and_notify(if_ptr, GLINK_LINK_STATE_DOWN);
+  
+  /* Invoke REMOTE_DISCONNECT for all channels associated with if_ptr */
+  glinki_scan_channels_and_notify_discon(if_ptr);
+  
+  glink_os_cs_release(&if_ptr->glink_core_priv->status_cs);
+}
+
+/*===========================================================================
+  FUNCTION      glinki_check_xport_and_notify
+===========================================================================*/
+/** 
+ * Notify this xport for link state change if applicable
+ *
+ * @param[in]  if_ptr                 transport interface pointer
+ * @param[in]  link_notif_data_param  parameter for link notif data
+ * @param[in]  state                  link state to notify
+ * @param[out] out                    unused
+ * 
+ * @return       NONE
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+static void glinki_check_xport_and_notify
+(
+  glink_transport_if_type  *if_ptr,
+  void                     *link_notif_data_param,
+  uint32                    state,
+  void                    **out
+)
+{
+  glink_core_xport_ctx_type  *xport_ctx;
+  glink_link_notif_data_type *link_notif_data;
+  glink_link_info_type        link_info;
+  
+  GLINK_OS_UNREFERENCED_PARAM( out );
+  
+  ASSERT(link_notif_data_param && if_ptr->glink_core_priv);
+  
+  link_notif_data = (glink_link_notif_data_type *)link_notif_data_param;
+  xport_ctx = if_ptr->glink_core_priv;
+  
+  if (link_notif_data->xport == NULL ||
+      0 == glink_os_string_compare(xport_ctx->xport, link_notif_data->xport))
+  {
+    /* xport not specified, or it is specified and matches the current xport */
+    /* Invoke registered callback */
+    link_info.xport = xport_ctx->xport;
+    link_info.remote_ss = xport_ctx->remote_ss;
+    link_info.link_state = (glink_link_state_type)state;
+    
+    link_notif_data->link_notifier(&link_info, link_notif_data->priv);
+  }
+}
+
+/*===========================================================================
+  FUNCTION      glinki_check_xport_link_up_and_notify
+===========================================================================*/
+/** 
+ * Notify this xport for link state change if applicable
+ *
+ * @param[in]  if_ptr                 transport interface pointer
+ * @param[in]  link_notif_data_param  parameter for link notif data
+ * @param[in]  state                  link state to notify
+ * @param[out] out                    unused. but just passed as parameter
+ * 
+ * @return       NONE
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+static void glinki_check_xport_link_up_and_notify
+(
+  glink_transport_if_type  *if_ptr,
+  void                     *link_notif_data_param,
+  uint32                    state,
+  void                    **out
+)
+{
+  if (!glinki_xport_linkup(if_ptr))
+  {
+    return;
+  }
+  
+  glinki_check_xport_and_notify(if_ptr, link_notif_data_param, state, out);
+}
+
+/*===========================================================================
+  EXTERNAL FUNCTION DEFINITIONS
+===========================================================================*/
+/*===========================================================================
+FUNCTION      glink_init
+
+DESCRIPTION   Initializes the GLink core library.
+
+ARGUMENTS     None
+
+RETURN VALUE  None
+
+SIDE EFFECTS  None
+===========================================================================*/
+void glink_init(void)
+{
+  uint32 i;
+  boolean cs_created = FALSE;
+
+#if defined(GLINK_MEMORY_LOGGING)
+  cs_created = glink_os_cs_init(&glink_mem_log_cs);
+  ASSERT(cs_created);
+#elif defined(GLINK_OS_DEFINED_LOGGING)
+  OS_LOG_INIT();
+#endif
+  
+  smem_list_init(&glink_link_notif_list);
+  cs_created = glink_os_cs_init(&glink_link_notif_list_cs);
+  ASSERT(cs_created);
+  
+  /* Create/Initalize crtitical sections */
+  for (i = 0; i < GLINK_NUM_HOSTS; ++i)
+  {
+    cs_created = glink_os_cs_init(&glink_transport_q_cs[i]);
+    ASSERT(cs_created);
+    smem_list_init(&glink_registered_transports[i]);
+  }
+}
+
+/*===========================================================================
+  FUNCTION      glinki_add_ch_to_xport
+===========================================================================*/
+/** 
+ * Add remote/local channel context to xport open channel queue
+ *
+ * @param[in]    if_ptr            Pointer to xport if on which channel is to
+ *                                 be opened
+ * @param[in]    req_if_ptr        Pointer to xport if on which channel 
+ *                                 actually wants to open
+ * @param[in]    ch_ctx            channel context
+ * @param[out]   allocated_ch_ctx  Pointer to channel context pointer
+ * @param[in]    local_open        flag to determine if channel is opened 
+ *                                 locally or remotely
+ * @param[in]    migrated_ch_prio  negotiated xport priority
+ *                                 (used to send priority via remote_open_ack to 
+ *                                  remote side)
+ *
+ * @return       G-Link standard error type
+ *
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+glink_err_type glinki_add_ch_to_xport
+(
+  glink_transport_if_type  *if_ptr,
+  glink_channel_ctx_type   *ch_ctx,
+  glink_channel_ctx_type  **allocated_ch_ctx,
+  unsigned int              local_open,
+  glink_xport_priority      migrated_ch_prio
+)
+{
+  glink_err_type              status;
+  glink_channel_ctx_type     *open_ch_ctx;
+  glink_core_xport_ctx_type  *xport_ctx;
+  boolean                     valid_open_call;
+
+  if ( if_ptr == NULL          ||
+       ch_ctx->name[0] == '\0' ||
+       allocated_ch_ctx == NULL )
+  {
+    return GLINK_STATUS_INVALID_PARAM;
+  }
+  
+  xport_ctx = if_ptr->glink_core_priv;
+  
+  /* See if channel already exists in open_list */
+  glink_os_cs_acquire(&xport_ctx->channel_q_cs);
+  
+  open_ch_ctx = glinki_find_ch_ctx_by_name(xport_ctx,
+                                           ch_ctx->name,
+                                           (boolean)local_open,
+                                           &valid_open_call);
+  
+  if ( !valid_open_call )
+  {
+    glink_os_free(ch_ctx);
+    glink_os_cs_release(&xport_ctx->channel_q_cs);
+    return GLINK_STATUS_FAILURE;
+  }
+  
+  if (!open_ch_ctx)
+  {
+    /* check if a new channel can be added */
+    if ((uint32)smem_list_count(&xport_ctx->open_list) >= xport_ctx->max_lcid)
+    {
+      glink_os_cs_release(&xport_ctx->channel_q_cs);
+      glink_os_free(ch_ctx);
+      return GLINK_STATUS_OUT_OF_RESOURCES;
+    }
+    
+    /* Channel not in the list - it was not previously opened */
+    ch_ctx->if_ptr = if_ptr;
+    *allocated_ch_ctx = ch_ctx;
+
+    /* Set channel state */
+    if (local_open)
+    {
+      /* This is a local open */
+      ch_ctx->local_state = GLINK_LOCAL_CH_OPENING;
+    }
+    else
+    {
+      ch_ctx->remote_state = GLINK_REMOTE_CH_OPENED;
+    }
+
+    glink_os_cs_init(&ch_ctx->tx_cs);
+    glink_os_cs_init(&ch_ctx->qos_cs);
+
+    /* make sure next LCID is not used in currently open channels */
+    open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
+
+    while (open_ch_ctx)
+    {
+      if (open_ch_ctx->lcid == xport_ctx->free_lcid)
+      {
+        xport_ctx->free_lcid++;
+        
+        if (xport_ctx->free_lcid >= xport_ctx->max_lcid)
+        {
+          xport_ctx->free_lcid = 1;
+        }
+
+        open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
+        continue;
+      }
+
+      open_ch_ctx = smem_list_next(open_ch_ctx);
+    }
+
+    ch_ctx->lcid = xport_ctx->free_lcid;
+
+    /* Append the channel to the transport interface's open_list */
+    smem_list_append(&if_ptr->glink_core_priv->open_list, ch_ctx);
+
+    /* release lock before context switch otherwise it is causing deadlock */
+    glink_os_cs_release(&xport_ctx->channel_q_cs);
+    
+    /* Send the OPEN command to transport */
+    if (local_open)
+    {
+      status = if_ptr->tx_cmd_ch_open(if_ptr, ch_ctx->lcid,
+                                      ch_ctx->name,
+                                      migrated_ch_prio);
+    }
+    else
+    {
+      /* initialize channel resources */
+      status = xport_ctx->channel_init(ch_ctx);
+
+      if_ptr->tx_cmd_ch_remote_open_ack(if_ptr, ch_ctx->rcid, migrated_ch_prio);
+    }
+
+    if (status != GLINK_STATUS_SUCCESS)
+    {
+      /* Remove the channel from the transport interface's open_list */
+      xport_ctx->free_lcid--;
+      glinki_dequeue_item(&if_ptr->glink_core_priv->open_list,
+                          ch_ctx,
+                          &xport_ctx->channel_q_cs);
+      
+      /* free the ch_ctx structure and return */
+      xport_ctx->channel_cleanup(ch_ctx);
+      glink_os_free(ch_ctx);
+    }
+    else
+    {
+      //Update the Filter
+      glinki_update_logging_filter(*allocated_ch_ctx, FALSE);
+    }
+
+    return status;
+  }
+  
+  if (local_open)
+  {
+    /* LOCAL OPEN REQUEST */
+    
+    ch_ctx->rcid     = open_ch_ctx->rcid;
+    ch_ctx->lcid     = open_ch_ctx->lcid;
+    ch_ctx->pintents = open_ch_ctx->pintents;
+    ch_ctx->if_ptr   = open_ch_ctx->if_ptr;
+
+    if (ch_ctx->pintents != NULL)
+    {
+      ch_ctx->pintents->ch_ctx = ch_ctx;
+    }
+
+    ch_ctx->remote_state = open_ch_ctx->remote_state;
+    ch_ctx->local_state  = GLINK_LOCAL_CH_OPENING;
+    
+    /* release lock before context switch otherwise it is causing
+     * deadlock */
+    smem_list_delete(&xport_ctx->open_list, open_ch_ctx);
+    smem_list_append(&xport_ctx->open_list, ch_ctx);
+
+    glink_os_cs_release(&xport_ctx->channel_q_cs);
+
+    glink_os_free(open_ch_ctx);
+    *allocated_ch_ctx = ch_ctx;
+    
+    /* Send open cmd to transport */
+    status = if_ptr->tx_cmd_ch_open(if_ptr, 
+                                    ch_ctx->lcid,
+                                    ch_ctx->name,
+                                    migrated_ch_prio);
+  }
+  else
+  { 
+    /* REMOTE OPEN REQUEST */
+    open_ch_ctx->rcid = ch_ctx->rcid;
+    *allocated_ch_ctx = open_ch_ctx;
+    status = xport_ctx->channel_init(open_ch_ctx);
+
+    if (status == GLINK_STATUS_SUCCESS)
+    {
+      open_ch_ctx->remote_state = GLINK_REMOTE_CH_OPENED;
+    }
+    
+    /* release lock before context switch otherwise it is causing deadlock */
+    glink_os_cs_release(&xport_ctx->channel_q_cs);
+    
+    /* Send ACK to transport */
+    if_ptr->tx_cmd_ch_remote_open_ack(if_ptr,
+                                      open_ch_ctx->rcid,
+                                      migrated_ch_prio);
+    
+    if (status == GLINK_STATUS_SUCCESS)
+    {
+      /* Inform the client */
+      if (open_ch_ctx->local_state == GLINK_LOCAL_CH_OPENED)
+      {
+        open_ch_ctx->notify_state(open_ch_ctx, 
+                                  open_ch_ctx->priv, 
+                                  GLINK_CONNECTED);
+      }
+    }
+
+    glink_os_free(ch_ctx);
+  } /* end If - else (local_open) */
+  
+  /* If the channel was added to be closed later by channel migration
+     do not update the filter */
+  if ( status == GLINK_STATUS_SUCCESS )
+  {
+    //Update the Filter - Reset Boolean=FALSE
+    glinki_update_logging_filter( *allocated_ch_ctx, FALSE );
+  }
+  
+  return status;
+}
+
+/*===========================================================================
+  FUNCTION      glinki_channel_fully_opened
+===========================================================================*/
+/** 
+ * Check whether this channel is fully opened or not (local & remote)
+ * This also checks transport status
+ *
+ * @param[in]  handle        glink channel handle
+ *
+ * @return     TRUE,  if channel is fully opened
+ *             FASLE, otherwise
+ *
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+boolean glinki_channel_fully_opened
+(
+  glink_handle_type          handle
+)
+{
+  boolean ch_fully_opened = TRUE;
+
+  if (!glinki_xport_linkup(handle->if_ptr))
+  {
+    return FALSE;
+  }
+  
+  glink_os_cs_acquire( &handle->if_ptr->glink_core_priv->channel_q_cs );
+  
+  if (handle->local_state != GLINK_LOCAL_CH_OPENED ||
+      handle->remote_state != GLINK_REMOTE_CH_OPENED)
+  {
+    ch_fully_opened = FALSE;
+  }
+
+  glink_os_cs_release( &handle->if_ptr->glink_core_priv->channel_q_cs );
+  
+  return ch_fully_opened;
+}
+
+/*===========================================================================
+FUNCTION      glink_core_register_transport
+
+DESCRIPTION   Transport calls this API to register its interface with GLINK 
+              Core
+
+ARGUMENTS   *if_ptr   Pointer to interface instance; must be unique
+                      for each edge
+                         
+            *cfg      Pointer to transport configuration structure.
+
+RETURN VALUE  Standard GLINK error codes.
+
+SIDE EFFECTS  None
+===========================================================================*/
+glink_err_type glink_core_register_transport
+(
+  glink_transport_if_type       *if_ptr,
+  glink_core_transport_cfg_type *cfg
+)
+{
+  unsigned int remote_host = 0;
+  glink_core_xport_ctx_type *xport_ctx;
+
+  /* Param validation */
+  if (if_ptr == NULL          ||
+      cfg == NULL             ||
+      cfg->name == NULL       ||
+      cfg->remote_ss == NULL  ||
+      cfg->version == NULL    ||
+      cfg->version_count == 0 ||
+      cfg->max_cid == 0)
+  {
+    GLINK_LOG_ERROR_EVENT( GLINK_EVENT_REGISTER_XPORT, "", "", "", 
+        GLINK_STATUS_INVALID_PARAM);    
+    return GLINK_STATUS_INVALID_PARAM;
+  }
+
+  if(if_ptr->tx_cmd_version == NULL             ||
+     if_ptr->tx_cmd_version_ack == NULL         ||
+     if_ptr->set_version == NULL                ||
+     if_ptr->tx_cmd_ch_open == NULL             ||
+     if_ptr->tx_cmd_ch_close == NULL            ||
+     if_ptr->tx_cmd_ch_remote_open_ack == NULL  ||
+     if_ptr->tx_cmd_ch_remote_close_ack == NULL ||
+     if_ptr->ssr  == NULL)
+  {
+    GLINK_LOG_ERROR_EVENT( GLINK_EVENT_REGISTER_XPORT, "", 
+                           cfg->name, 
+                           cfg->remote_ss, 
+                           GLINK_STATUS_INVALID_PARAM );    
+    return GLINK_STATUS_INVALID_PARAM;;
+  }
+
+  remote_host = glinki_find_remote_host(cfg->remote_ss);
+
+  if(remote_host == GLINK_NUM_HOSTS )
+  {
+    /* Unknown transport name trying to register with GLink */
+    GLINK_LOG_ERROR_EVENT( GLINK_EVENT_REGISTER_XPORT, "", 
+                           cfg->name, 
+                           cfg->remote_ss, 
+                           GLINK_STATUS_INVALID_PARAM );
+    return GLINK_STATUS_INVALID_PARAM;
+  }
+
+  /* Set the glink_core_if_ptr to point to the default interface */
+  if_ptr->glink_core_if_ptr = glink_core_get_default_interface();
+
+  /* Allocate/fill out the GLink private context data */
+  {
+     xport_ctx = glink_os_calloc(sizeof(glink_core_xport_ctx_type));
+    if(xport_ctx == NULL)
+    {
+      GLINK_LOG_ERROR_EVENT( GLINK_EVENT_REGISTER_XPORT, "", 
+                             cfg->name, 
+                             cfg->remote_ss, 
+                             GLINK_STATUS_OUT_OF_RESOURCES );
+    
+      return GLINK_STATUS_OUT_OF_RESOURCES;
+    }
+
+    xport_ctx->xport = cfg->name;
+    xport_ctx->remote_ss = cfg->remote_ss;
+    xport_ctx->free_lcid = 1; /* lcid 0 is reserved for invalid channel */
+    xport_ctx->max_lcid = cfg->max_cid; /* Max channel ID supported by transport */
+    xport_ctx->version_array = cfg->version;
+    xport_ctx->version_indx = (int32)cfg->version_count - 1;
+
+    glink_os_cs_init(&xport_ctx->channel_q_cs);
+    glink_os_cs_init(&xport_ctx->liid_cs);
+    glink_os_cs_init(&xport_ctx->status_cs);
+
+    glink_os_cs_acquire(&xport_ctx->channel_q_cs);
+    smem_list_init(&xport_ctx->open_list);
+    glink_os_cs_release(&xport_ctx->channel_q_cs);
+
+    /* Set the glink_core_if_ptr to point to the allocated structure */
+    if_ptr->glink_core_priv = xport_ctx;
+    xport_ctx->status = GLINK_XPORT_REGISTERED;
+  }
+  
+  /* Push the transport interface into appropriate queue */
+  glinki_enqueue_item(&glink_registered_transports[remote_host],
+                      if_ptr,
+                      &glink_transport_q_cs[remote_host]);
+
+  GLINK_LOG_EVENT_NO_FILTER( GLINK_EVENT_REGISTER_XPORT, "", 
+                  xport_ctx->xport,
+                  xport_ctx->remote_ss,
+                  GLINK_STATUS_SUCCESS);
+
+  return GLINK_STATUS_SUCCESS;
+}
+
+/*===========================================================================
+  FUNCTION      glinki_register_link_notif_data
+===========================================================================*/
+/** 
+ * Register link notification data
+ *
+ * @param[in]  link_notif_data  parameter for link notif data
+ * 
+ * @return       NONE
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+void glinki_register_link_notif_data
+(
+  glink_link_notif_data_type *link_notif_data
+)
+{
+  glinki_enqueue_item(&glink_link_notif_list,
+                      (void *)link_notif_data,
+                      &glink_link_notif_list_cs);
+}
+
+/*===========================================================================
+  FUNCTION      glinki_deregister_link_notif_data
+===========================================================================*/
+/** 
+ * Deregister link notification data
+ *
+ * @param[in]  link_notif_data  parameter for link notif data
+ * 
+ * @return       NONE
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+void glinki_deregister_link_notif_data
+(
+  glink_link_notif_data_type *link_notif_data
+)
+{
+  glinki_dequeue_item(&glink_link_notif_list,
+                      (void *)link_notif_data,
+                      &glink_link_notif_list_cs);
+}
+
+/*===========================================================================
+  FUNCTION      glinki_scan_xports_and_notify
+===========================================================================*/
+/** 
+ * Scan xports and notify link up state event
+ *
+ * @param[in]  link_notif_data  parameter for link notif data
+ * 
+ * @return       NONE
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+void glinki_scan_xports_and_notify
+(
+  glink_link_notif_data_type *link_notif_data
+)
+{
+  unsigned int          remote_host;
+  glink_link_state_type link_state = GLINK_LINK_STATE_UP;
+  
+  ASSERT(link_notif_data);
+  
+  /* Find matching subsystem */
+  for (remote_host = 0; remote_host < GLINK_NUM_HOSTS; ++remote_host)
+  {
+    if (link_notif_data->remote_ss != NULL &&
+        0 != glink_os_string_compare(glink_hosts_supported[remote_host],
+                                     link_notif_data->remote_ss))
+    {
+      /* client is not interested in this remote SS */
+      continue;
+    }
+    
+    glinki_xports_for_each(glink_hosts_supported[remote_host],
+                           glinki_check_xport_link_up_and_notify,
+                           link_notif_data,
+                           link_state,
+                           NULL);
+  }
+}
+
+/*===========================================================================
+  FUNCTION      glinki_scan_notif_list_and_notify
+===========================================================================*/
+/** 
+ * Scan registered link notification list and notify of xport link state change
+ *
+ * @param[in]  if_ptr  pointer to xport interface
+ * @param[in]  state   link state to notify
+ * 
+ * @return       NONE
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+void glinki_scan_notif_list_and_notify
+(
+  glink_transport_if_type *if_ptr,
+  glink_link_state_type    state
+)
+{
+  glink_link_notif_data_type *link_notif_data;
+
+  glink_os_cs_acquire(&glink_link_notif_list_cs);
+  
+  for (link_notif_data = smem_list_first(&glink_link_notif_list);
+       link_notif_data != NULL;
+       link_notif_data = smem_list_next(link_notif_data))
+  {
+    if( link_notif_data->remote_ss == NULL || 
+        0 == glink_os_string_compare( if_ptr->glink_core_priv->remote_ss,
+                                      link_notif_data->remote_ss ) ) 
+    {
+      glinki_check_xport_and_notify(if_ptr,
+                                    link_notif_data,
+                                    (uint32)state,
+                                    NULL);
+    }
+  }
+  
+  glink_os_cs_release(&glink_link_notif_list_cs);
+} /* glinki_scan_notif_list_and_notify */
+
+/*===========================================================================
+  FUNCTION      glinki_ssr
+===========================================================================*/
+/** 
+ * Notify all the xports of ssr event in this edge
+ *
+ * @param[in]    remote_ss name of remote subsystem
+ * 
+ * @return       NONE
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+void glink_ssr(const char* remote_ss)
+{
+  glinki_xports_for_each(remote_ss,
+                         glinki_notify_xport_ssr,
+                         NULL,
+                         0,
+                         NULL);
+}
+
+/*===========================================================================
+  FUNCTION      glinki_xport_linkup
+===========================================================================*/
+/** 
+ * Check whether this transport is in linkup state or not
+ *
+ * @param[in]    if_ptr     transport interface pointer
+ * 
+ * @return       TRUE   if this xport is in link up state
+ *               FALSE  otherwise
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+boolean glinki_xport_linkup
+(
+  glink_transport_if_type *if_ptr
+)
+{
+  return if_ptr->glink_core_priv->status == GLINK_XPORT_LINK_UP;
+}
+
+/*===========================================================================
+  FUNCTION      glinki_xports_for_each
+===========================================================================*/
+/** 
+ * Scan all the transports in given edge and perform client's function for each
+ * transport
+ *
+ * @param[in]    remote_ss    name of remote subsystem, NULL string not accepted
+ * @param[in]    client_ex_fn client function to perform on each xport
+ * @param[in]    param1       first parameter to use in client_ex_fn
+ * @param[in]    param2       second parameter to use in client_ex_fn
+ * @param[out]   out          value to return in case client wants
+ *
+ * @return       None.
+ *
+ * @sideeffects  None.
+ *
+ * This routine ASSUMES it is safe to traverse the glink_registered_transports 
+ * without a lock. This is only true if the following conditions are met
+ * 1) Only append/traverse operations are allowed on this list (No insert, delete)
+ * 2) Append should make sure at no instance of time we have an uninitialized 
+ * pointer(next) along the list
+ */
+/*=========================================================================*/
+void glinki_xports_for_each
+(
+  const char         *remote_ss,
+  glink_client_ex_fn  client_ex_fn,
+  void               *param1,
+  uint32              param2,
+  void              **out
+)
+{
+  glink_transport_if_type *if_iter_ptr;
+  
+  uint32 remote_host = glinki_find_remote_host(remote_ss);
+  
+  ASSERT(remote_host < GLINK_NUM_HOSTS);
+  
+  
+  for(if_iter_ptr = smem_list_first(&glink_registered_transports[remote_host]);
+      if_iter_ptr != NULL;
+      if_iter_ptr = smem_list_next(if_iter_ptr))
+  {
+    client_ex_fn(if_iter_ptr, param1, param2, out);
+  }
+}
+
+/*===========================================================================
+  FUNCTION      glinki_xports_find
+===========================================================================*/
+/** 
+ * Scan all the transports in given edge and finds transport that satisfy
+ * client's condition
+ *
+ * @param[in]    remote_ss      name of remote subsystem, NULL string not accepted
+ * @param[in]    client_cond_fn client function to check if this transport is 
+ *                              what client is looking for
+ * @param[in]    cond1          first condition to use in client_ex_fn
+ * @param[in]    cond2          second condition to use in client_ex_fn
+ * @param[out]   out            value to return in case client wants
+ *
+ * @return       pointer to glink_transport_if_type struct
+ *               NULL if there isn't any xport matches client's search condition
+ *
+ * @sideeffects  None.
+ *
+ * This routine ASSUMES it is safe to traverse the glink_registered_transports 
+ * without a lock. This is only true if the following conditions are met
+ * 1) Only append/traverse operations are allowed on this list (No insert/delete)
+ * 2) Append should make sure at no instance of time we have an uninitialized 
+ * pointer(next) along the list
+ */
+/*=========================================================================*/
+glink_transport_if_type *glinki_xports_find
+(
+  const char           *remote_ss,
+  glink_client_cond_fn  client_cond_fn,
+  void                 *cond1,
+  uint32                cond2,
+  void                **out
+)
+{
+  glink_transport_if_type *if_iter_ptr;
+  
+  uint32 remote_host = glinki_find_remote_host(remote_ss);
+  
+  ASSERT(remote_host < GLINK_NUM_HOSTS);
+  
+  for (if_iter_ptr = smem_list_first(&glink_registered_transports[remote_host]);
+       if_iter_ptr != NULL;
+       if_iter_ptr = smem_list_next(if_iter_ptr))
+  {
+    if(client_cond_fn(if_iter_ptr, cond1, cond2, out))
+    {
+      break;
+    }
+  }
+  
+  return if_iter_ptr;
+}
+
+/*===========================================================================
+  FUNCTION      glinki_find_ch_ctx_by_lcid
+===========================================================================*/
+/** 
+ * Find channel context by lcid
+ *
+ * @param[in]    xport_ctx  Pointer to transport private context
+ * @param[in]    lcid       local channel ID
+ *
+ * @return       pointer to glink channel context
+ *
+ * @sideeffects  This function needs to be protected by channel_q_cs
+ *               Caller is responsible grab/release mutex when calling this
+ */
+/*=========================================================================*/
+glink_channel_ctx_type *glinki_find_ch_ctx_by_lcid
+(
+  glink_core_xport_ctx_type *xport_ctx,
+  uint32                     lcid
+)
+{
+  glink_channel_ctx_type *open_ch_ctx;
+  
+  for (open_ch_ctx = smem_list_first(&xport_ctx->open_list);
+       open_ch_ctx;
+       open_ch_ctx = smem_list_next(open_ch_ctx))
+  {
+    if (open_ch_ctx->lcid == lcid)
+    {
+      return open_ch_ctx;
+    }
+  }
+  
+  /* open_ch_ctx will be NULL here. Using this instead of ASSERT(0)
+    to avoid unreachable code warning */
+  ASSERT( open_ch_ctx != NULL );
+  return NULL;
+}
+
+/*===========================================================================
+  FUNCTION      glinki_find_ch_ctx_by_rcid
+===========================================================================*/
+/** 
+ * Find channel context by rcid
+ *
+ * @param[in]    xport_ctx  Pointer to transport private context
+ * @param[in]    rcid       remote channel ID
+ *
+ * @return       pointer to glink channel context
+ *
+ * @sideeffects  This function needs to be protected by channel_q_cs
+ *               Caller is responsible grab/release mutex when calling this
+ */
+/*=========================================================================*/
+glink_channel_ctx_type *glinki_find_ch_ctx_by_rcid
+(
+  glink_core_xport_ctx_type *xport_ctx,
+  uint32                     rcid
+)
+{
+  glink_channel_ctx_type *open_ch_ctx;
+  
+  for (open_ch_ctx = smem_list_first(&xport_ctx->open_list);
+       open_ch_ctx;
+       open_ch_ctx = smem_list_next(open_ch_ctx))
+  {
+    if (open_ch_ctx->rcid == rcid)
+    {
+      return open_ch_ctx;
+    }
+  }
+  
+  /* open_ch_ctx will be NULL here. Using this instead of ASSERT(0)
+    to avoid unreachable code warning */
+  ASSERT( open_ch_ctx != NULL ); 
+  return NULL;
+}
+
+/*===========================================================================
+  FUNCTION      glinki_find_ch_ctx_by_name
+===========================================================================*/
+/** 
+ * Find channel context by channel name, called by local/remote open function
+ * This function will also indicate (valid_open_call) if this open call would
+ * be valid or not
+ *
+ * @param[in]    xport_ctx  Pointer to transport private context
+ * @param[in]    ch_name    channel name
+ * @param[in]    local_open       flag to indicate this is local open call
+ * @param[out]   valid_open_call  tell whether this open call would be valid
+ *                                or not
+ *
+ * @return       pointer to glink channel context
+ *               NULL if channel doesn't exist
+ *
+ * @sideeffects  This function needs to be protected by channel_q_cs
+ *               Caller is responsible grab/release mutex when calling this
+ */
+/*=========================================================================*/
+glink_channel_ctx_type *glinki_find_ch_ctx_by_name
+(
+  glink_core_xport_ctx_type *xport_ctx,
+  const char                *ch_name,
+  boolean                    local_open,
+  boolean                   *valid_open_call
+)
+{
+  glink_channel_ctx_type *open_ch_ctx;
+  glink_channel_ctx_type *ch_ctx_found = NULL;
+  glink_remote_state_type remote_state;
+  glink_local_state_type  local_state;
+  
+  ASSERT( valid_open_call != NULL );
+  *valid_open_call = TRUE;
+  
+  for(open_ch_ctx = smem_list_first(&xport_ctx->open_list);
+        open_ch_ctx != NULL;
+      open_ch_ctx = smem_list_next(open_ch_ctx))
+  {
+    remote_state = open_ch_ctx->remote_state;
+    local_state = open_ch_ctx->local_state;
+    
+    if ( 0 != glink_os_string_compare(open_ch_ctx->name, ch_name) ||
+         remote_state == GLINK_REMOTE_CH_CLEANUP ||
+         remote_state == GLINK_REMOTE_CH_SSR_RESET )
+    {
+      continue;
+    }
+    
+    if ( ( local_open == TRUE && local_state == GLINK_LOCAL_CH_INIT ) || 
+         ( local_open == FALSE && remote_state == GLINK_REMOTE_CH_INIT ) )
+    {
+      /* Local/Remote side already opened channel */
+      ch_ctx_found = open_ch_ctx;
+    }
+    else if ( ( local_open == TRUE && local_state != GLINK_LOCAL_CH_CLOSED ) ||
+              ( local_open == FALSE && remote_state != GLINK_REMOTE_CH_CLOSED ) )
+    {
+      /* Local/Remote side is trying to open channel without closing old one */
+      *valid_open_call = FALSE;
+      break;
+    }
+  }
+  
+  return ch_ctx_found;
+}
+
+/*===========================================================================
+  FUNCTION      glinki_find_remote_host
+===========================================================================*/
+/** 
+ * return remote subsystem ID based on remote subsystem name
+ *
+ * @param[in]    remote_ss  remote subsystem name
+ *
+ * @return       remote subsystem ID
+ *
+ * @sideeffects  None.
+ */
+/*=========================================================================*/
+uint32 glinki_find_remote_host
+(
+  const char *remote_ss
+)
+{
+  uint32 remote_host;
+
+  for(remote_host = 0; remote_host < GLINK_NUM_HOSTS; remote_host++) 
+  {
+    if( 0 == glink_os_string_compare(glink_hosts_supported[remote_host],
+                                     remote_ss))
+    {
+      /* Match found, break out of loop */
+      break;
+    }
+  }
+  
+  return remote_host;
+}
+
+/*===========================================================================
+  FUNCTION      glinki_find_best_xport
+===========================================================================*/
+/** 
+ * This function gives best available transport for give edge
+ *
+ * @param[in]    remote_host  Index into glink_registered_transports array of
+ *                            registered transports list per edge
+ * 
+ * @return       pointer to glink_transport_if_type
+ *               Null, if transport not found
+ *
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+glink_transport_if_type *glinki_find_best_xport
+(
+  const char *remote_ss
+)
+{
+  glink_transport_if_type *best_if_ptr = NULL;
+  glink_xport_priority priority = GLINK_MIN_PRIORITY;
+  
+  glinki_xports_for_each(remote_ss,
+                         glinki_update_best_xport,
+                         (void *)&priority,
+                         0,
+                         (void **)&best_if_ptr);
+  
+  return best_if_ptr;
+}
+
+/*===========================================================================
+  FUNCTION      glinki_find_requested_xport
+===========================================================================*/
+/** 
+ * Find requested or best transport depending on client's request
+ *
+ * @param[in]    xport_name         name of transport
+ * @param[in]    remote_ss          remote subsystem name
+ * @param[in]    open_ch_option     option client gave when called glink_open
+ * @param[out]   suggested_priority best xport priority glink suggests
+ *
+ * @return       pointer to glink_transport_if_type struct
+ *
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+glink_transport_if_type *glinki_find_requested_xport
+(
+  const char           *xport_name,
+  const char           *remote_ss,
+  uint32                open_ch_option,
+  glink_xport_priority *suggested_priority
+)
+{
+  glink_transport_if_type *best_xport = glinki_find_best_xport(remote_ss);
+  glink_transport_if_type *xport_found = NULL;
+  
+  *suggested_priority = GLINK_INVALID_PRIORITY;
+
+  if (!xport_name)
+  {
+    if (best_xport)
+    {
+      *suggested_priority = best_xport->glink_priority;
+    }
+    
+    return best_xport;
+  }
+  
+  xport_found = glinki_xports_find(remote_ss,
+                                   glinki_client_requested_xport_check,
+                                   (void *)xport_name,
+                                   0,
+                                   NULL);
+  
+  if (!xport_found)
+  {
+    return NULL;
+  }
+  
+  if ((open_ch_option & GLINK_OPT_INITIAL_XPORT) != 0)
+  {
+    *suggested_priority = best_xport->glink_priority;
+  }
+  else
+  {
+    /* Client is not willing to migrate to better transport */
+    *suggested_priority = xport_found->glink_priority;
+  }
+  
+  return xport_found;
+}
+
+/*===========================================================================
+  FUNCTION      glinki_find_xport_by_priority
+===========================================================================*/
+/** 
+ * This function returns glink_transport_if pointer based on transport priority
+ *
+ * @param[in]    prio        glink xport prio
+ * @param[in]    remote_ss   remote subsytem name
+ *
+ * @return       pointer to glink_transport_if_type struct
+ *               NULL, if it's not registered or transport not found with
+ *                     the priority
+ *
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+glink_transport_if_type *glinki_find_xport_by_priority
+(
+  glink_xport_priority  prio,
+  const char           *remote_ss
+)
+{
+  return glinki_xports_find(remote_ss,
+                            glinki_xport_priority_comp,
+                            NULL,
+                            (uint32)prio,
+                            NULL);
+}
+
+/*===========================================================================
+  FUNCTION      glinki_enqueue_item
+===========================================================================*/
+/** 
+ * Enqueue item to smem list in protected context
+ * 
+ * @param[in]    smem_list  smem list to enqueue
+ * @param[in]    item       item to queue
+ * @param[in]    cs         mutex to protect the list
+ *
+ * @return       None.
+ *
+ * @sideeffects  None.
+ */
+/*=========================================================================*/
+void glinki_enqueue_item
+(
+  smem_list_type *smem_list_ptr,
+  void           *item,
+  os_cs_type     *cs
+)
+{
+  glink_os_cs_acquire(cs);
+  smem_list_append(smem_list_ptr, item);
+  glink_os_cs_release(cs);
+}
+
+/*===========================================================================
+  FUNCTION      glinki_dequeue_item
+===========================================================================*/
+/** 
+ *  Dequeue item from smem list in protected context
+ * 
+ * @param[in]    smem_list  smem list to dequeue from 
+ * @param[in]    item       item to dequeue
+ * @param[in]    cs         mutex to protect the list
+ *
+ * @return       None.
+ *
+ * @sideeffects  None.
+ */
+/*=========================================================================*/
+void glinki_dequeue_item
+(
+  smem_list_type *smem_list_ptr,
+  void           *item,
+  os_cs_type     *cs
+)
+{
+  glink_os_cs_acquire(cs);
+  smem_list_delete(smem_list_ptr, item);
+  glink_os_cs_release(cs);
+}
+
+/*===========================================================================
+  FUNCTION      glinki_acquire_edge_lock
+===========================================================================*/
+/** 
+ *  Acquires the transport_q_cs lock for the specified edge
+ * 
+ * @param[in]    remote_ss  Name of the remote sub system on the edge
+ *
+ * @return       None.
+ *
+ * @sideeffects  None.
+ */
+/*=========================================================================*/
+void glinki_acquire_edge_lock(const char *ss_name)
+{
+    uint32 remote_host;
+    remote_host = glinki_find_remote_host(ss_name);
+    glink_os_cs_acquire(&glink_transport_q_cs[remote_host]);
+}
+
+/*===========================================================================
+  FUNCTION      glinki_release_edge_lock
+===========================================================================*/
+/** 
+ *  Releases the transport_q_cs lock for the specified edge
+ * 
+ * @param[in]    remote_ss  Name of the remote sub system on the edge
+ *
+ * @return       None.
+ *
+ * @sideeffects  None.
+ */
+/*=========================================================================*/
+void glinki_release_edge_lock(const char *ss_name)
+{
+    uint32 remote_host;
+    remote_host = glinki_find_remote_host(ss_name);
+    glink_os_cs_release(&glink_transport_q_cs[remote_host]);
+}
+
+#if defined(GLINK_MEMORY_LOGGING)
+/* ============ Internal Logging API ================ */
+void glink_mem_log
+(
+  glink_log_event_type type,
+  const char *msg,
+  const char *xport,
+  const char *remote_ss,
+  uint32 param
+)
+{
+#ifdef DEBUG_GLINK
+  dprintf(INFO, "%s:%u, event:%d, msg:%s, xport:%s, remote_ss:%s, param:%u\n", func, line, type, msg, xport, remote_ss, param);
+#endif
+}
+#endif
+
+#ifdef FEATURE_TRACER_PACKET
+/*===========================================================================
+FUNCTION      glink_tracer_packet_log_pctx_pkt
+===========================================================================*/
+/** 
+ * Log tracer packet event. Tracer packet is included in glink_core_tx_pkt
+ * and needs to use vprovider to extract it
+ * 
+ * @param[in]  pctx     pointer to glink_core_tx_pkt_type
+ * @param[in]  event_id event_id
+ * 
+ * @return         None
+ *
+ * @sideeffects    None
+ */
+/*=========================================================================*/
+void glink_tracer_packet_log_pctx_pkt
+(
+  glink_core_tx_pkt_type  *pctx,
+  uint32                   event_id
+)
+{
+  tracer_pkt_result_type  tracer_pkt_log_result;
+  void                   *tracer_pkt_data;
+  size_t                  tracer_pkt_size;
+  
+  tracer_pkt_data = pctx->vprovider(pctx->iovec, 0, &tracer_pkt_size);
+  
+  if (tracer_pkt_size != pctx->size)
+  {
+    GLINK_LOG_EVENT_NO_FILTER( GLINK_EVENT_TXV_INVALID_BUFFER, "", "", "",
+                    tracer_pkt_size);
+  }
+
+  tracer_pkt_log_result = tracer_packet_log_event(tracer_pkt_data, (uint16)event_id);
+  if (tracer_pkt_log_result != TRACER_PKT_STATUS_SUCCESS)
+  {
+    GLINK_LOG_EVENT_NO_FILTER( GLINK_EVENT_TRACER_PKT_FAILURE, "", "", "",
+                    tracer_pkt_log_result);
+  }
+}
+#endif
+
+/*===========================================================================
+  FUNCTION      glinki_update_logging_filter
+===========================================================================*/
+/** 
+ *  Update/Reset the logging filter if the name and remote host of the  
+ *  logging filter matches to that of the passed channel context
+ * 
+ * @param[in]    chnl_ctx   Channel content to match/compare
+ * @param[in]    reset      Indicate Update(FALSE) or Reset(TRUE)
+ *
+ * @return       None.
+ */
+/*=========================================================================*/
+#if defined(GLINK_OS_DEFINED_LOGGING) || defined(GLINK_MEMORY_LOGGING)
+void glinki_update_logging_filter
+(
+  glink_channel_ctx_type  *chnl_ctx, 
+  boolean                 reset
+)
+{
+  if ( ( log_filter_cfg.ch_filter_status == TRUE )  && 
+       ( (chnl_ctx) != NULL )   && 
+       ( glink_os_string_compare( (chnl_ctx)->name,
+                                 log_filter_cfg.ch_name) == 0 ) &&
+       ( log_filter_cfg.remote_host ==
+         glinki_find_remote_host((chnl_ctx)->if_ptr->glink_core_priv->remote_ss) ) 
+     )
+  {
+    if (reset == FALSE) /* Update the Filter */
+    {
+      log_filter_cfg.ch_ctx = (chnl_ctx);
+      log_filter_cfg.ch_lcid = (chnl_ctx)->lcid;
+      log_filter_cfg.ch_rcid = (chnl_ctx)->rcid;
+    }
+    else  /* Reset the Filter */
+    {
+      log_filter_cfg.ch_ctx = NULL;
+      log_filter_cfg.ch_lcid = 0;
+      log_filter_cfg.ch_rcid = 0;
+      log_filter_cfg.remote_host = (uint32)-1;        
+    }
+  }
+}
+
+#else
+void glinki_update_logging_filter(glink_channel_ctx_type *chnl_ctx, boolean reset)
+{
+    GLINK_OS_UNREFERENCED_PARAM( chnl_ctx );
+    GLINK_OS_UNREFERENCED_PARAM( reset );
+}
+#endif
diff --git a/platform/msm_shared/glink/glink_vector.c b/platform/msm_shared/glink/glink_vector.c
index 31f0883..4ca2692 100644
--- a/platform/msm_shared/glink/glink_vector.c
+++ b/platform/msm_shared/glink/glink_vector.c
@@ -109,12 +109,6 @@
     return NULL;
   }
 
-  if (!iovec_l->vlist)
-  {
-    // create vlist and map virtual from physical addresses
-    ASSERT(0);
-  }
-
   if (!iovec_l->vlast || iovec_l->vlast->start_offset > offset)
   {
        iovec_l->vlast = iovec_l->vlist;
@@ -167,12 +161,6 @@
     return NULL;
   }
 
-  if (!iovec_l->plist)
-  {
-    // create plist and get physical addresses from virtual
-    ASSERT(0); // not implemented
-  }
-
   if (!iovec_l->plast || iovec_l->plast->start_offset > offset)
   {
        iovec_l->plast = iovec_l->plist;
diff --git a/platform/msm_shared/glink/xport_rpm.c b/platform/msm_shared/glink/xport_rpm.c
index 68a6c80..31785d2 100644
--- a/platform/msm_shared/glink/xport_rpm.c
+++ b/platform/msm_shared/glink/xport_rpm.c
@@ -49,8 +49,12 @@
 #define XPORT_RPM_NAME "RPM"
 
 #define XPORT_RPM_LOG(msg, remote_host, param) \
-          GLINK_LOG_EVENT(GLINK_EVENT_XPORT_INTERNAL, msg, XPORT_RPM_NAME, \
-            remote_host, (uint32)param)
+	if ((log_filter_cfg.xport_filter_mask &                                     \
+       (1 << GLINK_XPORT_RPM_MASK_BIT)) != 0 )                                \
+  {                                                                           \
+    GLINK_LOG_EVENT_NO_FILTER(GLINK_EVENT_XPORT_INTERNAL, msg, XPORT_RPM_NAME,\
+			       remote_host, (uint32)param);                               \
+  }
 
 #define MSGRAM_READ32(ctx, ind) (*(volatile uint32*)&(ctx)->rx_fifo[ind])
 #define CHECK_INDEX_WRAP_AROUND(ind, size) \
@@ -172,9 +176,9 @@
 )
 {
   /* read out the write index to initiate a bus transaction from MSG RAM */
-  volatile uint32 write_ind = ctx_ptr->tx_desc->write_ind;
 
-  XPORT_RPM_LOG("Send event write ind", ctx_ptr->pcfg->remote_ss, write_ind);
+ 	XPORT_RPM_LOG("Send event write ind", ctx_ptr->pcfg->remote_ss, 
+                (volatile uint32)ctx_ptr->tx_desc->write_ind);
 
   // notify rpm
   dprintf(SPEW, "%s:%d: Notify RPM with IPC interrupt\n", __func__, __LINE__);
diff --git a/platform/msm_shared/include/bam.h b/platform/msm_shared/include/bam.h
index bfeb34b..67b2f5f 100644
--- a/platform/msm_shared/include/bam.h
+++ b/platform/msm_shared/include/bam.h
@@ -71,7 +71,6 @@
 #define BAM_DATA_READ                   0
 #define BAM_DATA_WRITE                  1
 
-#define BAM_DESC_CNT_TRSHLD_REG(x)      (0x0008 + (x))
 #define COUNT_TRESHOLD_MASK             0xFF
 #define BAM_IRQ_MASK                    (1 << 31)
 #define P_IRQ_MASK                      (1)
diff --git a/platform/msm_shared/include/boot_verifier.h b/platform/msm_shared/include/boot_verifier.h
index efe0c1b..3b6d649 100644
--- a/platform/msm_shared/include/boot_verifier.h
+++ b/platform/msm_shared/include/boot_verifier.h
@@ -158,4 +158,7 @@
 bool boot_verify_validate_keystore(unsigned char * user_addr);
 /* Function to check if partition is allowed to flash in verified mode */
 bool boot_verify_flash_allowed(const char * entry);
+bool boot_verify_compare_sha256(unsigned char *image_ptr,
+		unsigned int image_size, unsigned char *signature_ptr, RSA *rsa);
+KEYSTORE *boot_gerity_get_oem_keystore();
 #endif
diff --git a/platform/msm_shared/include/glink.h b/platform/msm_shared/include/glink.h
index b36fba0..9f1d655 100644
--- a/platform/msm_shared/include/glink.h
+++ b/platform/msm_shared/include/glink.h
@@ -63,14 +63,30 @@
 /** GLink status/return codes */
 typedef enum {
   GLINK_STATUS_SUCCESS = 0,
-  GLINK_STATUS_FAILURE,
-  GLINK_STATUS_INVALID_PARAM,
-  GLINK_STATUS_NOT_INIT,
-  GLINK_STATUS_OUT_OF_RESOURCES,
-  GLINK_STATUS_NO_TRANSPORT
+  GLINK_STATUS_INVALID_PARAM             = -1,
+  GLINK_STATUS_NOT_INIT                  = -2,
+  GLINK_STATUS_OUT_OF_RESOURCES          = -3,
+  /* Failure due to lack of transport */
+  GLINK_STATUS_NO_TRANSPORT              = -4 ,
+  /* TX failure when there is no remote intent queued */
+  GLINK_STATUS_NO_REMOTE_INTENT_FOUND    = -5,
+  /* Failure of a glink_* call when channel is not fully opened yet */
+  GLINK_STATUS_CH_NOT_FULLY_OPENED       = -6,
+  /* Failure due to closing the same channel twice */
+  GLINK_STATUS_CH_ALREADY_CLOSED         = -7,
+  /* Returned when intent APIs are used over an intent less xport */
+  GLINK_STATUS_API_NOT_SUPPORTED         = -8,
+  /* Failure specific to QoS algorithm/implementation */
+  GLINK_STATUS_QOS_FAILURE               = -9,
+  /* Failure due to tx_cmd* calls */
+  GLINK_STATUS_TX_CMD_FAILURE            = -10,
+  /* For other Failures not covered above */
+  GLINK_STATUS_FAILURE                   = -11,
+  /* Failures relating to GLink operation timeout */
+  GLINK_STATUS_TIMEOUT                   = -12
 }glink_err_type;
 
-/** List of possible suvsystems */
+/** List of possible subsystems */
 /**
   "apss"   Application Processor Subsystem
   "mpss"   Modem subsystem
diff --git a/platform/msm_shared/include/glink_core_if.h b/platform/msm_shared/include/glink_core_if.h
index 67cd106..fd4d6be 100644
--- a/platform/msm_shared/include/glink_core_if.h
+++ b/platform/msm_shared/include/glink_core_if.h
@@ -42,7 +42,6 @@
 /*===========================================================================
                         INCLUDE FILES
 ===========================================================================*/
-
 #include "smem_list.h"
 #include "glink.h"
 #include "glink_transport_if.h"
@@ -51,6 +50,17 @@
 /*===========================================================================
                       MACRO DECLARATIONS
 ===========================================================================*/
+/* Limit of the proportion of total QoS requests
+   =GLINK_QOS_RATE_LIMIT_COEFF_N / GLINK_QOS_RATE_LIMIT_COEFF_D
+ */
+#define GLINK_QOS_RATE_LIMIT_COEFF_N 7
+#define GLINK_QOS_RATE_LIMIT_COEFF_D 10
+
+/* Number of QoS tokens given at refill */
+#define GLINK_QOS_TOKENS (10) 
+
+/* Number of QoS buckets */
+#define GLINK_QOS_BUCKETS (1)
 
 /*===========================================================================
                       TYPE DECLARATIONS
@@ -88,11 +98,15 @@
   os_event_type event;   /* Event to signal Tx thread */
   os_cs_type tx_q_cs;    /* Lock to protect Tx queue */
   smem_list_type tx_q;   /* Tx channel queue */
+  uint32 qos_rate_sum;   /* Sum of rates of registered QoS requests */
 } glink_tx_xport_ctx_type;
 
 /** G-Link Local channel states */
 typedef enum
 {
+  /** Initial State before entering channel state machine */
+  GLINK_LOCAL_CH_INIT,
+  
   /** Local G-Link channel is fully closed */
   GLINK_LOCAL_CH_CLOSED,
 
@@ -110,6 +124,9 @@
 /** G-Link Remote channel states */
 typedef enum
 {
+  /** Initial State before entering channel state machine */
+  GLINK_REMOTE_CH_INIT,
+
   /** Remote G-Link channel is closed */
   GLINK_REMOTE_CH_CLOSED,
 
@@ -117,7 +134,12 @@
   GLINK_REMOTE_CH_OPENED,
 
   /* Glink channel state when SSR is received from remote sub-system */
-  GLINK_REMOTE_CH_SSR_RESET
+  GLINK_REMOTE_CH_SSR_RESET,
+
+  /** G-Link channel is pending cleanup. 
+      This state is used for deferred channel cleanup in case 
+      it sits in Tx scheduler queue */
+  GLINK_REMOTE_CH_CLEANUP
 
 }glink_remote_state_type;
 
@@ -144,14 +166,6 @@
   uint32                  features /* Features */
 );
 
-/** Sets the core version used by the transport; called after completing
- *  negotiation.*/
-typedef void (*set_core_version_fn)
-(
-  glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
-  uint32                  version  /* Version */
-);
-
 /** Receive remote channel open request; expected response is
  *  glink_transport_if_type:: tx_cmd_ch_remote_open_ack */
 typedef void (*rx_cmd_ch_remote_open_fn)
@@ -307,7 +321,7 @@
   const glink_core_version_type *version_array;
 
   /** Keep track of version array index in use */
-  uint32                        version_indx;
+  int32                         version_indx;
 
   /* Keeps track of the current status of the transport */
   glink_transport_status_type   status;
@@ -319,13 +333,17 @@
   /* Transport's capabilities */
   uint32                        xport_capabilities;
 
+  /* Max lcid */
+  uint32                        max_lcid;
+
   /* Free lcid */
   uint32                        free_lcid;
 
   /* Keeps track of the open channels for this transport/edge combination */
   smem_list_type                open_list;
 
-  /* Critical section to protect access to open_list */
+  /* Critical section to protect access to open_list and channel state of all 
+     channels in that open_list */
   os_cs_type                    channel_q_cs;
 
   /* Local channel intents queued so far. This also helps determining liid
@@ -372,10 +390,6 @@
   /** Receive ACK to previous glink_transport_if_type::tx_cmd_version command */
   rx_cmd_version_ack_fn          rx_cmd_version_ack;
 
-  /** Sets the core version used by the transport; called after completing
-   *  negotiation.*/
-  set_core_version_fn            set_core_version;
-
   /** Receive remote channel open request; expected response is
    *  glink_transport_if_type:: tx_cmd_ch_remote_open_ack */
   rx_cmd_ch_remote_open_fn       rx_cmd_ch_remote_open;
diff --git a/platform/msm_shared/include/glink_internal.h b/platform/msm_shared/include/glink_internal.h
index bdd434c..fb6b854 100644
--- a/platform/msm_shared/include/glink_internal.h
+++ b/platform/msm_shared/include/glink_internal.h
@@ -36,9 +36,7 @@
 ===========================================================================*/
 
 /*===========================================================================
-
                         INCLUDE FILES
-
 ===========================================================================*/
 #include "smem_list.h"
 #include "glink.h"
@@ -55,15 +53,74 @@
 #define GLINK_VERSION 0
 #define GLINK_FEATURE_FLAGS 0
 #define GLINK_NUM_HOSTS     7
+#define GLINK_INVALID_CID   0
 
 /*===========================================================================
                            MACRO DEFINITIONS
 ===========================================================================*/
-#define GLINK_LOG_EVENT(type, ch_name, xport, remote_ss, param) \
-  glink_mem_log(__FUNCTION__, __LINE__, type, ch_name, xport, remote_ss, param);
 
+/* Macros to enable/select glink logging and stats collection
+ * GLINK_MEMORY_LOGGING     --> Enable memory based logging
+ * GLINK_OS_DEFINED_LOGGING --> Enable OS defined logging (uLog for ADSP/MPSS/SLPI)
+ * These will be selectively defined by the top level Glink Scons file
+ */
+/**** Logging macros GLINK_LOG_* ****/
+#if defined(GLINK_MEMORY_LOGGING)
 #define GLINK_MEM_LOG_SIZE 128
 
+/* Used for xport logging where channel name information is unavaliable */
+#define GLINK_LOG_EVENT_NO_FILTER(type, ch_name, xport, remote_ss, param) \
+  glink_mem_log(type, ch_name, xport, remote_ss, param);
+
+/* Filtering based on ch_ctx, If ch_ctx is not available we should be using 
+  *_NO_FILTER macro for logging */
+#define GLINK_LOG_EVENT(chnl_ctx, type, ch_name, xport, remote_ss, param)  \
+  if ((log_filter_cfg.ch_filter_status == FALSE) ||                        \
+      ((chnl_ctx) == log_filter_cfg.ch_ctx))                               \
+  {                                                                        \
+    glink_mem_log(type, ch_name, xport, remote_ss, param);                 \
+  }
+
+#define GLINK_LOG_ERROR_EVENT(type, ch_name, xport, remote_ss, param)      \
+  glink_mem_log(type, ch_name, xport, remote_ss, param);
+
+#elif defined(GLINK_OS_DEFINED_LOGGING)
+
+/* Used for xport logging where channel name information is unavaliable */
+#define GLINK_LOG_EVENT_NO_FILTER(type, ch_name, xport, remote_ss, param) \
+  OS_LOG_MSG(5, "[%x, %s, %s, %s, %x]" , type, ch_name,                   \
+             xport, remote_ss, param);
+
+/* Filtering based on ch_ctx, If ch_ctx is not available we should be using 
+  *_NO_FILTER macro for logging */
+#define GLINK_LOG_EVENT(chnl_ctx, type, ch_name, xport, remote_ss, param)  \
+  if ((log_filter_cfg.ch_filter_status == FALSE) ||                        \
+      ((chnl_ctx) == log_filter_cfg.ch_ctx))                               \
+  {                                                                        \
+    OS_LOG_MSG(5, "[%x, %s, %s, %s, %x]" , type, ch_name,                  \
+               xport, remote_ss, param);                                   \
+  }
+
+#define GLINK_LOG_ERROR_EVENT(type, ch_name, xport, remote_ss, param)	 \
+  OS_LOG_ERROR(5, "[%x, %s, %s, %s, %x]" , type, ch_name,                \
+               xport, remote_ss, param);
+#else
+#define GLINK_LOG_EVENT(lcid, type, ch_name, xport, remote_ss, param) 
+#define GLINK_LOG_ERROR_EVENT(type, ch_name, xport, remote_ss, param)
+#define GLINK_LOG_EVENT_NO_FILTER(type, ch_name, xport, remote_ss, param)
+#endif
+
+/**** Macros used for collecting channel stats ****/
+#if defined(GLINK_CHANNEL_STATS_ENABLED)
+#define GLINK_UPDATE_CHANNEL_STATS(ch_stats, var_name, size_in_bytes)               \
+  {                                                                           \
+      (ch_stats).var_name##_count++;                                          \
+      (ch_stats).var_name##_bytes += (size_in_bytes);                         \
+  }
+#else
+#define GLINK_UPDATE_CHANNEL_STATS(ch_stats, var_name, size_in_bytes)
+#endif
+
 /*===========================================================================
                            TYPE DEFINITIONS
 ===========================================================================*/
@@ -95,14 +152,35 @@
   GLINK_EVENT_CH_MIGRATION_IN_PROGRESS,
   GLINK_EVENT_XPORT_INTERNAL,
   GLINK_EVENT_TRACER_PKT_FAILURE,
-  GLINK_EVENT_TXV_INVALID_BUFFER
+  GLINK_EVENT_TXV_INVALID_BUFFER,
+  GLINK_EVENT_CH_QOS_REG,
+  GLINK_EVENT_CH_QOS_CANCEL,
+  GLINK_EVENT_CH_QOS_START,
+  GLINK_EVENT_CH_QOS_STOP,
+  GLINK_EVENT_INVALID_REMOTE_SS,
+  GLINK_EVENT_REGISTER_LINK_STATE_CB,
+  GLINK_EVENT_DEREGISTER_LINK_STATE_CB,
+  GLINK_EVENT_LB_CLIENT,
+  GLINK_EVENT_SSR
 }glink_log_event_type;
 
+/*Bit index of logging mask of differnt xport. The corresponding bit index 
+  in glink_xport_log_filter_mask will disable(0) or enable(1) logging*/
+typedef enum {
+  GLINK_XPORT_RPM_MASK_BIT,
+  GLINK_XPORT_SMEM_MASK_BIT,
+  GLINK_XPORT_SMD_MASK_BIT,
+  GLINK_XPORT_UART_MASK_BIT
+}glink_xport_logging_mask_type;
+
 typedef struct _glink_channel_intents_type {
 
   /* Link for a channel in Tx queue */
   struct _glink_channel_intents_type* next;
 
+  /* Pointer to channel context */
+  glink_channel_ctx_type        *ch_ctx;
+
   /* Critical section to protest access to intent queues */
   os_cs_type                    intent_q_cs;
 
@@ -137,6 +215,85 @@
 
 } glink_channel_intents_type;
 
+
+typedef struct _glink_channel_qos_type {
+  /* qos request count */
+  uint32                        qos_req_count;
+
+  /* qos request packet size */
+  size_t                        qos_pkt_size;
+
+  /* qos request latency */
+  uint32                        qos_latency_us;
+
+  /* qos request rate */
+  uint32                        qos_rate;
+
+  /* qos priority */
+  uint32                        qos_tokens;
+
+  /* qos transport context */
+  void                          *qos_transport_ctx;
+
+  /* qos start time for priority balancing */
+  os_timetick_type              qos_start_priority_time;
+
+} glink_channel_qos_type;
+
+/*This structure holds all the relevant stats per channel used for debugging*/
+typedef struct _glink_channel_stats_type {
+  /* Total number of bytes sent by the client */
+  uint64 tx_request_bytes;
+
+  /* Total number of bytes sent by the client for which we got tx_done */
+  uint64 tx_done_bytes;
+
+  /* Total number of tx requests */
+  uint32 tx_request_count;
+
+  /* total number of tx_done events */
+  uint32 tx_done_count;
+  
+  /* Total number of bytes recieved by the client */
+  uint64 rx_notify_bytes;
+
+  /* Total number of bytes for which we got rx_done */
+  uint64 rx_done_bytes;
+  
+  /* Total number of rx_notify events */
+  uint32 rx_notify_count;
+  
+  /* Total number of rx_done events */
+  uint32 rx_done_count;
+
+} glink_channel_stats_type;
+
+/* Contains the configuration for logging within core and xport */
+typedef struct _glink_logging_filter_cfg {
+    
+  /* GLink channel filter status */
+  boolean ch_filter_status;
+
+  /* channel filter name */
+  char ch_name[GLINK_CH_NAME_LEN];
+  
+  /* corresponding lcid of the filter */
+  uint32 ch_lcid;
+  
+  /* corresponding rcid of the filter*/
+  uint32 ch_rcid;
+  
+  /* corresponding remote host*/
+  uint32 remote_host;
+
+  /* Corresponding channel context */
+  glink_channel_ctx_type *ch_ctx;
+
+  /* xport logging mask */
+  uint32 xport_filter_mask;
+  
+}glink_logging_filter_cfg_type;
+
 struct glink_channel_ctx {
   /* Link needed for use with list APIs.  Must be at the head of the struct */
   smem_list_link_type                 link;
@@ -156,9 +313,6 @@
   /* Remote channel state */
   glink_remote_state_type             remote_state;
 
-  /* Critical section to protect channel states */
-  os_cs_type                          ch_state_cs;
-
   /* Channel local control signal state */
   uint32                              local_sigs;
 
@@ -171,6 +325,15 @@
   /* channel intent collection */
   glink_channel_intents_type          *pintents;
 
+  /* Critical section to protest access to QoS context */
+  os_cs_type                          qos_cs;
+
+  /* qos priority */
+  uint32                              qos_priority;
+
+  /* channel QoS context */
+  glink_channel_qos_type              *qosctx;
+  
   /* Interface pointer with with this channel is registered */
   glink_transport_if_type             *if_ptr;
 
@@ -214,26 +377,16 @@
   *   or local side closed the port. Optional */
   glink_notify_tx_abort_cb            notify_tx_abort;
 
-  /* glink transport if pointer for preferred channel */
-  glink_transport_if_type             *req_if_ptr;
-
-  /* flag to check if channel is marked for deletion
-   * This is workaround to prevent channel migration algorithm from finding channel
-   * which should be closed but has not been closed yet. This case occurs when glink_close
-   * is called for closing channel on initial xport and it is being opened on other xport.
-   * This may lead to remote side opening channel on neogitated xport from which local side
-   * will get remote open again. In this case channel to be closed will be found for negotiation
-   * on initial xport again and channel migration algorithm will be triggered(again)  */
-  boolean                             tag_ch_for_close;
-
   /* save glink open config options */
   uint32                              ch_open_options;
+#if defined(GLINK_CHANNEL_STATS_ENABLED)
+  /* Structure that constains per channel stats */
+  glink_channel_stats_type             ch_stats;
+#endif
 };
 
 
 typedef struct _glink_mem_log_entry_type {
-  const char *func;
-  uint32 line;
   glink_log_event_type type;
   const char *msg;
   const char *xport;
@@ -252,17 +405,37 @@
   void                      *priv;         /* Notification priv ptr */
 } glink_link_notif_data_type;
 
+
+/* Function pointer used to iterate glink registered transports
+ * glink_client_cond_fn is used to find specifc transport client wants
+ * glink_client_ex_fn will execute client's operation on specific/all transports
+ * depends on client's choice */
+typedef boolean (*glink_client_cond_fn)
+(
+  glink_transport_if_type *if_ptr,
+  void                    *cond1,   /* First condition to compare */
+  uint32                   cond2,   /* Second condition to compare */
+  void                   **out      /* Client private return value */
+);
+
+typedef void (*glink_client_ex_fn)
+(
+  glink_transport_if_type *if_ptr,
+  void                    *param1,   /* First parameter */
+  uint32                   param2,   /* Second parameter */
+  void                   **out      /* Client private return value */
+);
+
 /*===========================================================================
                               GLOBAL DATA DECLARATIONS
 ===========================================================================*/
-extern os_cs_type *glink_transport_q_cs;
 extern const char *glink_hosts_supported[GLINK_NUM_HOSTS];
-extern smem_list_type glink_registered_transports[];
 
+/* Used for filtering logs*/
+extern glink_logging_filter_cfg_type log_filter_cfg;
 /*===========================================================================
                     LOCAL FUNCTION DEFINITIONS
 ===========================================================================*/
-
 /*===========================================================================
                     EXTERNAL FUNCTION DEFINITIONS
 ===========================================================================*/
@@ -478,250 +651,6 @@
 );
 
 /*===========================================================================
-FUNCTION      glink_set_core_version
-
-DESCRIPTION   Sets the core version used by the transport; called after
-              completing negotiation.
-
-ARGUMENTS   *if_ptr    Pointer to interface instance; must be unique
-                       for each edge
-
-             version   Negotiated transport version
-
-RETURN VALUE  None.
-
-SIDE EFFECTS  None
-===========================================================================*/
-void glink_set_core_version
-(
-  glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
-  uint32                  version  /* Version */
-);
-
-/*===========================================================================
-                           CHANNEL CONTEXT APIS
-===========================================================================*/
-
-/*===========================================================================
-FUNCTION      glinki_ch_is_fully_opened
-
-DESCRIPTION   Determine if both the local and remote channel state is fully
-              open
-
-ARGUMENTS     *cfg_ptr   - Pointer to channel context
-
-RETURN VALUE  True if fully opened, false otherwise.
-
-SIDE EFFECTS  None
-===========================================================================*/
-boolean glinki_ch_is_fully_opened
-(
-  glink_channel_ctx_type *ctx
-);
-
-
-/*===========================================================================
-FUNCTION      glinki_ch_push_local_rx_intent
-
-DESCRIPTION   Create and push a local receive intent to internal list
-
-ARGUMENTS     *cfg_ptr   - Pointer to channel context
-
-              *pkt_priv  - Client-provided opaque data
-
-              size       - Size of Receive Intent
-
-RETURN VALUE  Pointer to the new intent
-
-SIDE EFFECTS  None
-===========================================================================*/
-glink_rx_intent_type* glinki_ch_push_local_rx_intent
-(
-  glink_channel_ctx_type *ctx,
-  const void             *pkt_priv,
-  size_t                 size
-);
-
-/*===========================================================================
-FUNCTION      glinki_ch_get_local_rx_intent
-
-DESCRIPTION   Lookup a local receive intent
-
-ARGUMENTS     *cfg_ptr    - Pointer to channel context
-
-              liid        - Local Receive Intent ID
-
-RETURN VALUE  Pointer to the intent or NULL if not match is found.
-
-SIDE EFFECTS  None
-===========================================================================*/
-glink_rx_intent_type* glinki_ch_get_local_rx_intent
-(
-  glink_channel_ctx_type *ctx,
-  uint32                 liid
-);
-
-/*===========================================================================
-FUNCTION      glinki_ch_remove_local_rx_intent
-
-DESCRIPTION   Removes Local Receive Intent ID
-
-ARGUMENTS     *cfg_ptr    - Pointer to channel context
-
-              liid        - Local Receive Intent ID
-
-RETURN VALUE  None
-
-SIDE EFFECTS  None
-===========================================================================*/
-void glinki_ch_remove_local_rx_intent
-(
-  glink_channel_ctx_type *ctx,
-  uint32                 liid
-);
-
-/*===========================================================================
-FUNCTION      glinki_ch_set_local_rx_intent_notified
-
-DESCRIPTION   Sets the state of the intent as client-notified
-
-ARGUMENTS     *cfg_ptr    - Pointer to channel context
-
-              *intent_ptr - Pointer to the receive intent
-
-RETURN VALUE  None
-
-SIDE EFFECTS  None
-===========================================================================*/
-void glinki_ch_set_local_rx_intent_notified
-(
-  glink_channel_ctx_type *ctx,
-  glink_rx_intent_type   *intent_ptr
-);
-
-/*===========================================================================
-FUNCTION      glinki_ch_get_local_rx_intent_notified
-
-DESCRIPTION   Lookup a Local Receive Intent ID that is in the client-notified
-              state
-
-ARGUMENTS     *cfg_ptr    - Pointer to channel context
-
-              *ptr        - Data pointer of receive buffer from client
-                            (passed in through glink_rx_done)
-
-RETURN VALUE  Pointer to the intent or NULL if not match is found.
-
-SIDE EFFECTS  None
-===========================================================================*/
-glink_rx_intent_type* glinki_ch_get_local_rx_intent_notified
-(
-  glink_channel_ctx_type *ctx,
-  void                   *ptr
-);
-
-/*===========================================================================
-FUNCTION      glinki_ch_remove_local_rx_intent_notified
-
-DESCRIPTION   Removes the Local Receive Intent
-
-ARGUMENTS     *cfg_ptr    - Pointer to channel context
-
-              *intent_ptr - Pointer to the receive intent
-
-RETURN VALUE  New channel context or NULL
-
-SIDE EFFECTS  None
-===========================================================================*/
-glink_channel_ctx_type* glinki_ch_remove_local_rx_intent_notified
-(
-  glink_channel_ctx_type *ctx,
-  glink_rx_intent_type   *intent_ptr
-);
-
-/*===========================================================================
-FUNCTION      glinki_ch_push_remote_rx_intent
-
-DESCRIPTION   Adds a new Remote Receive Intent
-
-ARGUMENTS     *cfg_ptr    - Pointer to channel context
-
-              size        - Size of the Remote Receive Intent
-
-RETURN VALUE  None
-
-SIDE EFFECTS  None
-===========================================================================*/
-void glinki_ch_push_remote_rx_intent
-(
-  glink_channel_ctx_type *ctx,
-  size_t                 size
-);
-
-/*===========================================================================
-FUNCTION      glinki_ch_pop_remote_rx_intent
-
-DESCRIPTION   Removes a Remote Receive Intent
-
-ARGUMENTS     *cfg_ptr    - Pointer to channel context
-
-              size        - Size of the Remote Receive Intent
-
-              *riid_ptr   - Pointer to the Remote Receive Intent
-
-RETURN VALUE  Standard GLink Err code.
-
-SIDE EFFECTS  None
-===========================================================================*/
-glink_err_type glinki_ch_pop_remote_rx_intent
-(
-  glink_channel_ctx_type *ctx,
-  size_t                size,
-  uint32                *riid_ptr
-);
-
-/*===========================================================================
-FUNCTION      glinki_ch_get_tx_pending_remote_done
-
-DESCRIPTION   Lookup packet transmit context for a packet that is waiting for
-              the remote-done notification.
-
-ARGUMENTS     *cfg_ptr    - Pointer to channel context
-
-              riid        - Remote Receive Intent ID
-
-RETURN VALUE  Pointer to the transmit packet context or NULL if not match is
-              found.
-
-SIDE EFFECTS  None
-===========================================================================*/
-glink_core_tx_pkt_type* glinki_ch_get_tx_pending_remote_done
-(
-  glink_channel_ctx_type *ctx,
-  uint32                 riid
-);
-
-/*===========================================================================
-FUNCTION      glinki_ch_remove_tx_pending_remote_done
-
-DESCRIPTION   Removes a packet transmit context for a packet that is waiting
-              for the remote-done notification.
-
-ARGUMENTS     *cfg_ptr    - Pointer to channel context
-
-              *tx_pkt     - Pointer to the packet context to remove
-
-RETURN VALUE  None
-
-SIDE EFFECTS  None
-===========================================================================*/
-void glinki_ch_remove_tx_pending_remote_done
-(
-  glink_channel_ctx_type       *ctx,
-  glink_core_tx_pkt_type       *tx_pkt
-);
-
-/*===========================================================================
   FUNCTION      glinki_add_ch_to_xport
 ===========================================================================*/
 /**
@@ -729,8 +658,6 @@
  *
  * @param[in]    if_ptr            Pointer to xport if on which channel is to
  *                                 be opened
- * @param[in]    req_if_ptr        Pointer to xport if on which channel
- *                                 actually wants to open
  * @param[in]    ch_ctx            channel context
  * @param[out]   allocated_ch_ctx  Pointer to channel context pointer
  * @param[in]    local_open        flag to determine if channel is opened
@@ -747,7 +674,6 @@
 glink_err_type glinki_add_ch_to_xport
 (
   glink_transport_if_type  *if_ptr,
-  glink_transport_if_type  *req_if_ptr,
   glink_channel_ctx_type   *ch_ctx,
   glink_channel_ctx_type  **allocated_ch_ctx,
   unsigned int              local_open,
@@ -756,8 +682,6 @@
 
 void glink_mem_log
 (
-  const char *func,
-  uint32 line,
   glink_log_event_type type,
   const char *msg,
   const char *xport,
@@ -827,4 +751,490 @@
 /*=========================================================================*/
 void glink_core_setup_intentless_xport(glink_transport_if_type *if_ptr);
 
+/*===========================================================================
+  FUNCTION      glink_core_setup_intent_xport
+===========================================================================*/
+/**
+
+  Initializes internal core functions based on the transport capabilities.
+
+  @param[in]  if_ptr   The Pointer to the interface instance.
+
+  @return     None.
+
+  @sideeffects  None.
+*/
+/*=========================================================================*/
+void glink_core_setup_intent_xport(glink_transport_if_type *if_ptr);
+
+/*===========================================================================
+  FUNCTION      glink_core_qos_get_priority
+===========================================================================*/
+/**
+
+  Calculates pinitial priority for QoS request.
+
+  @param[in]  if_ptr   The Pointer to the interface instance.
+  @param[in]  req_rate The requested rate.
+
+  @return     Priority.
+
+  @sideeffects  None.
+*/
+/*=========================================================================*/
+uint32 glink_core_qos_get_priority(glink_transport_if_type *if_ptr, uint32 req_rate);
+
+/*===========================================================================
+  FUNCTION      glinki_channel_fully_opened
+===========================================================================*/
+/** 
+ * Check whether this channel is fully opened or not (local & remote)
+ * This also checks transport status
+ *
+ * @param[in]  handle        glink channel handle
+ *
+ * @return     TRUE,  if channel is fully opened
+ *             FASLE, otherwise
+ *
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+boolean glinki_channel_fully_opened
+(
+  glink_handle_type          handle
+);
+
+/*===========================================================================
+  FUNCTION      glink_core_qos_cancel
+===========================================================================*/
+/**
+
+  Releases QoS resources.
+
+  @param[in]  open_ch_ctx  Pointer to the channel context.
+
+  @return     None.
+
+  @sideeffects  None.
+*/
+/*=========================================================================*/
+void glink_core_qos_cancel(glink_channel_ctx_type *open_ch_ctx);
+
+/*===========================================================================
+  FUNCTION      glinki_register_link_notif_data
+===========================================================================*/
+/** 
+ * Register link notification data
+ *
+ * @param[in]  link_notif_data  parameter for link notif data
+ * 
+ * @return       NONE
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+void glinki_register_link_notif_data
+(
+  glink_link_notif_data_type *link_notif_data
+);
+
+/*===========================================================================
+  FUNCTION      glinki_deregister_link_notif_data
+===========================================================================*/
+/** 
+ * Deregister link notification data
+ *
+ * @param[in]  link_notif_data  parameter for link notif data
+ * 
+ * @return       NONE
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+void glinki_deregister_link_notif_data
+(
+  glink_link_notif_data_type *link_notif_data
+);
+
+/*===========================================================================
+  FUNCTION      glinki_scan_xports_and_notify
+===========================================================================*/
+/** 
+ * Scan xports and notify link up state event
+ *
+ * @param[in]  link_notif_data  parameter for link notif data
+ * 
+ * @return       NONE
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+void glinki_scan_xports_and_notify
+(
+  glink_link_notif_data_type *link_notif_data
+);
+
+/*===========================================================================
+  FUNCTION      glinki_scan_notif_list_and_notify
+===========================================================================*/
+/** 
+ * Scan registered link notification list and notify of xport link state change
+ *
+ * @param[in]  if_ptr  pointer to xport interface
+ * @param[in]  state   link state to notify
+ * 
+ * @return       NONE
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+void glinki_scan_notif_list_and_notify
+(
+  glink_transport_if_type *if_ptr,
+  glink_link_state_type state
+);
+
+/*===========================================================================
+  FUNCTION      glinki_xport_linkup
+===========================================================================*/
+/** 
+ * Check whether this transport is in linkup state or not
+ *
+ * @param[in]    if_ptr     transport interface pointer
+ * 
+ * @return       TRUE   if this xport is in link up state
+ *               FALSE  otherwise
+ * 
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+boolean glinki_xport_linkup
+(
+  glink_transport_if_type *if_ptr
+);
+
+/*===========================================================================
+  FUNCTION      glinki_xports_for_each
+===========================================================================*/
+/** 
+ * Scan all the transports in given edge and perform client's function for each
+ * transport
+ *
+ * @param[in]    remote_ss    name of remote subsystem, NULL string not accepted
+ * @param[in]    client_ex_fn client function to perform when desired xport is 
+ *                            found
+ * @param[in]    cond1        first condition to use in client_ex_fn
+ * @param[in]    cond2        second condition to use in client_ex_fn
+ * @param[out]   out          value to return in case client wants
+ *
+ * @return       None.
+ *
+ * @sideeffects  None.
+ */
+/*=========================================================================*/
+void glinki_xports_for_each
+(
+  const char         *remote_ss,
+  glink_client_ex_fn  client_ex_fn,
+  void               *param1,
+  uint32              param2,
+  void              **out
+);
+
+/*===========================================================================
+  FUNCTION      glinki_xports_find
+===========================================================================*/
+/** 
+ * Scan all the transports in given edge and finds transport that satisfy
+ * client's condition
+ *
+ * @param[in]    remote_ss      name of remote subsystem, NULL string not accepted
+ * @param[in]    client_cond_fn client function to check if this transport is 
+ *                              what client is looking for
+ * @param[in]    cond1          first condition to use in client_ex_fn
+ * @param[in]    cond2          second condition to use in client_ex_fn
+ * @param[out]   out            value to return in case client wants
+ *
+ * @return       pointer to glink_transport_if_type struct
+ *               NULL if there isn't any xport matches client's search condition
+ *
+ * @sideeffects  None.
+ */
+/*=========================================================================*/
+glink_transport_if_type *glinki_xports_find
+(
+  const char           *remote_ss,
+  glink_client_cond_fn  client_cond_fn,
+  void                 *cond1,
+  uint32                cond2,
+  void                **out
+);
+
+/*===========================================================================
+  FUNCTION      glinki_find_ch_ctx_by_lcid
+===========================================================================*/
+/** 
+ * Find channel context by lcid
+ *
+ * @param[in]    xport_ctx  Pointer to transport private context
+ * @param[in]    lcid       local channel ID
+ *
+ * @return       pointer to glink channel context
+ *
+ * @sideeffects  This function needs to be protected by channel_q_cs
+ *               Caller is responsible grab/release mutex when calling this
+ */
+/*=========================================================================*/
+glink_channel_ctx_type *glinki_find_ch_ctx_by_lcid
+(
+  glink_core_xport_ctx_type *xport_ctx,
+  uint32                     lcid
+);
+
+/*===========================================================================
+  FUNCTION      glinki_find_ch_ctx_by_rcid
+===========================================================================*/
+/** 
+ * Find channel context by rcid
+ *
+ * @param[in]    xport_ctx  Pointer to transport private context
+ * @param[in]    rcid       remote channel ID
+ *
+ * @return       pointer to glink channel context
+ *
+ * @sideeffects  This function needs to be protected by channel_q_cs
+ *               Caller is responsible grab/release mutex when calling this
+ */
+/*=========================================================================*/
+glink_channel_ctx_type *glinki_find_ch_ctx_by_rcid
+(
+  glink_core_xport_ctx_type *xport_ctx,
+  uint32                     rcid
+);
+
+/*===========================================================================
+  FUNCTION      glinki_find_ch_ctx_by_name
+===========================================================================*/
+/** 
+ * Find channel context by channel name, called by local/remote open function
+ * This function will also indicate (valid_open_call) if this open call would
+ * be valid or not
+ *
+ * @param[in]    xport_ctx  Pointer to transport private context
+ * @param[in]    ch_name    channel name
+ * @param[in]    local_open       flag to indicate this is local open call
+ * @param[out]   valid_open_call  tell whether this open call would be valid
+ *                                or not
+ *
+ * @return       pointer to glink channel context
+ *               NULL if channel doesn't exist
+ *
+ * @sideeffects  This function needs to be protected by channel_q_cs
+ *               Caller is responsible grab/release mutex when calling this
+ */
+/*=========================================================================*/
+glink_channel_ctx_type *glinki_find_ch_ctx_by_name
+(
+  glink_core_xport_ctx_type *xport_ctx,
+  const char                *ch_name,
+  boolean                    local_open,
+  boolean                   *valid_open_call
+);
+
+/*===========================================================================
+  FUNCTION      glinki_find_remote_host
+===========================================================================*/
+/** 
+ * return remote subsystem ID based on remote subsystem name
+ *
+ * @param[in]    remote_ss  remote subsystem name
+ *
+ * @return       remote subsystem ID
+ *
+ * @sideeffects  None.
+ */
+/*=========================================================================*/
+uint32 glinki_find_remote_host
+(
+  const char *remote_ss
+);
+
+/*===========================================================================
+  FUNCTION      glink_get_best_xport
+===========================================================================*/
+/** 
+ * This function gives best available transport for give edge
+ *
+ * @param[in]    remote_ss  Name of remote subsystem
+ * 
+ * @return       pointer to glink_transport_if_type
+ *
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+glink_transport_if_type *glinki_find_best_xport
+(
+  const char *remote_ss
+);
+
+/*===========================================================================
+  FUNCTION      glinki_find_requested_xport
+===========================================================================*/
+/** 
+ * Find requested or best transport depending on client's request
+ *
+ * @param[in]    xport_name         name of transport
+ * @param[in]    remote_ss          remote subsystem name
+ * @param[in]    open_ch_option     option client gave when called glink_open
+ * @param[out]   suggested_priority best xport priority glink suggests
+ *
+ * @return       pointer to glink_transport_if_type struct
+ *
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+glink_transport_if_type *glinki_find_requested_xport
+(
+  const char           *xport_name,
+  const char           *remote_ss,
+  uint32                open_ch_option,
+  glink_xport_priority *suggested_priority
+);
+
+/*===========================================================================
+  FUNCTION      glinki_find_xport_by_priority
+===========================================================================*/
+/** 
+ * This function returns glink_transport_if pointer based on transport priority
+ *
+ * @param[in]    prio        glink xport prio
+ * @param[in]    remote_ss   remote subsytem name
+ *
+ * @return       pointer to glink_transport_if_type struct
+ *
+ * @sideeffects  NONE
+ */
+/*=========================================================================*/
+glink_transport_if_type *glinki_find_xport_by_priority
+(
+  glink_xport_priority  prio,
+  const char           *remote_ss
+);
+
+/*===========================================================================
+  FUNCTION      glinki_enqueue_item
+===========================================================================*/
+/** 
+ *  Enqueue item to smem list in protected context
+ * 
+ * @param[in]    smem_list  smem list to enqueue
+ * @param[in]    item       item to enqueue
+ * @param[in]    cs         mutex to protect the list
+ *
+ * @return       None.
+ *
+ * @sideeffects  None.
+ */
+/*=========================================================================*/
+void glinki_enqueue_item
+(
+  smem_list_type *smem_list_ptr,
+  void           *item,
+  os_cs_type     *cs
+);
+
+/*===========================================================================
+  FUNCTION      glinki_dequeue_item
+===========================================================================*/
+/** 
+ *  Dequeue item from smem list in protected context
+ * 
+ * @param[in]    smem_list  smem list to dequeue from 
+ * @param[in]    item       item to dequeue
+ * @param[in]    cs         mutex to protect the list
+ *
+ * @return       None.
+ *
+ * @sideeffects  None.
+ */
+/*=========================================================================*/
+void glinki_dequeue_item
+(
+  smem_list_type *smem_list_ptr,
+  void           *item,
+  os_cs_type     *cs
+);
+
+/*===========================================================================
+  FUNCTION      glinki_update_logging_filter
+===========================================================================*/
+/** 
+ *  Update/Reset the logging filter if the name and remote host of the  
+ *  logging filter matches to that of the passed channel context
+ * 
+ * @param[in]    chnl_ctx   Channel content to match/compare
+ * @param[in]    reset      Indicate Update(FALSE) or Reset(TRUE)
+ *
+ * @return       None.
+ */
+/*=========================================================================*/
+void glinki_update_logging_filter
+(
+  glink_channel_ctx_type *chnl_ctx, 
+  boolean reset
+);
+
+/*===========================================================================
+  FUNCTION      glinki_acquire_edge_lock
+===========================================================================*/
+/** 
+ *  Acquires the transport_q_cs lock for the specified edge
+ * 
+ * @param[in]    remote_ss  Name of the remote sub system on the edge
+ *
+ * @return       None.
+ *
+ * @sideeffects  None.
+ */
+/*=========================================================================*/
+void glinki_acquire_edge_lock(const char *ss_name);
+
+/*===========================================================================
+  FUNCTION      glinki_release_edge_lock
+===========================================================================*/
+/** 
+ *  Releases the transport_q_cs lock for the specified edge
+ * 
+ * @param[in]    remote_ss  Name of the remote sub system on the edge
+ *
+ * @return       None.
+ *
+ * @sideeffects  None.
+ */
+/*=========================================================================*/
+void glinki_release_edge_lock(const char *ss_name);
+
+#ifdef FEATURE_TRACER_PACKET
+/*===========================================================================
+FUNCTION      glink_tracer_packet_log_pctx_pkt
+===========================================================================*/
+/** 
+ * Log tracer packet event. Tracer packet is included in glink_core_tx_pkt
+ * and needs to use vprovider to extract it
+ * 
+ * @param[in]  pctx     pointer to glink_core_tx_pkt_type
+ * @param[in]  event_id event_id
+ * 
+ * @return         None
+ *
+ * @sideeffects    None
+ */
+/*=========================================================================*/
+void glink_tracer_packet_log_pctx_pkt
+(
+  glink_core_tx_pkt_type  *pctx,
+  uint32                   event_id
+);
+#endif
+
 #endif /* GLINK_INTERNAL_H */
diff --git a/platform/msm_shared/include/glink_os_type.h b/platform/msm_shared/include/glink_os_type.h
index a129372..c904ee4 100644
--- a/platform/msm_shared/include/glink_os_type.h
+++ b/platform/msm_shared/include/glink_os_type.h
@@ -49,6 +49,13 @@
 ===========================================================================*/
 
 #define OS_LOG_INIT( ) glink_os_log_init()
+#define GLINK_OS_SEC_TO_USEC (1000000ULL)
+#define GLINK_OS_SEC_TO_TICK (19200000ULL)
+
+#define GLINK_OS_TICK_TO_USEC(t) ((t)*10ULL/192ULL)
+#define GLINK_OS_USEC_TO_TICK(u) ((u)*192ULL/10ULL)
+
+#define GLINK_OS_UNREFERENCED_PARAM( param ) ( void )param
 
 /*===========================================================================
                         TYPE DEFINITIONS
@@ -88,4 +95,6 @@
   uint32_t irq_out;
 } os_ipc_intr_type;
 
+typedef unsigned long long os_timetick_type;
+
 #endif /* OS_TYPE_H */
diff --git a/platform/msm_shared/include/glink_transport_if.h b/platform/msm_shared/include/glink_transport_if.h
index 84056b0..7ebe1fd 100644
--- a/platform/msm_shared/include/glink_transport_if.h
+++ b/platform/msm_shared/include/glink_transport_if.h
@@ -42,8 +42,8 @@
 /*===========================================================================
                         INCLUDE FILES
 ===========================================================================*/
+#include <glink.h>
 #include <smem_list.h>
-#include <glink_os_utils.h>
 
 /*===========================================================================
                       MACRO DECLARATIONS
@@ -83,7 +83,8 @@
   GLINK_XPORT_RPM = 100,
   GLINK_XPORT_SMD = 200,
   GLINK_XPORT_CP_ENGINE = 300,
-  GLINK_MIN_PRIORITY = GLINK_XPORT_CP_ENGINE,
+  GLINK_XPORT_UART = 400,
+  GLINK_MIN_PRIORITY = 100000,
   GLINK_INVALID_PRIORITY
 } glink_xport_priority;
 
@@ -93,7 +94,6 @@
 
   void       *data;      /* Pointer to the data buffer to be transmitted */
   const void *pkt_priv;  /* Per packet private data */
-  uint32     cid;        /* Local channel ID being used to transmit data */
   uint32     iid;        /* Remote intent ID being used to transmit data */
   size_t     size;       /* Size of data buffer */
   size_t     size_remaining; /* Size left to transmit */
@@ -264,6 +264,76 @@
   glink_transport_if_type *if_ptr   /* Pointer to the interface instance */
 );
 
+/** Provides data rate (tokens/sec) achievable by the transport for given 
+    packet size and latency. */
+typedef uint32 (*get_req_rate_fn)
+(
+  glink_transport_if_type *if_ptr,    /* Pointer to the interface instance */
+  uint32                  latency_us, /* latency in us */
+  size_t                  pkt_size    /* Size of the packet */
+);
+
+/** Allocates context structure to use by transport servicing given QoS request. */
+typedef void* (*alloc_req_ctx_fn)
+(
+  glink_transport_if_type *if_ptr,    /* Pointer to the interface instance */
+  uint32                  latency_us, /* latency in us */
+  size_t                  pkt_size    /* Size of the packet */
+);
+
+/** Frees context structure used by transport servicing given QoS request. */
+typedef void (*free_req_ctx_fn)
+(
+  glink_transport_if_type *if_ptr,    /* Pointer to the interface instance */
+  void                    *qos_ctx    /* Pointer to the transport QoS context */
+);
+
+/** Starts QoS mode. */
+typedef void (*start_req_fn)
+(
+  glink_transport_if_type *if_ptr,    /* Pointer to the interface instance */
+  void                    *qos_ctx    /* Pointer to the transport QoS context */
+);
+
+/** Stops QoS mode. */
+typedef void (*stop_req_fn)
+(
+  glink_transport_if_type *if_ptr,    /* Pointer to the interface instance */
+  void                    *qos_ctx    /* Pointer to the transport QoS context */
+);
+
+/** Provides ramp up time in microseconds. */
+typedef uint32 (*get_ramp_time_fn)
+(
+  glink_transport_if_type *if_ptr,    /* Pointer to the interface instance */
+  void                    *qos_ctx    /* Pointer to the transport QoS context */
+);
+
+
+/**
+* Data Structure for GLink Core to call into transport QoS API
+*
+* This structure is used by the GLink core to operate transport
+* This set of function pointers to to be filled in by the transport
+* abstraction layer.
+*/
+typedef struct glink_transport_qos_if_s {
+  /** Provides maximum data rate (tokens/sec) associated with transport. */
+  uint32 max_rate;
+  /** Provides data rate achievable by the transport for given request. */
+  get_req_rate_fn  get_req_rate;
+  /** Allocates context structure to use by transport servicing given QoS request. */
+  alloc_req_ctx_fn alloc_req_ctx;
+  /** Frees context structure used by transport servicing given QoS request. */
+  free_req_ctx_fn  free_req_ctx;
+  /** Starts QoS mode. */
+  start_req_fn     start_req;
+  /** Stops QoS mode. */
+  stop_req_fn      stop_req;
+  /** Provides ramp up time in microseconds. */
+  get_ramp_time_fn get_ramp_time;
+
+} glink_transport_qos_if_type;
 
 /**
  * Data Structure for GLink Core to call into transport API
@@ -359,6 +429,9 @@
 
   /* glink transport priority */
   glink_xport_priority                glink_priority;
+
+  /* pointer to glink transport QoS interface */
+  glink_transport_qos_if_type        *qos_functbl;
 };
 
 #endif //GLINK_TRANSPORT_IF_H
diff --git a/platform/msm_shared/include/glink_vector.h b/platform/msm_shared/include/glink_vector.h
index 863c19a..9f705ec 100644
--- a/platform/msm_shared/include/glink_vector.h
+++ b/platform/msm_shared/include/glink_vector.h
@@ -37,9 +37,7 @@
 
 
 /*===========================================================================
-
                         INCLUDE FILES
-
 ===========================================================================*/
 #include "glink.h"
 
diff --git a/platform/msm_shared/mipi_dsi.c b/platform/msm_shared/mipi_dsi.c
index 06c4804..0474f37 100644
--- a/platform/msm_shared/mipi_dsi.c
+++ b/platform/msm_shared/mipi_dsi.c
@@ -781,7 +781,7 @@
 		writel(data, ctl_base + COMMAND_MODE_MDP_STREAM1_TOTAL);
 
 		if (dsc->dsi_dsc_config)
-			dsc->dsi_dsc_config(pinfo->mipi.ctl_base, DSI_VIDEO_MODE, dsc);
+			dsc->dsi_dsc_config(pinfo->mipi.ctl_base, DSI_CMD_MODE, dsc);
 	} else {
 
 		writel((img_width * ystride + 1) << 16 | 0x0039,
diff --git a/platform/msm_shared/mmc_sdhci.c b/platform/msm_shared/mmc_sdhci.c
index 3bc7110..20eb840 100644
--- a/platform/msm_shared/mmc_sdhci.c
+++ b/platform/msm_shared/mmc_sdhci.c
@@ -2178,7 +2178,7 @@
 	 * As per emmc 4.5 spec section 7.4.27, calculate the erase timeout
 	 * erase_timeout = 300ms * ERASE_TIMEOUT_MULT * num_erase_grps
 	 */
-	erase_timeout = (300 * 1000 * card->ext_csd[MMC_ERASE_TIMEOUT_MULT] * num_erase_grps);
+	erase_timeout = ((uint64_t)300 * 1000 * card->ext_csd[MMC_ERASE_TIMEOUT_MULT] * num_erase_grps);
 
 	/* Send CMD38 to perform erase */
 	if (mmc_send_erase(dev, erase_timeout))
diff --git a/platform/msm_shared/qmp_usb30_phy.c b/platform/msm_shared/qmp_usb30_phy.c
index 54a8831..91aed89 100644
--- a/platform/msm_shared/qmp_usb30_phy.c
+++ b/platform/msm_shared/qmp_usb30_phy.c
@@ -36,6 +36,7 @@
 #include <clock.h>
 #include <debug.h>
 #include <qtimer.h>
+#include <platform.h>
 
 #define HS_PHY_COMMON_CTRL             0xEC
 #define USE_CORECLK                    BIT(14)
@@ -64,15 +65,11 @@
 	{0x174, 0x30}, /* QSERDES_COM_CLK_SELECT */
 	{0x194, 0x06}, /* QSERDES_COM_CMN_CONFIG */
 	{0x19c, 0x01}, /* QSERDES_COM_SVS_MODE_CLK_SEL */
-	{0x178, 0x01}, /* QSERDES_COM_HSCLK_SEL */
+	{0x178, 0x00}, /* QSERDES_COM_HSCLK_SEL */
 	{0x70, 0x0F}, /* USB3PHY_QSERDES_COM_BG_TRIM */
 	{0x48, 0x0F}, /* USB3PHY_QSERDES_COM_PLL_IVCO */
 	{0x3C, 0x04}, /* QSERDES_COM_SYS_CLK_CTRL */
 
-	/* Res_code Settings */
-	{0xC4, 0x15}, /* USB3PHY_QSERDES_COM_RESCODE_DIV_NUM */
-	{0x1B8, 0x1F}, /* QSERDES_COM_CMN_MISC2 */
-
 	/* PLL & Loop filter settings */
 	{0xd0, 0x82}, /* QSERDES_COM_DEC_START_MODE0 */
 	{0xdc, 0x55}, /* QSERDES_COM_DIV_FRAC_START1_MODE0 */
@@ -134,6 +131,15 @@
 	{0x600, 0x00}, /* USB3_PHY_SW_RESET */
 };
 
+#if PLATFORM_USE_QMP_MISC
+struct qmp_reg qmp_misc_settings_rev2[] =
+{
+	{0x178, 0x01}, /* QSERDES_COM_HSCLK_SEL */
+	{0xC4, 0x15}, /* USB3PHY_QSERDES_COM_RESCODE_DIV_NUM */
+	{0x1B8, 0x1F}, /* QSERDES_COM_CMN_MISC2 */
+};
+#endif
+
 __WEAK uint32_t target_override_pll()
 {
 	return 0;
@@ -265,6 +271,11 @@
 		for (i = 0 ; i < qmp_reg_size; i++)
 			writel(qmp_settings_rev2[i].val, QMP_PHY_BASE + qmp_settings_rev2[i].off);
 
+#if PLATFORM_USE_QMP_MISC
+		if (platform_use_qmp_misc_settings())
+			for (i = 0; i < ARRAY_SIZE(qmp_misc_settings_rev2); i++)
+				writel(qmp_misc_settings_rev2[i].val, QMP_PHY_BASE + qmp_misc_settings_rev2[i].off);
+#endif
 		if (target_override_pll())
 		{
 			qmp_reg_size = sizeof(qmp_override_pll_rev2) / sizeof(struct qmp_reg);
diff --git a/platform/msm_shared/qusb2_phy.c b/platform/msm_shared/qusb2_phy.c
index fab6e09..871bbcc 100644
--- a/platform/msm_shared/qusb2_phy.c
+++ b/platform/msm_shared/qusb2_phy.c
@@ -25,7 +25,7 @@
  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-
+#include <arch/defines.h>
 #include <platform/iomap.h>
 #include <qusb2_phy.h>
 #include <reg.h>
@@ -55,6 +55,10 @@
 	udelay(10);
 	writel(val & ~BIT(0), GCC_QUSB2_PHY_BCR);
 
+	/* configure the abh2 phy to wait state */
+	writel(0x11, PERIPH_SS_AHB2PHY_TOP_CFG);
+	dmb();
+
 	/* set CLAMP_N_EN and stay with disabled USB PHY */
 	writel(0x23, QUSB2PHY_PORT_POWERDOWN);
 
diff --git a/platform/msm_shared/reboot.c b/platform/msm_shared/reboot.c
index 2fe514e..8f53633 100644
--- a/platform/msm_shared/reboot.c
+++ b/platform/msm_shared/reboot.c
@@ -69,14 +69,12 @@
 unsigned check_hard_reboot_mode(void)
 {
 	uint8_t hard_restart_reason = 0;
-	uint8_t value = 0;
 
 	/* Read reboot reason and scrub it
 	 * Bit-5, bit-6 and bit-7 of SOFT_RB_SPARE for hard reset reason
 	 */
-	value = REG_READ(PON_SOFT_RB_SPARE);
-	hard_restart_reason = value >> 5;
-	REG_WRITE(PON_SOFT_RB_SPARE, value & 0x1f);
+	hard_restart_reason = REG_READ(PON_SOFT_RB_SPARE);
+	REG_WRITE(PON_SOFT_RB_SPARE, hard_restart_reason & 0x1f);
 
 	return hard_restart_reason;
 }
@@ -112,7 +110,7 @@
 
 #if USE_PON_REBOOT_REG
 	value = REG_READ(PON_SOFT_RB_SPARE);
-	value |= ((reboot_reason << 5) & 0xff);
+	value |= reboot_reason;
 	REG_WRITE(PON_SOFT_RB_SPARE, value);
 #else
 	writel(reboot_reason, RESTART_REASON_ADDR);
diff --git a/platform/msm_shared/reboot.h b/platform/msm_shared/reboot.h
index c87f9d8..bf39988 100644
--- a/platform/msm_shared/reboot.h
+++ b/platform/msm_shared/reboot.h
@@ -26,9 +26,15 @@
  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+#if USE_PON_REBOOT_REG
+#define RECOVERY_MODE     0x20
+#define FASTBOOT_MODE     0x40
+#define ALARM_BOOT        0x60
+#else
 #define FASTBOOT_MODE     0x77665500
 #define RECOVERY_MODE     0x77665502
 #define ALARM_BOOT        0x77665503
+#endif
 
 #define RTC_TRG           4
 #define PON_SOFT_RB_SPARE 0x88F
diff --git a/platform/msm_shared/rpmb/rpmb_listener.c b/platform/msm_shared/rpmb/rpmb_listener.c
index c9623e2..480a235 100644
--- a/platform/msm_shared/rpmb/rpmb_listener.c
+++ b/platform/msm_shared/rpmb/rpmb_listener.c
@@ -97,7 +97,7 @@
 
 	init_resp->cmd_id = init_req_p->cmd_id;
 	init_resp->version = RPMB_LSTNR_VERSION_2;
-	init_resp->num_sectors = rpmb_info->size / RPMB_SECTOR_SIZE;
+	init_resp->num_sectors = rpmb_info->size;
 	init_resp->rel_wr_count = rpmb_info->rel_wr_count;
 	init_resp->dev_type = rpmb_info->dev_type;
 }
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index eb7107d..bffa003 100644
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -55,6 +55,7 @@
 		$(LOCAL_DIR)/rpm-ipc.o \
 		$(LOCAL_DIR)/glink/glink_api.o \
 		$(LOCAL_DIR)/glink/glink_core_if.o \
+		$(LOCAL_DIR)/glink/glink_core_internal.o \
 		$(LOCAL_DIR)/glink/glink_rpmcore_setup.o \
 		$(LOCAL_DIR)/glink/glink_core_intentless_xport.o \
 		$(LOCAL_DIR)/glink/glink_os_utils_dal.o \
diff --git a/platform/msm_shared/sdhci.c b/platform/msm_shared/sdhci.c
index bfab9f1..f114b47 100644
--- a/platform/msm_shared/sdhci.c
+++ b/platform/msm_shared/sdhci.c
@@ -441,7 +441,13 @@
 
 		if (int_status  & SDHCI_INT_STS_CMD_COMPLETE)
 			break;
-		else if (int_status & SDHCI_ERR_INT_STAT_MASK && !host->tuning_in_progress)
+		/*
+		* Some controllers set the data timout first on issuing an erase & take time
+		* to set data complete interrupt. We need to wait hoping the controller would
+		* set data complete
+		*/
+		else if (int_status & SDHCI_ERR_INT_STAT_MASK && !host->tuning_in_progress &&
+				!((REG_READ16(host, SDHCI_ERR_INT_STS_REG) & SDHCI_DAT_TIMEOUT_MASK)))
 			goto err;
 
 		/*
diff --git a/platform/msm_shared/smem.h b/platform/msm_shared/smem.h
index 0afa45f..a342f86 100644
--- a/platform/msm_shared/smem.h
+++ b/platform/msm_shared/smem.h
@@ -427,6 +427,11 @@
 	FSM9916  = 276,
 	APQ8076  = 277,
 	MSM8976  = 278,
+	MDMCALIFORNIUM1  = 279,
+	MDMCALIFORNIUM2  = 283,
+	MDMCALIFORNIUM3  = 284,
+	MDMCALIFORNIUM4  = 285,
+	MDMCALIFORNIUM5  = 286,
 	APQ8052  = 289,
 	MDMFERMIUM  = 290,
 	APQ8096  = 291,
@@ -468,6 +473,7 @@
 	HW_PLATFORM_SUBTYPE_DSDA = 7,
 	HW_PLATFORM_SUBTYPE_DSDA2 = 8,
 	HW_PLATFORM_SUBTYPE_SGLTE2 = 9,
+	HW_PLATFORM_SUBTYPE_POLARIS = 64,
 	HW_PLATFORM_SUBTYPE_32BITS = 0x7FFFFFFF
 };
 
diff --git a/project/msm8996.mk b/project/msm8996.mk
index 4f6d1db..f0e618a 100644
--- a/project/msm8996.mk
+++ b/project/msm8996.mk
@@ -70,8 +70,6 @@
 
 ifeq ($(ENABLE_MDTP_SUPPORT),1)
 DEFINES += MDTP_SUPPORT=1
-DEFINES += MDTP_EFUSE_ADDRESS=0x00070178 # QFPROM_CORR_ANTI_ROLLBACK_3_LSB_ADDR
-DEFINES += MDTP_EFUSE_START=0
 endif
 
 ifeq ($(ENABLE_LPAE_SUPPORT),1)
@@ -87,3 +85,7 @@
 ENABLE_REBOOT_MODULE := 1
 #fuse for Qusb tun2 config
 DEFINES += QFPROM_CORR_CALIB_ROW12_MSB=0x0007424C
+#Use misc settings for qmp
+DEFINES += PLATFORM_USE_QMP_MISC=1
+#Use PON register for reboot reason
+DEFINES += USE_PON_REBOOT_REG=1
diff --git a/target/init.c b/target/init.c
index fba226c..6eba00e 100644
--- a/target/init.c
+++ b/target/init.c
@@ -28,6 +28,11 @@
 #include <compiler.h>
 #include <dload_util.h>
 #include <sdhci_msm.h>
+#if PON_VIB_SUPPORT
+#include <smem.h>
+#include <vibrator.h>
+#include <board.h>
+#endif
 
 #define EXPAND(NAME) #NAME
 #define TARGET(NAME) EXPAND(NAME)
@@ -221,6 +226,39 @@
 	return DDR_CONFIG_VAL;
 }
 
+#if PON_VIB_SUPPORT
+uint32_t get_vibration_type()
+{
+	uint32_t ret = VIB_ERM_TYPE;
+	uint32_t hw_id = board_hardware_id();
+	uint32_t platform = board_platform_id();
+	switch(hw_id){
+	case HW_PLATFORM_MTP:
+		switch(platform){
+		case MSM8952:
+			ret = VIB_ERM_TYPE;
+			break;
+		case MSM8976:
+		case MSM8956:
+		case APQ8056:
+			ret = VIB_LRA_TYPE;
+			break;
+		default:
+			dprintf(CRITICAL,"Unsupported platform id\n");
+			break;
+		}
+		break;
+	case HW_PLATFORM_QRD:
+		ret = VIB_ERM_TYPE;
+		break;
+	default:
+		dprintf(CRITICAL,"Unsupported platform id\n");
+		break;
+	}
+	return ret;
+}
+#endif
+
 /* Return Build variant */
 __WEAK bool target_build_variant_user()
 {
diff --git a/target/mdm9635/init.c b/target/mdm9635/init.c
index 7557d75..807e3be 100644
--- a/target/mdm9635/init.c
+++ b/target/mdm9635/init.c
@@ -285,17 +285,17 @@
 	return restart_reason;
 }
 
-int get_target_boot_params(const char *cmdline, const char *part, char *buf,
-			   int buflen)
+int get_target_boot_params(const char *cmdline, const char *part, char **buf)
 {
 	struct ptable *ptable;
 	int system_ptn_index = -1;
+	/*allocate buflen for largest string*/
+	uint32_t buflen = strlen(" root=/dev/mtdblock") + sizeof(int) + 1; /*1 character for null termination*/
 
-	if (!cmdline || !part || !buf || buflen < 0) {
+	if (!cmdline || !part ) {
 		dprintf(CRITICAL, "WARN: Invalid input param\n");
 		return -1;
 	}
-
 	ptable = flash_get_ptable();
 	if (!ptable) {
 		dprintf(CRITICAL,
@@ -303,10 +303,16 @@
 		return -1;
 	}
 
+	*buf = (char *)malloc(buflen);
+	if(!(*buf)) {
+		dprintf(CRITICAL,"Unable to allocate memory for boot params\n");
+		return -1;
+	}
 	system_ptn_index = ptable_get_index(ptable, part);
 	if (system_ptn_index < 0) {
 		dprintf(CRITICAL,
 			"WARN: Cannot get partition index for %s\n", part);
+		free(*buf);
 		return -1;
 	}
 
@@ -320,17 +326,17 @@
 			(strstr(cmdline, " root="))))
 			dprintf(DEBUG, "DEBUG: cmdline has root=\n");
 		else
-			snprintf(buf, buflen, " root=/dev/mtdblock%d",
+			snprintf(*buf, buflen, " root=/dev/mtdblock%d",
 					system_ptn_index);
 	} else if (strstr(cmdline, "rootfstype=ubifs")){
 		if (((!strncmp(cmdline, "ubi.mtd=", strlen("ubi.mtd="))) ||
 			(strstr(cmdline, " ubi.mtd="))))
 			dprintf(DEBUG, "DEBUG: cmdline has ubi.mtd=\n");
 		else
-			snprintf(buf, buflen, " ubi.mtd=%d",
+			snprintf(*buf, buflen, " ubi.mtd=%d",
 				system_ptn_index);
 	}
-
+	/*in success case buf will be freed in the calling function of this*/
 	return 0;
 }
 
diff --git a/target/mdm9640/init.c b/target/mdm9640/init.c
index 2d2bb4b..565b0b2 100644
--- a/target/mdm9640/init.c
+++ b/target/mdm9640/init.c
@@ -234,13 +234,13 @@
 	return restart_reason;
 }
 
-int get_target_boot_params(const char *cmdline, const char *part, char *buf,
-			   int buflen)
+int get_target_boot_params(const char *cmdline, const char *part, char **buf)
 {
 	struct ptable *ptable;
 	int system_ptn_index = -1;
+	uint32_t buflen;
 
-	if (!cmdline || !part || !buf || buflen < 0) {
+	if (!cmdline || !part ) {
 		dprintf(CRITICAL, "WARN: Invalid input param\n");
 		return -1;
 	}
@@ -248,11 +248,19 @@
 	if (!strstr(cmdline, "root=/dev/ram")) /* This check is to handle kdev boot */
 	{
 		if (!target_is_emmc_boot()) {
+
+			buflen = strlen(UBI_CMDLINE) + strlen(" root=ubi0:rootfs ubi.mtd=") + sizeof(int) + 1;
+			*buf = (char *)malloc(buflen);
+			if(!(*buf)) {
+				dprintf(CRITICAL,"Unable to allocate memory for boot params\n");
+				return -1;
+			}
 			/* Below is for NAND boot */
 			ptable = flash_get_ptable();
 			if (!ptable) {
 				dprintf(CRITICAL,
 						"WARN: Cannot get flash partition table\n");
+				free(*buf);
 				return -1;
 			}
 
@@ -260,23 +268,32 @@
 			if (system_ptn_index < 0) {
 				dprintf(CRITICAL,
 					"WARN: Cannot get partition index for %s\n", part);
+				free(*buf);
 				return -1;
 			}
 			/* Adding command line parameters according to target boot type */
-			snprintf(buf, buflen, UBI_CMDLINE);
-			snprintf(buf+strlen(buf), buflen, " root=ubi0:rootfs ubi.mtd=%d", system_ptn_index);
+			snprintf(*buf, buflen, UBI_CMDLINE);
+			snprintf(*buf+strlen(*buf), buflen, " root=ubi0:rootfs ubi.mtd=%d", system_ptn_index);
 		}
 		else {
+			buflen = strlen("EXT4_CMDLINE") + sizeof(int) +1;
+			*buf = (char *)malloc(buflen);
+			if(!(*buf)) {
+				dprintf(CRITICAL,"Unable to allocate memory for boot params\n");
+				return -1;
+			}
 			/* Below is for emmc boot */
 			system_ptn_index = partition_get_index(part) + 1; /* Adding +1 as offsets for eMMC start at 1 and NAND at 0 */
 			if (system_ptn_index < 0) {
 				dprintf(CRITICAL,
 						"WARN: Cannot get partition index for %s\n", part);
+				free(*buf);
 				return -1;
 			}
-			snprintf(buf, buflen, EXT4_CMDLINE"%d", system_ptn_index);
+			snprintf(*buf, buflen, EXT4_CMDLINE"%d", system_ptn_index);
 		}
 	}
+	/*in success case buf will be freed in the calling function of this*/
 	return 0;
 }
 
diff --git a/target/mdmfermium/init.c b/target/mdmfermium/init.c
index 8c58278..1ccc227 100644
--- a/target/mdmfermium/init.c
+++ b/target/mdmfermium/init.c
@@ -83,6 +83,7 @@
 #define QPIC_NAND_MAX_DESC_LEN   0x7FFF
 
 #define LAST_NAND_PTN_LEN_PATTERN 0xFFFFFFFF
+#define UBI_CMDLINE " rootfstype=ubifs rootflags=bulk_read"
 
 struct qpic_nand_init_config config;
 
@@ -209,22 +210,34 @@
 	return restart_reason;
 }
 
-int get_target_boot_params(const char *cmdline, const char *part, char *buf,int buflen)
+int get_target_boot_params(const char *cmdline, const char *part, char **buf)
 {
 	struct ptable *ptable;
 	int system_ptn_index = -1;
+	uint32_t buflen = strlen(UBI_CMDLINE) + strlen(" root=ubi0:rootfs ubi.mtd=") + sizeof(int) + 1; /* 1 byte for null character*/
+
+	*buf = (char *)malloc(buflen);
+	if(!(*buf)) {
+		dprintf(CRITICAL,"Unable to allocate memory for boot params\n");
+		return -1;
+	}
 
 	ptable = flash_get_ptable();
 	if (!ptable) {
 		dprintf(CRITICAL,"WARN: Cannot get flash partition table\n");
+		free(*buf);
 		return -1;
 	}
 
 	system_ptn_index = ptable_get_index(ptable, part);
 	if (system_ptn_index < 0) {
 		dprintf(CRITICAL,"WARN: Cannot get partition index for %s\n", part);
+		free(*buf);
 		return -1;
 	}
+	/* Adding command line parameters according to target boot type */
+	snprintf(*buf, buflen, UBI_CMDLINE);
+
 	/*check if cmdline contains "root=" at the beginning of buffer or
 	* " root=" in the middle of buffer.
 	*/
@@ -232,7 +245,8 @@
 		(strstr(cmdline, " root="))))
 		dprintf(DEBUG, "DEBUG: cmdline has root=\n");
 	else
-		snprintf(buf, buflen, " root=/dev/mtdblock%d",system_ptn_index);
+		snprintf(*buf+strlen(*buf), buflen, " root=ubi0:rootfs ubi.mtd=%d", system_ptn_index);
+		/*in success case buf will be freed in the calling function of this*/
 	return 0;
 }
 
diff --git a/target/mdmfermium/meminfo.c b/target/mdmfermium/meminfo.c
index b66166e..acaaa14 100644
--- a/target/mdmfermium/meminfo.c
+++ b/target/mdmfermium/meminfo.c
@@ -90,6 +90,5 @@
 
 unsigned target_get_max_flash_size(void)
 {
-	/*24.5MB*/
 	return (SCRATCH_REGION1_SIZE + SCRATCH_REGION2_SIZE);
 }
diff --git a/target/mdmfermium/rules.mk b/target/mdmfermium/rules.mk
index ed3553f..59f53ff 100644
--- a/target/mdmfermium/rules.mk
+++ b/target/mdmfermium/rules.mk
@@ -4,17 +4,17 @@
 
 PLATFORM := mdmfermium
 
-MEMBASE := 0x87A00000 # SDRAM
+MEMBASE := 0x82900000 # SDRAM
 MEMSIZE := 0x00100000 # 1MB
 
-SCRATCH_ADDR                        := 0x81200000
-SCRATCH_REGION1                     := 0x81200000
-SCRATCH_REGION1_SIZE                := 0x1800000  # 24MB
-SCRATCH_REGION2                     := 0x87F80000
-SCRATCH_REGION2_SIZE                := 0x80000    # 512KB
+SCRATCH_ADDR                        := 0x88000000
+SCRATCH_REGION1                     := 0x88000000
+SCRATCH_REGION1_SIZE                := 0x08000000 # 128MB
+SCRATCH_REGION2                     := 0x0
+SCRATCH_REGION2_SIZE                := 0x0
 
 KERNEL_REGION                       := 0x80000000
-KERNEL_REGION_SIZE                  := 0x1200000 # 18MB
+KERNEL_REGION_SIZE                  := 0x2000000 # 20MB
 
 BASE_ADDR                           := 0x80000000
 
@@ -33,7 +33,6 @@
 	BASE_ADDR=$(BASE_ADDR) \
 	SCRATCH_ADDR=$(SCRATCH_ADDR) \
 	SCRATCH_REGION1=$(SCRATCH_REGION1) \
-	SCRATCH_REGION2=$(SCRATCH_REGION2) \
 	SCRATCH_REGION1_SIZE=$(SCRATCH_REGION1_SIZE) \
 	SCRATCH_REGION2_SIZE=$(SCRATCH_REGION2_SIZE) \
 	KERNEL_REGION=$(KERNEL_REGION) \
diff --git a/target/msm8909/init.c b/target/msm8909/init.c
index b115bf8..166cec4 100644
--- a/target/msm8909/init.c
+++ b/target/msm8909/init.c
@@ -466,22 +466,29 @@
         splash_override = override;
 }
 
-int get_target_boot_params(const char *cmdline, const char *part, char *buf,
-                           int buflen)
+int get_target_boot_params(const char *cmdline, const char *part, char **buf)
 {
 	struct ptable *ptable;
 	int system_ptn_index = -1;
+	uint32_t buflen;
 
 	if (!target_is_emmc_boot()) {
 		if (!cmdline || !part || !buf || buflen < 0) {
 			dprintf(CRITICAL, "WARN: Invalid input param\n");
 			return -1;
 		}
+		buflen = strlen(" root=/dev/mtdblock") + sizeof(int) + 1; /*1 character for null termination*/
+		*buf = (char *)malloc(buflen);
+		if(!(*buf)) {
+			dprintf(CRITICAL,"Unable to allocate memory for boot params\n");
+			return -1;
+		}
 
 		ptable = flash_get_ptable();
 		if (!ptable) {
 			dprintf(CRITICAL,
 				"WARN: Cannot get flash partition table\n");
+			free(*buf);
 			return -1;
 		}
 
@@ -489,6 +496,7 @@
 		if (system_ptn_index < 0) {
 			dprintf(CRITICAL,
 				"WARN: Cannot get partition index for %s\n", part);
+			free(*buf);
 			return -1;
 		}
 
@@ -500,8 +508,9 @@
 			(strstr(cmdline, " root="))))
 			dprintf(DEBUG, "DEBUG: cmdline has root=\n");
 		else
-			snprintf(buf, buflen, " root=/dev/mtdblock%d",
+			snprintf(*buf, buflen, " root=/dev/mtdblock%d",
                                  system_ptn_index);
+		/*in success case buf will be freed in the calling function of this*/
 	}
 
 	return 0;
@@ -548,7 +557,7 @@
 	if (is_cold_boot &&
 			(!(pon_reason & HARD_RST)) &&
 			(!(pon_reason & KPDPWR_N)) &&
-			((pon_reason & USB_CHG) || (pon_reason & DC_CHG)))
+			((pon_reason & USB_CHG) || (pon_reason & DC_CHG) || (pon_reason & CBLPWR_N)))
 		return 1;
 	else
 		return 0;
diff --git a/target/msm8952/oem_panel.c b/target/msm8952/oem_panel.c
index 57e069f..30a56e9 100644
--- a/target/msm8952/oem_panel.c
+++ b/target/msm8952/oem_panel.c
@@ -53,6 +53,7 @@
 #include "include/panel_hx8399a_1080p_video.h"
 #include "include/panel_nt35597_wqxga_dsc_video.h"
 #include "include/panel_nt35597_wqxga_dsc_cmd.h"
+#include "include/panel_hx8394d_720p_video.h"
 
 /*---------------------------------------------------------------------------*/
 /* static panel selection variable                                           */
@@ -67,6 +68,7 @@
 	HX8399A_1080P_VIDEO_PANEL,
 	NT35597_WQXGA_DSC_VIDEO_PANEL,
 	NT35597_WQXGA_DSC_CMD_PANEL,
+	HX8394D_720P_VIDEO_PANEL,
 	UNKNOWN_PANEL
 };
 
@@ -88,6 +90,7 @@
 	{"hx8399a_1080p_video", HX8399A_1080P_VIDEO_PANEL},
 	{"nt35597_wqxga_dsc_video", NT35597_WQXGA_DSC_VIDEO_PANEL},
 	{"nt35597_wqxga_dsc_cmd", NT35597_WQXGA_DSC_CMD_PANEL},
+	{"hx8394d_720p_video", HX8394D_720P_VIDEO_PANEL},
 };
 
 static uint32_t panel_id;
@@ -403,6 +406,31 @@
 		pinfo->dsc.dsi_dsc_config = mdss_dsc_dsi_config;
 		pinfo->dsc.mdp_dsc_config = mdss_dsc_mdp_config;
 		break;
+	case HX8394D_720P_VIDEO_PANEL:
+		panelstruct->paneldata	  = &hx8394d_720p_video_panel_data;
+		panelstruct->panelres	  = &hx8394d_720p_video_panel_res;
+		panelstruct->color		  = &hx8394d_720p_video_color;
+		panelstruct->videopanel   = &hx8394d_720p_video_video_panel;
+		panelstruct->commandpanel = &hx8394d_720p_video_command_panel;
+		panelstruct->state		  = &hx8394d_720p_video_state;
+		panelstruct->laneconfig   = &hx8394d_720p_video_lane_config;
+		panelstruct->paneltiminginfo
+					 = &hx8394d_720p_video_timing_info;
+		panelstruct->panelresetseq
+					 = &hx8394d_720p_video_panel_reset_seq;
+		panelstruct->backlightinfo = &hx8394d_720p_video_backlight;
+		pinfo->mipi.panel_on_cmds
+					= hx8394d_720p_video_on_command;
+		pinfo->mipi.num_of_panel_on_cmds
+					= HX8394D_720P_VIDEO_ON_COMMAND;
+		pinfo->mipi.panel_off_cmds
+					= hx8394d_720p_video_off_command;
+		pinfo->mipi.num_of_panel_off_cmds
+					= HX8394D_720P_VIDEO_OFF_COMMAND;
+		memcpy(phy_db->timing,
+				hx8394d_720p_video_timings, TIMING_SIZE);
+		pinfo->mipi.signature = HX8394D_720P_VIDEO_SIGNATURE;
+		break;
 	case UNKNOWN_PANEL:
 	default:
 		memset(panelstruct, 0, sizeof(struct panel_struct));
@@ -434,6 +462,7 @@
 {
 	uint32_t hw_id = board_hardware_id();
 	int32_t panel_override_id;
+	uint32_t target_id, plat_hw_ver_major;
 
 	if (panel_name) {
 		panel_override_id = panel_name_to_id(supp_panels,
@@ -467,7 +496,17 @@
 			panel_id = TRULY_1080P_VIDEO_PANEL;
 		break;
 	case HW_PLATFORM_QRD:
-		panel_id = OTM1906C_1080P_CMD_PANEL;
+		target_id = board_target_id();
+		plat_hw_ver_major = ((target_id >> 16) & 0xFF);
+
+		/*
+		 * 8952 SKUM DVT2 - HX8399A 1080p video panel
+		 * 8952 SKUM EVT1/EVT2 - OTM1906C 1080p cmd panel
+		 */
+		if (plat_hw_ver_major >= 4)
+			panel_id = HX8399A_1080P_VIDEO_PANEL;
+		else
+			panel_id = OTM1906C_1080P_CMD_PANEL;
 
 		/* QRD EVT1 uses OTM1906C, and EVT2 uses HX8399A */
 		if (platform_is_msm8956()) {
diff --git a/target/msm8952/target_display.c b/target/msm8952/target_display.c
index f4664ec..b2585fc 100644
--- a/target/msm8952/target_display.c
+++ b/target/msm8952/target_display.c
@@ -51,15 +51,6 @@
 #include "include/display_resource.h"
 #include "gcdb_display.h"
 
-#define DSC_CMD_PANEL "dsc_cmd_panel"
-#define DSC_VID_PANEL "dsc_vid_panel"
-#define DSC_VID_PANEL_ADV7533_1080P "dsc_vid_panel_adv7533_1080p"
-#define DSC_CMD_PANEL_ADV7533_1080P "dsc_cmd_panel_adv7533_1080p"
-#define DSC_CMD_PANEL_STRING "1:dsi:0:none:1:qcom,mdss_dsi_nt35597_dsc_wqxga_cmd:cfg:single_dsi"
-#define DSC_VID_PANEL_STRING "1:dsi:0:none:1:qcom,mdss_dsi_nt35597_dsc_wqxga_video:cfg:single_dsi"
-#define DSC_CMD_PANEL_ADV7533_1080P_STRING "1:dsi:0:qcom,mdss_dsi_adv7533_1080p:1:qcom,mdss_dsi_nt35597_dsc_wqxga_cmd:cfg:dual_dsi"
-#define DSC_VID_PANEL_ADV7533_1080P_STRING "1:dsi:0:qcom,mdss_dsi_adv7533_1080p:1:qcom,mdss_dsi_nt35597_dsc_wqxga_video:cfg:dual_dsi"
-
 /*---------------------------------------------------------------------------*/
 /* GPIO configuration                                                        */
 /*---------------------------------------------------------------------------*/
@@ -529,55 +520,7 @@
 
 bool target_display_panel_node(char *pbuf, uint16_t buf_size)
 {
-	int prefix_string_len = strlen(DISPLAY_CMDLINE_PREFIX);
-	bool ret = true;
-	struct oem_panel_data oem = mdss_dsi_get_oem_data();
-
-	if (!strcmp(oem.panel, DSC_CMD_PANEL)) {
-		if (buf_size < (prefix_string_len +
-			strlen(DSC_CMD_PANEL_STRING))) {
-			dprintf(CRITICAL, "DSC command line argument is greater than buffer size\n");
-			return false;
-		}
-		strlcpy(pbuf, DISPLAY_CMDLINE_PREFIX, buf_size);
-		buf_size -= prefix_string_len;
-		pbuf += prefix_string_len;
-		strlcpy(pbuf, DSC_CMD_PANEL_STRING, buf_size);
-	} else if (!strcmp(oem.panel, DSC_VID_PANEL)) {
-		if (buf_size < (prefix_string_len +
-			strlen(DSC_VID_PANEL_STRING))) {
-			dprintf(CRITICAL, "DSC command line argument is greater than buffer size\n");
-			return false;
-		}
-		strlcpy(pbuf, DISPLAY_CMDLINE_PREFIX, buf_size);
-		buf_size -= prefix_string_len;
-		pbuf += prefix_string_len;
-		strlcpy(pbuf, DSC_VID_PANEL_STRING, buf_size);
-	} else if (!strcmp(oem.panel, DSC_VID_PANEL_ADV7533_1080P)) {
-		if (buf_size < (prefix_string_len +
-			strlen(DSC_VID_PANEL_ADV7533_1080P_STRING))) {
-			dprintf(CRITICAL, "DSC command line argument is greater than buffer size\n");
-			return false;
-		}
-		strlcpy(pbuf, DISPLAY_CMDLINE_PREFIX, buf_size);
-		buf_size -= prefix_string_len;
-		pbuf += prefix_string_len;
-		strlcpy(pbuf, DSC_VID_PANEL_ADV7533_1080P_STRING, buf_size);
-	} else if (!strcmp(oem.panel, DSC_CMD_PANEL_ADV7533_1080P)) {
-		if (buf_size < (prefix_string_len +
-			strlen(DSC_CMD_PANEL_ADV7533_1080P_STRING))) {
-			dprintf(CRITICAL, "DSC command line argument is greater than buffer size\n");
-			return false;
-		}
-		strlcpy(pbuf, DISPLAY_CMDLINE_PREFIX, buf_size);
-		buf_size -= prefix_string_len;
-		pbuf += prefix_string_len;
-		strlcpy(pbuf, DSC_CMD_PANEL_ADV7533_1080P_STRING, buf_size);
-	} else {
-		ret = gcdb_display_cmdline_arg(pbuf, buf_size);
-	}
-
-	return ret;
+	return gcdb_display_cmdline_arg(pbuf, buf_size);
 }
 
 void target_display_init(const char *panel_name)
@@ -592,10 +535,6 @@
 	if (!strcmp(oem.panel, NO_PANEL_CONFIG)
 		|| !strcmp(oem.panel, SIM_VIDEO_PANEL)
 		|| !strcmp(oem.panel, SIM_CMD_PANEL)
-		|| !strcmp(oem.panel, DSC_CMD_PANEL)
-		|| !strcmp(oem.panel, DSC_VID_PANEL)
-		|| !strcmp(oem.panel, DSC_CMD_PANEL_ADV7533_1080P)
-		|| !strcmp(oem.panel, DSC_VID_PANEL_ADV7533_1080P)
 		|| oem.skip) {
 		dprintf(INFO, "Selected panel: %s\nSkip panel configuration\n",
 			oem.panel);
diff --git a/target/msm8996/include/target/display.h b/target/msm8996/include/target/display.h
index eddc0c8..a8623d2 100644
--- a/target/msm8996/include/target/display.h
+++ b/target/msm8996/include/target/display.h
@@ -66,7 +66,7 @@
 /*---------------------------------------------------------------------------*/
 #define DISPLAY_CMDLINE_PREFIX " mdss_mdp.panel="
 
-#define MIPI_FB_ADDR  0x82400000
+#define MIPI_FB_ADDR  0x83400000
 
 #define MIPI_HSYNC_PULSE_WIDTH       16
 #define MIPI_HSYNC_BACK_PORCH_DCLK   32
diff --git a/target/msm8996/init.c b/target/msm8996/init.c
index 017b8d2..9f49ceb 100644
--- a/target/msm8996/init.c
+++ b/target/msm8996/init.c
@@ -285,8 +285,16 @@
 	 * Charging should happen as early as possible, any other driver
 	 * initialization before this should consider the power impact
 	 */
-	if (board_hardware_id() == HW_PLATFORM_MTP)
-		pm_appsbl_chg_check_weak_battery_status(1);
+	switch(board_hardware_id())
+	{
+		case HW_PLATFORM_MTP:
+		case HW_PLATFORM_FLUID:
+			pm_appsbl_chg_check_weak_battery_status(1);
+			break;
+		default:
+			/* Charging not supported */
+			break;
+	};
 #endif
 
 	if (rpmb_init() < 0)
@@ -312,12 +320,13 @@
 int target_cont_splash_screen()
 {
 	uint8_t splash_screen = 0;
-	if(!splash_override) {
+	if(!splash_override && !pm_appsbl_charging_in_progress()) {
 		switch(board_hardware_id())
 		{
 			case HW_PLATFORM_SURF:
 			case HW_PLATFORM_MTP:
 			case HW_PLATFORM_FLUID:
+			case HW_PLATFORM_QRD:
 				dprintf(SPEW, "Target_cont_splash=1\n");
 				splash_screen = 1;
 				break;
diff --git a/target/msm8996/mdtp_defs.c b/target/msm8996/mdtp_defs.c
new file mode 100644
index 0000000..195da03
--- /dev/null
+++ b/target/msm8996/mdtp_defs.c
@@ -0,0 +1,84 @@
+/* Copyright (c) 2015, 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, Inc. 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.
+ *
+ */
+
+#include "mdtp_defs.h"
+
+#define MDTP_EFUSE_ADDRESS_MSM8996  0x00070178  // QFPROM_CORR_ANTI_ROLLBACK_3_LSB_ADDR
+#define MDTP_EFUSE_START_MSM8996    0
+
+struct mdtp_ui_defs mdtp_ui_defs_msm8996 = {
+        // Image dimensions
+        1412,     // error_msg_width;
+        212,      // error_msg_height;
+        1364,     // main_text_width;
+        288,      // main_text_height;
+        180,      // pin_digit_width;
+        180,      // pin_digit_height;
+        644,      // ok_button_width;
+        158,      // ok_button_height;
+        1384,     // digits_instructions_width;
+        166,      // digits_instructions_height;
+        920,      // pin_instructions_width;
+        204,      // pin_instructions_height;
+
+        // Image offsets
+        0x1000,   // error_msg_offset;
+        0xDD000,  // initial_delay_offset;
+        0x1FD000, // enter_pin_offset;
+        0x31D000, // invalid_pin_offset;
+        0x43D000, // pin_digit_0_offset;
+        0x18000,  // pin_digits_offset;
+        0x52D000, // pin_selected_digit_0_offset;
+        0x61D000, // ok_button_offset;
+        0x668000, // selected_ok_button_offset;
+        0x6B3000, // digits_instructions_offset;
+        0x75C000, // pin_instructions_offset;
+
+        //Display settings
+        12        // digit_space;
+};
+
+struct mdtp_ui_defs mdtp_get_target_ui_defs()
+{
+    return mdtp_ui_defs_msm8996;
+}
+
+int mdtp_get_target_efuse(struct mdtp_target_efuse* target_efuse)
+{
+    if (target_efuse == NULL)
+    {
+        dprintf(CRITICAL, "mdtp: mdtp_get_target_efuse: ERROR, target_efuse is NULL\n");
+        return -1;
+    }
+
+    target_efuse->address = MDTP_EFUSE_ADDRESS_MSM8996;
+    target_efuse->start = MDTP_EFUSE_START_MSM8996;
+
+    return 0;
+}
diff --git a/target/msm8996/oem_panel.c b/target/msm8996/oem_panel.c
index 3fbb979..25ef683 100644
--- a/target/msm8996/oem_panel.c
+++ b/target/msm8996/oem_panel.c
@@ -53,6 +53,7 @@
 #include "include/panel_sharp_wqxga_dualdsi_video.h"
 #include "include/panel_jdi_qhd_dualdsi_video.h"
 #include "include/panel_jdi_qhd_dualdsi_cmd.h"
+#include "include/panel_r69007_wqxga_cmd.h"
 
 /*---------------------------------------------------------------------------*/
 /* static panel selection variable                                           */
@@ -65,6 +66,7 @@
 	NT35597_WQXGA_DSC_CMD_PANEL,
 	JDI_QHD_DUALDSI_VIDEO_PANEL,
 	JDI_QHD_DUALDSI_CMD_PANEL,
+	R69007_WQXGA_CMD_PANEL,
 	UNKNOWN_PANEL
 };
 
@@ -80,6 +82,7 @@
 	{"nt35597_wqxga_dsc_cmd", NT35597_WQXGA_DSC_CMD_PANEL},
 	{"jdi_qhd_dualdsi_video", JDI_QHD_DUALDSI_VIDEO_PANEL},
 	{"jdi_qhd_dualdsi_cmd", JDI_QHD_DUALDSI_CMD_PANEL},
+	{"r69007_wqxga_cmd", R69007_WQXGA_CMD_PANEL},
 };
 
 static uint32_t panel_id;
@@ -341,6 +344,36 @@
 			jdi_qhd_dualdsi_thulium_video_timings,
 			MAX_TIMING_CONFIG * sizeof(uint32_t));
 		break;
+	case R69007_WQXGA_CMD_PANEL:
+		pan_type = PANEL_TYPE_DSI;
+		pinfo->lcd_reg_en = 0;
+		panelstruct->paneldata    = &r69007_wqxga_cmd_panel_data;
+		panelstruct->panelres     = &r69007_wqxga_cmd_panel_res;
+		panelstruct->color        = &r69007_wqxga_cmd_color;
+		panelstruct->videopanel   = &r69007_wqxga_cmd_video_panel;
+		panelstruct->commandpanel = &r69007_wqxga_cmd_command_panel;
+		panelstruct->state        = &r69007_wqxga_cmd_state;
+		panelstruct->laneconfig   = &r69007_wqxga_cmd_lane_config;
+		panelstruct->paneltiminginfo
+			= &r69007_wqxga_cmd_timing_info;
+		panelstruct->panelresetseq
+					 = &r69007_wqxga_cmd_reset_seq;
+		panelstruct->backlightinfo = &r69007_wqxga_cmd_backlight;
+
+		pinfo->labibb = &r69007_wqxga_cmd_labibb;
+
+		pinfo->mipi.panel_on_cmds
+			= r69007_wqxga_cmd_on_command;
+		pinfo->mipi.num_of_panel_on_cmds
+			= R69007_WQXGA_CMD_ON_COMMAND;
+		pinfo->mipi.panel_off_cmds
+			= r69007_wqxga_cmd_off_command;
+		pinfo->mipi.num_of_panel_off_cmds
+			= R69007_WQXGA_CMD_OFF_COMMAND;
+		memcpy(phy_db->timing,
+			r69007_wqxga_thulium_cmd_timings,
+			MAX_TIMING_CONFIG * sizeof(uint32_t));
+		break;
 	default:
 	case UNKNOWN_PANEL:
 		pan_type = PANEL_TYPE_UNKNOWN;
@@ -381,6 +414,9 @@
 	case HW_PLATFORM_SURF:
 		panel_id = SHARP_WQXGA_DUALDSI_VIDEO_PANEL;
 		break;
+	case HW_PLATFORM_QRD:
+		panel_id = R69007_WQXGA_CMD_PANEL;
+		break;
 	default:
 		dprintf(CRITICAL, "Display not enabled for %d HW type\n"
 					, hw_id);
diff --git a/target/msm8996/rules.mk b/target/msm8996/rules.mk
index 2205f60..fa207a4 100644
--- a/target/msm8996/rules.mk
+++ b/target/msm8996/rules.mk
@@ -2,6 +2,9 @@
 
 INCLUDES += -I$(LOCAL_DIR)/include -I$(LK_TOP_DIR)/platform/msm_shared
 INCLUDES += -I$(LK_TOP_DIR)/dev/gcdb/display -I$(LK_TOP_DIR)/dev/gcdb/display/include
+ifeq ($(ENABLE_MDTP_SUPPORT),1)
+INCLUDES += -I$(LK_TOP_DIR)/app/aboot
+endif
 
 PLATFORM := msm8996
 
@@ -52,3 +55,8 @@
 OBJS += \
     $(LOCAL_DIR)/regulator.o
 endif
+
+ifeq ($(ENABLE_MDTP_SUPPORT),1)
+OBJS += \
+	$(LOCAL_DIR)/mdtp_defs.o
+endif
diff --git a/target/msm8996/target_display.c b/target/msm8996/target_display.c
index 839e23e..ebede20 100644
--- a/target/msm8996/target_display.c
+++ b/target/msm8996/target_display.c
@@ -124,7 +124,6 @@
 static int thulium_wled_backlight_ctrl(uint8_t enable)
 {
 	qpnp_wled_enable_backlight(enable);
-	qpnp_ibb_enable(enable);
 	return NO_ERROR;
 }
 
@@ -243,8 +242,6 @@
 			pm_pwm_enable(false);
 			pm8x41_enable_mpp(&mpp, MPP_DISABLE);
 		}
-		/* Need delay before power on regulators */
-		mdelay(20);
 		/* Enable WLED backlight control */
 		ret = thulium_wled_backlight_ctrl(enable);
 		break;
@@ -260,8 +257,6 @@
 		} else {
 			pm8x41_enable_mpp(&mpp, MPP_DISABLE);
 		}
-		/* Need delay before power on regulators */
-		mdelay(20);
 		ret = thulium_pwm_backlight_ctrl(enable);
 		break;
 	default:
@@ -421,7 +416,7 @@
 		mdelay(10);
 		wled_init(pinfo);
 		qpnp_ibb_enable(true);	/* +5V and -5V */
-		mdelay(50);
+		mdelay(20);
 
 		if (pinfo->lcd_reg_en)
 			lcd_reg_enable();