Hi Shawn Thanks for the review. 1. As you suggested replaced EXT_CSD_BKOPS_LEVEL_PM_SUSPEND calling EXT_CSD_BKOPS_LEVEL_2 directly. 2. Returning -EBUSY from the point I do in the code, stops the path to enter suspend( i.e. calling mmc_power_off() and mmc_card_set_suspended()) Did I get this wrong ? Thanks Uri -----Original Message----- From: Shawn Lin [mailto:shawn.lin@xxxxxxxxxxxxxx] Sent: Wednesday, January 18, 2017 4:00 AM To: Uri Yanai; ulf.hansson@xxxxxxxxxx Cc: shawn.lin@xxxxxxxxxxxxxx; linux-mmc@xxxxxxxxxxxxxxx; chris@xxxxxxxxxx; Alex Lemberg Subject: Re: [PATCH 3/3] mmc: Checking BKOPS status prior to Suspend On 2017/1/17 20:15, Uri Yanai wrote: > If asked to do device Runtime Suspend while in BKOPS and auto BKOPS is > enabled return –EBUSY > The commit msg isn't correct as the code just return -EBUSY when the level of BKOPS is EXT_CSD_BKOPS_LEVEL_PM_SUSPEND. And how do you decide that EXT_CSD_BKOPS_LEVEL_2 should be used. From the spec, it means "performance being impacted". It would be good to know a bit details inside the eMMC firmware. BTW, should we use EXT_CSD_BKOPS_LEVEL_2 directly since it looks more strightforward? > Change-Id: Ie4b38a32fe98179f0bca5b57edaaa47a02d0a389 > Signed-off-by: Uri Yanai <uri.yanai@xxxxxxxxxxx> > Signed-off-by: Alex Lemberg <alex.lemberg@xxxxxxxxxxx> > --- > drivers/mmc/core/mmc.c | 35 ++++++++++++++++++++++++++++------- > include/linux/mmc/mmc.h | 2 ++ > 2 files changed, 30 insertions(+), 7 deletions(-) > > diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index > f70f6a1..21f5851 100644 > --- a/drivers/mmc/core/mmc.c > +++ b/drivers/mmc/core/mmc.c > @@ -1942,7 +1942,8 @@ static void mmc_detect(struct mmc_host *host) > } > } > > -static int _mmc_suspend(struct mmc_host *host, bool is_suspend) > +static int _mmc_suspend(struct mmc_host *host, bool is_suspend, > + bool is_runtime_pm) > { > int err = 0; > unsigned int notify_type = is_suspend ? EXT_CSD_POWER_OFF_SHORT : > @@ -1953,10 +1954,30 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend) > if (mmc_card_suspended(host->card)) > goto out; > > - if (mmc_card_doing_bkops(host->card)) { > - err = mmc_stop_bkops(host->card); > - if (err) > + if (mmc_card_doing_bkops(host->card) || > + host->card->ext_csd.auto_bkops_en) { > + err = mmc_read_bkops_status(host->card); > + if (err) { > + pr_err("%s: error %d reading BKOPS Status\n", > + mmc_hostname(host), err); > goto out; > + } > + if (is_runtime_pm && host->card->ext_csd.raw_bkops_status >= > + EXT_CSD_BKOPS_LEVEL_PM_SUSPEND) { > + /* > + * We don’t allow Runtime Suspend while device still > + * needs time to complete internal BKOPS, returning > + * -EBUSY while BKOPS level is above > + * EXT_CSD_BKOPS_LEVEL_PM_SUSPEND > + */ > + err = -EBUSY; > + goto out; > + } > + if (mmc_card_doing_bkops(host->card)) { > + err = mmc_stop_bkops(host->card); > + if (err) > + goto out; > + } > } > > err = mmc_flush_cache(host->card); > @@ -1987,7 +2008,7 @@ static int mmc_suspend(struct mmc_host *host) { > int err; > > - err = _mmc_suspend(host, true); > + err = _mmc_suspend(host, true, false); > if (!err) { > pm_runtime_disable(&host->card->dev); > pm_runtime_set_suspended(&host->card->dev); > @@ -2034,7 +2055,7 @@ static int mmc_shutdown(struct mmc_host *host) > err = _mmc_resume(host); > > if (!err) > - err = _mmc_suspend(host, false); > + err = _mmc_suspend(host, false, false); > > return err; > } > @@ -2058,7 +2079,7 @@ static int mmc_runtime_suspend(struct mmc_host *host) > if (!(host->caps & MMC_CAP_AGGRESSIVE_PM)) > return 0; > > - err = _mmc_suspend(host, true); > + err = _mmc_suspend(host, true, true); > if (err) > pr_err("%s: error %d doing aggressive suspend\n", > mmc_hostname(host), err); > diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index > 126b8d5..2633274 100644 > --- a/include/linux/mmc/mmc.h > +++ b/include/linux/mmc/mmc.h > @@ -445,6 +445,8 @@ struct _mmc_csd { > */ > #define EXT_CSD_BKOPS_LEVEL_2 0x2 > > +#define EXT_CSD_BKOPS_LEVEL_PM_SUSPEND EXT_CSD_BKOPS_LEVEL_2 > + > /* > * BKOPS modes > */ > -- Best Regards Shawn Lin ��.n��������+%������w��{.n�����{��i��)��jg��������ݢj����G�������j:+v���w�m������w�������h�����٥