diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index d40f6c852727c978ade296978c08e8f4097121f8..d0c8249866effdd43261aa750ecb783e54b1f67e 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -44,6 +44,11 @@
 #include "sd_ops.h"
 #include "sdio_ops.h"
 
+#include <linux/fs.h>
+#include <linux/delay.h>
+
+extern void kernel_restart(char *cmd);
+
 /*
  * Background operations can take a long time, depending on the housekeeping
  * operations the card has to perform.
@@ -1468,6 +1473,40 @@ void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type)
 	mmc_host_clk_release(host);
 }
 
+void mmc_force_poweroff_notify(struct mmc_host *host)
+{
+	int err = 0;
+	unsigned int timeout;
+
+	mmc_claim_host(host);
+
+	if (mmc_card_is_sleep(host->card)) {
+		BUG_ON(!host->bus_ops->resume);
+		err = host->bus_ops->resume(host);
+	}
+
+	if (err) {
+		pr_err("failed to resume for force poweroff notify\n");
+		return;
+	}
+
+	timeout = host->card->ext_csd.generic_cmd6_time;
+
+	pr_info("sending poweroff notify\n");
+	err = mmc_switch(host->card, EXT_CSD_CMD_SET_NORMAL,
+		EXT_CSD_POWER_OFF_NOTIFICATION,
+		EXT_CSD_POWER_OFF_SHORT, timeout);
+	if (err && err != -EBADMSG) {
+		pr_err("Device failed to respond within %d poweroff time\n",
+			timeout);
+		return;
+	}
+
+	pr_info("poweroff notify sent\n");
+	mmc_release_host(host);
+	return;
+}
+
 /*
  * Apply power to the MMC stack.  This is a two-stage process.
  * First, we enable power to the card without the clock running.
@@ -2868,6 +2907,29 @@ int mmc_pm_notify(struct notifier_block *notify_block,
 }
 #endif
 
+
+/* force send poweroff notify to Kingston eMMC
+ * while long press power key before hw reset
+ */
+int force_poweroff_notify(struct notifier_block *notify_block,
+			unsigned long mode, void *unused)
+{
+	struct mmc_host *host = container_of(
+		notify_block, struct mmc_host, force_poweroff_notifier);
+
+	if (host->card == NULL)
+		return 0;
+	/* only for Kingston card */
+	if (mmc_card_mmc(host->card)
+		&& host->card->cid.manfid == 0x70) {
+		emergency_sync();
+		emergency_remount();
+		msleep(1000);
+		kernel_restart(NULL);
+	}
+	return 0;
+}
+
 #ifdef CONFIG_MMC_EMBEDDED_SDIO
 void mmc_set_embedded_sdio_data(struct mmc_host *host,
 				struct sdio_cis *cis,
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index 85d273775ac08260d207816c19e15e7be36f57f0..2b4c51ff39aa490d8f0750b07ec5f12c92f7700c 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -47,6 +47,7 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage,
 void mmc_set_timing(struct mmc_host *host, unsigned int timing);
 void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type);
 void mmc_power_off(struct mmc_host *host);
