diff mbox series

[v2] mmc: core: issue power off notification when host is removed

Message ID 1604311475-15307-1-git-send-email-yoshihiro.shimoda.uh@renesas.com (mailing list archive)
State Superseded
Delegated to: Geert Uytterhoeven
Headers show
Series [v2] mmc: core: issue power off notification when host is removed | expand

Commit Message

Yoshihiro Shimoda Nov. 2, 2020, 10:04 a.m. UTC
User is possible to turn the power off after a host was removed.
So, call _mmc_suspend() to issue the power off notification when
a host is removing. Note that, to prevent _mmc_resume() calling
in mmc_runtime_resume(), call mmc_card_clr_suspended() in
mmc_remove() before mmc_remove_card(). Otherwise, _mmc_resume()
call mmc_init_card() while removing the host.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
 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@renesas.com/

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

Comments

Yoshihiro Shimoda Nov. 5, 2020, 12:04 p.m. UTC | #1
Hi Ulf,

> From: Yoshihiro Shimoda, Sent: Monday, November 2, 2020 7:05 PM
> 
> User is possible to turn the power off after a host was removed.
> So, call _mmc_suspend() to issue the power off notification when
> a host is removing. Note that, to prevent _mmc_resume() calling
> in mmc_runtime_resume(), call mmc_card_clr_suspended() in
> mmc_remove() before mmc_remove_card(). Otherwise, _mmc_resume()
> call mmc_init_card() while removing the host.
> 
> Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> ---
>  Changes from v1:
>  - Reuse _mmc_suspend() instead of direct mmc_poweroff_notify() calling
>   to check suspended flag while removing.

I'm afraid again, but I would like to drop this patch too because
my colleague found an issue which the following timeout happened
when we read a boot partition, and then unbind the controller.

    [  463.073168] renesas_sdhi_internal_dmac ee140000.mmc: timeout waiting for hardware interrupt (CMD6)

The issue happened on the following mmc_blk_part_switch() calling.
And the function was called after _mmc_suspend() in mmc_remove() called
mmc_power_off(). So, perhaps, we should avoid mmc_power_off() calling
in mmc_remove().

As another solution, we can stop to call mmc_blk_part_switch()
in mmc_blk_remove(). However, in such case we need to modify
mmc-test driver for switching the partition [1].
---
static void mmc_blk_remove(struct mmc_card *card)
{
        struct mmc_blk_data *md = dev_get_drvdata(&card->dev);

        mmc_blk_remove_debugfs(card, md);
        mmc_blk_remove_parts(card, md);
        pm_runtime_get_sync(&card->dev);
        if (md->part_curr != md->part_type) {
                mmc_claim_host(card->host);
                mmc_blk_part_switch(card, md->part_type);   // here
                mmc_release_host(card->host);
        }
<snip>
---

[1] According to the following commit, we need to switch the partition
before we use mmc-test driver.
---
commit ddd6fa7e794e62af3ec3eb4ffdc78489885701f2
Author: Adrian Hunter <adrian.hunter@intel.com>
Date:   Thu Jun 23 13:40:26 2011 +0300

    mmc: block: switch card to User Data Area when removing the block driver

    The MMC block driver and other drivers (e.g. mmc-test) will expect
    the card to be switched to the User Data Area eMMC partition when
    they start.  Hence the MMC block driver should ensure it is that
    way when it is removed.

    Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
    Cc: Andrei Warkentin <andreiw@motorola.com>
    Signed-off-by: Chris Ball <cjb@laptop.org>
---

Best regards,
Yoshihiro Shimoda
diff mbox series

Patch

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index ff3063c..0f83466 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1983,11 +1983,16 @@  static int mmc_poweroff_notify(struct mmc_card *card, unsigned int notify_type)
 	return err;
 }
 
+static int _mmc_suspend(struct mmc_host *host, bool is_suspend);
 /*
  * Host is being removed. Free up the current card.
  */
 static void mmc_remove(struct mmc_host *host)
 {
+	_mmc_suspend(host, false);
+	/* Prevent _mmc_resume() calling in mmc_runtime_resume() */
+	mmc_card_clr_suspended(host->card);
+
 	mmc_remove_card(host->card);
 	host->card = NULL;
 }