Merge "platform: Correct EOT_PACKET_CTRL register offset"
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index a578cc3..1d94211 100755
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -126,6 +126,7 @@
 static const char *baseband_dsda    = " androidboot.baseband=dsda";
 static const char *baseband_dsda2   = " androidboot.baseband=dsda2";
 static const char *baseband_sglte2  = " androidboot.baseband=sglte2";
+static const char *warmboot_cmdline = " qpnp-power-on.warm_boot=1";
 
 static unsigned page_size = 0;
 static unsigned page_mask = 0;
@@ -237,6 +238,7 @@
 	const char *boot_dev_cmdline = NULL;
 #endif
 	int pause_at_bootup = 0;
+	bool warm_boot = false;
 	bool gpt_exists = partition_gpt_exists();
 	int have_target_boot_params = 0;
 
@@ -332,6 +334,11 @@
 		cmdline_len += strlen(display_panel_buf);
 	}
 
+	if (target_warm_boot()) {
+		warm_boot = true;
+		cmdline_len += strlen(warmboot_cmdline);
+	}
+
 	if (cmdline_len > 0) {
 		const char *src;
 		unsigned char *dst = (unsigned char*) malloc((cmdline_len + 4) & (~3));
@@ -362,6 +369,11 @@
 		if (have_cmdline) --dst;
 		have_cmdline = 1;
 		while ((*dst++ = *src++));
+		if (warm_boot) {
+			if (have_cmdline) --dst;
+			src = warmboot_cmdline;
+			while ((*dst++ = *src++));
+		}
 
 		if (boot_into_recovery && gpt_exists) {
 			src = secondary_gpt_enable;
diff --git a/dev/gcdb/display/include/panel_jdi_1080p_video.h b/dev/gcdb/display/include/panel_jdi_1080p_video.h
index e390da4..cdef652 100755
--- a/dev/gcdb/display/include/panel_jdi_1080p_video.h
+++ b/dev/gcdb/display/include/panel_jdi_1080p_video.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -133,7 +133,7 @@
 /*---------------------------------------------------------------------------*/
 
 static struct videopanel_info jdi_1080p_video_video_panel = {
-  0, 0, 0, 0, 1, 1, 2, 0, 0
+  0, 0, 0, 0, 1, 1, 2, 0, 0x9
 };
 
 /*---------------------------------------------------------------------------*/
diff --git a/dev/pmic/pm8921/include/dev/pm8921_pwm.h b/dev/pmic/pm8921/include/dev/pm8921_pwm.h
index 50442f7..10fb1da 100644
--- a/dev/pmic/pm8921/include/dev/pm8921_pwm.h
+++ b/dev/pmic/pm8921/include/dev/pm8921_pwm.h
@@ -151,7 +151,7 @@
     uint8_t clk;
     uint8_t pre_div;
     uint8_t pre_div_exp;
-    uint8_t pwm_value;
+    uint32_t pwm_value;
     uint8_t bypass_lut;
     uint8_t pwm_ctl[NUM_LPG_CTL_REGS];
 };
diff --git a/dev/pmic/pm8x41/include/pm8x41.h b/dev/pmic/pm8x41/include/pm8x41.h
index 34c4b9c..56ae327 100644
--- a/dev/pmic/pm8x41/include/pm8x41.h
+++ b/dev/pmic/pm8x41/include/pm8x41.h
@@ -202,6 +202,7 @@
 int pm8x41_ldo_control(struct pm8x41_ldo *ldo, uint8_t enable);
 uint8_t pm8x41_get_pmic_rev();
 uint8_t pm8x41_get_pon_reason();
+uint32_t pm8x41_get_pwrkey_is_pressed();
 void pm8x41_config_output_mpp(struct pm8x41_mpp *mpp);
 void pm8x41_enable_mpp(struct pm8x41_mpp *mpp, enum mpp_en_ctl enable);
 uint8_t pm8x41_get_is_cold_boot();
diff --git a/dev/pmic/pm8x41/include/pm8x41_hw.h b/dev/pmic/pm8x41/include/pm8x41_hw.h
index c696ef6..a1c2e6d 100644
--- a/dev/pmic/pm8x41/include/pm8x41_hw.h
+++ b/dev/pmic/pm8x41/include/pm8x41_hw.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -82,6 +82,7 @@
 
 /* PON Peripheral register bit values */
 #define RESIN_ON_INT_BIT                      1
+#define KPDPWR_ON_INT_BIT                     0
 #define RESIN_BARK_INT_BIT                    4
 #define S2_RESET_EN_BIT                       7
 
diff --git a/dev/pmic/pm8x41/include/pm_vib.h b/dev/pmic/pm8x41/include/pm_vib.h
new file mode 100644
index 0000000..9b10327
--- /dev/null
+++ b/dev/pmic/pm8x41/include/pm_vib.h
@@ -0,0 +1,38 @@
+/* Copyright (c) 2014, 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.
+ */
+#ifndef __DEV_PMIC_VIB_VIBRATOR_H
+#define __DEV_PMIC_VIB_VIBRATOR_H
+
+#define QPNP_VIB_EN_CTL             0x1c046
+#define QPNP_VIB_VTG_CTL            0x1c041
+#define QPNP_VIB_VTG_SET_MASK       0x1F
+#define QPNP_VIB_DEFAULT_VTG_LVL    22
+
+void pm_vib_turn_on(void);
+void pm_vib_turn_off(void);
+#endif/* __DEV_PMIC_VIB_VIBRATOR_H */
diff --git a/dev/pmic/pm8x41/pm8x41.c b/dev/pmic/pm8x41/pm8x41.c
index b846d9c..1e9f16c 100644
--- a/dev/pmic/pm8x41/pm8x41.c
+++ b/dev/pmic/pm8x41/pm8x41.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -219,6 +219,19 @@
 	return (rt_sts & BIT(RESIN_ON_INT_BIT));
 }
 
