diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index e864187..c2e5a66 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -297,24 +297,13 @@ static int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
 	return 0;
 }
 
-/**
- *	mmc_start_bkops - start BKOPS for supported cards
- *	@card: MMC card to start BKOPS
- *	@form_exception: A flag to indicate if this function was
- *			 called due to an exception raised by the card
- *
- *	Start background operations whenever requested.
- *	When the urgent BKOPS bit is set in a R1 command response
- *	then background operations should be started immediately.
-*/
-void mmc_start_bkops(struct mmc_card *card, bool from_exception)
+static void  mmc_start_man_bkops(struct mmc_card *card,
+				 bool from_exception)
 {
 	int err;
 	int timeout;
 	bool use_busy_signal;
 
-	BUG_ON(!card);
-
 	if (!card->ext_csd.man_bkops_en || mmc_card_doing_bkops(card))
 		return;
 
@@ -347,7 +336,7 @@ void mmc_start_bkops(struct mmc_card *card, bool from_exception)
 			EXT_CSD_BKOPS_START, 1, timeout,
 			use_busy_signal, true, false);
 	if (err) {
-		pr_warn("%s: Error %d starting bkops\n",
+		pr_warn("%s: Error %d starting manual bkops\n",
 			mmc_hostname(card->host), err);
 		mmc_retune_release(card->host);
 		goto out;
@@ -365,6 +354,55 @@ void mmc_start_bkops(struct mmc_card *card, bool from_exception)
 out:
 	mmc_release_host(card->host);
 }
+
+static void  mmc_start_auto_bkops(struct mmc_card *card)
+{
+	int err;
+
+	/* If it's already enable auto_bkops, nothing to do */
+	if (card->ext_csd.auto_bkops_en)
+		return;
+
+	mmc_claim_host(card->host);
+
+	mmc_retune_hold(card->host);
+
+	err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+			EXT_CSD_BKOPS_EN, 2,
+			card->ext_csd.generic_cmd6_time);
+	if (err)
+		pr_warn("%s: Error %d starting auto bkops\n",
+			mmc_hostname(card->host), err);
+
+	card->ext_csd.auto_bkops_en = true;
+	mmc_card_set_doing_bkops(card);
+	mmc_retune_release(card->host);
+	mmc_release_host(card->host);
+}
+
+
+/**
+ *	mmc_start_bkops - start BKOPS for supported cards
+ *	@card: MMC card to start BKOPS
+ *	@form_exception: A flag to indicate if this function was
+ *			 called due to an exception raised by the card
+ *          @is_auto: A flag to indicate if we should use auto bkops
+ *
+ *	Start background operations whenever requested.
+ *	When the urgent BKOPS bit is set in a R1 command response
+ *	then background operations should be started immediately, which is
+ *	only needed for man_bkops.
+*/
+void mmc_start_bkops(struct mmc_card *card, bool from_exception,
+		     bool is_auto)
+{
+	BUG_ON(!card);
+
+	if (is_auto)
+		return mmc_start_auto_bkops(card);
+	else
+		return mmc_start_man_bkops(card, from_exception);
+}
 EXPORT_SYMBOL(mmc_start_bkops);
 
 /*
@@ -610,7 +648,9 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
 			if (areq)
 				mmc_post_req(host, areq->mrq, -EINVAL);
 
-			mmc_start_bkops(host->card, true);
+			/* Prefer to use auto bkops for eMMC 5.1 or later */
+			mmc_start_bkops(host->card, true,
+					host->card->ext_csd.rev >= 8);
 
 			/* prepare the request again */
 			if (areq)
@@ -751,20 +791,10 @@ int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries
 
 EXPORT_SYMBOL(mmc_wait_for_cmd);
 
