diff options
Diffstat (limited to 'drivers/mmc/host/sdhci.c')
-rwxr-xr-x | drivers/mmc/host/sdhci.c | 68 |
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); |