[PATCH v3] mmc: core: Issue power off notification in mmc_remove()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



User is possible to turn the power off after a host was removed.
So, call mmc_poweroff_notify(EXT_CSD_NO_POWER_NOTIFICATION)
in mmc_remove(). Note that the mmc and host driver will be
in the following modes when mmc_remove() is called:

 1. mmc_card_suspended() == false &&
    power_off_notification == EXT_CSD_POWER_ON
 2. mmc_card_suspended() == true &&
    power_off_notification == EXT_CSD_POWER_OFF_{SHORT,LONG}
 3. mmc_card_suspended() == true && mmc_sleep() was called

So, mmc_remove() calls _mmc_resume() anyway for the cases.
Otherwise:

 - _mmc_resume will be called via mmc_runtime_resume() and then
   power_off_notification will be set to EXT_CSD_POWER_ON.
 - timeout will happen in mmc_blk_part_switch() via mmc_blk_remove()
   if "part_curr" of mmc block is not set to default.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@xxxxxxxxxxx>
---
 Changes from v2:
 - Fix an issue which timeout happens if part_curr is not default.
 https://patchwork.kernel.org/project/linux-renesas-soc/patch/1604311475-15307-1-git-send-email-yoshihiro.shimoda.uh@xxxxxxxxxxx/

 Changes from v1:
 - Reuse _mmc_suspend() instead of direct mmc_poweroff_notify() calling
  to check suspended flag while removing.
  https://patchwork.kernel.org/project/linux-renesas-soc/patch/1602581312-23607-1-git-send-email-yoshihiro.shimoda.uh@xxxxxxxxxxx/


 drivers/mmc/core/mmc.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index ff3063c..18413f2 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1983,11 +1983,35 @@ static int mmc_poweroff_notify(struct mmc_card *card, unsigned int notify_type)
 	return err;
 }
 
+static int _mmc_resume(struct mmc_host *host);
 /*
  * Host is being removed. Free up the current card.
  */
 static void mmc_remove(struct mmc_host *host)
 {
+	/*
+	 * The mmc and host driver will be in the following modes here:
+	 *  1. mmc_card_suspended() == false &&
+	 *     power_off_notification == EXT_CSD_POWER_ON
+	 *  2. mmc_card_suspended() == true &&
+	 *     power_off_notification == EXT_CSD_POWER_OFF_{SHORT,LONG}
+	 *  3. mmc_card_suspended() == true && mmc_sleep() was called
+	 *
+	 * So, call _mmc_resume() here anyway for the cases. Otherwise:
+	 *  - _mmc_resume will be called via mmc_runtime_resume() and then
+	 *    power_off_notification will be set to EXT_CSD_POWER_ON.
+	 *  - timeout will happen in mmc_blk_part_switch() via mmc_blk_remove()
+	 *    if "part_curr" of mmc block is not set to default.
+	 */
+	_mmc_resume(host);
+
+	/* Disable power_off_notification byte in the ext_csd register */
+	if (host->card->ext_csd.rev >= 6) {
+		mmc_claim_host(host);
+		mmc_poweroff_notify(host->card, EXT_CSD_NO_POWER_NOTIFICATION);
+		mmc_release_host(host);
+	}
+
 	mmc_remove_card(host->card);
 	host->card = NULL;
 }
-- 
2.7.4




[Index of Archives]     [Linux Memonry Technology]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux