Merge "platform: msm8996: Add support for CE clocks"
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 0800957..07a8d76 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -58,6 +58,7 @@
 #include <boot_verifier.h>
 #include <image_verify.h>
 #include <decompress.h>
+#include <platform/timer.h>
 #if USE_RPMB_FOR_DEVINFO
 #include <rpmb.h>
 #endif
@@ -791,6 +792,7 @@
 		{
 			dprintf(CRITICAL,
 					"Device verification failed. Rebooting into recovery.\n");
+			mdelay(1000);
 			reboot_device(RECOVERY_MODE);
 		}
 		else
diff --git a/dev/pmic/pm8x41/pm8x41.c b/dev/pmic/pm8x41/pm8x41.c
index 583145a..6733656 100644
--- a/dev/pmic/pm8x41/pm8x41.c
+++ b/dev/pmic/pm8x41/pm8x41.c
@@ -364,6 +364,7 @@
 	*/
 	/* disable PS_HOLD_RESET */
 	pm8xxx_reg_write(slave_id[0], PON_PS_HOLD_RESET_CTL2, 0x0);
+	pm8xxx_reg_write(slave_id[1], PON_PS_HOLD_RESET_CTL2, 0x0);
 
 	/* Delay needed for disable to kick in. */
 	udelay(300);
@@ -373,7 +374,8 @@
 		pm8xxx_reg_write(slave_id[i], PON_PS_HOLD_RESET_CTL, reset_type);
 
 	/* enable PS_HOLD_RESET */
-	pm8xxx_reg_write(slave_id[0], PON_PS_HOLD_RESET_CTL2, BIT(S2_RESET_EN_BIT));
+	for (i = 0; i < ARRAY_SIZE(slave_id); i++)
+		pm8xxx_reg_write(slave_id[i], PON_PS_HOLD_RESET_CTL2, BIT(S2_RESET_EN_BIT));
 }
 
 void pm8x41_v2_reset_configure(uint8_t reset_type)
