Re: [PATCH V2] mmc: sdhci-msm: Disable CQE during SDHC reset

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

 




On 3/4/2020 7:40 PM, Adrian Hunter wrote:
On 4/03/20 3:10 pm, Veerabhadrarao Badiganti wrote:
Hi Adrian

On 3/4/2020 5:58 PM, Adrian Hunter wrote:
On 4/03/20 1:54 pm, Veerabhadrarao Badiganti wrote:
When SDHC gets reset (E.g. in suspend path), CQE also gets reset
and goes to disable state. But s/w state still points it as CQE
is in enabled state. Since s/w and h/w states goes out of sync,
it results in s/w request timeout for subsequent CQE requests.

To synchronize CQE s/w and h/w state during SDHC reset,
explicitly disable CQE after reset.
Shouldn't you be calling cqhci_suspend() / cqhci_resume() in the suspend and
resume paths?
This issue is seen during mmc runtime suspend.  I can add it
sdhci_msm_runtime_suspend

but sdhci_msm runtime delay is aggressive, its 50ms. It may get invoked very
frequently.

So Im of the opinion that disabling CQE very often from platform runtime
suspend is overkill.
It doesn't look like sdhci-msm calls any sdhci.c pm ops, so how does SDHC
get reset?

With MMC_CAP_AGGRESSIVE_PM flag enabled, it getting called from mmc_runtime_suspend()

Below is the call stack()

   sdhci_reset
  sdhci_do_reset
  sdhci_init
  sdhci_set_ios
  mmc_set_initial_state
  mmc_power_off
 _mmc_suspend
  mmc_runtime_suspend

Signed-off-by: Veerabhadrarao Badiganti <vbadigan@xxxxxxxxxxxxxx>
---
Changes since V1:
     - Disable CQE only when SDHC undergoes s/w reset for all.
---
   drivers/mmc/host/sdhci-msm.c | 9 ++++++++-
   1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 53b79ee..75929d3 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -1823,6 +1823,13 @@ static void sdhci_msm_set_regulator_caps(struct
sdhci_msm_host *msm_host)
       pr_debug("%s: supported caps: 0x%08x\n", mmc_hostname(mmc), caps);
   }
   +static void sdhci_msm_reset(struct sdhci_host *host, u8 mask)
+{
+    sdhci_reset(host, mask);
+    if ((host->mmc->caps2 & MMC_CAP2_CQE) && (mask & SDHCI_RESET_ALL))
+        cqhci_suspend(host->mmc);
+}
+
   static const struct sdhci_msm_variant_ops mci_var_ops = {
       .msm_readl_relaxed = sdhci_msm_mci_variant_readl_relaxed,
       .msm_writel_relaxed = sdhci_msm_mci_variant_writel_relaxed,
@@ -1861,7 +1868,7 @@ static void sdhci_msm_set_regulator_caps(struct
sdhci_msm_host *msm_host)
   MODULE_DEVICE_TABLE(of, sdhci_msm_dt_match);
     static const struct sdhci_ops sdhci_msm_ops = {
-    .reset = sdhci_reset,
+    .reset = sdhci_msm_reset,
       .set_clock = sdhci_msm_set_clock,
       .get_min_clock = sdhci_msm_get_min_clock,
       .get_max_clock = sdhci_msm_get_max_clock,




[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