Merge "dev:pmi, target: check Usb connection for power off charging" into lk.lnx.1.0-dev.1.0
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index beb8181..2b7cc10 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -1468,6 +1468,12 @@
 
 #if DEVICE_TREE
 		dt_actual = ROUND_TO_PAGE(hdr->dt_size, page_mask);
+
+		if (UINT_MAX < ((uint64_t)kernel_actual + (uint64_t)ramdisk_actual+ (uint64_t)dt_actual + page_size)) {
+			dprintf(CRITICAL, "Integer overflow detected in bootimage header fields\n");
+			return -1;
+		}
+
 		imagesize_actual = (page_size + kernel_actual + ramdisk_actual + dt_actual);
 
 		if (check_aboot_addr_range_overlap(hdr->tags_addr, hdr->dt_size))
@@ -1476,6 +1482,10 @@
 			return -1;
 		}
 #else
+		if (UINT_MAX < ((uint64_t)kernel_actual + (uint64_t)ramdisk_actual+ page_size)) {
+			dprintf(CRITICAL, "Integer overflow detected in bootimage header fields\n");
+			return -1;
+		}
 		imagesize_actual = (page_size + kernel_actual + ramdisk_actual);
 #endif
 
@@ -3075,9 +3085,10 @@
 {
 	char *p = NULL;
 	const char *delim = " \t\n\r";
+	char *sp;
 
 	if (arg) {
-		p = strtok((char *)arg, delim);
+		p = strtok_r((char *)arg, delim, &sp);
 		if (p) {
 			if (!strncmp(p, "0", 1)) {
 				device.charger_screen_enabled = 0;
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
index ae73869..0fe301a 100644
--- a/dev/gcdb/display/include/panel_jdi_4k_dualdsi_video_nofbc.h
+++ b/dev/gcdb/display/include/panel_jdi_4k_dualdsi_video_nofbc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2016, 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
@@ -178,7 +178,7 @@
 };
 
 static struct labibb_desc jdi_4k_dualdsi_video_nofbc_labibb = {
-	0, 1, 5500000, 5500000, 5500000, 5500000, 3, 3, 1
+	0, 1, 5500000, 5500000, 5500000, 5500000, 3, 3, 1, 0
 };
 
 #endif /*_PANEL_JDI_4K_DUALDSI_VIDEO_NOFBC__H_*/
diff --git a/dev/gcdb/display/include/panel_nt35597_wqxga_dsc_cmd.h b/dev/gcdb/display/include/panel_nt35597_wqxga_dsc_cmd.h
index f1a39b0..2e8f306 100644
--- a/dev/gcdb/display/include/panel_nt35597_wqxga_dsc_cmd.h
+++ b/dev/gcdb/display/include/panel_nt35597_wqxga_dsc_cmd.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2016, 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
@@ -319,7 +319,7 @@
 };
 
 static struct labibb_desc nt35597_wqxga_dsc_cmd_labibb = {
-	0, 1, 5500000, 5500000, 5500000, 5500000, 3, 3, 1
+	0, 1, 5500000, 5500000, 5500000, 5500000, 3, 3, 1, 0
 };
 
 /*---------------------------------------------------------------------------*/
diff --git a/dev/gcdb/display/include/panel_nt35597_wqxga_dsc_video.h b/dev/gcdb/display/include/panel_nt35597_wqxga_dsc_video.h
index 572d2d5..f1f5247 100644
--- a/dev/gcdb/display/include/panel_nt35597_wqxga_dsc_video.h
+++ b/dev/gcdb/display/include/panel_nt35597_wqxga_dsc_video.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2016, 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
@@ -306,7 +306,7 @@
 };
 
 static struct labibb_desc nt35597_wqxga_dsc_video_labibb = {
-	0, 1, 5500000, 5500000, 5500000, 5500000, 3, 3, 1
+	0, 1, 5500000, 5500000, 5500000, 5500000, 3, 3, 1, 0
 };
 
 /*---------------------------------------------------------------------------*/
diff --git a/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_cmd.h b/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_cmd.h
index 17248ba..432d40b 100644
--- a/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_cmd.h
+++ b/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_cmd.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2016, 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
@@ -260,7 +260,7 @@
 };
 
 static struct labibb_desc nt35597_wqxga_dualdsi_cmd_labibb = {
-	0, 1, 5500000, 5500000, 5500000, 5500000, 3, 3, 1
+	0, 1, 5500000, 5500000, 5500000, 5500000, 3, 3, 1, 0
 };
 
 /*---------------------------------------------------------------------------*/
diff --git a/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_video.h b/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_video.h
index 556d657..bc14996 100644
--- a/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_video.h
+++ b/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_video.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2016, 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
@@ -252,7 +252,7 @@
 };
 
 static struct labibb_desc nt35597_wqxga_dualdsi_video_labibb = {
-	0, 1, 5500000, 5500000, 5500000, 5500000, 3, 3, 1
+	0, 1, 5500000, 5500000, 5500000, 5500000, 3, 3, 1, 0
 };
 
 /*---------------------------------------------------------------------------*/
