summaryrefslogtreecommitdiff
path: root/drivers/mmc/host/sdhci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host/sdhci.c')
-rwxr-xr-xdrivers/mmc/host/sdhci.c68
1 files changed, 37 insertions, 31 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 29e9b154a84a..50904b60cc61 100755
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -94,7 +94,7 @@ static void sdhci_enable_clk(struct sdhci_host *host)
static void sdhci_disable_clk(struct sdhci_host *host, int delay)
{
- if (host->clk_mgr_en && sdhci_can_gate_clk(host)) {
+ if (host->clk_mgr_en) {
if (delay == 0 && !in_interrupt()) {
if (host->ops->platform_clk_ctrl && host->clk_status)
host->ops->platform_clk_ctrl(host, false);
@@ -308,7 +308,8 @@ static void sdhci_led_control(struct led_classdev *led,
sdhci_activate_led(host);
spin_unlock_irqrestore(&host->lock, flags);
- sdhci_disable_clk(host, CLK_TIMEOUT);
+ if (!sdhci_is_sdio_attached(host))
+ sdhci_disable_clk(host, CLK_TIMEOUT);
}
#endif
@@ -1255,7 +1256,7 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
* *
\*****************************************************************************/
-static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
+void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
{
struct sdhci_host *host;
bool present;
@@ -1340,18 +1341,6 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
if (host->flags & SDHCI_DEVICE_DEAD)
goto out;
- if (ios->finish_tuning_flag) {
- if (host->ops->post_tuning)
- host->ops->post_tuning(host);
- goto out;
- }
-
- if (ios->tuning_flag) {
- /* means this request is for tuning only */
- if (host->ops->pre_tuning)
- host->ops->pre_tuning(host, ios->tuning);
- goto out;
- }
/*
* Reset the chip on each power off.
* Should clear out any weird states.
@@ -1412,8 +1401,7 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
if ((ios->timing == MMC_TIMING_UHS_SDR50) ||
(ios->timing == MMC_TIMING_UHS_SDR104) ||
(ios->timing == MMC_TIMING_UHS_DDR50) ||
- (ios->timing == MMC_TIMING_UHS_SDR25) ||
- (ios->timing == MMC_TIMING_UHS_SDR12))
+ (ios->timing == MMC_TIMING_UHS_SDR25))
ctrl |= SDHCI_CTRL_HISPD;
ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
@@ -1488,7 +1476,7 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
* signalling timeout and CRC errors even on CMD0. Resetting
* it on each ios seems to solve the problem.
*/
- if(host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS)
+ if (host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS)
sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
out:
@@ -1516,7 +1504,8 @@ static int check_ro(struct sdhci_host *host)
& SDHCI_WRITE_PROTECT);
spin_unlock_irqrestore(&host->lock, flags);
- sdhci_disable_clk(host, CLK_TIMEOUT);
+ if (!sdhci_is_sdio_attached(host))
+ sdhci_disable_clk(host, CLK_TIMEOUT);
/* This quirk needs to be replaced by a callback-function later */
return host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT ?
@@ -1702,6 +1691,14 @@ static int sdhci_execute_tuning(struct mmc_host *mmc)
return 0;
}
+ if (ctrl & SDHCI_CTRL_EXEC_TUNING) {
+ if (host->ops->platform_execute_tuning) {
+ spin_unlock(&host->lock);
+ enable_irq(host->irq);
+ return host->ops->platform_execute_tuning(host);
+ }
+ }
+
sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
/*
@@ -2053,7 +2050,8 @@ static void sdhci_tasklet_finish(unsigned long param)
mmiowb();
spin_unlock_irqrestore(&host->lock, flags);
- sdhci_disable_clk(host, CLK_TIMEOUT);
+ if (!sdhci_is_sdio_attached(host))
+ sdhci_disable_clk(host, CLK_TIMEOUT);
mmc_request_done(host->mmc, mrq);
}
@@ -2381,9 +2379,8 @@ int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state)
/* Disable tuning since we are suspending */
if (host->version >= SDHCI_SPEC_300 && host->tuning_count &&
host->tuning_mode == SDHCI_TUNING_MODE_1) {
+ del_timer_sync(&host->tuning_timer);
host->flags &= ~SDHCI_NEEDS_RETUNING;
- mod_timer(&host->tuning_timer, jiffies +
- host->tuning_count * HZ);
}
ret = mmc_suspend_host(host->mmc);
@@ -2400,7 +2397,8 @@ out:
* mmc_suspend_host may disable the clk
*/
sdhci_enable_clk(host);
- sdhci_disable_clk(host, 0);
+ if (!sdhci_is_sdio_attached(host))
+ sdhci_disable_clk(host, 0);
return ret;
}
@@ -2438,7 +2436,8 @@ int sdhci_resume_host(struct sdhci_host *host)
out:
/* sync worker */
- sdhci_disable_clk(host, 0);
+ if (!sdhci_is_sdio_attached(host))
+ sdhci_disable_clk(host, 0);
/* Set the re-tuning expiration flag */
if ((host->version >= SDHCI_SPEC_300) && host->tuning_count &&
@@ -2458,7 +2457,8 @@ void sdhci_enable_irq_wakeups(struct sdhci_host *host)
val = sdhci_readb(host, SDHCI_WAKE_UP_CONTROL);
val |= SDHCI_WAKE_ON_INT;
sdhci_writeb(host, val, SDHCI_WAKE_UP_CONTROL);
- sdhci_disable_clk(host, CLK_TIMEOUT);
+ if (!sdhci_is_sdio_attached(host))
+ sdhci_disable_clk(host, CLK_TIMEOUT);
}
EXPORT_SYMBOL_GPL(sdhci_enable_irq_wakeups);
@@ -2606,7 +2606,8 @@ int sdhci_add_host(struct sdhci_host *host)
printk(KERN_ERR
"%s: Hardware doesn't specify base clock "
"frequency.\n", mmc_hostname(mmc));
- sdhci_disable_clk(host, 0);
+ if (!sdhci_is_sdio_attached(host))
+ sdhci_disable_clk(host, 0);
return -ENODEV;
}
host->max_clk = host->ops->get_max_clock(host);
@@ -2622,7 +2623,8 @@ int sdhci_add_host(struct sdhci_host *host)
printk(KERN_ERR
"%s: Hardware doesn't specify timeout clock "
"frequency.\n", mmc_hostname(mmc));
- sdhci_disable_clk(host, 0);
+ if (!sdhci_is_sdio_attached(host))
+ sdhci_disable_clk(host, 0);
return -ENODEV;
}
}
@@ -2810,7 +2812,8 @@ int sdhci_add_host(struct sdhci_host *host)
if (mmc->ocr_avail == 0) {
printk(KERN_ERR "%s: Hardware doesn't report any "
"support voltages.\n", mmc_hostname(mmc));
- sdhci_disable_clk(host, 0);
+ if (!sdhci_is_sdio_attached(host))
+ sdhci_disable_clk(host, 0);
return -ENODEV;
}
@@ -2934,7 +2937,8 @@ int sdhci_add_host(struct sdhci_host *host)
(host->flags & SDHCI_USE_SDMA) ? "DMA" : "PIO");
sdhci_enable_card_detection(host);
- sdhci_disable_clk(host, CLK_TIMEOUT);
+ if (!sdhci_is_sdio_attached(host))
+ sdhci_disable_clk(host, CLK_TIMEOUT);
return 0;
#ifdef CONFIG_SDHCI_USE_LEDS_CLASS
@@ -2945,7 +2949,8 @@ reset:
untasklet:
tasklet_kill(&host->card_tasklet);
tasklet_kill(&host->finish_tasklet);
- sdhci_disable_clk(host, 0);
+ if (!sdhci_is_sdio_attached(host))
+ sdhci_disable_clk(host, 0);
return ret;
}
@@ -2985,7 +2990,8 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
sdhci_enable_clk(host);
if (!dead)
sdhci_reset(host, SDHCI_RESET_ALL);
- sdhci_disable_clk(host, 0);
+ if (!sdhci_is_sdio_attached(host))
+ sdhci_disable_clk(host, 0);
free_irq(host->irq, host);