aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2014-04-25 13:00:12 +0100
committerChris Ball <chris@printf.net>2014-05-22 08:33:30 -0400
commitda91a8f9c0f56d75b35bfe2e2456187ab55b3639 (patch)
tree0b1eb88167d37461dc1d9aa56919f715e61095b1 /drivers/mmc
parentmmc: sdhci: move remaining power handling into sdhci_set_power() (diff)
downloadlinux-dev-da91a8f9c0f56d75b35bfe2e2456187ab55b3639.tar.xz
linux-dev-da91a8f9c0f56d75b35bfe2e2456187ab55b3639.zip
mmc: sdhci: track whether preset mode is currently enabled in hardware
Track whether preset mode is currently enabled in hardware, and use that when making decisions elsewhere in the code rather than reading the register and checking the bit. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Tested-by: Markus Pargmann <mpa@pengutronix.de> Tested-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Chris Ball <chris@printf.net>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/sdhci.c44
1 files changed, 26 insertions, 18 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index effd9e5d1d81..447eef8217c7 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -205,9 +205,14 @@ static void sdhci_do_reset(struct sdhci_host *host, u8 mask)
host->ops->reset(host, mask);
- if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
- if ((host->ops->enable_dma) && (mask & SDHCI_RESET_ALL))
- host->ops->enable_dma(host);
+ if (mask & SDHCI_RESET_ALL) {
+ if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
+ if (host->ops->enable_dma)
+ host->ops->enable_dma(host);
+ }
+
+ /* Resetting the controller clears many */
+ host->preset_enabled = false;
}
}
@@ -1126,8 +1131,7 @@ void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
return;
if (host->version >= SDHCI_SPEC_300) {
- if (sdhci_readw(host, SDHCI_HOST_CONTROL2) &
- SDHCI_CTRL_PRESET_VAL_ENABLE) {
+ if (host->preset_enabled) {
u16 pre_val;
clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
@@ -1493,13 +1497,13 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
(ios->timing == MMC_TIMING_UHS_SDR25))
ctrl |= SDHCI_CTRL_HISPD;
- ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
- if (!(ctrl_2 & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
+ if (!host->preset_enabled) {
sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
/*
* We only need to set Driver Strength if the
* preset value enable is not set.
*/
+ ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
ctrl_2 &= ~SDHCI_CTRL_DRV_TYPE_MASK;
if (ios->drv_type == MMC_SET_DRIVER_TYPE_A)
ctrl_2 |= SDHCI_CTRL_DRV_TYPE_A;
@@ -2018,26 +2022,30 @@ out:
static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable)
{
- u16 ctrl;
-
/* Host Controller v3.00 defines preset value registers */
if (host->version < SDHCI_SPEC_300)
return;
- ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
-
/*
* We only enable or disable Preset Value if they are not already
* enabled or disabled respectively. Otherwise, we bail out.
*/
- if (enable && !(ctrl & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
- ctrl |= SDHCI_CTRL_PRESET_VAL_ENABLE;
- sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
- host->flags |= SDHCI_PV_ENABLED;
- } else if (!enable && (ctrl & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
- ctrl &= ~SDHCI_CTRL_PRESET_VAL_ENABLE;
+ if (host->preset_enabled != enable) {
+ u16 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+
+ if (enable)
+ ctrl |= SDHCI_CTRL_PRESET_VAL_ENABLE;
+ else
+ ctrl &= ~SDHCI_CTRL_PRESET_VAL_ENABLE;
+
sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
- host->flags &= ~SDHCI_PV_ENABLED;
+
+ if (enable)
+ host->flags |= SDHCI_PV_ENABLED;
+ else
+ host->flags &= ~SDHCI_PV_ENABLED;
+
+ host->preset_enabled = enable;
}
}