Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mmc: sdhci-sprd: Fix the incorrect soft reset operation when runtime resuming

The SD host controller specification defines 3 types software reset:
software reset for data line, software reset for command line and software
reset for all. Software reset for all means this reset affects the entire
Host controller except for the card detection circuit.

In sdhci_runtime_resume_host() we always do a software "reset for all",
which causes the Spreadtrum variant controller to work abnormally after
resuming. To fix the problem, let's do a software reset for the data and
the command part, rather than "for all".

However, as sdhci_runtime_resume() is a common sdhci function and we don't
want to change the behaviour for other variants, let's introduce a new
in-parameter for it. This enables the caller to decide if a "reset for all"
shall be done or not.

Signed-off-by: Baolin Wang <baolin.wang@linaro.org>
Fixes: fb8bd90f83c4 ("mmc: sdhci-sprd: Add Spreadtrum's initial host controller")
Cc: stable@vger.kernel.org
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

authored by

Baolin Wang and committed by
Ulf Hansson
c6303c5d e21a712a

+12 -12
+1 -1
drivers/mmc/host/sdhci-acpi.c
··· 883 883 884 884 sdhci_acpi_byt_setting(&c->pdev->dev); 885 885 886 - return sdhci_runtime_resume_host(c->host); 886 + return sdhci_runtime_resume_host(c->host, 0); 887 887 } 888 888 889 889 #endif
+1 -1
drivers/mmc/host/sdhci-esdhc-imx.c
··· 1705 1705 esdhc_pltfm_set_clock(host, imx_data->actual_clock); 1706 1706 } 1707 1707 1708 - err = sdhci_runtime_resume_host(host); 1708 + err = sdhci_runtime_resume_host(host, 0); 1709 1709 if (err) 1710 1710 goto disable_ipg_clk; 1711 1711
+1 -1
drivers/mmc/host/sdhci-of-at91.c
··· 289 289 } 290 290 291 291 out: 292 - return sdhci_runtime_resume_host(host); 292 + return sdhci_runtime_resume_host(host, 0); 293 293 } 294 294 #endif /* CONFIG_PM */ 295 295
+2 -2
drivers/mmc/host/sdhci-pci-core.c
··· 167 167 168 168 err_pci_runtime_suspend: 169 169 while (--i >= 0) 170 - sdhci_runtime_resume_host(chip->slots[i]->host); 170 + sdhci_runtime_resume_host(chip->slots[i]->host, 0); 171 171 return ret; 172 172 } 173 173 ··· 181 181 if (!slot) 182 182 continue; 183 183 184 - ret = sdhci_runtime_resume_host(slot->host); 184 + ret = sdhci_runtime_resume_host(slot->host, 0); 185 185 if (ret) 186 186 return ret; 187 187 }
+1 -1
drivers/mmc/host/sdhci-pxav3.c
··· 554 554 if (!IS_ERR(pxa->clk_core)) 555 555 clk_prepare_enable(pxa->clk_core); 556 556 557 - return sdhci_runtime_resume_host(host); 557 + return sdhci_runtime_resume_host(host, 0); 558 558 } 559 559 #endif 560 560
+1 -1
drivers/mmc/host/sdhci-s3c.c
··· 745 745 clk_prepare_enable(busclk); 746 746 if (ourhost->cur_clk >= 0) 747 747 clk_prepare_enable(ourhost->clk_bus[ourhost->cur_clk]); 748 - ret = sdhci_runtime_resume_host(host); 748 + ret = sdhci_runtime_resume_host(host, 0); 749 749 return ret; 750 750 } 751 751 #endif
+1 -1
drivers/mmc/host/sdhci-sprd.c
··· 696 696 if (ret) 697 697 goto clk_disable; 698 698 699 - sdhci_runtime_resume_host(host); 699 + sdhci_runtime_resume_host(host, 1); 700 700 return 0; 701 701 702 702 clk_disable:
+1 -1
drivers/mmc/host/sdhci-xenon.c
··· 638 638 priv->restore_needed = false; 639 639 } 640 640 641 - ret = sdhci_runtime_resume_host(host); 641 + ret = sdhci_runtime_resume_host(host, 0); 642 642 if (ret) 643 643 goto out; 644 644 return 0;
+2 -2
drivers/mmc/host/sdhci.c
··· 3320 3320 } 3321 3321 EXPORT_SYMBOL_GPL(sdhci_runtime_suspend_host); 3322 3322 3323 - int sdhci_runtime_resume_host(struct sdhci_host *host) 3323 + int sdhci_runtime_resume_host(struct sdhci_host *host, int soft_reset) 3324 3324 { 3325 3325 struct mmc_host *mmc = host->mmc; 3326 3326 unsigned long flags; ··· 3331 3331 host->ops->enable_dma(host); 3332 3332 } 3333 3333 3334 - sdhci_init(host, 0); 3334 + sdhci_init(host, soft_reset); 3335 3335 3336 3336 if (mmc->ios.power_mode != MMC_POWER_UNDEFINED && 3337 3337 mmc->ios.power_mode != MMC_POWER_OFF) {
+1 -1
drivers/mmc/host/sdhci.h
··· 781 781 int sdhci_suspend_host(struct sdhci_host *host); 782 782 int sdhci_resume_host(struct sdhci_host *host); 783 783 int sdhci_runtime_suspend_host(struct sdhci_host *host); 784 - int sdhci_runtime_resume_host(struct sdhci_host *host); 784 + int sdhci_runtime_resume_host(struct sdhci_host *host, int soft_reset); 785 785 #endif 786 786 787 787 void sdhci_cqe_enable(struct mmc_host *mmc);