> > Signed-off-by: Wolfram Sang <wsa+renesas@xxxxxxxxxxxxxxxxxxxx> > > [1] https://patchwork.kernel.org/project/linux-renesas-soc/patch/1602581312-23607-1-git-send-email-yoshihiro.shimoda.uh@xxxxxxxxxxx/ > [2] https://patchwork.kernel.org/project/linux-mmc/patch/1605005330-7178-1-git-send-email-yoshihiro.shimoda.uh@xxxxxxxxxxx/ > --- > > RFC to see if the direction is proper. Obvious improvements are removing > the debug printout and check if the forward declaration can be avoided. > This was lightly tested on a Renesas Salvator board. Accessing the eMMC > after unbind/bind and suspend/resume showed no regressions. > > drivers/mmc/core/mmc.c | 29 +++++++++++++++++++++-------- > 1 file changed, 21 insertions(+), 8 deletions(-) > > diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c > index 6a23be214543..bd4381fa182f 100644 > --- a/drivers/mmc/core/mmc.c > +++ b/drivers/mmc/core/mmc.c > @@ -32,6 +32,12 @@ > #define MIN_CACHE_EN_TIMEOUT_MS 1600 > #define CACHE_FLUSH_TIMEOUT_MS 30000 /* 30s */ > > +enum mmc_pm_reason { > + MMC_PM_REASON_SHUTDOWN, > + MMC_PM_REASON_SUSPEND, > + MMC_PM_REASON_UNBIND, > +}; > + > static const unsigned int tran_exp[] = { > 10000, 100000, 1000000, 10000000, > 0, 0, 0, 0 > @@ -2032,11 +2038,13 @@ static int mmc_poweroff_notify(struct mmc_card *card, unsigned int notify_type) > return err; > } > > +static int _mmc_suspend(struct mmc_host *host, enum mmc_pm_reason reason); > /* > * Host is being removed. Free up the current card. > */ > static void mmc_remove(struct mmc_host *host) > { > + _mmc_suspend(host, MMC_PM_REASON_UNBIND); Calling _mmc_suspend() here, will put the mmc card into sleep/power-off state and the card will also be powered-off. During this period, we may receive I/O requests in the mmc-blk-queue, which then the mmc block device driver tries to serve. This may lead to that we call the host driver's ops, with the state MMC_POWER_OFF and asking it to serve requests. This doesn't work and will hang some of the host HW/drivers. To be able to put the mmc card into sleep/power-off state, we first need to prevent the mmc-blk-queue from serving any additional I/O requests, which is what mmc_remove_card() does. :-) Although, we can't call _mmc_suspend() after mmc_remove_card() as the mmc_card may have been freed by then. Hmm... > mmc_remove_card(host->card); > host->card = NULL; > } [...] Kind regards Uffe