diff --git a/dev/gcdb/display/include/panel_r69006_1080p_cmd.h b/dev/gcdb/display/include/panel_r69006_1080p_cmd.h
index dc84080..01c8d17 100755
--- a/dev/gcdb/display/include/panel_r69006_1080p_cmd.h
+++ b/dev/gcdb/display/include/panel_r69006_1080p_cmd.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2016, 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
@@ -376,10 +376,9 @@
 };
 
 static struct labibb_desc r69006_1080p_cmd_labibb = {
-	0, 1, 5700000, 5700000, 5700000, 5700000, 3, 3, 1
+	0, 1, 5700000, 5700000, 5700000, 5700000, 3, 3, 1, 0
 };
 
-
 #define R69006_1080P_CMD_PANEL_ON_DELAY 32
 
 #define R69006_1080P_CMD_SIGNATURE 0xFFFF
diff --git a/dev/gcdb/display/include/panel_r69006_1080p_video.h b/dev/gcdb/display/include/panel_r69006_1080p_video.h
index aaf679c..82be298 100755
--- a/dev/gcdb/display/include/panel_r69006_1080p_video.h
+++ b/dev/gcdb/display/include/panel_r69006_1080p_video.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2016, 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
@@ -301,7 +301,7 @@
 };
 
 static struct labibb_desc r69006_1080p_video_labibb = {
-	0, 1, 5700000, 5700000, 5700000, 5700000, 3, 3, 1
+	0, 1, 5700000, 5700000, 5700000, 5700000, 3, 3, 1, 0
 };
 
 /*---------------------------------------------------------------------------*/
diff --git a/dev/gcdb/display/include/panel_r69007_wqxga_cmd.h b/dev/gcdb/display/include/panel_r69007_wqxga_cmd.h
index 70a5225..dab049b 100644
--- a/dev/gcdb/display/include/panel_r69007_wqxga_cmd.h
+++ b/dev/gcdb/display/include/panel_r69007_wqxga_cmd.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2016, 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
@@ -368,7 +368,7 @@
 };
 
 static struct labibb_desc r69007_wqxga_cmd_labibb = {
-	0, 1, 5500000, 5500000, 5500000, 5500000, 3, 3, 1
+	0, 1, 5500000, 5500000, 5500000, 5500000, 3, 3, 1, 0
 };
 
 /*---------------------------------------------------------------------------*/
diff --git a/dev/gcdb/display/include/panel_sharp_wqxga_dualdsi_video.h b/dev/gcdb/display/include/panel_sharp_wqxga_dualdsi_video.h
index 470ddda..f317ed3 100644
--- a/dev/gcdb/display/include/panel_sharp_wqxga_dualdsi_video.h
+++ b/dev/gcdb/display/include/panel_sharp_wqxga_dualdsi_video.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2016, 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
@@ -156,7 +156,7 @@
 };
 
 static struct labibb_desc sharp_wqxga_dualdsi_video_labibb = {
-	0, 1, 5500000, 5500000, 5500000, 5500000, 3, 3, 1
+	0, 1, 5500000, 5500000, 5500000, 5500000, 3, 3, 1, 0
 };
 
 /*---------------------------------------------------------------------------*/
diff --git a/dev/qpnp_wled/include/qpnp_wled.h b/dev/qpnp_wled/include/qpnp_wled.h
index dcd4a8a..3f03703 100644
--- a/dev/qpnp_wled/include/qpnp_wled.h
+++ b/dev/qpnp_wled/include/qpnp_wled.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2016, 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
@@ -44,6 +44,10 @@
 #define QPNP_WLED_SWITCH_FREQ_REG(b)           (b + 0x4C)
 #define QPNP_WLED_OVP_REG(b)                   (b + 0x4D)
 #define QPNP_WLED_ILIM_REG(b)                  (b + 0x4E)
+#define QPNP_WLED_VLOOP_COMP_RES(b)            (b + 0x55)
+#define QPNP_WLED_VLOOP_COMP_GM(b)             (b + 0x56)
+#define QPNP_WLED_PSM_CTRL(b)                  (b + 0x5B)
+#define QPNP_WLED_TEST4(b)		       (b + 0xE5)
 
 #define QPNP_WLED_EN_MASK                      0x7F
 #define QPNP_WLED_EN_SHIFT                     7
@@ -134,6 +138,9 @@
 #define QPNP_WLED_MODULE_RDY_SHIFT             7
 #define QPNP_WLED_MODULE_EN_MASK               0x7F
 #define QPNP_WLED_MODULE_EN_SHIFT              7
+#define QPNP_IBB_SWIRE_RDY_MASK               0x40
+#define QPNP_IBB_SWIRE_RDY_SHIFT              6
+#define QPNP_IBB_MODULE_EN_MASK               0x80
 #define QPNP_WLED_DISP_SEL_MASK                0x7F
 #define QPNP_WLED_DISP_SEL_SHIFT               7
 