diff --git a/dev/qpnp_haptic/qpnp_haptic.c b/dev/qpnp_haptic/qpnp_haptic.c
new file mode 100644
index 0000000..1bdadee
--- /dev/null
+++ b/dev/qpnp_haptic/qpnp_haptic.c
@@ -0,0 +1,150 @@
+/* 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 <spmi.h>
+#include <platform/iomap.h>
+#include <pm_vib.h>
+
+#define HAPTIC_BASE (PMI_ADDR_BASE+ 0xC000)
+#define QPNP_HAP_EN_CTL_REG (HAPTIC_BASE + 0x46)
+#define QPNP_HAP_EN_CTL2_REG (HAPTIC_BASE + 0x48)
+#define QPNP_HAP_ACT_TYPE_REG (HAPTIC_BASE + 0x4C)
+#define QPNP_HAP_WAV_SHAPE_REG (HAPTIC_BASE + 0x4D)
+#define QPNP_HAP_PLAY_MODE_REG (HAPTIC_BASE + 0x4E)
+#define QPNP_HAP_LRA_AUTO_RES_REG (HAPTIC_BASE + 0x4F)
+#define QPNP_HAP_VMAX_REG (HAPTIC_BASE + 0x51)
+#define QPNP_HAP_ILIM_REG (HAPTIC_BASE + 0x52)
+#define QPNP_HAP_SC_DEB_REG (HAPTIC_BASE + 0x53)
+#define QPNP_HAP_RATE_CFG1_REG (HAPTIC_BASE + 0x54)
+#define QPNP_HAP_RATE_CFG2_REG (HAPTIC_BASE + 0x55)
+#define QPNP_HAP_INT_PWM_REG (HAPTIC_BASE + 0x56)
+#define QPNP_HAP_PWM_CAP_REG (HAPTIC_BASE + 0x58)
+#define QPNP_HAP_BRAKE_REG (HAPTIC_BASE + 0x5C)
+#define QPNP_HAP_PLAY_REG (HAPTIC_BASE + 0x70)
+
+#define QPNP_HAP_ACT_TYPE_MASK 0x01
+#define QPNP_HAP_PLAY_MODE_MASK 0x3F
+#define QPNP_HAP_DIRECT 0x0
+#define QPNP_HAP_VMAX_MASK 0x3F
+#define QPNP_HAP_VMAX 0x22
+#define QPNP_HAP_ILIM_MASK 0x01
+#define QPNP_HAP_ILIM 0x01
+#define QPNP_HAP_SC_DEB_MASK 0x07
+#define QPNP_HAP_SC_DEB_8CLK 0x01
+#define QPNP_HAP_INT_PWM_MASK 0x03
+#define QPNP_HAP_INT_PWM_505KHZ 0x01
+#define QPNP_HAP_WAV_SHAPE_MASK 0x01
+#define QPNP_HAP_WAV_SHAPE_SQUARE 0x01
+#define QPNP_HAP_PWM_CAP_MASK 0x03
+#define QPNP_HAP_PWM_CAP_13PF 0x01
+#define QPNP_HAP_RATE_CFG1_MASK 0xFF
+#define QPNP_HAP_RATE_CFG1_7_0 0x1C
+#define QPNP_HAP_RATE_CFG2_MASK 0x0F
+#define QPNP_HAP_RATE_CFG2_11_8 0x04
+#define QPNP_HAP_EN_BRAKE_EN_MASK 0x01
+#define QPNP_HAP_EN_BRAKING_EN 0x01
+#define QPNP_HAP_BRAKE_VMAX_MASK 0xFF
+#define QPNP_HAP_BRAKE_VMAX 0xF
+#define QPNP_HAP_ERM 0x1
+#define QPNP_HAP_PLAY_MASK 0x80
+#define QPNP_HAP_PLAY_EN 0x80
+#define QPNP_HAP_MASK 0x80
+#define QPNP_HAP_EN 0x80
+#define QPNP_HAP_PLAY_DIS 0x00
+#define QPNP_HAP_DIS 0x00
+#define QPNP_HAP_BRAKE_MASK 0xFE
+#define QPNP_HAP_LRA_AUTO_DISABLE 0x00
+#define QPNP_HAP_LRA_AUTO_MASK 0x70
+
+/* Turn on vibrator */
+void pm_vib_turn_on(void)
+{
+	/* 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);
+
+	/* 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);
+
+	/* 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);
+
+	/* Configure the VMAX register */
+	pmic_spmi_reg_mask_write(QPNP_HAP_VMAX_REG,
+					QPNP_HAP_VMAX_MASK, QPNP_HAP_VMAX);
+
+	/* Sets current limit to 800mA*/
+	pmic_spmi_reg_mask_write(QPNP_HAP_ILIM_REG,
+					QPNP_HAP_ILIM_MASK, QPNP_HAP_ILIM);
+
+	/* Configure the short circuit debounce register as DEB_8CLK*/
+	pmic_spmi_reg_mask_write(QPNP_HAP_SC_DEB_REG,
+					QPNP_HAP_SC_DEB_MASK, QPNP_HAP_SC_DEB_8CLK);
+
+	/* Configure the INTERNAL_PWM register as 505KHZ and 13PF*/
+	pmic_spmi_reg_mask_write(QPNP_HAP_INT_PWM_REG,
+					QPNP_HAP_INT_PWM_MASK, QPNP_HAP_INT_PWM_505KHZ);
+	pmic_spmi_reg_mask_write(QPNP_HAP_PWM_CAP_REG,
+					QPNP_HAP_PWM_CAP_MASK, QPNP_HAP_PWM_CAP_13PF);
+
+	/* Configure the WAVE SHAPE register as SQUARE*/
+	pmic_spmi_reg_mask_write(QPNP_HAP_WAV_SHAPE_REG,
+					QPNP_HAP_WAV_SHAPE_MASK, QPNP_HAP_WAV_SHAPE_SQUARE);
+
+	/* Configure RATE_CFG1 and RATE_CFG2 registers for haptic rate. */
+	pmic_spmi_reg_mask_write(QPNP_HAP_RATE_CFG1_REG,
+					QPNP_HAP_RATE_CFG1_MASK, QPNP_HAP_RATE_CFG1_7_0);
+	pmic_spmi_reg_mask_write(QPNP_HAP_RATE_CFG2_REG,
+					QPNP_HAP_RATE_CFG2_MASK, QPNP_HAP_RATE_CFG2_11_8);
+
+	/* Configure BRAKE register, PATTERN1 & PATTERN2 as VMAX. */
+	pmic_spmi_reg_mask_write(QPNP_HAP_EN_CTL2_REG,
+					QPNP_HAP_EN_BRAKE_EN_MASK, QPNP_HAP_EN_BRAKING_EN);
+	pmic_spmi_reg_mask_write(QPNP_HAP_BRAKE_REG,
+					QPNP_HAP_BRAKE_VMAX_MASK, QPNP_HAP_BRAKE_VMAX);
+
+	/* Enable control register */
+	pmic_spmi_reg_mask_write(QPNP_HAP_EN_CTL_REG,
+					QPNP_HAP_PLAY_MASK, QPNP_HAP_PLAY_EN);
+
+	/* Enable play register */
+	pmic_spmi_reg_mask_write(QPNP_HAP_PLAY_REG, QPNP_HAP_MASK, QPNP_HAP_EN);
+}
+
+/* Turn off vibrator */
+void pm_vib_turn_off(void)
+{
+	/* Disable control register */
+	pmic_spmi_reg_mask_write(QPNP_HAP_EN_CTL_REG,
+					QPNP_HAP_PLAY_MASK, QPNP_HAP_PLAY_DIS);
+
+	/* Disable play register */
+	pmic_spmi_reg_mask_write(QPNP_HAP_PLAY_REG, QPNP_HAP_MASK, QPNP_HAP_DIS);
+}
diff --git a/dev/qpnp_haptic/rules.mk b/dev/qpnp_haptic/rules.mk
new file mode 100644
index 0000000..8922bb7
--- /dev/null
+++ b/dev/qpnp_haptic/rules.mk
@@ -0,0 +1,8 @@
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+INCLUDES += -I$(LOCAL_DIR)/include
+
+ifeq ($(ENABLE_HAP_VIB_SUPPORT),true)
+OBJS += \
+	$(LOCAL_DIR)/qpnp_haptic.o
+endif
diff --git a/include/target.h b/include/target.h
index 772afdf..2a3579a 100644
--- a/include/target.h
+++ b/include/target.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2008 Travis Geiselbrecht
  *
- * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2015, 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
@@ -79,6 +79,7 @@
 void target_usb_stop(void);
 uint32_t target_get_hlos_subtype(void);
 void shutdown_device();
+uint32_t target_is_pwrkey_pon_reason(void);
 bool target_warm_boot(void);
 bool target_use_signed_kernel(void);
 int _emmc_recovery_init(void);
diff --git a/platform/msm8909/platform.c b/platform/msm8909/platform.c
index 8fcac08..e59f69e 100644
--- a/platform/msm8909/platform.c
+++ b/platform/msm8909/platform.c
@@ -34,6 +34,7 @@
 #include <mmu.h>
 #include <arch/arm/mmu.h>
 #include <smem.h>
+#include <target/display.h>
 
 #define MB (1024*1024)
 
@@ -63,6 +64,7 @@
 	{    A7_SS_BASE,        A7_SS_BASE,       A7_SS_SIZE,       IOMAP_MEMORY},
 	{    SYSTEM_IMEM_BASE,  SYSTEM_IMEM_BASE, 1,                IMEM_MEMORY},
 	{    MSM_SHARED_BASE,   MSM_SHARED_BASE,  1,                COMMON_MEMORY},
+	{    MIPI_FB_ADDR,      MIPI_FB_ADDR,     10,              COMMON_MEMORY},
 };
 
 static struct smem_ram_ptable ram_ptable;
diff --git a/platform/msm8952/include/platform/iomap.h b/platform/msm8952/include/platform/iomap.h
index 29d8749..94488b5 100644
--- a/platform/msm8952/include/platform/iomap.h
+++ b/platform/msm8952/include/platform/iomap.h
@@ -70,6 +70,9 @@
 
 #define CLK_CTL_BASE                       0x1800000
 
+#define PMI_SLAVE_ID 3
+#define PMI_ADDR_BASE (PMI_SLAVE_ID << 16)
+
 #define SPMI_BASE                          0x02000000
 #define SPMI_GENI_BASE                     (SPMI_BASE + 0xA000)
 #define SPMI_PIC_BASE                      (SPMI_BASE +  0x01800000)
diff --git a/platform/msm_shared/boot_verifier.c b/platform/msm_shared/boot_verifier.c
index 4819eeb..e76fed2 100644
--- a/platform/msm_shared/boot_verifier.c
+++ b/platform/msm_shared/boot_verifier.c
@@ -38,6 +38,7 @@
 #include <rsa.h>
 #include <string.h>
 #include <openssl/err.h>
+#include <platform.h>
 
 static KEYSTORE *oem_keystore;
 static KEYSTORE *user_keystore;
@@ -470,6 +471,8 @@
 			dprintf(INFO, "boot_verifier: Device is in YELLOW boot state.\n");
 			break;
 		case RED:
+			display_fbcon_message("Security Error:  This phone has been flashed with unauthorized software & is locked. Call your mobile operator for additional support.Please note that				repair/return for this issue may have additional cost.\n");
+
 			dprintf(INFO, "boot_verifier: Device is in RED boot state.\n");
 			break;
 	}