+/* Return 1 if power key is pressed */
+uint32_t pm8x41_get_pwrkey_is_pressed()
+{
+	uint8_t pwr_sts = 0;
+
+	pwr_sts = REG_READ(PON_INT_RT_STS);
+
+	if (pwr_sts & BIT(KPDPWR_ON_INT_BIT))
+		return 1;
+	else
+		return 0;
+}
+
 void pm8x41_v2_reset_configure(uint8_t reset_type)
 {
 	uint8_t val;
diff --git a/dev/pmic/pm8x41/pm8x41_vib.c b/dev/pmic/pm8x41/pm8x41_vib.c
new file mode 100644
index 0000000..7dbba77
--- /dev/null
+++ b/dev/pmic/pm8x41/pm8x41_vib.c
@@ -0,0 +1,60 @@
+/* Copyright (c) 2014, 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 <bits.h>
+#include <debug.h>
+#include <reg.h>
+#include <pm8x41.h>
+#include <pm_vib.h>
+
+#define QPNP_VIB_EN    BIT(7)
+
+/* Turn on vibrator */
+void pm_vib_turn_on(void)
+{
+	uint8_t val;
+
+	val = pm8x41_reg_read(QPNP_VIB_VTG_CTL);
+	val &= ~QPNP_VIB_VTG_SET_MASK;
+	val |= (QPNP_VIB_DEFAULT_VTG_LVL & QPNP_VIB_VTG_SET_MASK);
+	pm8x41_reg_write(QPNP_VIB_VTG_CTL, val);
+
+	val = pm8x41_reg_read(QPNP_VIB_EN_CTL);
+	val |= QPNP_VIB_EN;
+	pm8x41_reg_write(QPNP_VIB_EN_CTL, val);
+}
+
+/* Turn off vibrator */
+void pm_vib_turn_off(void)
+{
+	uint8_t val;
+
+	val = pm8x41_reg_read(QPNP_VIB_EN_CTL);
+	val &= ~QPNP_VIB_EN;
+	pm8x41_reg_write(QPNP_VIB_EN_CTL, val);
+}
diff --git a/dev/pmic/pm8x41/rules.mk b/dev/pmic/pm8x41/rules.mk
index 1cecf27..3713a4e 100644
--- a/dev/pmic/pm8x41/rules.mk
+++ b/dev/pmic/pm8x41/rules.mk
@@ -6,3 +6,8 @@
 	$(LOCAL_DIR)/pm8x41.o \
 	$(LOCAL_DIR)/pm8x41_adc.o \
 	$(LOCAL_DIR)/pm8x41_wled.o
+
+ifeq ($(ENABLE_PON_VIB_SUPPORT),true)
+OBJS += \
+	$(LOCAL_DIR)/pm8x41_vib.o
+endif
diff --git a/dev/vib/include/vibrator.h b/dev/vib/include/vibrator.h
new file mode 100644
index 0000000..d6fb8bf
--- /dev/null
+++ b/dev/vib/include/vibrator.h
@@ -0,0 +1,37 @@
+/* Copyright (c) 2014, 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.
+ */
+#ifndef __DEV_VIB_VIBRATOR_H
+#define __DEV_VIB_VIBRATOR_H
+
+#define VIB_TIMER_DEFAULT_TIMEOUT   250
+
+void vib_turn_on(void);
+void vib_turn_off(void);
+void vib_timed_turn_on(const uint32_t);
+void wait_vib_timeout(void);
+#endif				/* __DEV_VIB_VIBRATOR_H */
diff --git a/dev/vib/rules.mk b/dev/vib/rules.mk
new file mode 100644
index 0000000..e9e1d10
--- /dev/null
+++ b/dev/vib/rules.mk
@@ -0,0 +1,6 @@
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+INCLUDES += -I$(LOCAL_DIR)/include
+
+OBJS += \
+	$(LOCAL_DIR)/vibrator.o
diff --git a/dev/vib/vibrator.c b/dev/vib/vibrator.c
new file mode 100644
index 0000000..e8cb8c7
--- /dev/null
+++ b/dev/vib/vibrator.c
@@ -0,0 +1,83 @@
+/* Copyright (c) 2014, 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 <debug.h>
+#include <reg.h>
+#include <stdlib.h>
+#include <kernel/timer.h>
+#include <platform/timer.h>
+#include <vibrator.h>
+#include <pm_vib.h>
+
+#define CHECK_VIB_TIMER_FREQUENCY    50
+
+static struct timer vib_timer;
+static uint32_t vib_timeout;
+
+/* Function to turn on vibrator */
+void vib_turn_on()
+{
+	pm_vib_turn_on();
+}
+
+/* Function to turn off vibrator */
+void vib_turn_off()
+{
+	pm_vib_turn_off();
+}
+
+/* Function to turn off vibrator when the vib_timer is expired. */
+static enum handler_return vib_timer_func(struct timer *v_timer, void *arg)
+{
+	timer_cancel(&vib_timer);
+	vib_turn_off();
+	vib_timeout=1;
+
+	return INT_RESCHEDULE;
+}
+
+/*
+ * Function to turn on vibrator.
+ * vibrate_time - the time of phone vibrate.
+ */
+void vib_timed_turn_on(const uint32_t vibrate_time)
+{
+	vib_turn_on();
+	vib_timeout=0;
+	timer_initialize(&vib_timer);
+	timer_set_oneshot(&vib_timer, vibrate_time, vib_timer_func, NULL);
+}
+
+/* Wait for vibrator timer expired */
+void wait_vib_timeout(void)
+{
+	while (!vib_timeout) {
+		/* every 50ms to check if the vibrator timer is timeout*/
+		thread_sleep(CHECK_VIB_TIMER_FREQUENCY);
+	}
+}
diff --git a/platform/mdm9x35/include/platform/iomap.h b/platform/mdm9x35/include/platform/iomap.h
index cf84ee7..81fd263 100755
--- a/platform/mdm9x35/include/platform/iomap.h
+++ b/platform/mdm9x35/include/platform/iomap.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -55,6 +55,9 @@
 #define MPM2_MPM_SLEEP_TIMETICK_COUNT_VAL    0xFC4A3000
 #define MPM2_MPM_PS_HOLD                     0xFC4AB000
 
+#define BS_INFO_OFFSET            (0x6B0)
+#define BS_INFO_ADDR              (MSM_SHARED_IMEM_BASE + BS_INFO_OFFSET)
+
 #define SPMI_BASE                 0xFC4C0000
 #define SPMI_GENI_BASE            (SPMI_BASE + 0xA000)
 #define SPMI_PIC_BASE             (SPMI_BASE + 0xB000)
diff --git a/platform/mdm9x35/platform.c b/platform/mdm9x35/platform.c
index cab35c5..3604205 100755
--- a/platform/mdm9x35/platform.c
+++ b/platform/mdm9x35/platform.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -110,6 +110,16 @@
 	return 0;
 }
 