-/**
- *	mmc_stop_bkops - stop ongoing BKOPS
- *	@card: MMC card to check BKOPS
- *
- *	Send HPI command to stop ongoing background operations to
- *	allow rapid servicing of foreground operations, e.g. read/
- *	writes. Wait until the card comes out of the programming state
- *	to avoid errors in servicing read/write requests.
- */
-int mmc_stop_bkops(struct mmc_card *card)
+static int mmc_stop_man_bkops(struct mmc_card *card)
 {
 	int err = 0;
 
-	BUG_ON(!card);
 	err = mmc_interrupt_hpi(card);
 
 	/*
@@ -779,6 +809,51 @@ int mmc_stop_bkops(struct mmc_card *card)
 
 	return err;
 }
+
+static int mmc_stop_auto_bkops(struct mmc_card *card)
+{
+	int err = 0;
+
+	if (!card->ext_csd.auto_bkops_en)
+		return 0;
+
+	err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+			EXT_CSD_BKOPS_EN, 0, MMC_BKOPS_MAX_TIMEOUT,
+			true, true, false);
+	if (err)
+		pr_warn("%s: Error %d stoping auto bkops\n",
+			mmc_hostname(card->host), err);
+
+	card->ext_csd.auto_bkops_en = false;
+	mmc_card_clr_doing_bkops(card);
+	mmc_retune_release(card->host);
+
+	return err;
+}
+
+/**
+ *	mmc_stop_bkops - stop ongoing BKOPS
+ *	@card: MMC card to check BKOPS
+ *	@is_auto: A flag to indicate if we should use auto bkops
+ *
+ *	Send HPI command to stop ongoing background operations to
+ *	allow rapid servicing of foreground operations, e.g. read/
+ *	writes. Wait until the card comes out of the programming state
+ *	to avoid errors in servicing read/write requests.
+ *
+ *	But for auto bkops, we could only disable AUTO_EN instead of
+ *	sending HPI. And the firmware could do it automatically.
+ *
+ */
+int mmc_stop_bkops(struct mmc_card *card, bool is_auto)
+{
+	BUG_ON(!card);
+
+	if (is_auto)
+		return mmc_stop_auto_bkops(card);
+	else
+		return mmc_stop_man_bkops(card);
+}
 EXPORT_SYMBOL(mmc_stop_bkops);
 
 int mmc_read_bkops_status(struct mmc_card *card)
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 61d6b34..c65bea7 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -508,6 +508,13 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd)
 		/* check whether the eMMC card supports BKOPS */
 		if (ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1) {
 			card->ext_csd.bkops = 1;
+
+			/* for eMMC v5.1 or later, we could use auto_bkops */
+			if (card->ext_csd.rev >= 8)
+				card->ext_csd.auto_bkops_en =
+					(ext_csd[EXT_CSD_BKOPS_EN] &
+						EXT_CSD_AUTO_BKOPS_MASK);
+
 			card->ext_csd.man_bkops_en =
 					(ext_csd[EXT_CSD_BKOPS_EN] &
 						EXT_CSD_MANUAL_BKOPS_MASK);
@@ -516,6 +523,9 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd)
 			if (!card->ext_csd.man_bkops_en)
 				pr_debug("%s: MAN_BKOPS_EN bit is not set\n",
 					mmc_hostname(card->host));
+			if (!card->ext_csd.auto_bkops_en)
+				pr_debug("%s: AUTO_BKOPS_EN bit is not set\n",
+					mmc_hostname(card->host));
 		}
 
 		/* check whether the eMMC card supports HPI */
@@ -1241,7 +1251,7 @@ static int mmc_select_hs400es(struct mmc_card *card)
 	}
 
 	err = mmc_select_bus_width(card);
-	if (IS_ERR_VALUE(err))
+	if (err < 0)
 		goto out_err;
 
 	/* Switch card to HS mode */
@@ -1676,6 +1686,21 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
 	mmc_select_powerclass(card);
 
 	/*
+	 * Enable auto bkops feature which is mandatory for
+	 * eMMC v5.1 or later
+	 */
+	if (card->ext_csd.rev >= 8) {
+		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+				 EXT_CSD_BKOPS_EN, 2,
+				 card->ext_csd.generic_cmd6_time);
+		if (err)
+			pr_warn("%s: Error %d starting auto bkops\n",
+				mmc_hostname(card->host), err);
+
+		card->ext_csd.auto_bkops_en = true;
+	}
+
+	/*
 	 * Enable HPI feature (if supported)
 	 */
 	if (card->ext_csd.hpi) {
@@ -1898,7 +1923,8 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
 		goto out;
 
 	if (mmc_card_doing_bkops(host->card)) {
-		err = mmc_stop_bkops(host->card);
+		err = mmc_stop_bkops(host->card,
+				     host->card->ext_csd.rev >= 8);
 		if (err)
 			goto out;
 	}
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 22defc2..f82f9be 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -84,6 +84,7 @@ struct mmc_ext_csd {
 	unsigned int		hpi_cmd;		/* cmd used as HPI */
 	bool			bkops;		/* background support bit */
 	bool			man_bkops_en;	/* manual bkops enable bit */
+	bool			auto_bkops_en;	/* auto bkops enbale bit */
 	unsigned int            data_sector_size;       /* 512 bytes or 4KB */
 	unsigned int            data_tag_unit_size;     /* DATA TAG UNIT size */
 	unsigned int		boot_ro_lock;		/* ro lock support */
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
index b01e77d..45d53ef 100644
--- a/include/linux/mmc/core.h
+++ b/include/linux/mmc/core.h
@@ -140,7 +140,7 @@ struct mmc_request {
 struct mmc_card;
 struct mmc_async_req;
 
-extern int mmc_stop_bkops(struct mmc_card *);
+extern int mmc_stop_bkops(struct mmc_card *, bool);
 extern int mmc_read_bkops_status(struct mmc_card *);
 extern struct mmc_async_req *mmc_start_req(struct mmc_host *,
 					   struct mmc_async_req *, int *);
@@ -150,7 +150,7 @@ extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int);
 extern int mmc_app_cmd(struct mmc_host *, struct mmc_card *);
 extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *,
 	struct mmc_command *, int);
-extern void mmc_start_bkops(struct mmc_card *card, bool from_exception);
+extern void mmc_start_bkops(struct mmc_card *, bool, bool);
 extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int);
 extern int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error);
 extern int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd);
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index c376209..a1cced9 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -436,6 +436,7 @@ struct _mmc_csd {
  * BKOPS modes
  */
 #define EXT_CSD_MANUAL_BKOPS_MASK	0x01
+#define EXT_CSD_AUTO_BKOPS_MASK		0x02
 
 /*
  * MMC_SWITCH access modes