+void mmc_force_poweroff_notify(struct mmc_host *host);
 
 static inline void mmc_delay(unsigned int ms)
 {
@@ -70,6 +71,9 @@ int mmc_attach_mmc(struct mmc_host *host);
 int mmc_attach_sd(struct mmc_host *host);
 int mmc_attach_sdio(struct mmc_host *host);
 
+int force_poweroff_notify(struct notifier_block *notify_block,
+			unsigned long mode, void *unused);
+
 /* Module parameters */
 extern bool use_spi_crc;
 
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 29b64f0b7c862e74327b0286757f9c68e0adf0e3..e249788661a9ac4f6c512422ecd0276182415b33 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -27,6 +27,8 @@
 #include "core.h"
 #include "host.h"
 
+#include <linux/gpio_keys.h>
+
 #define cls_dev_to_mmc_host(d)	container_of(d, struct mmc_host, class_dev)
 
 static void mmc_host_classdev_release(struct device *dev)
@@ -335,6 +337,8 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
 #ifdef CONFIG_PM
 	host->pm_notify.notifier_call = mmc_pm_notify;
 #endif
+	host->force_poweroff_notifier.notifier_call = force_poweroff_notify;
+	register_resetkey_notifier(&host->force_poweroff_notifier);
 
 	/*
 	 * By default, hosts do not support SGIO or large requests.
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index ea1eca731ae5323607c08c5a6474bf1340a1376f..e56d8479b9453eb650334e5b0346c59f2b417c7c 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1464,6 +1464,8 @@ static int mmc_suspend(struct mmc_host *host)
 		err = mmc_card_sleep(host);
 	else if (!mmc_host_is_spi(host))
 		mmc_deselect_cards(host);
+
+	mmc_card_set_sleep(host->card);
 	host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
 
 out:
@@ -1484,6 +1486,7 @@ static int mmc_resume(struct mmc_host *host)
 	BUG_ON(!host);
 	BUG_ON(!host->card);
 
+	mmc_card_clr_sleep(host->card);
 	mmc_claim_host(host);
 	err = mmc_init_card(host, host->ocr, host->card);
 	mmc_release_host(host);
@@ -1496,6 +1499,7 @@ static int mmc_power_restore(struct mmc_host *host)
 	int ret;
 
 	host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
+	mmc_card_clr_sleep(host->card);
 	mmc_claim_host(host);
 	ret = mmc_init_card(host, host->ocr, host->card);
 	mmc_release_host(host);
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 91aa05f94bb5f0febdda0097cf52e9f9921a3443..8781bfeb114ab843cf61122537c67fbe0465499a 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -60,6 +60,7 @@
 
 #include "msm_sdcc.h"
 #include "msm_sdcc_dml.h"
+#include "../core/core.h"
 
 #define DRIVER_NAME "msm-sdcc"
 
@@ -6256,6 +6257,21 @@ static int msmsdcc_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static void msmsdcc_shutdown(struct platform_device *pdev)
+{
+	struct mmc_host *mmc = mmc_get_drvdata(pdev);
+
+	if (!mmc || !mmc->card)
+		return;
+
+	/* only for Kingston eMMC */
+	if (mmc_card_mmc(mmc->card)
+		&& mmc->card->cid.manfid == 0x70)
+		mmc_force_poweroff_notify(mmc);
+
+	return;
+}
+
 #ifdef CONFIG_MSM_SDIO_AL
 int msmsdcc_sdio_al_lpm(struct mmc_host *mmc, bool enable)
 {
@@ -6616,6 +6632,7 @@ MODULE_DEVICE_TABLE(of, msmsdcc_dt_match);
 static struct platform_driver msmsdcc_driver = {
 	.probe		= msmsdcc_probe,
 	.remove		= msmsdcc_remove,
+	.shutdown	= msmsdcc_shutdown,
 	.driver		= {
 		.name	= "msm_sdcc",
 		.pm	= &msmsdcc_dev_pm_ops,
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 6aade3e4d34fb4eea7b0bbd31cb5b1bf5e750978..9d698ed331a965346bbecaa831ce57810e076368 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -300,6 +300,7 @@ struct mmc_card {
 #define MMC_STATE_HIGHSPEED_200	(1<<8)		/* card is in HS200 mode */
 #define MMC_STATE_DOING_BKOPS	(1<<10)		/* card is doing BKOPS */
 #define MMC_STATE_NEED_BKOPS	(1<<11)		/* card needs to do BKOPS */
+#define MMC_STATE_SLEEP		(1<<12)		/* card is in sleep/deselect state */
 	unsigned int		quirks; 	/* card quirks */
 #define MMC_QUIRK_LENIENT_FN0	(1<<0)		/* allow SDIO FN0 writes outside of the VS CCCR range */
 #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1)	/* use func->cur_blksize */
@@ -472,6 +473,7 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data)
 #define mmc_card_removed(c)	((c) && ((c)->state & MMC_CARD_REMOVED))
 #define mmc_card_doing_bkops(c)	((c)->state & MMC_STATE_DOING_BKOPS)
 #define mmc_card_need_bkops(c)	((c)->state & MMC_STATE_NEED_BKOPS)
+#define mmc_card_is_sleep(c)	((c)->state & MMC_STATE_SLEEP)
 
 #define mmc_card_set_present(c)	((c)->state |= MMC_STATE_PRESENT)
 #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY)
@@ -487,6 +489,9 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data)
 #define mmc_card_clr_doing_bkops(c)	((c)->state &= ~MMC_STATE_DOING_BKOPS)
 #define mmc_card_set_need_bkops(c)	((c)->state |= MMC_STATE_NEED_BKOPS)
 #define mmc_card_clr_need_bkops(c)	((c)->state &= ~MMC_STATE_NEED_BKOPS)
+#define mmc_card_set_sleep(c)	((c)->state |= MMC_STATE_SLEEP)
+#define mmc_card_clr_sleep(c)	((c)->state &= ~MMC_STATE_SLEEP)
+
 /*
  * Quirk add/remove for MMC products.
  */
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index e7d34fc168395f896b80103e678e5c895af12f50..df526d6d12e991dce7d289e0a37cc94d79828f92 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -169,6 +169,7 @@ struct mmc_host {
 	u32			ocr_avail_sd;	/* SD-specific OCR */
 	u32			ocr_avail_mmc;	/* MMC-specific OCR */
 	struct notifier_block	pm_notify;
+	struct notifier_block	force_poweroff_notifier;
 
 #define MMC_VDD_165_195		0x00000080	/* VDD voltage 1.65 - 1.95 */
 #define MMC_VDD_20_21		0x00000100	/* VDD voltage 2.0 ~ 2.1 */