mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 10:00:17 +00:00
mmc: sdhci-sprd: Fix the incorrect soft reset operation when runtime resuming
[ Upstream commitc6303c5d52] 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:fb8bd90f83("mmc: sdhci-sprd: Add Spreadtrum's initial host controller") Cc: stable@vger.kernel.org Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
c0e2dbd7d7
commit
cb77c43fa0
@@ -883,7 +883,7 @@ static int sdhci_acpi_runtime_resume(struct device *dev)
|
||||
|
||||
sdhci_acpi_byt_setting(&c->pdev->dev);
|
||||
|
||||
return sdhci_runtime_resume_host(c->host);
|
||||
return sdhci_runtime_resume_host(c->host, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1705,7 +1705,7 @@ static int sdhci_esdhc_runtime_resume(struct device *dev)
|
||||
esdhc_pltfm_set_clock(host, imx_data->actual_clock);
|
||||
}
|
||||
|
||||
err = sdhci_runtime_resume_host(host);
|
||||
err = sdhci_runtime_resume_host(host, 0);
|
||||
if (err)
|
||||
goto disable_ipg_clk;
|
||||
|
||||
|
||||
@@ -289,7 +289,7 @@ static int sdhci_at91_runtime_resume(struct device *dev)
|
||||
}
|
||||
|
||||
out:
|
||||
return sdhci_runtime_resume_host(host);
|
||||
return sdhci_runtime_resume_host(host, 0);
|
||||
}
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@ static int sdhci_pci_runtime_suspend_host(struct sdhci_pci_chip *chip)
|
||||
|
||||
err_pci_runtime_suspend:
|
||||
while (--i >= 0)
|
||||
sdhci_runtime_resume_host(chip->slots[i]->host);
|
||||
sdhci_runtime_resume_host(chip->slots[i]->host, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ static int sdhci_pci_runtime_resume_host(struct sdhci_pci_chip *chip)
|
||||
if (!slot)
|
||||
continue;
|
||||
|
||||
ret = sdhci_runtime_resume_host(slot->host);
|
||||
ret = sdhci_runtime_resume_host(slot->host, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -554,7 +554,7 @@ static int sdhci_pxav3_runtime_resume(struct device *dev)
|
||||
if (!IS_ERR(pxa->clk_core))
|
||||
clk_prepare_enable(pxa->clk_core);
|
||||
|
||||
return sdhci_runtime_resume_host(host);
|
||||
return sdhci_runtime_resume_host(host, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -745,7 +745,7 @@ static int sdhci_s3c_runtime_resume(struct device *dev)
|
||||
clk_prepare_enable(busclk);
|
||||
if (ourhost->cur_clk >= 0)
|
||||
clk_prepare_enable(ourhost->clk_bus[ourhost->cur_clk]);
|
||||
ret = sdhci_runtime_resume_host(host);
|
||||
ret = sdhci_runtime_resume_host(host, 0);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -497,7 +497,7 @@ static int sdhci_sprd_runtime_resume(struct device *dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
sdhci_runtime_resume_host(host);
|
||||
sdhci_runtime_resume_host(host, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -638,7 +638,7 @@ static int xenon_runtime_resume(struct device *dev)
|
||||
priv->restore_needed = false;
|
||||
}
|
||||
|
||||
ret = sdhci_runtime_resume_host(host);
|
||||
ret = sdhci_runtime_resume_host(host, 0);
|
||||
if (ret)
|
||||
goto out;
|
||||
return 0;
|
||||
|
||||
@@ -3320,7 +3320,7 @@ int sdhci_runtime_suspend_host(struct sdhci_host *host)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sdhci_runtime_suspend_host);
|
||||
|
||||
int sdhci_runtime_resume_host(struct sdhci_host *host)
|
||||
int sdhci_runtime_resume_host(struct sdhci_host *host, int soft_reset)
|
||||
{
|
||||
struct mmc_host *mmc = host->mmc;
|
||||
unsigned long flags;
|
||||
@@ -3331,7 +3331,7 @@ int sdhci_runtime_resume_host(struct sdhci_host *host)
|
||||
host->ops->enable_dma(host);
|
||||
}
|
||||
|
||||
sdhci_init(host, 0);
|
||||
sdhci_init(host, soft_reset);
|
||||
|
||||
if (mmc->ios.power_mode != MMC_POWER_UNDEFINED &&
|
||||
mmc->ios.power_mode != MMC_POWER_OFF) {
|
||||
|
||||
@@ -781,7 +781,7 @@ void sdhci_adma_write_desc(struct sdhci_host *host, void **desc,
|
||||
int sdhci_suspend_host(struct sdhci_host *host);
|
||||
int sdhci_resume_host(struct sdhci_host *host);
|
||||
int sdhci_runtime_suspend_host(struct sdhci_host *host);
|
||||
int sdhci_runtime_resume_host(struct sdhci_host *host);
|
||||
int sdhci_runtime_resume_host(struct sdhci_host *host, int soft_reset);
|
||||
#endif
|
||||
|
||||
void sdhci_cqe_enable(struct mmc_host *mmc);
|
||||
|
||||
Reference in New Issue
Block a user