@@ -148,6 +155,7 @@
 #define QPNP_WLED_IBB_PWRDN_DLY_MAX_MS         3
 #define IBB_LAB_VREG_STEP_SIZE                 100000
 #define QPNP_LABIBB_OUTPUT_VOLTAGE             0x41
+#define QPNP_LABIBB_PS_CTL		       0x50
 #define QPNP_LAB_OUTPUT_OVERRIDE_EN            BIT(7)
 #define QPNP_LAB_SET_VOLTAGE_MASK              (BIT(4) - 1)
 #define QPNP_IBB_SET_VOLTAGE_MASK              (BIT(6) - 1)
@@ -260,6 +268,8 @@
 	uint32_t ibb_max_volt;
 	uint32_t ibb_init_volt;
 	uint32_t lab_init_volt;
+	bool lab_ibb_swire_control;
+	bool wled_avdd_control;
 };
 
 struct qpnp_wled_config_data {
@@ -273,6 +283,8 @@
 	uint32_t ibb_max_volt;
 	uint32_t ibb_init_volt;
 	uint32_t lab_init_volt;
+	bool lab_ibb_swire_control;
+	bool wled_avdd_control;
 };
 /* WLED Initial Setup */
 int qpnp_wled_init(struct qpnp_wled_config_data *config);
diff --git a/dev/qpnp_wled/qpnp_wled.c b/dev/qpnp_wled/qpnp_wled.c
index 0ae44a3..9cedbb7 100644
--- a/dev/qpnp_wled/qpnp_wled.c
+++ b/dev/qpnp_wled/qpnp_wled.c
@@ -1,4 +1,4 @@
- /* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ /* Copyright (c) 2014-2016, 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
@@ -95,6 +95,21 @@
 	return 0;
 }
 
+static int qpnp_wled_ibb_swire_rdy(struct qpnp_wled *wled,
+				uint16_t base_addr, bool state)
+{
+	uint8_t reg;
+
+	reg = pm8x41_wled_reg_read(
+			QPNP_WLED_MODULE_EN_REG(base_addr));
+	/* Do not enable IBB module when SWIRE ready is set */
+	reg &= ~(QPNP_IBB_SWIRE_RDY_MASK | QPNP_IBB_MODULE_EN_MASK);
+	reg |= (state << QPNP_IBB_SWIRE_RDY_SHIFT);
+	pm8x41_wled_reg_write(QPNP_WLED_MODULE_EN_REG(base_addr), reg);
+
+	return 0;
+}
+
 int qpnp_ibb_enable(bool state)
 {
 	int rc = 0;
@@ -119,7 +134,10 @@
 		pm8x41_wled_reg_write(QPNP_WLED_LAB_IBB_RDY_REG(gwled->lab_base), reg);
 	}
 
-	rc = qpnp_wled_enable(gwled, gwled->ibb_base, state);
+	if (gwled->disp_type_amoled && gwled->lab_ibb_swire_control)
+		rc = qpnp_wled_ibb_swire_rdy(gwled, gwled->ibb_base, state);
+	else
+		rc = qpnp_wled_enable(gwled, gwled->ibb_base, state);
 
 	return rc;
 }
@@ -141,12 +159,14 @@
 			return;
 		}
 	}
-	rc = qpnp_wled_enable(gwled, gwled->ctrl_base, enable);
 
-	if (rc) {
-		dprintf(CRITICAL,"wled %sable failed\n",
-					enable ? "en" : "dis");
-		return;
+	if (!gwled->disp_type_amoled || !gwled->wled_avdd_control) {
+		rc = qpnp_wled_enable(gwled, gwled->ctrl_base, enable);
+		if (rc) {
+			dprintf(CRITICAL, "wled %sable failed\n",
+						enable ? "en" : "dis");
+			return;
+		}
 	}
 
 }
@@ -195,6 +215,21 @@
 	if (rc < 0)
 		return rc;
 
+	/* Recommended WLED MDOS settings for AMOLED */
+	if (wled->disp_type_amoled) {
+		pm8x41_wled_reg_write(QPNP_WLED_VLOOP_COMP_RES(wled->ctrl_base),
+			0x8F);
+		pm8x41_wled_reg_write(QPNP_WLED_VLOOP_COMP_GM(wled->ctrl_base),
+			0x81);
+		pm8x41_wled_reg_write(QPNP_WLED_PSM_CTRL(wled->ctrl_base),
+			0x83);
+
+		rc = qpnp_wled_sec_access(wled, wled->ctrl_base);
+		if (rc)
+			return rc;
+		pm8x41_wled_reg_write(QPNP_WLED_TEST4(wled->ctrl_base), 0x13);
+	}
+
 	/* Configure the FEEDBACK OUTPUT register */
 	reg = pm8x41_wled_reg_read(
 			QPNP_WLED_FDBK_OP_REG(wled->ctrl_base));
@@ -402,6 +437,11 @@
 	if (rc < 0)
 		return rc;
 
