diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 14f262e..dc85ee1 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1096,12 +1096,12 @@ void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type)
 	mmc_host_clk_release(host);
 }
 
-static void mmc_poweroff_notify(struct mmc_host *host)
+int mmc_poweroff_notify(struct mmc_host *host)
 {
 	struct mmc_card *card;
 	unsigned int timeout;
 	unsigned int notify_type = EXT_CSD_NO_POWER_NOTIFICATION;
-	int err = 0;
+	int err = -EINVAL;
 
 	card = host->card;
 	mmc_claim_host(host);
@@ -1136,6 +1136,7 @@ static void mmc_poweroff_notify(struct mmc_host *host)
 		card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION;
 	}
 	mmc_release_host(host);
+	return err;
 }
 
 /*
@@ -1194,30 +1195,12 @@ static void mmc_power_up(struct mmc_host *host)
 
 void mmc_power_off(struct mmc_host *host)
 {
-	int err = 0;
 	mmc_host_clk_hold(host);
 
 	host->ios.clock = 0;
 	host->ios.vdd = 0;
 
 	/*
-	 * For eMMC 4.5 device send AWAKE command before
-	 * POWER_OFF_NOTIFY command, because in sleep state
-	 * eMMC 4.5 devices respond to only RESET and AWAKE cmd
-	 */
-	if (host->card && mmc_card_is_sleep(host->card) &&
-	    host->bus_ops->resume) {
-		err = host->bus_ops->resume(host);
-
-		if (!err)
-			mmc_poweroff_notify(host);
-		else
-			pr_warning("%s: error %d during resume "
-				   "(continue with poweroff sequence)\n",
-				   mmc_hostname(host), err);
-	}
-
-	/*
 	 * Reset ocr mask to be the highest possible voltage supported for
 	 * this mmc host. This value will be used at next power up.
 	 */
@@ -2076,6 +2059,7 @@ void mmc_stop_host(struct mmc_host *host)
 	host->pm_flags = 0;
 
 	mmc_bus_get(host);
+	mmc_poweroff_notify(host);
 	if (host->bus_ops && !host->bus_dead) {
 		/* Calling bus_ops->remove() with a claimed host can deadlock */
 		if (host->bus_ops->remove)
@@ -2112,7 +2096,8 @@ int mmc_power_save_host(struct mmc_host *host)
 
 	if (host->bus_ops->power_save)
 		ret = host->bus_ops->power_save(host);
-
+	host->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
+	mmc_poweroff_notify(host);
 	mmc_bus_put(host);
 
 	mmc_power_off(host);
@@ -2135,7 +2120,7 @@ int mmc_power_restore_host(struct mmc_host *host)
 		mmc_bus_put(host);
 		return -EINVAL;
 	}
-
+	host->power_notify_type = MMC_HOST_PW_NOTIFY_LONG;
 	mmc_power_up(host);
 	ret = host->bus_ops->power_restore(host);
 
@@ -2157,6 +2142,9 @@ int mmc_card_awake(struct mmc_host *host)
 	if (host->bus_ops && !host->bus_dead && host->bus_ops->awake)
 		err = host->bus_ops->awake(host);
 
+	if (!err)
+		mmc_card_clr_sleep(host->card);
+
 	mmc_bus_put(host);
 
 	return err;
@@ -2175,6 +2163,9 @@ int mmc_card_sleep(struct mmc_host *host)
 	if (host->bus_ops && !host->bus_dead && host->bus_ops->sleep)
 		err = host->bus_ops->sleep(host);
 
+	if (!err)
+		mmc_card_set_sleep(host->card);
+
 	mmc_bus_put(host);
 
 	return err;
@@ -2393,6 +2384,7 @@ int mmc_pm_notify(struct notifier_block *notify_block,
 			host->bus_ops->remove(host);
 
 		mmc_claim_host(host);
+		mmc_poweroff_notify(host);
 		mmc_detach_bus(host);
 		mmc_power_off(host);
 		mmc_release_host(host);
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index 3bdafbc..0bdc0fd 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -45,6 +45,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);
+int mmc_poweroff_notify(struct mmc_host *host);
 
 static inline void mmc_delay(unsigned int ms)
 {
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 02914d6..885ad61 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1338,12 +1338,18 @@ static int mmc_suspend(struct mmc_host *host)
 	BUG_ON(!host->card);
 
 	mmc_claim_host(host);
-	if (mmc_card_can_sleep(host)) {
-		err = mmc_card_sleep(host);
+	if (host->caps2 & MMC_CAP2_POWER_OFF_VCCQ_DURING_SUSPEND) {
+		err = mmc_poweroff_notify(host);
 		if (!err)
-			mmc_card_set_sleep(host->card);
-	} else if (!mmc_host_is_spi(host))
+			goto out;
+	}
+
+	if (mmc_card_can_sleep(host))
+		err = mmc_card_sleep(host);
+	else if (!mmc_host_is_spi(host))
 		mmc_deselect_cards(host);
+
+out:	
 	host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
 	mmc_release_host(host);
 
@@ -1364,11 +1370,11 @@ static int mmc_resume(struct mmc_host *host)
 	BUG_ON(!host->card);
 
 	mmc_claim_host(host);
-	if (mmc_card_is_sleep(host->card)) {
+	if (mmc_card_is_sleep(host->card))
 		err = mmc_card_awake(host);
-		mmc_card_clr_sleep(host->card);
-	} else
+	else
 		err = mmc_init_card(host, host->ocr, host->card);
+
 	mmc_release_host(host);
 
 	return err;
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 33a4d08..3749a42 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -237,6 +237,7 @@ struct mmc_host {
 #define MMC_CAP2_BROKEN_VOLTAGE	(1 << 7)	/* Use the broken voltage */
 #define MMC_CAP2_DETECT_ON_ERR	(1 << 8)	/* On I/O err check card removal */
 #define MMC_CAP2_HC_ERASE_SZ	(1 << 9)	/* High-capacity erase size */
+#define MMC_CAP2_POWER_OFF_VCCQ_DURING_SUSPEND	(1 << 10)
 
 	mmc_pm_flag_t		pm_caps;	/* supported pm features */
 	unsigned int        power_notify_type;