diff --git a/platform/msm_shared/include/spmi.h b/platform/msm_shared/include/spmi.h
index 85cd66a..b594da5 100644
--- a/platform/msm_shared/include/spmi.h
+++ b/platform/msm_shared/include/spmi.h
@@ -29,6 +29,8 @@
 #ifndef __SPMI_H
 #define __SPMI_H
 
+#include <sys/types.h>
+
 #if SPMI_CORE_V2
 #include <spmi_v2.h>
 #else
@@ -72,6 +74,10 @@
 #define SPMI_PIC_IRQ_CLEARn(n)               (SPMI_PIC_BASE + 0xA00 + 0x4 * (n))
 #endif
 
+#define SPMI_REG_OFFSET(_addr)   ((_addr) & 0xFF)
+#define SPMI_PERIPH_ID(_addr)    (((_addr) & 0xFF00) >> 8)
+#define SPMI_SLAVE_ID(_addr)     ((_addr) >> 16)
+
 #define PMIC_ARB_CMD_OPCODE_SHIFT            27
 #define PMIC_ARB_CMD_PRIORITY_SHIFT          26
 #define PMIC_ARB_CMD_SLAVE_ID_SHIFT          20
@@ -143,5 +149,8 @@
 	struct pmic_arb_param *param);
 unsigned int pmic_arb_read_cmd(struct pmic_arb_cmd *cmd,
 	struct pmic_arb_param *param);
+uint8_t pmic_spmi_reg_read(uint32_t addr);
+void pmic_spmi_reg_write(uint32_t addr, uint8_t val);
+void pmic_spmi_reg_mask_write(uint32_t addr, uint8_t mask, uint8_t val);
 
 #endif
diff --git a/platform/msm_shared/shutdown_detect.c b/platform/msm_shared/shutdown_detect.c
index 633dbac..b7410eb 100644
--- a/platform/msm_shared/shutdown_detect.c
+++ b/platform/msm_shared/shutdown_detect.c
@@ -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
@@ -9,7 +9,7 @@
  *     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
+ *   * 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.
  *
@@ -70,12 +70,16 @@
  */
 static uint32_t is_pwrkey_pon_reason()
 {
+#if PMI_CONFIGURED
+	return target_is_pwrkey_pon_reason();
+#else
 	uint8_t pon_reason = pm8x41_get_pon_reason();
 
 	if (pm8x41_get_is_cold_boot() && (pon_reason == KPDPWR_N))
 		return 1;
 	else
 		return 0;
+#endif
 }
 
 /*
diff --git a/platform/msm_shared/spmi.c b/platform/msm_shared/spmi.c
index 7408a9d..5af8eb7 100644
--- a/platform/msm_shared/spmi.c
+++ b/platform/msm_shared/spmi.c
@@ -389,6 +389,53 @@
 
 }
 
+/* SPMI helper functions */
+uint8_t pmic_spmi_reg_read(uint32_t addr)
+{
+	uint8_t val = 0;
+	struct pmic_arb_cmd cmd;
+	struct pmic_arb_param param;
+
+	cmd.address  = SPMI_PERIPH_ID(addr);
+	cmd.offset   = SPMI_REG_OFFSET(addr);
+	cmd.slave_id = SPMI_SLAVE_ID(addr);
+	cmd.priority = 0;
+
+	param.buffer = &val;
+	param.size   = 1;
+
+	pmic_arb_read_cmd(&cmd, &param);
+
+	return val;
+}
+
+void pmic_spmi_reg_write(uint32_t addr, uint8_t val)
+{
+	struct pmic_arb_cmd cmd;
+	struct pmic_arb_param param;
+
+	cmd.address  = SPMI_PERIPH_ID(addr);
+	cmd.offset   = SPMI_REG_OFFSET(addr);
+	cmd.slave_id = SPMI_SLAVE_ID(addr);
+	cmd.priority = 0;
+
+	param.buffer = &val;
+	param.size   = 1;
+
+	pmic_arb_write_cmd(&cmd, &param);
+}
+
+void pmic_spmi_reg_mask_write(uint32_t addr, uint8_t mask, uint8_t val)
+{
+	uint8_t reg;
+
+	reg = pmic_spmi_reg_read(addr);
+
+	reg &= ~mask;
+	reg |= val & mask;
+	pmic_spmi_reg_write(addr, reg);
+}
+
 void spmi_uninit()
 {
 	mask_interrupt(EE0_KRAIT_HLOS_SPMI_PERIPH_IRQ);
diff --git a/project/msm8909.mk b/project/msm8909.mk
index 59f63f7..64805e9 100644
--- a/project/msm8909.mk
+++ b/project/msm8909.mk
@@ -34,6 +34,7 @@
 DEFINES += ABOOT_FORCE_KERNEL64_ADDR=0x00080000
 
 DEFINES += BAM_V170=1
+DEFINES += ENABLE_FBCON_LOGGING=1
 
 #Enable the feature of long press power on
 DEFINES += LONG_PRESS_POWER_ON=1
diff --git a/project/msm8952.mk b/project/msm8952.mk
index 4ba2ff8..4cdcf6e 100644
--- a/project/msm8952.mk
+++ b/project/msm8952.mk
@@ -42,7 +42,7 @@
 endif
 
 #enable power on vibrator feature
-#ENABLE_PON_VIB_SUPPORT := true
+ENABLE_HAP_VIB_SUPPORT := true
 
 ifeq ($(EMMC_BOOT),1)
 DEFINES += _EMMC_BOOT=1
@@ -52,6 +52,10 @@
 DEFINES += PON_VIB_SUPPORT=1
 endif
 
+ifeq ($(ENABLE_HAP_VIB_SUPPORT),true)
+DEFINES += PON_VIB_SUPPORT=1
+endif
+
 ifeq ($(ENABLE_SMD_SUPPORT),1)
 DEFINES += SMD_SUPPORT=1
 endif
diff --git a/target/msm8952/init.c b/target/msm8952/init.c
index 1f4f60c..99550f5 100644
--- a/target/msm8952/init.c
+++ b/target/msm8952/init.c
@@ -61,6 +61,14 @@
 #include <shutdown_detect.h>
 #endif
 
+#if PON_VIB_SUPPORT
+#include <vibrator.h>
+#endif
+
+#if PON_VIB_SUPPORT
+#define VIBRATE_TIME    250
+#endif
+
 #define PMIC_ARB_CHANNEL_NUM    0
 #define PMIC_ARB_OWNER_ID       0
 #define TLMM_VOL_UP_BTN_GPIO    85
@@ -194,6 +202,15 @@
 	return pm8x41_resin_status();
 }
 
