Merge "platform: msm8916: correct the MPM2_MPM_PS_HOLD address"
diff --git a/platform/msm_shared/include/mmc_sdhci.h b/platform/msm_shared/include/mmc_sdhci.h
index abbe64d..398f982 100644
--- a/platform/msm_shared/include/mmc_sdhci.h
+++ b/platform/msm_shared/include/mmc_sdhci.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
@@ -97,6 +97,7 @@
 #define MMC_PART_CONFIG                           179
 #define MMC_ERASE_GRP_DEF                         175
 #define MMC_USR_WP                                171
+#define MMC_ERASE_TIMEOUT_MULT                    223
 #define MMC_HC_ERASE_GRP_SIZE                     224
 
 /* Values for ext csd fields */
diff --git a/platform/msm_shared/include/sdhci.h b/platform/msm_shared/include/sdhci.h
index a14b3b5..a660e29 100644
--- a/platform/msm_shared/include/sdhci.h
+++ b/platform/msm_shared/include/sdhci.h
@@ -87,6 +87,7 @@
 	uint32_t trans_mode;    /* Transfer mode, read/write */
 	uint32_t cmd_retry;     /* Retry the command, if card is busy */
 	uint32_t cmd23_support; /* If card supports cmd23 */
+	uint64_t cmd_timeout;   /* Command timeout in ms */
 	struct mmc_data data;   /* Data pointer */
 };
 
diff --git a/platform/msm_shared/mmc_sdhci.c b/platform/msm_shared/mmc_sdhci.c
index 127505c..f0d51ac 100644
--- a/platform/msm_shared/mmc_sdhci.c
+++ b/platform/msm_shared/mmc_sdhci.c
@@ -1937,7 +1937,7 @@
 /*
  * Send the erase CMD38, to erase the selected erase groups
  */
-static uint32_t mmc_send_erase(struct mmc_device *dev)
+static uint32_t mmc_send_erase(struct mmc_device *dev, uint64_t erase_timeout)
 {
 	struct mmc_command cmd;
 	uint32_t status;
@@ -1949,6 +1949,7 @@
 	cmd.argument = 0x00000000;
 	cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;
 	cmd.resp_type = SDHCI_CMD_RESP_R1B;
+	cmd.cmd_timeout = erase_timeout;
 
 	/* send command */
 	if (sdhci_send_command(&dev->host, &cmd))
@@ -1992,6 +1993,7 @@
 	uint32_t erase_end;
 	uint32_t blk_end;
 	uint32_t num_erase_grps;
+	uint64_t erase_timeout = 0;
 	uint32_t *out;
 	struct mmc_card *card;
 
@@ -2058,12 +2060,19 @@
 		return 1;
 	}
 
+	/*
+	 * As per emmc 4.5 spec section 7.4.27, calculate the erase timeout
+	 * erase_timeout = 300 * ERASE_TIMEOUT_MULT * num_erase_grps
+	 */
+	erase_timeout = (300 * card->ext_csd[MMC_ERASE_TIMEOUT_MULT] * num_erase_grps);
+
 	/* Send CMD38 to perform erase */
-	if (mmc_send_erase(dev))
+	if (mmc_send_erase(dev, erase_timeout))
 	{
 		dprintf(CRITICAL, "Failed to erase the specified partition\n");
 		return 1;
 	}
+
 	return 0;
 }
 
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index 68fb302..096336b 100755
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -197,7 +197,8 @@
             $(LOCAL_DIR)/crypto_hash.o \
             $(LOCAL_DIR)/crypto5_eng.o \
             $(LOCAL_DIR)/crypto5_wrapper.o \
-            $(LOCAL_DIR)/dload_util.o
+            $(LOCAL_DIR)/dload_util.o \
+            $(LOCAL_DIR)/shutdown_detect.o
 endif
 
 ifeq ($(PLATFORM),apq8084)
diff --git a/platform/msm_shared/sdhci.c b/platform/msm_shared/sdhci.c
index eeb47fc..a278dea 100644
--- a/platform/msm_shared/sdhci.c
+++ b/platform/msm_shared/sdhci.c
@@ -377,6 +377,7 @@
 	uint32_t int_status;
 	uint32_t trans_complete = 0;
 	uint32_t err_status;
+	uint64_t max_trans_retry = (cmd->cmd_timeout ? cmd->cmd_timeout : SDHCI_MAX_TRANS_RETRY);
 
 	do {
 		int_status = REG_READ16(host, SDHCI_NRML_INT_STS_REG);
@@ -449,7 +450,7 @@
 
 			retry++;
 			udelay(1000);
-			if (retry == SDHCI_MAX_TRANS_RETRY) {
+			if (retry == max_trans_retry) {
 				dprintf(CRITICAL, "Error: Transfer never completed\n");
 				ret = 1;
 				goto err;
diff --git a/project/msm8610.mk b/project/msm8610.mk
index 3f7dcbb..5bcad33 100644
--- a/project/msm8610.mk
+++ b/project/msm8610.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
@@ -29,6 +32,10 @@
 #is with the linker and file a bug report.
 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/msm8610/init.c b/target/msm8610/init.c
index 87daf47..29e9b08 100644
--- a/target/msm8610/init.c
+++ b/target/msm8610/init.c
@@ -51,6 +51,8 @@
 #include <platform/clock.h>
 #include <platform/timer.h>
 #include <crypto5_wrapper.h>
+#include <shutdown_detect.h>
+#include <vibrator.h>
 
 #define PMIC_ARB_CHANNEL_NUM    0
 #define PMIC_ARB_OWNER_ID       0
@@ -65,6 +67,7 @@
 #define CRYPTO_ENGINE_CMD_ARRAY_SIZE       20
 
 #define TLMM_VOL_UP_BTN_GPIO    72
+#define VIBRATE_TIME    250
 
 enum target_subtype {
 	HW_PLATFORM_SUBTYPE_SKUAA = 1,
@@ -176,12 +179,20 @@
 
 	target_sdc_init();
 
+	shutdown_detect();
+
+	/* turn on vibrator to indicate that phone is booting up to end user */
+	vib_timed_turn_on(VIBRATE_TIME);
+
 	if (target_use_signed_kernel())
 		target_crypto_init_params();
 }
 
 void target_uninit(void)
 {
+	/* wait for the vibrator timer is expried */
+	wait_vib_timeout();
+
 	mmc_put_card_to_sleep(dev);
 
 	if (crypto_initialized())
@@ -510,6 +521,24 @@
 	return 0;
 }
 
+/* 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;
diff --git a/target/msm8610/rules.mk b/target/msm8610/rules.mk
index 909e673..7ffcfe1 100644
--- a/target/msm8610/rules.mk
+++ b/target/msm8610/rules.mk
@@ -25,6 +25,7 @@
 	dev/pmic/pm8x41 \
 	dev/panel/msm \
 	dev/gcdb/display \
+	dev/vib \
 	lib/libfdt
 
 DEFINES += \