+	/* Disable LAB pulse skipping for AMOLED */
+	if (wled->disp_type_amoled)
+		pm8x41_wled_reg_write(wled->lab_base +
+			QPNP_LABIBB_PS_CTL, 0x00);
+
 	/* IBB active bias */
 	if (wled->ibb_pwrup_dly_ms > QPNP_WLED_IBB_PWRUP_DLY_MAX_MS)
 		wled->ibb_pwrup_dly_ms = QPNP_WLED_IBB_PWRUP_DLY_MAX_MS;
@@ -493,6 +533,8 @@
 	wled->ibb_max_volt = config->ibb_max_volt;
 	wled->ibb_init_volt = config->ibb_init_volt;
 	wled->lab_init_volt = config->lab_init_volt;
+	wled->lab_ibb_swire_control = config->lab_ibb_swire_control;
+	wled->wled_avdd_control = config->wled_avdd_control;
 
 	return 0;
 }
@@ -531,49 +573,68 @@
 	uint32_t new_uV;
 	uint8_t val, mask=0;
 
-	if (wled->lab_min_volt < wled->lab_init_volt) {
-		dprintf(CRITICAL,"qpnp_lab_regulator_set_voltage failed, min_uV %d is less than init volt %d\n",
-		wled->lab_min_volt, wled->lab_init_volt);
-		return rc;
+	if (!wled->disp_type_amoled || !wled->lab_ibb_swire_control) {
+		if (wled->lab_min_volt < wled->lab_init_volt) {
+			dprintf(CRITICAL,"qpnp_lab_regulator_set_voltage failed, min_uV %d is less than init volt %d\n",
+			wled->lab_min_volt, wled->lab_init_volt);
+			return rc;
+		}
+
+		val = (((wled->lab_min_volt - wled->lab_init_volt) +
+		(IBB_LAB_VREG_STEP_SIZE - 1)) / IBB_LAB_VREG_STEP_SIZE);
+		new_uV = val * IBB_LAB_VREG_STEP_SIZE + wled->lab_init_volt;
+
+		if (new_uV > wled->lab_max_volt) {
+			dprintf(CRITICAL,"qpnp_ibb_regulator_set_voltage unable to set voltage (%d %d)\n",
+			wled->lab_min_volt, wled->lab_max_volt);
+			return rc;
+		}
+		val |= QPNP_LAB_OUTPUT_OVERRIDE_EN;
+		mask = pm8x41_wled_reg_read(wled->lab_base +
+				QPNP_LABIBB_OUTPUT_VOLTAGE);
+		mask &= ~(QPNP_LAB_SET_VOLTAGE_MASK
+				| QPNP_LAB_OUTPUT_OVERRIDE_EN);
+		mask |= val & (QPNP_LAB_SET_VOLTAGE_MASK
+				| QPNP_LAB_OUTPUT_OVERRIDE_EN);
+
+		pm8x41_wled_reg_write(wled->lab_base +
+				QPNP_LABIBB_OUTPUT_VOLTAGE, mask);
+		udelay(2);
+
+		/*
+		 * IBB Set Voltage.
+		 * For AMOLED panels, the IBB voltage needs to be
+		 * controlled by panel.
+		 */
+		if (wled->ibb_min_volt < wled->ibb_init_volt) {
+			dprintf(CRITICAL, "qpnp_ibb_regulator_set_voltage failed, min_uV %d is less than init volt %d\n",
+			wled->ibb_min_volt, wled->ibb_init_volt);
+			return rc;
+		}
+
+		val = (((wled->ibb_min_volt - wled->ibb_init_volt) +
+			(IBB_LAB_VREG_STEP_SIZE - 1)) / IBB_LAB_VREG_STEP_SIZE);
+		new_uV = val * IBB_LAB_VREG_STEP_SIZE + wled->ibb_init_volt;
+		if (new_uV > wled->ibb_max_volt) {
+			dprintf(CRITICAL, "qpnp_ibb_regulator_set_voltage unable to set voltage %d %d\n",
+			wled->ibb_min_volt, wled->ibb_max_volt);
+			return rc;
+		}
+		val |= QPNP_LAB_OUTPUT_OVERRIDE_EN;
+		mask = pm8x41_wled_reg_read(wled->ibb_base +
+			QPNP_LABIBB_OUTPUT_VOLTAGE);
+		udelay(2);
+		mask &= ~(QPNP_IBB_SET_VOLTAGE_MASK |
+			QPNP_LAB_OUTPUT_OVERRIDE_EN);
+		mask |= (val & (QPNP_IBB_SET_VOLTAGE_MASK |
+			QPNP_LAB_OUTPUT_OVERRIDE_EN));
+
+		pm8x41_wled_reg_write(wled->ibb_base +
+			QPNP_LABIBB_OUTPUT_VOLTAGE, mask);
+	} else {
+		pm8x41_wled_reg_write(wled->ibb_base +
+			QPNP_LABIBB_OUTPUT_VOLTAGE, 0x00);
 	}
 
-	val = (((wled->lab_min_volt - wled->lab_init_volt) + (IBB_LAB_VREG_STEP_SIZE - 1)) / IBB_LAB_VREG_STEP_SIZE);
-	new_uV = val * IBB_LAB_VREG_STEP_SIZE + wled->lab_init_volt;
-
-	if (new_uV > wled->lab_max_volt) {
-		dprintf(CRITICAL,"qpnp_ibb_regulator_set_voltage unable to set voltage (%d %d)\n",
-		wled->lab_min_volt, wled->lab_max_volt);
-		return rc;
-	}
-	val |= QPNP_LAB_OUTPUT_OVERRIDE_EN;
-	mask = pm8x41_wled_reg_read(wled->lab_base + QPNP_LABIBB_OUTPUT_VOLTAGE);
-	mask &= ~(QPNP_LAB_SET_VOLTAGE_MASK | QPNP_LAB_OUTPUT_OVERRIDE_EN);
-	mask |= val & (QPNP_LAB_SET_VOLTAGE_MASK | QPNP_LAB_OUTPUT_OVERRIDE_EN);
-
-	pm8x41_wled_reg_write(wled->lab_base + QPNP_LABIBB_OUTPUT_VOLTAGE, mask);
-	udelay(2);
-
-	/* IBB Set Voltage */
-	if (wled->ibb_min_volt < wled->ibb_init_volt) {
-		dprintf(CRITICAL, "qpnp_ibb_regulator_set_voltage failed, min_uV %d is less than init volt %d\n",
-		wled->ibb_min_volt, wled->ibb_init_volt);
-		return rc;
-	}
-
-	val = (((wled->ibb_min_volt - wled->ibb_init_volt) + (IBB_LAB_VREG_STEP_SIZE - 1)) / IBB_LAB_VREG_STEP_SIZE);
-	new_uV = val * IBB_LAB_VREG_STEP_SIZE + wled->ibb_init_volt;
-	if (new_uV > wled->ibb_max_volt) {
-		dprintf(CRITICAL,"qpnp_ibb_regulator_set_voltage unable to set voltage %d %d\n",
-		wled->ibb_min_volt, wled->ibb_max_volt);
-		return rc;
-	}
-	val |= QPNP_LAB_OUTPUT_OVERRIDE_EN;
-	mask = pm8x41_wled_reg_read(wled->ibb_base + QPNP_LABIBB_OUTPUT_VOLTAGE);
-	udelay(2);
-	mask &= ~(QPNP_IBB_SET_VOLTAGE_MASK | QPNP_LAB_OUTPUT_OVERRIDE_EN);
-	mask |= (val & (QPNP_IBB_SET_VOLTAGE_MASK | QPNP_LAB_OUTPUT_OVERRIDE_EN));
-
-	pm8x41_wled_reg_write(wled->ibb_base + QPNP_LABIBB_OUTPUT_VOLTAGE,mask);
-
 	return 0;
 }