+uint32_t target_is_pwrkey_pon_reason()
+{
+	uint8_t pon_reason = pm8950_get_pon_reason();
+	if (pm8x41_get_is_cold_boot() && ((pon_reason == KPDPWR_N) || (pon_reason == (KPDPWR_N|PON1))))
+		return 1;
+	else
+		return 0;
+}
+
 static void target_keystatus()
 {
 	keys_init();
@@ -242,6 +259,12 @@
 #if LONG_PRESS_POWER_ON
 	shutdown_detect();
 #endif
+
+#if PON_VIB_SUPPORT
+	/* turn on vibrator to indicate that phone is booting up to end user */
+	vib_timed_turn_on(VIBRATE_TIME);
+#endif
+
 	if (target_use_signed_kernel())
 		target_crypto_init_params();
 
diff --git a/target/msm8952/rules.mk b/target/msm8952/rules.mk
index 3471c09..c488c21 100644
--- a/target/msm8952/rules.mk
+++ b/target/msm8952/rules.mk
@@ -15,10 +15,14 @@
 DEFINES += DISPLAY_TYPE_MIPI=1
 DEFINES += DISPLAY_TYPE_DSI6G=1
 
+DEFINES += PMI_CONFIGURED=1
+
 MODULES += \
 	dev/keys \
 	lib/ptable \
 	dev/pmic/pm8x41 \
+	dev/qpnp_haptic \
+	dev/vib \
 	lib/libfdt \
 	dev/qpnp_wled \
 	dev/gcdb/display
diff --git a/target/msm8996/init.c b/target/msm8996/init.c
index a8d0126..0042a7e 100644
--- a/target/msm8996/init.c
+++ b/target/msm8996/init.c
@@ -373,7 +373,7 @@
 	else
 		reset_type = PON_PSHOLD_HARD_RESET;
 
-	pm8x41_reset_configure(reset_type);
+	pm8994_reset_configure(reset_type);
 
 	/* Drop PS_HOLD for MSM */
 	writel(0x00, MPM2_MPM_PS_HOLD);
@@ -486,3 +486,20 @@
 
 	return ret;
 }
+
+void shutdown_device()
+{
+	dprintf(CRITICAL, "Going down for shutdown.\n");
+
+	/* Configure PMIC for shutdown. */
+	pm8994_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);
+}