+uint32_t platform_get_sclk_count(void)
+{
+	return readl(MPM2_MPM_SLEEP_TIMETICK_COUNT_VAL);
+}
+
+addr_t get_bs_info_addr()
+{
+	return ((addr_t)BS_INFO_ADDR);
+}
+
 void platform_init_mmu_mappings(void)
 {
 	struct smem_ram_ptable *ram_ptable;
diff --git a/platform/msm8916/include/platform/iomap.h b/platform/msm8916/include/platform/iomap.h
index 00c6bdf..94fd16d 100644
--- a/platform/msm8916/include/platform/iomap.h
+++ b/platform/msm8916/include/platform/iomap.h
@@ -29,12 +29,12 @@
 #ifndef _PLATFORM_MSM8916_IOMAP_H_
 #define _PLATFORM_MSM8916_IOMAP_H_
 
-#define MSM_IOMAP_BASE              0xF9000000
-#define MSM_IOMAP_END               0xFEFFFFFF
+#define MSM_IOMAP_BASE              0x0B000000
+#define MSM_IOMAP_END               0xBEFFFFF
 
 #define SDRAM_START_ADDR            0x80000000
 
-#define MSM_SHARED_BASE             0xFA000000
+#define MSM_SHARED_BASE             0x8E380000
 
 #define APPS_SS_BASE                0x0B000000
 
@@ -64,15 +64,15 @@
 #define SPMI_GENI_BASE              (SPMI_BASE + 0xA000)
 #define SPMI_PIC_BASE               (SPMI_BASE + 0xB000)
 
-#define MSM_CE1_BAM_BASE            0xFD404000
-#define MSM_CE1_BASE                0xFD41A000
+#define MSM_CE1_BAM_BASE            0x00704000
+#define MSM_CE1_BASE                0x0073A000
 
-#define TLMM_BASE_ADDR              0xFD510000
+#define TLMM_BASE_ADDR              0x1000000
 #define GPIO_CONFIG_ADDR(x)         (TLMM_BASE_ADDR + 0x1000 + (x)*0x10)
 #define GPIO_IN_OUT_ADDR(x)         (TLMM_BASE_ADDR + 0x1004 + (x)*0x10)
 
-#define MPM2_MPM_CTRL_BASE          0xFC4A1000
-#define MPM2_MPM_PS_HOLD            0xFC4AB000
+#define MPM2_MPM_CTRL_BASE          0x004A1000
+#define MPM2_MPM_PS_HOLD            0x004AB0000
 
 /* CE 2 */
 #define  GCC_CE2_BCR                (CLK_CTL_BASE + 0x1080)
diff --git a/platform/msm_shared/board.c b/platform/msm_shared/board.c
index 3e93888..161a2ea 100644
--- a/platform/msm_shared/board.c
+++ b/platform/msm_shared/board.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -104,18 +104,15 @@
 		board.platform_subtype = board_info_v8.platform_subtype;
 
 		/*
-		* fill in board.target with variant_id information
-		*                 bit no |31  24 | 23   16| 15   8 |7         0|
-		*          board.target =|subtype| major  | minor  |hw_platform|
-		* Have QRD board.target =| OEM   | EVT/DVT|Reserved| QRD        |
-		*
-		*/
-		if (board_info_v8.board_info_v3.hw_platform == HW_PLATFORM_QRD) {
-			board.target = (((board_info_v8.platform_subtype & 0xff) << 24) |
-					(((board_info_v8.platform_version >> 16) & 0xff) << 16) |
-					((board_info_v8.platform_version & 0xff) << 8) |
-					((board_info_v8.board_info_v3.hw_platform & 0xff) << 0));
-		}
+		 * fill in board.target with variant_id information
+		 * bit no         |31  24 | 23   16            | 15   8             |7         0|
+		 * board.target = |subtype| plat_hw_ver major  | plat_hw_ver minor  |hw_platform|
+		 *
+		 */
+		board.target = (((board_info_v8.platform_subtype & 0xff) << 24) |
+					   (((board_info_v8.platform_version >> 16) & 0xff) << 16) |
+					   ((board_info_v8.platform_version & 0xff) << 8) |
+					   (board_info_v8.board_info_v3.hw_platform & 0xff));
 
 		for (i = 0; i < SMEM_V8_SMEM_MAX_PMIC_DEVICES; i++) {
 			board.pmic_info[i].pmic_type = board_info_v8.pmic_info[i].pmic_type;
diff --git a/platform/msm_shared/crypto5_eng.c b/platform/msm_shared/crypto5_eng.c
index e9ea428..0f592f9 100644
--- a/platform/msm_shared/crypto5_eng.c
+++ b/platform/msm_shared/crypto5_eng.c
@@ -364,9 +364,6 @@
 	uint32_t iv_len = 0;
 	uint32_t *auth_iv = sha1_ctx->auth_iv;
 	uint32_t seg_cfg_val;
-	uint32_t total_bytes_to_write = sha256_ctx->bytes_to_write;
-	uint32_t bytes_to_write = total_bytes_to_write;
-	uint32_t burst_mask;
 
 	if(auth_alg == CRYPTO_AUTH_ALG_SHA1)
 	{
@@ -388,6 +385,8 @@
 	/* Initialize CE pointers. */
 	REG_WRITE_QUEUE_INIT(dev);
 
+	/* For authentication operation set the encryption cfg reg to 0 as per HPG */
+	REG_WRITE_QUEUE(dev, CRYPTO_ENCR_SEG_CFG(dev->base), 0);
 	REG_WRITE_QUEUE(dev, CRYPTO_AUTH_SEG_CFG(dev->base), seg_cfg_val);
 
 	for (i = 0; i < iv_len; i++)
@@ -398,31 +397,77 @@
 			REG_WRITE_QUEUE(dev, CRYPTO_AUTH_IVn(dev->base, i), (*(auth_iv + i)));
 	}
 
-	/* Check if the transfer length is a 8 beat burst multiple. */
-	burst_mask = CRYPTO_BURST_LEN - 1;
-	if (bytes_to_write & burst_mask)
-	{
-		/* Add trailer to make it a burst multiple. */
-		total_bytes_to_write = (bytes_to_write + burst_mask) & (~burst_mask);
-	}
-
-	sha256_ctx->bytes_to_write = total_bytes_to_write;
-
 	/* Typecast with crypto_SHA1_ctx because offset of auth_bytecnt
 	 * in both crypto_SHA1_ctx and crypto_SHA256_ctx are same.
 	 */
 	REG_WRITE_QUEUE(dev, CRYPTO_AUTH_BYTECNTn(dev->base, 0), ((crypto_SHA1_ctx *) ctx_ptr)->auth_bytecnt[0]);
 	REG_WRITE_QUEUE(dev, CRYPTO_AUTH_BYTECNTn(dev->base, 1), ((crypto_SHA1_ctx *) ctx_ptr)->auth_bytecnt[1]);
+}
 
-	/* Assume no header, always. */
-	REG_WRITE_QUEUE(dev, CRYPTO_AUTH_SEG_START(dev->base), 0);
+/* Function: crypto5_set_auth_cfg
+ * Arg     : dev, ptr to data buffer, buffer_size, burst_mask for alignment
+ * Return  : aligned buffer incase of unaligned data_ptr and total no. of bytes
+ *           passed to crypto HW(includes header and trailer size).
+ * Flow    : If data buffer is aligned, we just configure the crypto auth
+ *           registers for start, size of data etc. If buffer is unaligned
+ *           we align it to burst(64-byte) boundary and also make the no. of
+ *           bytes a multiple of 64 for bam and then configure the registers
+ *           for header/trailer settings.
+ */
 
+static void crypto5_set_auth_cfg(struct crypto_dev *dev, uint8_t **buffer,
+							uint8_t *data_ptr,
+							uint32_t burst_mask,
+							uint32_t bytes_to_write,
+							uint32_t *total_bytes_to_write)
+{
+	uint32_t minor_ver = 0;
+	uint32_t auth_seg_start = 0;
+
+	/* Bits 23:16 - minor version */
+        minor_ver = (readl(CRYPTO_VERSION(dev->base)) & 0x00FF0000) >> 16;
+
+	/* A H/W bug on Crypto 5.0.0 enforces a rule that the desc lengths must
+	 * be burst aligned. Here we use the header/trailer crypto register settings.
+         * buffer                : The previous 64 byte aligned address for data_ptr.
+         * CRYPTO_AUTH_SEG_START : Number of bytes to skip to reach the address data_ptr.
+         * CRYPTO_AUTH_SEG_SIZE  : Number of  bytes to be sent to crypto HW.
+         * CRYPTO_SEG_SIZE       : CRYPTO_AUTH_SEG_START + CRYPTO_AUTH_SEG_SIZE.
+         * Function: We pick a previous 64 byte aligned address buffer, and tell crypto to
+         * skip (data_ptr - buffer) number of bytes.
+         * This bug is fixed in 5.1.0 onwards.*/
+
+	if(minor_ver == 0)
+	{
+		if ((uint32_t) data_ptr & (CRYPTO_BURST_LEN - 1))
+		{
+			dprintf(CRITICAL, "Data start not aligned at burst length.\n");
+
+			*buffer = (uint8_t *)ROUNDDOWN((uint32_t)data_ptr, CRYPTO_BURST_LEN);
+
+			/* Header & Trailer */
+			*total_bytes_to_write = ((bytes_to_write +(data_ptr - *buffer) + burst_mask) & (~burst_mask));
+
+			auth_seg_start = (data_ptr - *buffer);
+		}
+		else
+		{
+			/* No header */
+			/* Add trailer to make it a burst multiple as 5.0.x HW mandates data to be a multiple of 64. */
+			*total_bytes_to_write = (bytes_to_write + burst_mask) & (~burst_mask);
+		}
+	}
+	else
+	{
+		/* No header. 5.1 crypto HW doesnt require alignment as partial reads and writes are possible*/
+		*total_bytes_to_write = bytes_to_write;
+	}
+
+	REG_WRITE_QUEUE(dev, CRYPTO_AUTH_SEG_START(dev->base), auth_seg_start);
 	REG_WRITE_QUEUE(dev, CRYPTO_AUTH_SEG_SIZE(dev->base), bytes_to_write);
-	REG_WRITE_QUEUE(dev, CRYPTO_SEG_SIZE(dev->base), total_bytes_to_write);
+	REG_WRITE_QUEUE(dev, CRYPTO_SEG_SIZE(dev->base), *total_bytes_to_write);
 	REG_WRITE_QUEUE(dev, CRYPTO_GOPROC(dev->base), GOPROC_GO);
-
 	REG_WRITE_QUEUE_DONE(dev, BAM_DESC_LOCK_FLAG | BAM_DESC_INT_FLAG);
-
 	REG_WRITE_EXEC(&dev->bam, 1, CRYPTO_WRITE_PIPE_INDEX);
 }
 
@@ -434,44 +479,22 @@
 	crypto_SHA256_ctx *sha256_ctx = (crypto_SHA256_ctx *) ctx_ptr;
 	uint32_t wr_flags = BAM_DESC_NWD_FLAG | BAM_DESC_INT_FLAG | BAM_DESC_EOT_FLAG;
 	uint32_t ret_status;
-	uint32_t minor_ver = 0;
 	uint8_t *buffer = NULL;
+	uint32_t total_bytes_to_write = 0;
 
-	/* Bits 23:16 - minor version */
-	minor_ver = (readl(CRYPTO_VERSION(dev->base)) & 0x00FF0000) >> 16;
-
-	/* A H/W bug on Crypto 5.0.0 enforces a rule that the desc lengths must be burst aligned.
-	 * This bug is fixed in 5.1.0 onwards.*/
-
-	if(minor_ver == 0)
-	{
-		if ((uint32_t) data_ptr & (CRYPTO_BURST_LEN - 1))
-		{
-			dprintf(CRITICAL, "Data start not aligned at burst length.\n");
-
-			buffer = (uint8_t *)memalign(CRYPTO_BURST_LEN, sha256_ctx->bytes_to_write);
-			if(!buffer)
-			{
-				dprintf(CRITICAL, "ERROR: Failed to allocate burst aligned crypto buffer\n");
-				ret_status = CRYPTO_ERR_FAIL;
-				goto CRYPTO_SEND_DATA_ERR;
-			}
-
-			memset(buffer, 0, sha256_ctx->bytes_to_write);
-			memcpy(buffer, data_ptr, sha256_ctx->bytes_to_write);
-		}
-	}
+	crypto5_set_auth_cfg(dev, &buffer, data_ptr, CRYPTO_BURST_LEN - 1, sha256_ctx->bytes_to_write,
+											&total_bytes_to_write);
 
 	if(buffer)
 	{
-		arch_clean_invalidate_cache_range((addr_t) buffer, sha256_ctx->bytes_to_write);
+		arch_clean_invalidate_cache_range((addr_t) buffer, total_bytes_to_write);
 
-		bam_status = ADD_WRITE_DESC(&dev->bam, buffer, sha256_ctx->bytes_to_write, wr_flags);
+		bam_status = ADD_WRITE_DESC(&dev->bam, buffer, total_bytes_to_write, wr_flags);
 	}
 	else
 	{
-		arch_clean_invalidate_cache_range((addr_t) data_ptr, sha256_ctx->bytes_to_write);
-		bam_status = ADD_WRITE_DESC(&dev->bam, data_ptr, sha256_ctx->bytes_to_write, wr_flags);
+		arch_clean_invalidate_cache_range((addr_t) data_ptr, total_bytes_to_write);
+		bam_status = ADD_WRITE_DESC(&dev->bam, data_ptr, total_bytes_to_write, wr_flags);
 	}
 
 	if (bam_status)
@@ -505,9 +528,6 @@
 
 CRYPTO_SEND_DATA_ERR:
 
-	if(buffer)
-		free(buffer);
-
 	return ret_status;
 }
 