diff --git a/include/platform.h b/include/platform.h
index de6e544..31de506 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2008 Travis Geiselbrecht
  *
- * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files
@@ -66,6 +66,7 @@
 int platform_is_msm8909();
 int platform_is_msm8992();
 int platform_is_msm8937();
+int platform_is_msmgold();
 int platform_is_msm8956();
 uint32_t platform_is_msm8976_v_1_1();
 int boot_device_mask(int);
diff --git a/platform/msm8952/msm8952-clock.c b/platform/msm8952/msm8952-clock.c
index bf87489..ea142d7 100644
--- a/platform/msm8952/msm8952-clock.c
+++ b/platform/msm8952/msm8952-clock.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2016, 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
@@ -650,7 +650,7 @@
 			msm8976_v_1_1_sdcc_clock_modify();
 	}
 
-	if (platform_is_msm8937())
+	if (platform_is_msm8937() || platform_is_msmgold())
 		msm8937_clock_override();
 
 	clk_init(msm_clocks_8952, ARRAY_SIZE(msm_clocks_8952));
diff --git a/platform/msm8952/platform.c b/platform/msm8952/platform.c
index 5eaa241..180d34b 100644
--- a/platform/msm8952/platform.c
+++ b/platform/msm8952/platform.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2016, 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
@@ -177,6 +177,26 @@
 	return 256;
 }
 
+int platform_is_msmgold()
+{
+	uint32_t platform = board_platform_id();
+	uint32_t ret = 0;
+
+	switch(platform)
+	{
+		case MSMGOLD:
+		case MSMGOLD2:
+		case MSMGOLD3:
+		case APQGOLD:
+			ret = 1;
+			break;
+		default:
+			ret = 0;
+	};
+
+	return ret;
+}
+
 int platform_is_msm8937()
 {
 	uint32_t platform = board_platform_id();
diff --git a/platform/msm_shared/display_menu.c b/platform/msm_shared/display_menu.c
index bb988df..dd8cb58 100644
--- a/platform/msm_shared/display_menu.c
+++ b/platform/msm_shared/display_menu.c
@@ -159,9 +159,9 @@
 			else
 				diff = max_x/factor - strlen(str);
 			for (i = 0; i < diff; i++) {
-				strcat(str_target, " ");
+				strlcat(str_target, " ", max_x);
 			}
-			strcat(str_target, str);
+			strlcat(str_target, str, max_x);
 			return str_target;
 		} else {
 			free(str_target);
@@ -247,14 +247,14 @@
 	if (type == DISPLAY_MENU_YELLOW) {
 		fp_buf = get_boot_fingerprint(&fp_size);
 		if (fp_buf != NULL) {
-			strncpy(fp_str_temp, (char const *)fp_buf, fp_size);
+			strlcpy(fp_str_temp, (char const *)fp_buf, fp_size);
 			for (i = 0; i < fp_size; i++) {
 				if(i == fp_size - 1)
-					sprintf(str_temp, "%02x", fp_str_temp[i]);
+					snprintf(str_temp, sizeof(str_temp), "%02x", fp_str_temp[i]);
 				else
-					sprintf(str_temp, "%02x-", fp_str_temp[i]);
+					snprintf(str_temp, sizeof(str_temp), "%02x-", fp_str_temp[i]);
 
-				strcat(fp_str, str_temp);
+				strlcat(fp_str, str_temp, sizeof(fp_str));
 			}
 		}
 		display_fbcon_menu_message("ID:", FBCON_COMMON_MSG, common_factor);
diff --git a/platform/msm_shared/hsusb.c b/platform/msm_shared/hsusb.c
index 6a8e9e6..5f8d3e4 100644
--- a/platform/msm_shared/hsusb.c
+++ b/platform/msm_shared/hsusb.c
@@ -906,6 +906,12 @@
 	/* create our configuration descriptor */
 	size = 9 + udc_ifc_desc_size(the_gadget);
 	desc = udc_descriptor_alloc(TYPE_CONFIGURATION, 0, size);
+	if(!desc)
+	{
+		dprintf(CRITICAL, "Failed to allocate device descriptor\n");
+		ASSERT(0);
+	}
+
 	data = desc->data;
 	data[0] = 0x09;
 	data[2] = size;
diff --git a/platform/msm_shared/include/msm_panel.h b/platform/msm_shared/include/msm_panel.h
index d2a338f..5671e02 100755
--- a/platform/msm_shared/include/msm_panel.h
+++ b/platform/msm_shared/include/msm_panel.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2016, 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
@@ -373,6 +373,7 @@
 	char pwr_up_delay; /* ndx to => 1250, 2500, 5000 and 10000 us */
 	char pwr_down_delay; /* ndx to => 1250, 2500, 5000 and 10000 us */
 	char ibb_discharge_en;
+	bool swire_control;
 };
 
 struct msm_panel_info {
diff --git a/platform/msm_shared/menu_keys_detect.c b/platform/msm_shared/menu_keys_detect.c
index 28766a7..b511859 100644
--- a/platform/msm_shared/menu_keys_detect.c
+++ b/platform/msm_shared/menu_keys_detect.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2016, 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
@@ -280,7 +280,7 @@
 {
 	int device_state[] = {RESTART, FASTBOOT, RECOVER, POWEROFF};
 
-	if(option_index < sizeof(device_state)) {
+	if(option_index < (sizeof(device_state)/sizeof(device_state[0]))) {
 		update_device_status(device_state[option_index], msg_info->msg_type);
 	} else {
 		dprintf(CRITICAL, "ERRPR: option index is overflow!!!\n");
@@ -329,6 +329,16 @@
 void keys_detect_init()
 {
 	wait_time = 0;
+
+	/* Waiting for all keys are released */
+	while(1) {
+		if(!keys[VOLUME_UP].keys_pressed_func() &&
+			!keys[VOLUME_DOWN].keys_pressed_func() &&
+			!keys[POWER_KEY].keys_pressed_func()) {
+			break;
+		}
+		thread_sleep(KEY_DETECT_FREQUENCY);
+	}
 }
 
 int select_msg_keys_detect(void *param) {
diff --git a/platform/msm_shared/smem.h b/platform/msm_shared/smem.h
index 05e9ede..5819d69 100644
--- a/platform/msm_shared/smem.h
+++ b/platform/msm_shared/smem.h
@@ -2,7 +2,7 @@
  * Copyright (c) 2009, Google Inc.
  * All rights reserved.
  *
- * Copyright (c) 2009-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2016, 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
@@ -447,6 +447,10 @@
 	MSMTITANIUM  = 293,
 	MSM8937 = 294,
 	APQ8037 = 295,
+	MSMGOLD = 303,
+	APQGOLD = 307,
+	MSMGOLD2 = 308,
+	MSMGOLD3 = 309,
 	APQTITANIUM = 304,
 };
 
diff --git a/platform/msmtitanium/include/platform/iomap.h b/platform/msmtitanium/include/platform/iomap.h
old mode 100755
new mode 100644
index 64779cb..d99c20b
--- a/platform/msmtitanium/include/platform/iomap.h
+++ b/platform/msmtitanium/include/platform/iomap.h
@@ -76,6 +76,12 @@
 #define MPM2_MPM_PS_HOLD                   0x004AB000
 #define MPM2_MPM_SLEEP_TIMETICK_COUNT_VAL  0x004A3000
 
+#define PMI_SLAVE_BASE           2
+#define PMI_FIRST_SLAVE_OFFSET   0
+#define PMI_SECOND_SLAVE_OFFSET  1
+#define PMI_FIRST_SLAVE_ADDR_BASE   (( PMI_SLAVE_BASE + PMI_FIRST_SLAVE_OFFSET ) << 16)
+#define PMI_SECOND_SLAVE_ADDR_BASE  (( PMI_SLAVE_BASE + PMI_SECOND_SLAVE_OFFSET) << 16)
+
 /* CRYPTO ENGINE */
 #define  MSM_CE1_BASE                      0x073A000
 #define  MSM_CE1_BAM_BASE                  0x0704000
@@ -211,7 +217,7 @@
 #define TCSR_TZ_WONCE               0x193D000
 #define TCSR_BOOT_MISC_DETECT       0x193D100
 
-#define DDR_START                          0x80000000
+#define DDR_START                          get_ddr_start()
 #define ABOOT_FORCE_KERNEL_ADDR            DDR_START + 0x8000
 #define ABOOT_FORCE_KERNEL64_ADDR          DDR_START + 0x80000
 #define ABOOT_FORCE_RAMDISK_ADDR           DDR_START + 0x2000000
diff --git a/platform/msmtitanium/platform.c b/platform/msmtitanium/platform.c
old mode 100755
new mode 100644
index 83d0b3b..32f51f5
--- a/platform/msmtitanium/platform.c
+++ b/platform/msmtitanium/platform.c
@@ -110,7 +110,7 @@
 	uint32_t i;
 	uint32_t sections;
 	uint32_t table_size = ARRAY_SIZE(mmu_section_table);
-	uint32_t ddr_start = get_ddr_start();
+	uint32_t ddr_start = DDR_START;
 	uint32_t smem_addr = platform_get_smem_base_addr();
 
 	/*Mapping the ddr start address for loading the kernel about 90 MB*/
diff --git a/project/msmtitanium.mk b/project/msmtitanium.mk
index 6cc2ada..75a9f7e 100755
--- a/project/msmtitanium.mk
+++ b/project/msmtitanium.mk
@@ -31,7 +31,7 @@
 DEFINES += BAM_V170=1
 
 #Enable the feature of long press power on
-#DEFINES += LONG_PRESS_POWER_ON=1
+DEFINES += LONG_PRESS_POWER_ON=1
 
 #Disable thumb mode
 ENABLE_THUMB := false
@@ -44,12 +44,16 @@
 endif
 
 #enable power on vibrator feature
-#ENABLE_PON_VIB_SUPPORT := true
+ENABLE_HAP_VIB_SUPPORT := true
 
 ifeq ($(EMMC_BOOT),1)
 DEFINES += _EMMC_BOOT=1
 endif
 
+ifeq ($(ENABLE_HAP_VIB_SUPPORT),true)
+DEFINES += PON_VIB_SUPPORT=1
+endif
+
 ifeq ($(ENABLE_PON_VIB_SUPPORT),true)
 DEFINES += PON_VIB_SUPPORT=1
 endif
diff --git a/target/msm8952/init.c b/target/msm8952/init.c
index 201e652..88ff454 100644
--- a/target/msm8952/init.c
+++ b/target/msm8952/init.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2016, 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
@@ -185,7 +185,7 @@
 
 	if(platform_is_msm8956())
 		vol_up_gpio = TLMM_VOL_UP_BTN_GPIO_8956;
-	else if(platform_is_msm8937())
+	else if(platform_is_msm8937() || platform_is_msmgold())
 		vol_up_gpio = TLMM_VOL_UP_BTN_GPIO_8937;
 	else
 		vol_up_gpio = TLMM_VOL_UP_BTN_GPIO;
@@ -263,7 +263,7 @@
 
 	spmi_init(PMIC_ARB_CHANNEL_NUM, PMIC_ARB_OWNER_ID);
 
-	if(platform_is_msm8937())
+	if(platform_is_msm8937() || platform_is_msmgold())
 	{
 		uint8_t pmi_rev = 0;
 		uint32_t pmi_type = 0;
@@ -375,12 +375,16 @@
 	case MSM8956:
 	case MSM8976:
 	case MSM8937:
+	case MSMGOLD:
+	case MSMGOLD2:
+	case MSMGOLD3:
 		board->baseband = BASEBAND_MSM;
 		break;
 	case APQ8052:
 	case APQ8056:
 	case APQ8076:
 	case APQ8037:
+	case APQGOLD:
 		board->baseband = BASEBAND_APQ;
 		break;
 	default:
diff --git a/target/msm8952/target_display.c b/target/msm8952/target_display.c
index 7d3c0d6..fa9faa1 100644
--- a/target/msm8952/target_display.c
+++ b/target/msm8952/target_display.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2016, 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
@@ -434,39 +434,53 @@
 	struct qpnp_wled_config_data config = {0};
 	struct labibb_desc *labibb;
 	int display_type = 0;
+	bool swire_control = 0;
+	bool wled_avdd_control = 0;
 
 	labibb = pinfo->labibb;
 
 	if (labibb)
 		display_type = labibb->amoled_panel;
 
+	if (display_type) {
+		swire_control = labibb->swire_control;
+		wled_avdd_control = true;
+	} else {
+		swire_control = false;
+		wled_avdd_control = false;
+	}
+
 	config.display_type = display_type;
 	config.lab_init_volt = 4600000;	/* fixed, see pmi register */
 	config.ibb_init_volt = 1400000;	/* fixed, see pmi register */
+	config.lab_ibb_swire_control = swire_control;
+	config.wled_avdd_control = wled_avdd_control;
 
-	if (labibb && labibb->force_config) {
-		config.lab_min_volt = labibb->lab_min_volt;
-		config.lab_max_volt = labibb->lab_max_volt;
-		config.ibb_min_volt = labibb->ibb_min_volt;
-		config.ibb_max_volt = labibb->ibb_max_volt;
-		config.pwr_up_delay = labibb->pwr_up_delay;
-		config.pwr_down_delay = labibb->pwr_down_delay;
-		config.ibb_discharge_en = labibb->ibb_discharge_en;
-	} else {
-		/* default */
-		config.pwr_up_delay = 3;
-		config.pwr_down_delay =  3;
-		config.ibb_discharge_en = 1;
-		if (display_type) {	/* amoled */
-			config.lab_min_volt = 4600000;
-			config.lab_max_volt = 4600000;
-			config.ibb_min_volt = 4000000;
-			config.ibb_max_volt = 4000000;
-		} else { /* lcd */
-			config.lab_min_volt = 5500000;
-			config.lab_max_volt = 5500000;
-			config.ibb_min_volt = 5500000;
-			config.ibb_max_volt = 5500000;
+	if(!swire_control) {
+		if (labibb && labibb->force_config) {
+			config.lab_min_volt = labibb->lab_min_volt;
+			config.lab_max_volt = labibb->lab_max_volt;
+			config.ibb_min_volt = labibb->ibb_min_volt;
+			config.ibb_max_volt = labibb->ibb_max_volt;
+			config.pwr_up_delay = labibb->pwr_up_delay;
+			config.pwr_down_delay = labibb->pwr_down_delay;
+			config.ibb_discharge_en = labibb->ibb_discharge_en;
+		} else {
+			/* default */
+			config.pwr_up_delay = 3;
+			config.pwr_down_delay =  3;
+			config.ibb_discharge_en = 1;
+			if (display_type) {	/* amoled */
+				config.lab_min_volt = 4600000;
+				config.lab_max_volt = 4600000;
+				config.ibb_min_volt = 4000000;
+				config.ibb_max_volt = 4000000;
+			} else { /* lcd */
+				config.lab_min_volt = 5500000;
+				config.lab_max_volt = 5500000;
+				config.ibb_min_volt = 5500000;
+				config.ibb_max_volt = 5500000;
+			}
 		}
 	}
 
diff --git a/target/msmtitanium/init.c b/target/msmtitanium/init.c
index 06d63ce..d37e4a9 100755
--- a/target/msmtitanium/init.c
+++ b/target/msmtitanium/init.c
@@ -63,6 +63,11 @@
 #include <shutdown_detect.h>
 #endif
 
+#if PON_VIB_SUPPORT
+#include <vibrator.h>
+#define VIBRATE_TIME 250
+#endif
+
 #define PMIC_ARB_CHANNEL_NUM    0
 #define PMIC_ARB_OWNER_ID       0
 #define TLMM_VOL_UP_BTN_GPIO    85
@@ -230,6 +235,10 @@
 	shutdown_detect();
 #endif
 
+#if PON_VIB_SUPPORT
+	vib_timed_turn_on(VIBRATE_TIME);
+#endif
+
 
 	if (target_use_signed_kernel())
 		target_crypto_init_params();
diff --git a/target/msmtitanium/rules.mk b/target/msmtitanium/rules.mk
index b338bea..e09b699 100644
--- a/target/msmtitanium/rules.mk
+++ b/target/msmtitanium/rules.mk
@@ -10,11 +10,14 @@
 BASE_ADDR        := 0x80000000
 SCRATCH_ADDR     := 0x90000000
 
+DEFINES += PMI_CONFIGURED=1
+
 MODULES += \
 	dev/keys \
 	dev/vib \
 	lib/ptable \
 	dev/pmic/pm8x41 \
+	dev/qpnp_haptic \
 	lib/libfdt
 
 DEFINES += \