diff --git a/platform/msm_shared/debug.c b/platform/msm_shared/debug.c
index 3349db7..28c053e 100644
--- a/platform/msm_shared/debug.c
+++ b/platform/msm_shared/debug.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2009, Google Inc.
  * All rights reserved.
- * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2014, 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
@@ -39,6 +39,10 @@
 #include <platform/timer.h>
 #include <platform.h>
 
+#if PON_VIB_SUPPORT
+#include <vibrator.h>
+#endif
+
 static void write_dcc(char c)
 {
 	uint32_t timeout = 10;
@@ -134,6 +138,9 @@
 
 void platform_halt(void)
 {
+#if PON_VIB_SUPPORT
+	vib_turn_off();
+#endif
 	if (set_download_mode(NORMAL_DLOAD) == 0)
 	{
 		dprintf(CRITICAL, "HALT: reboot into dload mode...\n");
diff --git a/platform/msm_shared/dev_tree.c b/platform/msm_shared/dev_tree.c
index ef81891..11eb736 100644
--- a/platform/msm_shared/dev_tree.c
+++ b/platform/msm_shared/dev_tree.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -391,14 +391,35 @@
 
 static int platform_dt_match(struct dt_entry *cur_dt_entry, uint32_t target_variant_id, uint32_t subtype_mask)
 {
-	/* 1. must match the platform_id, hardware_id, platform_version
+	/*
+	 * 1. Check if cur_dt_entry has platform_hw_version major & minor present?
+	 * 2. If present, calculate cur_dt_target_id for the current platform as:
+	 * 3. bit no |31  24 | 23   16| 15   8 |7         0|
+	 * 4.        |subtype| major  | minor  |hw_platform|
+	 */
+	uint32_t cur_dt_target_id ;
+
+	/*
+	 * if variant_id has platform_hw_ver has major = 0xff and minor = 0xff,
+	 * ignore the major & minor versions from the DTB entry
+	 */
+	if ((cur_dt_entry->variant_id & 0xffff00) == 0xffff00)
+		cur_dt_target_id  = (cur_dt_entry->variant_id & 0xff0000ff) | (target_variant_id & 0xffff00);
+	/*
+	 * We have a valid platform_hw_version major & minor numbers in the board-id, so
+	 * use the board-id from the DTB.
+	 * Note: For some QRD platforms the format used is qcom, board-id = <0xMVmVPT 0xPS>
+	 * where: MV: platform major ver, mV: platform minor ver, PT: platform type
+	 * PS: platform subtype, so we need to put PS @ bit 24-31 to be backward compatible.
+	 */
+	else
+		cur_dt_target_id = cur_dt_entry->variant_id | ((cur_dt_entry->board_hw_subtype & subtype_mask & 0xff) << 24);
+
+	/* 1. must match the platform_id, platform_hw_id, platform_version
 	*  2. soc rev number equal then return 0
 	*  3. dt soc rev number less than cdt return -1
 	*  4. otherwise return 1
 	*/
-	uint32_t cur_dt_target_id ;
-
-	cur_dt_target_id  = cur_dt_entry->variant_id | ((cur_dt_entry->board_hw_subtype & subtype_mask & 0xff) << 24);
 
 	if((cur_dt_entry->platform_id == board_platform_id()) &&
 		(cur_dt_target_id == target_variant_id)) {
@@ -491,17 +512,17 @@
 	}
 
 	if (found != 0) {
-		dprintf(INFO, "Using DTB entry %u/%08x/%u/%u for device %u/%08x/%u/%u\n",
+		dprintf(INFO, "Using DTB entry %u/%08x/0x%08x/%u for device %u/%08x/0x%08x/%u\n",
 				dt_entry_info->platform_id, dt_entry_info->soc_rev,
 				dt_entry_info->variant_id, dt_entry_info->board_hw_subtype,
 				board_platform_id(), board_soc_version(),
-				board_hardware_id(), board_hardware_subtype());
+				board_target_id(), board_hardware_subtype());
 		return 0;
 	}
 
-	dprintf(CRITICAL, "ERROR: Unable to find suitable device tree for device (%u/0x%08x/%u/%u)\n",
+	dprintf(CRITICAL, "ERROR: Unable to find suitable device tree for device (%u/0x%08x/0x%08x/%u)\n",
 			board_platform_id(), board_soc_version(),
-			board_hardware_id(), board_hardware_subtype());
+			board_target_id(), board_hardware_subtype());
 	return -1;
 }
 
@@ -515,16 +536,15 @@
 {
 	uint32_t target_variant_id;
 
-	if(board_hardware_id() == HW_PLATFORM_QRD) {
-		target_variant_id = board_target_id();
-		if (__dev_tree_get_entry_info(table, dt_entry_info, target_variant_id, 0xff) == 0) {
-			return 0;
-		}
+	target_variant_id = board_target_id();
+	if (__dev_tree_get_entry_info(table, dt_entry_info, target_variant_id, 0xff) == 0) {
+		return 0;
 	}
+
 	/*
-	* for compatible with version 1 and version 2 dtbtool
-	* will compare the subtype inside the variant id
-	*/
+	 * for compatible with version 1 and version 2 dtbtool
+	 * will compare the subtype inside the variant id
+	 */
 	target_variant_id = board_hardware_id() | ((board_hardware_subtype() & 0xff) << 24);
 	if (__dev_tree_get_entry_info(table, dt_entry_info, target_variant_id, 0xff) == 0) {
 		return 0;
@@ -792,20 +812,24 @@
 		return ret;
 	}
 
-	/* Adding the initrd-start to the chosen node */
-	ret = fdt_setprop_u32(fdt, offset, "linux,initrd-start", (uint32_t)ramdisk);
-	if (ret)
-	{
-		dprintf(CRITICAL, "ERROR: Cannot update chosen node [linux,initrd-start]\n");
-		return ret;
-	}
+	if (ramdisk_size) {
+		/* Adding the initrd-start to the chosen node */
+		ret = fdt_setprop_u32(fdt, offset, "linux,initrd-start",
+				      (uint32_t)ramdisk);
+		if (ret)
+		{
+			dprintf(CRITICAL, "ERROR: Cannot update chosen node [linux,initrd-start]\n");
+			return ret;
+		}
 
-	/* Adding the initrd-end to the chosen node */
-	ret = fdt_setprop_u32(fdt, offset, "linux,initrd-end", ((uint32_t)ramdisk + ramdisk_size));
-	if (ret)
-	{
-		dprintf(CRITICAL, "ERROR: Cannot update chosen node [linux,initrd-end]\n");
-		return ret;
+		/* Adding the initrd-end to the chosen node */
+		ret = fdt_setprop_u32(fdt, offset, "linux,initrd-end",
+				      ((uint32_t)ramdisk + ramdisk_size));
+		if (ret)
+		{
+			dprintf(CRITICAL, "ERROR: Cannot update chosen node [linux,initrd-end]\n");
+			return ret;
+		}
 	}
 
 	fdt_pack(fdt);
diff --git a/platform/msm_shared/include/shutdown_detect.h b/platform/msm_shared/include/shutdown_detect.h
new file mode 100644
index 0000000..23690c9
--- /dev/null
+++ b/platform/msm_shared/include/shutdown_detect.h
@@ -0,0 +1,33 @@
+/* Copyright (c) 2014, 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.
+ */
+
+#ifndef __PLATFORM_MSM_SHARED_SHUTDOWN_DETECT_H
+#define __PLATFORM_MSM_SHARED_SHUTDOWN_DETECT_H
+
+void shutdown_detect(void);
+#endif				/* __PLATFORM_MSM_SHARED_SHUTDOWN_DETECT_H */
diff --git a/platform/msm_shared/mmc.c b/platform/msm_shared/mmc.c
index ec6a88b..fd77583 100644
--- a/platform/msm_shared/mmc.c
+++ b/platform/msm_shared/mmc.c
@@ -2479,9 +2479,24 @@
 mmc_read(unsigned long long data_addr, unsigned int *out, unsigned int data_len)
 {
 	int val = 0;
-	val =
-	    mmc_boot_read_from_card(&mmc_host, &mmc_card, data_addr, data_len,
-				    out);
+	unsigned int data_limit = mmc_card.rd_block_len * 0xffff;
+	unsigned int this_len;
+
+	do {
+		this_len = (data_len > data_limit) ? data_limit : data_len;
+
+		val =
+		    mmc_boot_read_from_card(&mmc_host, &mmc_card, data_addr,
+				    this_len, out);
+
+		if (val != MMC_BOOT_E_SUCCESS)
+			return val;
+
+		data_len -= this_len;
+		data_addr += this_len;
+		out += (this_len / sizeof(*out));
+	} while (data_len > 0);
+
 	return val;
 }
 
diff --git a/platform/msm_shared/qpic_nand.c b/platform/msm_shared/qpic_nand.c
index 4c7dd6b..0c86597 100644
--- a/platform/msm_shared/qpic_nand.c
+++ b/platform/msm_shared/qpic_nand.c
@@ -1621,14 +1621,17 @@
 	uint32_t *spare = (unsigned *)flash_spare_bytes;
 	const unsigned char *image = data;
 	uint32_t wsize;
+	uint32_t spare_byte_count = 0;
 	int r;
 
+	spare_byte_count = ((flash.cw_size * flash.cws_per_page)- flash.page_size);
+
 	if(write_extra_bytes)
-		wsize = flash.page_size + flash.spare_size;
+		wsize = flash.page_size + spare_byte_count;
 	else
 		wsize = flash.page_size;
 
-	memset(spare, 0xff, (flash.spare_size / flash.cws_per_page));
+	memset(spare, 0xff, (spare_byte_count / flash.cws_per_page));
 
 	while (bytes > 0)
 	{
@@ -1664,7 +1667,7 @@
 
 		if (write_extra_bytes)
 		{
-			memcpy(rdwr_buf + flash.page_size, image + flash.page_size, flash.spare_size);
+			memcpy(rdwr_buf + flash.page_size, image + flash.page_size, spare_byte_count);
 			r = qpic_nand_write_page(page,
 									 NAND_CFG,
 									 rdwr_buf,
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index 06169a5..d3b994f 100755
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -133,7 +133,8 @@
             $(LOCAL_DIR)/crypto5_wrapper.o \
 			$(LOCAL_DIR)/dev_tree.o \
 			$(LOCAL_DIR)/gpio.o \
-			$(LOCAL_DIR)/dload_util.o
+			$(LOCAL_DIR)/dload_util.o \
+			$(LOCAL_DIR)/shutdown_detect.o
 endif
 
 ifeq ($(PLATFORM),mpq8092)
diff --git a/platform/msm_shared/scm.c b/platform/msm_shared/scm.c
index 5592f20..db09374 100644
--- a/platform/msm_shared/scm.c
+++ b/platform/msm_shared/scm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2014, 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
@@ -69,6 +69,7 @@
 
 	cmd = memalign(CACHE_LINE, ROUNDUP(len, CACHE_LINE));
 	if (cmd) {
+		memset(cmd, 0, len);
 		cmd->len = len;
 		cmd->buf_offset = offsetof(struct scm_command, buf);
 		cmd->resp_hdr_offset = cmd->buf_offset + cmd_size;
diff --git a/platform/msm_shared/shutdown_detect.c b/platform/msm_shared/shutdown_detect.c
new file mode 100644
index 0000000..a51c9ae
--- /dev/null
+++ b/platform/msm_shared/shutdown_detect.c
@@ -0,0 +1,160 @@
+/* Copyright (c) 2014, 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 <debug.h>
+#include <reg.h>
+#include <stdlib.h>
+#include <pm8x41.h>
+#include <pm8x41_hw.h>
+#include <kernel/timer.h>
+#include <platform/timer.h>
+#include <shutdown_detect.h>
+
+/* sleep clock is 32.768 khz, 0x8000 count per second */
+#define MPM_SLEEP_TIMETICK_COUNT    0x8000
+#define PWRKEY_LONG_PRESS_COUNT     0xC000
+#define QPNP_DEFAULT_TIMEOUT        250
+#define PWRKEY_DETECT_FREQUENCY     50
+
+static struct timer pon_timer;
+static uint32_t pon_timer_complete = 0;
+
+/*
+ * Function to check if the the power key is pressed long enough.
+ * Return 0 if boot time more than PWRKEY_LONG_PRESS_COUNT.
+ * Return 1 if boot time less than PWRKEY_LONG_PRESS_COUNT.
+ */
+static uint32_t is_pwrkey_time_expired()
+{
+	/* power on button tied in with PMIC KPDPWR. */
+	uint32_t sclk_count = platform_get_sclk_count();
+
+	/* Here check if the long press power-key lasts for 1.5s */
+	if (sclk_count > PWRKEY_LONG_PRESS_COUNT)
+		return 0;
+	else
+		return 1;
+}
+
+/*
+ * Function to check if the power on reason is power key triggered.
+ * Return 1 if it is triggered by power key.
+ * Return 0 if it is not triggered by power key.
+ */
+static uint32_t is_pwrkey_pon_reason()
+{
+	uint8_t pon_reason = pm8x41_get_pon_reason();
+
+	if (pm8x41_get_is_cold_boot() && (pon_reason == KPDPWR_N))
+		return 1;
+	else
+		return 0;
+}
+
+/*
+ * Main timer handle: check every PWRKEY_DETECT_FREQUENCY to see
+ * if power key is pressed.
+ * Shutdown the device if power key is release before
+ * (PWRKEY_LONG_PRESS_COUNT/MPM_SLEEP_TIMETICK_COUNT) seconds.
+ */
+static enum handler_return long_press_pwrkey_timer_func(struct timer *p_timer,
+	void *arg)
+{
+	uint32_t sclk_count = platform_get_sclk_count();
+
+	/*
+	 * The following condition is treated as the power key
+	 * is pressed long enough.
+	 * 1. if the power key is pressed last for PWRKEY_LONG_PRESS_COUNT.
+	 */
+	if (sclk_count > PWRKEY_LONG_PRESS_COUNT) {
+		timer_cancel(p_timer);
+		pon_timer_complete = 1;
+	} else {
+		if (pm8x41_get_pwrkey_is_pressed()) {
+			/*
+			 * For normal man response is > 0.1 secs, so we use 0.05 secs default
+			 * for software to be safely detect if there is a key release action.
+			 */
+			timer_set_oneshot(p_timer, PWRKEY_DETECT_FREQUENCY,
+				long_press_pwrkey_timer_func, NULL);
+		} else {
+			shutdown_device();
+		}
+	}
+
+	return INT_RESCHEDULE;
+}
+
+/*
+ * Function to wait until the power key is pressed long enough
+ */
+static void wait_for_long_pwrkey_pressed()
+{
+	uint32_t sclk_count = 0;
+
+	while (!pon_timer_complete) {
+		sclk_count = platform_get_sclk_count();
+		if (sclk_count > PWRKEY_LONG_PRESS_COUNT) {
+			timer_cancel(&pon_timer);
+			break;
+		}
+	}
+}
+
+/*
+ * Function to support for shutdown detection
+ * If below condition is met, the function will shut down
+ * the device. Otherwise it will do nothing and return to
+ * normal boot.
+ * condition:
+ * 1. it is triggered by power key &&
+ * 2. the power key is released before
+ * (PWRKEY_LONG_PRESS_COUNT/MPM_SLEEP_TIMETICK_COUNT) seconds.
+ */
+void shutdown_detect()
+{
+	/*
+	 * If it is booted by power key tirigger.
+	 * Initialize pon_timer and call long_press_pwrkey_timer_func
+	 * function to check if the power key is last press long enough.
+	 */
+	if (is_pwrkey_pon_reason() && is_pwrkey_time_expired()) {
+		timer_initialize(&pon_timer);
+		timer_set_oneshot(&pon_timer, 0, long_press_pwrkey_timer_func, NULL);
+
+		/*
+		 * Wait until long press power key timeout
+		 *
+		 * It will be confused to end users if we shutdown the device
+		 * after the splash screen displayed. But it can be moved the
+		 * wait here if the boot time is much more considered.
+		 */
+		wait_for_long_pwrkey_pressed();
+	}
+}
diff --git a/platform/msm_shared/usb30_dwc.c b/platform/msm_shared/usb30_dwc.c
index 9aa36cc..35b5c6c 100644
--- a/platform/msm_shared/usb30_dwc.c
+++ b/platform/msm_shared/usb30_dwc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -867,6 +867,12 @@
 
 	switch (event_id)
 	{
+	case DWC_EVENT_EP_CMD_COMPLETE:
+	{
+		dwc_dep_cmd_id_t cmd = DWC_EVENT_EP_EVENT_CMD_TYPE(*event);
+		DBG("\n cmd = %s has no action. ignored.", cmd_lookup[cmd]);
+	}
+		break;
 	case DWC_EVENT_EP_XFER_NOT_READY:
 		{
 			if (event_ctrl_stage == CONTROL_DATA_REQUEST)
@@ -923,6 +929,12 @@
 
 	switch (event_id)
 	{
+	case DWC_EVENT_EP_CMD_COMPLETE:
+	{
+		dwc_dep_cmd_id_t cmd = DWC_EVENT_EP_EVENT_CMD_TYPE(*event);
+		DBG("\n cmd = %s has no action. ignored.", cmd_lookup[cmd]);
+	}
+		break;
 	case DWC_EVENT_EP_XFER_NOT_READY:
 		{
 			if (event_ctrl_stage == CONTROL_DATA_REQUEST)/* data request */
diff --git a/project/msm8226.mk b/project/msm8226.mk
index 105ea95..f41a778 100644
--- a/project/msm8226.mk
+++ b/project/msm8226.mk
@@ -10,6 +10,9 @@
 EMMC_BOOT := 1
 ENABLE_SDHCI_SUPPORT := 1
 
+#enable power on vibrator feature
+ENABLE_PON_VIB_SUPPORT := true
+
 #DEFINES += WITH_DEBUG_DCC=1
 DEFINES += WITH_DEBUG_UART=1
 DEFINES += WITH_DEBUG_LOG_BUF=1
@@ -27,6 +30,10 @@
 #Disable thumb mode
 ENABLE_THUMB := false
 
+ifeq ($(ENABLE_PON_VIB_SUPPORT),true)
+DEFINES += PON_VIB_SUPPORT=1
+endif
+
 ifeq ($(ENABLE_SDHCI_SUPPORT),1)
 DEFINES += MMC_SDHCI_SUPPORT=1
 endif
diff --git a/target/apq8084/init.c b/target/apq8084/init.c
index cf7f18f..4a8c577 100644
--- a/target/apq8084/init.c
+++ b/target/apq8084/init.c
@@ -122,6 +122,7 @@
 struct ufs_dev ufs_device;
 
 extern void ulpi_write(unsigned val, unsigned reg);
+extern int _emmc_recovery_init(void);
 
 void target_early_init(void)
 {
@@ -173,7 +174,10 @@
 void target_uninit(void)
 {
 	if(target_boot_device_emmc())
+	{
 		mmc_put_card_to_sleep(dev);
+		sdhci_mode_disable(&dev->host);
+	}
 }
 
 /* Do target specific usb initialization */
@@ -398,7 +402,7 @@
 /* Detect the target type */
 void target_detect(struct board_data *board)
 {
-	board->target = LINUX_MACHTYPE_UNKNOWN;
+	/* This is alreay filled as part of board.c */
 }
 
 void set_cdp_baseband(struct board_data *board)
@@ -565,6 +569,11 @@
 	}
 }
 
+int emmc_recovery_init(void)
+{
+	return _emmc_recovery_init();
+}
+
 unsigned check_reboot_mode(void)
 {
 	uint32_t restart_reason = 0;
@@ -653,6 +662,14 @@
 	writel(val & ~BIT(0), GCC_USB30_PHY_COM_BCR);
 }
 
+bool target_warm_boot(void)
+{
+	uint8_t is_cold_boot = pm8x41_get_is_cold_boot();
+	if (is_cold_boot)
+		return false;
+	else
+		return true;
+}
 /* Set up params for h/w CE. */
 void target_crypto_init_params()
 {
diff --git a/target/fsm9900/init.c b/target/fsm9900/init.c
index ae2f91b..f728909 100644
--- a/target/fsm9900/init.c
+++ b/target/fsm9900/init.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -312,7 +312,7 @@
 /* Detect the target type */
 void target_detect(struct board_data *board)
 {
-	board->target = LINUX_MACHTYPE_UNKNOWN;
+	/* This property is filled as part of board.c */
 }
 
 /* Detect the modem type */
diff --git a/target/init.c b/target/init.c
index bd5b325..c5a202c 100644
--- a/target/init.c
+++ b/target/init.c
@@ -176,3 +176,9 @@
 __WEAK void target_usb_phy_reset(void)
 {
 }
+
+/* determine if target is in warm boot. */
+__WEAK bool target_warm_boot(void)
+{
+	return false;
+}
diff --git a/target/mdm9625/init.c b/target/mdm9625/init.c
index 77f7331..2298ff1 100644
--- a/target/mdm9625/init.c
+++ b/target/mdm9625/init.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -179,8 +179,7 @@
 /* Identify the current target */
 void target_detect(struct board_data *board)
 {
-	/* Not used. set to unknown */
-	board->target = LINUX_MACHTYPE_UNKNOWN;
+	/* This property is filled as part of board.c */
 }
 
 unsigned board_machtype(void)
diff --git a/target/mdm9635/init.c b/target/mdm9635/init.c
index 89e17ad..e882b95 100644
--- a/target/mdm9635/init.c
+++ b/target/mdm9635/init.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -186,8 +186,7 @@
 /* Identify the current target */
 void target_detect(struct board_data *board)
 {
-	/* Not used. set to unknown */
-	board->target = LINUX_MACHTYPE_UNKNOWN;
+	/* This property is filled as part of board.c */
 }
 
 unsigned board_machtype(void)
diff --git a/target/mpq8092/init.c b/target/mpq8092/init.c
index 1ac2c80..997a599 100644
--- a/target/mpq8092/init.c
+++ b/target/mpq8092/init.c
@@ -262,7 +262,7 @@
 /* Detect the target type */
 void target_detect(struct board_data *board)
 {
-	board->target = LINUX_MACHTYPE_UNKNOWN;
+	/* This property is filled as part of board.c */
 }
 
 void target_baseband_detect(struct board_data *board)
diff --git a/target/msm8226/init.c b/target/msm8226/init.c
index a72f592..aab5d8e 100644
--- a/target/msm8226/init.c
+++ b/target/msm8226/init.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -48,6 +48,8 @@
 #include <scm.h>
 #include <stdlib.h>
 #include <partition_parser.h>
+#include <shutdown_detect.h>
+#include <vibrator.h>
 
 extern  bool target_use_signed_kernel(void);
 static void set_sdc_power_ctrl(void);
@@ -65,6 +67,7 @@
 #define CRYPTO_ENGINE_CMD_ARRAY_SIZE       20
 
 #define TLMM_VOL_UP_BTN_GPIO    106
+#define VIBRATE_TIME    250
 
 #define SSD_CE_INSTANCE         1
 
@@ -247,6 +250,11 @@
 
 	target_sdc_init();
 
+	shutdown_detect();
+
+	/* turn on vibrator to indicate that phone is booting up to end user */
+	vib_timed_turn_on(VIBRATE_TIME);
+
 	/* Display splash screen if enabled */
 #if DISPLAY_SPLASH_SCREEN
 	dprintf(SPEW, "Display Init: Start\n");
@@ -356,11 +364,17 @@
 
 void reboot_device(unsigned reboot_reason)
 {
+	int ret = 0;
+
 	writel(reboot_reason, RESTART_REASON_ADDR);
 
 	/* Configure PMIC for warm reset */
 	pm8x41_reset_configure(PON_PSHOLD_WARM_RESET);
 
+	ret = scm_halt_pmic_arbiter();
+	if (ret)
+		dprintf(CRITICAL , "Failed to halt pmic arbiter: %d\n", ret);
+
 	/* Drop PS_HOLD for MSM */
 	writel(0x00, MPM2_MPM_PS_HOLD);
 
@@ -369,6 +383,24 @@
 	dprintf(CRITICAL, "Rebooting failed\n");
 }
 
+/* Configure PMIC and Drop PS_HOLD for shutdown */
+void shutdown_device()
+{
+	dprintf(CRITICAL, "Going down for shutdown.\n");
+
+	/* Configure PMIC for shutdown */
+	pm8x41_reset_configure(PON_PSHOLD_SHUTDOWN);
+
+	/* Drop PS_HOLD for MSM */
+	writel(0x00, MPM2_MPM_PS_HOLD);
+
+	mdelay(5000);
+
+	dprintf(CRITICAL, "shutdown failed\n");
+
+	ASSERT(0);
+}
+
 crypto_engine_type board_ce_type(void)
 {
 	return CRYPTO_ENGINE_TYPE_HW;
@@ -387,6 +419,9 @@
 
 void target_uninit(void)
 {
+	/* wait for the vibrator timer is expried */
+	wait_vib_timeout();
+
 	mmc_put_card_to_sleep(dev);
 
 	if (target_is_ssd_enabled())
@@ -416,15 +451,19 @@
 uint8_t target_panel_auto_detect_enabled()
 {
 	uint8_t ret = 0;
+	uint32_t hw_subtype = board_hardware_subtype();
 
         switch(board_hardware_id())
         {
 		case HW_PLATFORM_QRD:
-			/* Enable auto detect for DVT boards only */
-			if (((board_target_id() >> 16) & 0xFF) == 0x2)
-				ret = 1;
-			else
-				ret = 0;
+			if (hw_subtype != HW_PLATFORM_SUBTYPE_SKUF
+				&& hw_subtype != HW_PLATFORM_SUBTYPE_SKUG) {
+				/* Enable autodetect for 8x26 DVT boards only */
+				if (((board_target_id() >> 16) & 0xFF) == 0x2)
+					ret = 1;
+				else
+					ret = 0;
+			}
 			break;
 		case HW_PLATFORM_SURF:
 		case HW_PLATFORM_MTP:
diff --git a/target/msm8226/rules.mk b/target/msm8226/rules.mk
index f5c9596..3f9d1a3 100755
--- a/target/msm8226/rules.mk
+++ b/target/msm8226/rules.mk
@@ -26,6 +26,7 @@
 	dev/pmic/pm8x41 \
 	dev/panel/msm \
 	dev/gcdb/display \
+	dev/vib \
 	lib/libfdt
 
 DEFINES += \
diff --git a/target/msm8974/init.c b/target/msm8974/init.c
index 848307a..d60d477 100644
--- a/target/msm8974/init.c
+++ b/target/msm8974/init.c
@@ -402,7 +402,7 @@
 /* Detect the target type */
 void target_detect(struct board_data *board)
 {
-	board->target = LINUX_MACHTYPE_UNKNOWN;
+	/* This property is filled in board.c */
 }
 
 /* Detect the modem type */